[LLVMdev] [RFC] NoBuiltin Attribute

Chris Lattner clattner at apple.com
Tue Feb 19 10:23:46 PST 2013


On Feb 19, 2013, at 6:50 AM, Krzysztof Parzyszek <kparzysz at codeaurora.org> wrote:

> On 2/18/2013 8:08 PM, Chris Lattner wrote:
>> 
>> That code is presumably compiled by someone.  If whoever compiles it specifies -fno-builtin, the attribute would be added to it.  It doesn't affect its clients.
> 
> After reading the description quoted by Bill, I'm not sure what you mean by attaching the attribute to the function body.  Suppose I have my own version of strlen, written in whatever language and present in an .o file, and a function foo in C which calls strlen, which is compiled with clang.  It makes sense to put the "nobuiltin" attribute on the prototype of "strlen", since this way all the callers of the strlen would know what they are dealing with.

I think that there is general confusion here about what -fno-builtin does.  It is *not* an attribute that affects the definition of builtin functions, it is a statement that the code being compiled in the current translation unit should change behavior.

Consider two translation units, A.c and B.c:


--- A.c, compiled with -fno-builtin-puts
void foo() {
  printf("hello world\n");
}

--- B.c, compiled *without* -fno-builtin.

void bar() {
  printf("goodbye world\n");
}


After LTO, we need to know that it is safe to optimize goodbye world into a call to puts, even though: 1) there is no prototype at all in the IR for puts, 2) two different functions (foo and bar) have different builtin-optimization-allowedness.

There are only two correct ways to model this: 1) an IR attribute on the function *bodies* being compiled in a translation unit, or 2) as an IR attribute on each *call* in the code being compiled in a translation unit.

If we want to be pedantically correct, #2 is really the right way to go, because then differences in this attribute would not affect inlining.  For example, if we had:

--- C.c
void x() {
  foo();
  bar();
}

Then we should be able to inline both calls to printf into x(), then know that only one could be optimized.

-Chris





More information about the llvm-dev mailing list