summaryrefslogtreecommitdiffstats
path: root/llvm/tools/lto/LTOCodeGenerator.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-03-02 04:14:42 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-03-02 04:14:42 +0000
commit1e49a6d9bc3db451941b021f77a7c3551648bc58 (patch)
tree56598694cbd950c66efc61bf8b1bbaa0a5ce76f8 /llvm/tools/lto/LTOCodeGenerator.cpp
parentdaed6f6c39f163ce83bf049fd625c1d8e3233348 (diff)
downloadbcm5719-llvm-1e49a6d9bc3db451941b021f77a7c3551648bc58.tar.gz
bcm5719-llvm-1e49a6d9bc3db451941b021f77a7c3551648bc58.zip
Add a special streamer to libLTO that just records symbols definitions and
uses. The result produced by the streamer is used to give the linker more accurate information and to add to llvm.compiler.used. The second improvement removes the need for the user to add __attribute__((used)) to functions only used in inline asm. The first one lets us build firefox with LTO on Darwin :-) llvm-svn: 126830
Diffstat (limited to 'llvm/tools/lto/LTOCodeGenerator.cpp')
-rw-r--r--llvm/tools/lto/LTOCodeGenerator.cpp108
1 files changed, 75 insertions, 33 deletions
diff --git a/llvm/tools/lto/LTOCodeGenerator.cpp b/llvm/tools/lto/LTOCodeGenerator.cpp
index f72fdb0fca9..6739e067674 100644
--- a/llvm/tools/lto/LTOCodeGenerator.cpp
+++ b/llvm/tools/lto/LTOCodeGenerator.cpp
@@ -75,7 +75,6 @@ LTOCodeGenerator::LTOCodeGenerator()
{
InitializeAllTargets();
InitializeAllAsmPrinters();
- InitializeAllAsmParsers();
}
LTOCodeGenerator::~LTOCodeGenerator()
@@ -88,7 +87,13 @@ LTOCodeGenerator::~LTOCodeGenerator()
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
{
- return _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
+ bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
+
+ const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
+ for (int i = 0, e = undefs.size(); i != e; ++i)
+ _asmUndefinedRefs[undefs[i]] = 1;
+
+ return ret;
}
@@ -249,6 +254,34 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg)
return false;
}
+void LTOCodeGenerator::applyRestriction(GlobalValue &GV,
+ std::vector<const char*> &mustPreserveList,
+ SmallPtrSet<GlobalValue*, 8> &asmUsed,
+ Mangler &mangler) {
+ SmallString<64> Buffer;
+ mangler.getNameWithPrefix(Buffer, &GV, false);
+
+ if (GV.isDeclaration())
+ return;
+ if (_mustPreserveSymbols.count(Buffer))
+ mustPreserveList.push_back(GV.getName().data());
+ if (_asmUndefinedRefs.count(Buffer))
+ asmUsed.insert(&GV);
+}
+
+static void findUsedValues(GlobalVariable *LLVMUsed,
+ SmallPtrSet<GlobalValue*, 8> &UsedValues) {
+ if (LLVMUsed == 0) return;
+
+ 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);
+}
+
void LTOCodeGenerator::applyScopeRestrictions() {
if (_scopeRestrictionsDone) return;
Module *mergedModule = _linker.getModule();
@@ -258,38 +291,47 @@ void LTOCodeGenerator::applyScopeRestrictions() {
passes.add(createVerifierPass());
// mark which symbols can not be internalized
- if (!_mustPreserveSymbols.empty()) {
- MCContext Context(*_target->getMCAsmInfo(), NULL);
- Mangler mangler(Context, *_target->getTargetData());
- std::vector<const char*> mustPreserveList;
- SmallString<64> Buffer;
- for (Module::iterator f = mergedModule->begin(),
- e = mergedModule->end(); f != e; ++f) {
- Buffer.clear();
- mangler.getNameWithPrefix(Buffer, f, false);
- if (!f->isDeclaration() &&
- _mustPreserveSymbols.count(Buffer))
- mustPreserveList.push_back(f->getName().data());
- }
- for (Module::global_iterator v = mergedModule->global_begin(),
- e = mergedModule->global_end(); v != e; ++v) {
- Buffer.clear();
- mangler.getNameWithPrefix(Buffer, v, false);
- if (!v->isDeclaration() &&
- _mustPreserveSymbols.count(Buffer))
- mustPreserveList.push_back(v->getName().data());
- }
- for (Module::alias_iterator a = mergedModule->alias_begin(),
- e = mergedModule->alias_end(); a != e; ++a) {
- Buffer.clear();
- mangler.getNameWithPrefix(Buffer, a, false);
- if (!a->isDeclaration() &&
- _mustPreserveSymbols.count(Buffer))
- mustPreserveList.push_back(a->getName().data());
- }
- passes.add(createInternalizePass(mustPreserveList));
+ MCContext Context(*_target->getMCAsmInfo(), NULL);
+ Mangler mangler(Context, *_target->getTargetData());
+ std::vector<const char*> mustPreserveList;
+ SmallPtrSet<GlobalValue*, 8> asmUsed;
+
+ for (Module::iterator f = mergedModule->begin(),
+ e = mergedModule->end(); f != e; ++f)
+ applyRestriction(*f, mustPreserveList, asmUsed, mangler);
+ for (Module::global_iterator v = mergedModule->global_begin(),
+ e = mergedModule->global_end(); v != e; ++v)
+ applyRestriction(*v, mustPreserveList, asmUsed, mangler);
+ for (Module::alias_iterator a = mergedModule->alias_begin(),
+ e = mergedModule->alias_end(); a != e; ++a)
+ applyRestriction(*a, mustPreserveList, asmUsed, mangler);
+
+ GlobalVariable *LLVMCompilerUsed =
+ mergedModule->getGlobalVariable("llvm.compiler.used");
+ findUsedValues(LLVMCompilerUsed, asmUsed);
+ if (LLVMCompilerUsed)
+ LLVMCompilerUsed->eraseFromParent();
+
+ const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
+ std::vector<Constant*> asmUsed2;
+ for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(),
+ e = asmUsed.end(); i !=e; ++i) {
+ GlobalValue *GV = *i;
+ Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
+ asmUsed2.push_back(c);
}
-
+
+ llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
+ LLVMCompilerUsed =
+ new llvm::GlobalVariable(*mergedModule, ATy, false,
+ llvm::GlobalValue::AppendingLinkage,
+ llvm::ConstantArray::get(ATy, asmUsed2),
+ "llvm.compiler.used");
+
+ LLVMCompilerUsed->setSection("llvm.metadata");
+
+ passes.add(createInternalizePass(mustPreserveList));
+
// apply scope restrictions
passes.run(*mergedModule);
OpenPOWER on IntegriCloud