<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>                     Module-Level Attributes</div><div><br></div><div><br></div><div>Overview</div><div>--------</div><div><br></div><div>LLVM currently lacks the ability to specify an attribute on a module as a</div><div>whole. This isn't typically a problem as most optimizations and code</div><div>transformations rely upon more finer-grained information, such as function</div><div>attributes. However, some transformations, in particular LTO, may need to know</div><div>information about the module. As a side-benefit, it could be used to reduce the</div><div>number of global variables which are currently used only to convey information</div><div>to the back-end, linker, et al.</div><div><br></div><div>Proposal</div><div>--------</div><div><br></div><div>Syntax:</div><div><br></div><div>   ml-attr ::= 'module' 'attr' NAME ('[' NAME (',' NAME)* ']')?</div><div><br></div><div>where the optional list of NAMEs in the square brackets represents sub-attributes</div><div>of the main attribute.</div><div><br></div><div>Semantics:</div><div><br></div><div>Module-level attributes are looked at only by those parts of the compiler which</div><div>care about them. Deleting a module attribute may effect code generation. Each module-</div><div>level attribute will have its own documented semantics for how it may be used.</div><div><br></div><div>Example:</div><div><br></div><div>The Objective-C imageinfo section isn't merged correctly for the following.</div><div><br></div><div>t.mm:</div><div>#import <Foundation/Foundation.h></div><div><br></div><div>NSAutoreleasePool *foo();</div><div><br></div><div>int main() {</div><div>  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];</div><div>  NSAutoreleasePool *pond = foo();</div><div>  return 0;</div><div>}</div><div><br></div><div>f.mm:</div><div>#import <Foundation/Foundation.h></div><div><br></div><div>NSAutoreleasePool *foo() {</div><div>  return [[NSAutoreleasePool alloc] init];</div><div>}</div><div><br></div><div>$ llvm-g++ -fobjc-gc t.mm -c -flto</div><div>$ llvm-g++ -fno-objc-gc f.mm -c -flto</div><div>$ llvm-g++ t.o f.o -flto -framework Foundation</div><div>ld: warning: section __DATA/__objc_imageinfo__DATA has unexpectedly large size 16 in /tmp/lto.o</div><div>$</div><div><br></div><div>In this example, LTO is concatenating the imageinfo sections instead of</div><div>performing a proper merge.</div><div><br></div><div>Here are the LLVM global variables that contain the imageinfo information.</div><div><br></div><div>-fno-objc-gc:</div><div>@OBJC_IMAGE_INFO = private constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"</div><div><br></div><div>-fobjc-gc-only:</div><div>@OBJC_IMAGE_INFO = private constant [2 x i32] [i32 0, i32 22], section "__DATA, __objc_imageinfo, regular, no_dead_strip"</div><div><br></div><div>With module-level attributes, these global variables wouldn't exist. Instead,</div><div>they would be replaced by something like this:</div><div><br></div><div>-fno-objc-gc:</div><div>module attr ImageInfo [CorrectedSynthesize]</div><div><br></div><div>-fobjc-gc-only:</div><div>module attr ImageInfo [CorrectedSynthesize, GCOnly]</div><div><br></div><div>LTO would see that the module attributes are incompatible and will reject trying</div><div>to link the two modules.</div><div><br></div><div>Comments?</div><div><br></div><div>-bw</div><div><br></div></body></html>