This is an archive of the discontinued LLVM Phabricator instance.

[LLVM-C] Add C APIs to access DebugLoc info
ClosedPublic

Authored by jberdine on Sep 17 2018, 6:25 PM.

Details

Summary

Add thin shims to C interface to provide access to DebugLoc info for
Instructions, GlobalVariables and Functions.

Diff Detail

Event Timeline

jberdine created this revision.Sep 17 2018, 6:25 PM
whitequark requested changes to this revision.Sep 17 2018, 6:42 PM

Why are there three sets of functions that all operate on LLVMValueRef? Can't we make it a single set of functions?

All new C API functions that return strings must accept an unsigned *Length parameter.

Since this is a rather nontrivial addition to the C API, I think you should split this into a C patch which I'd like to get a second opinion on, and then a separate OCaml patch.

This revision now requires changes to proceed.Sep 17 2018, 6:42 PM
jberdine updated this revision to Diff 165989.Sep 18 2018, 9:20 AM
jberdine retitled this revision from [LLVM-C][OCaml] Add C and OCaml APIs to access DebugLoc info to [LLVM-C] Add C APIs to access DebugLoc info.
jberdine edited the summary of this revision. (Show Details)

split LLVM-C from OCaml changes

I don't know if this is the idiomatic way to do dynamic dispatch in C, feedback very welcome.

I put these functions after the Metadata ones, but there might be a better place.

@whitequark, did you have someone in mind to look at these LLVM-C changes, or should I do some git blaming?

whitequark added a subscriber: echristo.

@deadalnix, @echristo, any opinion on this C API?

abdulras added inline comments.
lib/IR/Core.cpp
1162

I think that unwrap(Val) should be possible to be hoisted rather than done in each case.

1163

Can't you hoist the unwrap here into the conditional?

if (const auto *I = unwrap<Instruction>(Val))
1164

Please mark the Length parameter as _Nonnull, add an assert, or add a check for Length being non-null here.

1176

I think that this is better with an early return:

if (GVEs.size() == 0) {
  *Length = 0;
  return nullptr;
}
StringRef S = GVEs[0]->getVariable()->getDirectory();
*Length = S.size();
return S.data();
1186

Similar with an early return.

1188

This is going to get "optimized" away in NDEBUG builds. If you hoist the S out of the cases, and sink the Length assignment and return, you at least get predictable behaviour.

1219

Similar behavioural changes as above.

1234

Similar behavioural changes.

1237–1240

Why not:

if (const auto *I = unwrap<Instruction>(Val))
  if (const auto &L = I->getDebugLoc())
    return L->getColumn();
return 0;
hiraditya added inline comments.
lib/IR/Core.cpp
1188

This assert will not trigger in a release build. Is there a better way to handle this?

1218

Same as above

hiraditya added inline comments.Sep 24 2018, 8:15 AM
lib/IR/Core.cpp
1170

getVariable can return nullptr

jberdine updated this revision to Diff 166793.Sep 24 2018, 5:44 PM

Suggested changes to LLVMGetDebugLocDirectory and LLVMGetDebugLocColumn, will update LLVMGetDebugLocFilename and LLVMGetDebugLocLine when LLVMGetDebugLocDirectory settles

jberdine marked 6 inline comments as done.Sep 24 2018, 5:53 PM
jberdine added inline comments.
lib/IR/Core.cpp
1162

Can further hoisting be done now?

1164

I added an assert above instead of _Nonnull since this is expected to be called from outside, where an attribute is less likely to be checkable.

1188

Do you expect the current version to be so "optimized"? (I'm not positive I grokked what you had in mind with 'sink the Length assignment and return'.)

jberdine marked an inline comment as done.Sep 24 2018, 5:55 PM
compnerd requested changes to this revision.Sep 25 2018, 10:33 AM
compnerd added a subscriber: compnerd.
compnerd added inline comments.
lib/IR/Core.cpp
1162

Not sure I understand the comment about _Nonnull not being able to check-able.

1169

The use of the goto is unnecessary. Just do:

if (GVEs.Size())
  if (const DIGlobalVariable *DGV = GVEs[0]->getVariable())
    S = DGV->getDirectory();
1176

The goto is unnecesary. Just do:

if (const DISubprogram *DSP = F->getSubprogram())
  S = DSP->getDirectory();
1188

Yes, it isn't unheard of for builds to be done without asserts enabled, so that is a valid concern.

1215

I think that this can be rewritten similar to the function above.

1230

I think that it makes sense to use the same pattern with the conditional assignments.

This revision now requires changes to proceed.Sep 25 2018, 10:33 AM
hiraditya added inline comments.Sep 25 2018, 2:12 PM
lib/IR/Core.cpp
1225

GVEs[0]->getVariable() can return nullptr.

jberdine updated this revision to Diff 168720.Oct 8 2018, 3:47 PM
jberdine marked 9 inline comments as done.

Rely on default initialization of StringRef, and use conditional assignment instead of early return.

lib/IR/Core.cpp
1162

This is an entry point that gets called from other language bindings via their foreign function interfaces, which are unlikely to check _Nonnull, or even be able to "see" it since they are essentially written against the ABI.

compnerd added inline comments.Oct 9 2018, 4:43 PM
lib/IR/Core.cpp
1162

The _Nonnull is a hint to the compiler that the value is non-null. When building that against a header that declares it, the compiler should ensure that the value being passed is non-null. The problem is that the assertion can be compiled out (-DNDEBUG). Maybe change this to a if (!Length) return nullptr?

1176

Add a return nullptr. The assertion can be compiled out.

1183

Same as above, either annotate with _Nonnull or change this to an early return.

1197

Same as above, add a return nullptr.

1204

Please change this to unsigned to match the return type of DebugLoc::getLine.

1217

Please add a return -1 here since the assert can be compiled out.

1223

Please change this to an unsigned to match the return type of DebugLoc::getColumn.

jberdine updated this revision to Diff 168921.Oct 9 2018, 5:37 PM
jberdine marked 6 inline comments as done.

early return instead of assert, unsigned instead of int

jberdine marked an inline comment as done.Oct 9 2018, 5:37 PM
compnerd accepted this revision.Oct 10 2018, 8:53 AM

This seems reasonable to me. @whitequark, are you okay with them too? To @whitequark's original point, I think that the dispatching the type based on a query is pretty cool (you can do an enumeration + union output), but, I think API-wise, this is safer and easier to work with, not to mention also simplifies the implementation.

whitequark accepted this revision.Oct 10 2018, 12:38 PM

Looks good to me now, thanks @compnerd !

This revision is now accepted and ready to land.Oct 10 2018, 12:38 PM

Thanks for your help and patience! This has certainly improved a lot from the first version I submitted.

Would one of you mind committing this?

jberdine updated this revision to Diff 169101.Oct 10 2018, 2:47 PM

rebase and squash

compnerd closed this revision.Oct 10 2018, 4:55 PM

SVN r344202