summaryrefslogtreecommitdiffstats
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-08-22 06:25:46 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-08-22 06:25:46 +0000
commitdc4c8cf9acbf7d70853b3d876b0c0f3090d46aac (patch)
treeda6598195ad457a40d242ee3719f714ac5d02926 /llvm/lib/LTO/LTO.cpp
parentd310b47c23024a8a9c46d5029984855404598369 (diff)
downloadbcm5719-llvm-dc4c8cf9acbf7d70853b3d876b0c0f3090d46aac.tar.gz
bcm5719-llvm-dc4c8cf9acbf7d70853b3d876b0c0f3090d46aac.zip
[LTO] Handles commons in monolithic LTO
The gold-plugin was doing this internally, now the API is handling commons correctly based on the given resolution. Differential Revision: https://reviews.llvm.org/D23739 llvm-svn: 279417
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r--llvm/lib/LTO/LTO.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 8ceb5a2c1c8..39ec4e26c4f 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -292,6 +292,14 @@ Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input,
break;
}
}
+ // Common resolution: collect the maximum size/alignment.
+ // FIXME: right now we ignore the prevailing information, it is not clear
+ // what is the "right" behavior here.
+ if (Sym.getFlags() & object::BasicSymbolRef::SF_Common) {
+ auto &CommonRes = RegularLTO.Commons[Sym.getIRName()];
+ CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
+ CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment());
+ }
// FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit.
}
@@ -361,6 +369,31 @@ Error LTO::run(AddOutputFn AddOutput) {
}
Error LTO::runRegularLTO(AddOutputFn AddOutput) {
+ // Make sure commons have the right size/alignment: we kept the largest from
+ // all the prevailing when adding the inputs, and we apply it here.
+ for (auto &I : RegularLTO.Commons) {
+ ArrayType *Ty =
+ ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size);
+ GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);
+ if (OldGV && OldGV->getType()->getElementType() == Ty) {
+ // Don't create a new global if the type is already correct, just make
+ // sure the alignment is correct.
+ OldGV->setAlignment(I.second.Align);
+ continue;
+ }
+ auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,
+ GlobalValue::CommonLinkage,
+ ConstantAggregateZero::get(Ty), "");
+ GV->setAlignment(I.second.Align);
+ if (OldGV) {
+ OldGV->replaceAllUsesWith(ConstantExpr::getBitCast(GV, OldGV->getType()));
+ GV->takeName(OldGV);
+ OldGV->eraseFromParent();
+ } else {
+ GV->setName(I.first);
+ }
+ }
+
if (Conf.PreOptModuleHook &&
!Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
return Error();
OpenPOWER on IntegriCloud