Hi Reid, all,
+llvm-dev as this RFC involves changes in Clang and LLVM.
This RFC has stagnated and I think that’s partially because the proposal isn’t particularly elegant and is light on details. We’ve been having a rethink and have a slightly different implementation to propose that we (I) hope will be nicer.
** Rationale (for llvm-dev) **
The goal of this proposed feature is to provide a migration path toward Clang for developers in the automotive domain. As Javed has mentioned, AUTOSAR, an automotive standard, mandates the use of a #pragma in header files to determine in which sections initialized and uninitialized data get put.
This feature is implemented in our legacy ARM Compiler 5 toolchain and we’re also aware of GCC forks used across the automotive space that have this feature implemented compatible with the ARM Compiler 5 implementation.
The documentation is here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124985290.html
** Proposed syntax and (vague) semantics **
As this is a new pragma for Clang and isn’t ARM-specific, we’ve invented a less ARM-specific syntax. Bikeshedding is expected and welcome.
#pragma clang section bss(".mybss") rodata(".myrodata") data(".mydata") text(".mytext")
The pragma applies to all global variable and function declarations from the pragma to the end of the translation unit. The pragma should ideally be pushable and poppable, but that is outside the scope of this RFC. The pragma also applies to static local declarations within functions.
All global variables and functions affected by this pragma have their default ELF section destinations changed. Globals with attribute((section())) are not affected (the attribute trumps the pragma).
This pragma is only defined to work sensibly for ELF targets.
** Proposed implementation **
There are, I believe, three possible implementation stategies:
- Clang internally sets the “section” on all globals it creates. No changes in LLVM.
- Clang sets some module-level attribute describing the default section names. The LLVM backend takes this into account when deciding the section name for a global when it emits it (AsmPrinter).
- Clang sets the default section names as attributes on all globals. The LLVM backend takes this into account when deciding the section name for a global when it emits it (AsmPrinter).
(1) and (3) work with LTO. (2) interacts badly with LTO so is discounted.
(1) requires Clang to perform the decision into exactly what section a global will go, which is the wrong place for several previously mentioned reasons (midend optimizations could promote .data → .bss, clang currently doesn’t have the mechanics to test if an initializer is zero or not, LLVM does).
(2) and (3) have the advantage that the section type does not need to be inferred by LLVM from its name. This means we don’t need the horrible string matching (m/^.bss./ → BSS, m/^.data./ → Data, etc) in the AsmPrinter - users can specify whatever names they like for bss sections without confusing the compiler.
Our previous proposal was (1). We are now proposing (3).
For (3), I think there are three distinct steps, none of which are particularly invasive:
a) Allow arbitrary attributes on GlobalVariables. Currently these are restricted to Functions only; I believe mainly because noone had a usecase for attributes on variables.
b) Teach the clang frontend about the new pragma and CodeGen to add the attributes to globals
c) Teach AsmPrinter to inspect these attributes if they exist and take them into account when choosing sections.
All comments more than welcome,
James