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())