diff options
Diffstat (limited to 'tools/lto/LTOCodeGenerator.cpp')
-rw-r--r-- | tools/lto/LTOCodeGenerator.cpp | 108 |
1 files changed, 75 insertions, 33 deletions
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index f72fdb0fca..6739e06767 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/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); |