summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/ElimAvailExtern.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/ElimAvailExtern.cpp b/llvm/lib/Transforms/IPO/ElimAvailExtern.cpp
index e13c00a92e4..0e138cbbc7a 100644
--- a/llvm/lib/Transforms/IPO/ElimAvailExtern.cpp
+++ b/llvm/lib/Transforms/IPO/ElimAvailExtern.cpp
@@ -49,9 +49,46 @@ ModulePass *llvm::createEliminateAvailableExternallyPass() {
return new EliminateAvailableExternally();
}
+static void convertAliasToDeclaration(GlobalAlias &GA, Module &M) {
+ GlobalValue *GVal = GA.getBaseObject();
+ GlobalValue *NewGV;
+ if (auto *GVar = dyn_cast<GlobalVariable>(GVal)) {
+ GlobalVariable *NewGVar = new GlobalVariable(
+ M, GVar->getType()->getElementType(), GVar->isConstant(),
+ GVar->getLinkage(), /*init*/ nullptr, GA.getName(), GVar,
+ GVar->getThreadLocalMode(), GVar->getType()->getAddressSpace());
+ NewGV = NewGVar;
+ NewGV->copyAttributesFrom(GVar);
+ } else {
+ auto *F = dyn_cast<Function>(GVal);
+ assert(F);
+ Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
+ GA.getName(), &M);
+ NewGV = NewF;
+ NewGV->copyAttributesFrom(F);
+ }
+ GA.replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, GA.getType()));
+ GA.eraseFromParent();
+}
+
bool EliminateAvailableExternally::runOnModule(Module &M) {
bool Changed = false;
+ // Convert any aliases that alias with an available externally
+ // value (which will be turned into declarations later on in this routine)
+ // into declarations themselves. All aliases must be definitions, and
+ // must alias with a definition. So this involves creating a declaration
+ // equivalent to the alias's base object.
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;) {
+ // Increment the iterator first since we may delete the current alias.
+ GlobalAlias &GA = *(I++);
+ GlobalValue *GVal = GA.getBaseObject();
+ if (!GVal->hasAvailableExternallyLinkage())
+ continue;
+ convertAliasToDeclaration(GA, M);
+ Changed = true;
+ }
+
// Drop initializers of available externally global variables.
for (GlobalVariable &GV : M.globals()) {
if (!GV.hasAvailableExternallyLinkage())
@@ -65,6 +102,7 @@ bool EliminateAvailableExternally::runOnModule(Module &M) {
GV.removeDeadConstantUsers();
GV.setLinkage(GlobalValue::ExternalLinkage);
NumVariables++;
+ Changed = true;
}
// Drop the bodies of available externally functions.
@@ -76,6 +114,7 @@ bool EliminateAvailableExternally::runOnModule(Module &M) {
F.deleteBody();
F.removeDeadConstantUsers();
NumFunctions++;
+ Changed = true;
}
return Changed;
OpenPOWER on IntegriCloud