diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/ElimAvailExtern.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/ElimAvailExtern.cpp | 39 |
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; |