This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Force attribute used on functions marked as always_inline.
AbandonedPublic

Authored by davide on Jan 10 2019, 3:56 PM.

Details

Summary

If the functions are always inlined, the compiler is not forced
to emit their body, so the debugger can't evaluate them.

e.g.

$1 = (StringRef) "patatino"
(lldb) expr $1.size()
error: Couldn't lookup symbols:

attribute((used)) forces the symbols to be emitted even if
they're not referenced. An alternatve proposed was that of
dropping always_inline entirely from LLVM, as it should be
used exclusively where not inlining a function causes correctness
issues. Some concerns have been raised about tblgen being too
slow without the annotations.

Event Timeline

davide created this revision.Jan 10 2019, 3:56 PM
dexonsmith added inline comments.Jan 10 2019, 4:04 PM
llvm/include/llvm/ADT/SmallVector.h
128

I don't think we want this for Release or RelWithDebInfo builds since it will bloat the binaries. How is LLVM_ATTRIBUTE_USED conditionalized in those cases?

llvm/include/llvm/ADT/StringRef.h
127

This already has LLVM_NODISCARD. How does that differ from LLVM_ATTRIBUTE_USED?

davide marked 2 inline comments as done.Jan 10 2019, 4:42 PM
davide added inline comments.
llvm/include/llvm/ADT/SmallVector.h
128

Thanks, I agree this should be emitted only at -O0.
Is there an easy way of conveying that information?

llvm/include/llvm/ADT/StringRef.h
127

They're completely different attributes, to the best of my knowledge.

  1. attribute((used)) forces the symbol to be emitted even if unreferenced.

http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Variable-Attributes.html

  1. [[nodiscard]] causes the compiler to emit a warning if the return value is discarded.

https://en.cppreference.com/w/cpp/language/attributes

Example:

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000fa3 a.out`main at pat.cpp:12:3
   9   	
   10  	int main(void) {
   11  	  Baciotto blondie;
-> 12  	  return blondie.patatino();
   13  	}
(lldb) p blondie
(Baciotto) $0 = {}
(lldb) p blondie.patatino()
(int) $1 = 23
(lldb) ^D
Davides-Mac-Pro:bin davide$ cat pat.cpp 
class Baciotto {
public:
  __attribute__((used))
  __attribute__((always_inline))
  int patatino() {
    return 23;
  }
};

int main(void) {
  Baciotto blondie;
  return blondie.patatino();
}

If you use [[nodiscard]], the symbol won't be emitted.

I honestly still think this is a poor alternative. I much prefer optimized tablegen if it matters. I'd much prefer defaulting to that in non-release builds as well. I think we should be using fewer attributes to manually hijack the optimizer and instead simply let the optimizer do its job when it is needed. =/

What about creating a new macrothat carry the semantic we're looking for here: "LLVM_KEEP_FOR_DEBUG"?
We can conditionally define it based on NDEBUG or add a CMake flag for it that is enabled in debug build (the latter has the advantage that it would allow to turn it on even in release builds when needing to debug these)

I honestly still think this is a poor alternative. I much prefer optimized tablegen if it matters. I'd much prefer defaulting to that in non-release builds as well. I think we should be using fewer attributes to manually hijack the optimizer and instead simply let the optimizer do its job when it is needed. =/

There's no optimizer here as this is, by definition, unoptimized code.
I tend to share your feelings here about the fact that slapping bajillion attributes on functions isn't great.
I don't have any strong preferences (I just care about evaluating expression in the debugger :), I'm just mostly worried that the slowdown might be unacceptable for people. But I assume we can always re-evaluate this later.

What about creating a new macrothat carry the semantic we're looking for here: "LLVM_KEEP_FOR_DEBUG"?
We can conditionally define it based on NDEBUG or add a CMake flag for it that is enabled in debug build (the latter has the advantage that it would allow to turn it on even in release builds when needing to debug these)

In case we decide to go this route, I guess something like this will do.

How big is the slowdown?

davide abandoned this revision.Jan 22 2019, 1:44 PM

Decided to go with a different approach.