forked from OSchip/llvm-project
implement a new magic global "llvm.compiler.used" which is like llvm.used, but
doesn't cause ".no_dead_strip" to be emitted on darwin. llvm-svn: 76399
This commit is contained in:
parent
4e4eb0b00c
commit
58f9bb2ccd
|
@ -94,6 +94,8 @@
|
|||
<li><a href="#intrinsic_globals">Intrinsic Global Variables</a>
|
||||
<ol>
|
||||
<li><a href="#intg_used">The '<tt>llvm.used</tt>' Global Variable</a></li>
|
||||
<li><a href="#intg_compiler_used">The '<tt>llvm.compiler.used</tt>'
|
||||
Global Variable</a></li>
|
||||
<li><a href="#intg_global_ctors">The '<tt>llvm.global_ctors</tt>'
|
||||
Global Variable</a></li>
|
||||
<li><a href="#intg_global_dtors">The '<tt>llvm.global_dtors</tt>'
|
||||
|
@ -2168,8 +2170,9 @@ call void asm sideeffect "eieio", ""()
|
|||
|
||||
<p>LLVM has a number of "magic" global variables that contain data that affect
|
||||
code generation or other IR semantics. These are documented here. All globals
|
||||
of this sort should have a section specified as "llvm.metadata". This section
|
||||
and all globals that start with "llvm." are reserved for LLVM.</p>
|
||||
of this sort should have a section specified as "<tt>llvm.metadata</tt>". This
|
||||
section and all globals that start with "<tt>llvm.</tt>" are reserved for use
|
||||
by LLVM.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
|
@ -2206,6 +2209,24 @@ object file to prevent the assembler and linker from molesting the symbol.</p>
|
|||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="intg_compiler_used">The '<tt>llvm.compiler.used</tt>' Global Variable</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>@llvm.compiler.used</tt> directive is the same as the
|
||||
<tt>@llvm.used</tt> directive, except that it only prevents the compiler from
|
||||
touching the symbol. On targets that support it, this allows an intelligent
|
||||
linker to optimize references to the symbol without being impeded as it would be
|
||||
by <tt>@llvm.used</tt>.</p>
|
||||
|
||||
<p>This is a rare construct that should only be used in rare circumstances, and
|
||||
should not be exposed to source languages.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="intg_global_ctors">The '<tt>llvm.global_ctors</tt>' Global Variable</a>
|
||||
|
|
|
@ -112,8 +112,9 @@ private:
|
|||
// common EH frames.
|
||||
std::vector<Function *> Personalities;
|
||||
|
||||
// UsedFunctions - the functions in the llvm.used list in a more easily
|
||||
// searchable format.
|
||||
/// UsedFunctions - The functions in the @llvm.used list in a more easily
|
||||
/// searchable format. This does not include the functions in
|
||||
/// llvm.compiler.used.
|
||||
SmallPtrSet<const Function *, 32> UsedFunctions;
|
||||
|
||||
/// UsedDbgLabels - labels are used by debug info entries.
|
||||
|
@ -240,9 +241,11 @@ public:
|
|||
return Personalities;
|
||||
}
|
||||
|
||||
// UsedFunctions - Return set of the functions in the llvm.used list.
|
||||
const SmallPtrSet<const Function *, 32>& getUsedFunctions() const {
|
||||
return UsedFunctions;
|
||||
/// isUsedFunction - Return true if the functions in the llvm.used list. This
|
||||
/// does not return true for things in llvm.compiler.used unless they are also
|
||||
/// in llvm.used.
|
||||
bool isUsedFunction(const Function *F) {
|
||||
return UsedFunctions.count(F);
|
||||
}
|
||||
|
||||
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
||||
|
|
|
@ -466,13 +466,13 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
|||
/// special global used by LLVM. If so, emit it and return true, otherwise
|
||||
/// do nothing and return false.
|
||||
bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
|
||||
if (GV->getName() == "llvm.used") {
|
||||
if (GV->isName("llvm.used")) {
|
||||
if (TAI->getUsedDirective() != 0) // No need to emit this at all.
|
||||
EmitLLVMUsedList(GV->getInitializer());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore debug and non-emitted data.
|
||||
// Ignore debug and non-emitted data. This handles llvm.compiler.used.
|
||||
if (GV->getSection() == "llvm.metadata" ||
|
||||
GV->hasAvailableExternallyLinkage())
|
||||
return true;
|
||||
|
|
|
@ -229,7 +229,7 @@ void DwarfException::EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
|
|||
// retains the function in this case, and there is code around that depends
|
||||
// on unused functions (calling undefined externals) being dead-stripped to
|
||||
// link correctly. Yes, there really is.
|
||||
if (MMI->getUsedFunctions().count(EHFrameInfo.function))
|
||||
if (MMI->isUsedFunction(EHFrameInfo.function))
|
||||
if (const char *UsedDirective = TAI->getUsedDirective())
|
||||
O << UsedDirective << EHFrameInfo.FnName << "\n\n";
|
||||
}
|
||||
|
|
|
@ -88,7 +88,8 @@ void MachineModuleInfo::EndFunction() {
|
|||
/// AnalyzeModule - Scan the module for global debug information.
|
||||
///
|
||||
void MachineModuleInfo::AnalyzeModule(Module &M) {
|
||||
// Insert functions in the llvm.used array into UsedFunctions.
|
||||
// Insert functions in the llvm.used array (but not llvm.compiler.used) into
|
||||
// UsedFunctions.
|
||||
GlobalVariable *GV = M.getGlobalVariable("llvm.used");
|
||||
if (!GV || !GV->hasInitializer()) return;
|
||||
|
||||
|
|
|
@ -138,7 +138,9 @@ bool InternalizePass::runOnModule(Module &M) {
|
|||
|
||||
// Never internalize the llvm.used symbol. It is used to implement
|
||||
// attribute((used)).
|
||||
// FIXME: Shouldn't this just filter on llvm.metadata section??
|
||||
ExternalNames.insert("llvm.used");
|
||||
ExternalNames.insert("llvm.compiler.used");
|
||||
|
||||
// Never internalize anchors used by the machine module info, else the info
|
||||
// won't find them. (see MachineModuleInfo.)
|
||||
|
|
|
@ -157,32 +157,26 @@ static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) {
|
|||
}
|
||||
|
||||
/// Find values that are marked as llvm.used.
|
||||
void findUsedValues(Module &M,
|
||||
SmallPtrSet<const GlobalValue*, 8>& llvmUsedValues) {
|
||||
if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) {
|
||||
llvmUsedValues.insert(LLVMUsed);
|
||||
// Collect values that are preserved as per explicit request.
|
||||
// llvm.used is used to list these values.
|
||||
if (ConstantArray *Inits =
|
||||
dyn_cast<ConstantArray>(LLVMUsed->getInitializer())) {
|
||||
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(Inits->getOperand(i)))
|
||||
llvmUsedValues.insert(GV);
|
||||
else if (ConstantExpr *CE =
|
||||
dyn_cast<ConstantExpr>(Inits->getOperand(i)))
|
||||
if (CE->getOpcode() == Instruction::BitCast)
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0)))
|
||||
llvmUsedValues.insert(GV);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void findUsedValues(GlobalVariable *LLVMUsed,
|
||||
SmallPtrSet<const GlobalValue*, 8> &UsedValues) {
|
||||
if (LLVMUsed == 0) return;
|
||||
UsedValues.insert(LLVMUsed);
|
||||
|
||||
ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer());
|
||||
if (Inits == 0) return;
|
||||
|
||||
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
|
||||
if (GlobalValue *GV =
|
||||
dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
|
||||
UsedValues.insert(GV);
|
||||
}
|
||||
|
||||
/// StripSymbolNames - Strip symbol names.
|
||||
bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
|
||||
|
||||
SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
|
||||
findUsedValues(M, llvmUsedValues);
|
||||
findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
|
||||
findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
|
||||
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I) {
|
||||
|
@ -210,7 +204,8 @@ bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
|
|||
bool StripDebugInfo(Module &M) {
|
||||
|
||||
SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
|
||||
findUsedValues(M, llvmUsedValues);
|
||||
findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
|
||||
findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
|
||||
|
||||
SmallVector<GlobalVariable *, 2> CUs;
|
||||
SmallVector<GlobalVariable *, 4> GVs;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep no_dead_strip | count 1
|
||||
; We should have a .no_dead_strip directive for Z but not for X/Y.
|
||||
|
||||
@X = internal global i8 4
|
||||
@Y = internal global i32 123
|
||||
@Z = internal global i8 4
|
||||
|
||||
@llvm.used = appending global [1 x i8*] [ i8* @Z ], section "llvm.metadata"
|
||||
@llvm.compiler_used = appending global [2 x i8*] [ i8* @X, i8* bitcast (i32* @Y to i8*)], section "llvm.metadata"
|
Loading…
Reference in New Issue