diff options
-rw-r--r-- | llvm/tools/bugpoint/BugDriver.h | 5 | ||||
-rw-r--r-- | llvm/tools/bugpoint/CrashDebugger.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/bugpoint/ExtractFunction.cpp | 36 |
3 files changed, 41 insertions, 4 deletions
diff --git a/llvm/tools/bugpoint/BugDriver.h b/llvm/tools/bugpoint/BugDriver.h index 1bd2e80a630..45fcf74aa6b 100644 --- a/llvm/tools/bugpoint/BugDriver.h +++ b/llvm/tools/bugpoint/BugDriver.h @@ -321,6 +321,11 @@ void PrintFunctionList(const std::vector<Function*> &Funcs); /// void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs); +// DeleteGlobalInitializer - "Remove" the global variable by deleting its +// initializer, making it external. +// +void DeleteGlobalInitializer(GlobalVariable *GV); + // DeleteFunctionBody - "Remove" the function by deleting all of it's basic // blocks, making it external. // diff --git a/llvm/tools/bugpoint/CrashDebugger.cpp b/llvm/tools/bugpoint/CrashDebugger.cpp index 1bfcc87e06e..631a58455c5 100644 --- a/llvm/tools/bugpoint/CrashDebugger.cpp +++ b/llvm/tools/bugpoint/CrashDebugger.cpp @@ -162,7 +162,7 @@ ReduceCrashingGlobalVariables::TestGlobalVariables( // playing with... for (GlobalVariable &I : M->globals()) if (I.hasInitializer() && !GVSet.count(&I)) { - I.setInitializer(nullptr); + DeleteGlobalInitializer(&I); I.setLinkage(GlobalValue::ExternalLinkage); } @@ -664,7 +664,7 @@ static bool DebugACrash(BugDriver &BD, for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasInitializer()) { - I->setInitializer(nullptr); + DeleteGlobalInitializer(&*I); I->setLinkage(GlobalValue::ExternalLinkage); DeletedInit = true; } diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp index 21d3d984599..7b98cb8fb55 100644 --- a/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/llvm/tools/bugpoint/ExtractFunction.cpp @@ -179,11 +179,43 @@ std::unique_ptr<Module> BugDriver::extractLoop(Module *M) { return NewM; } +static void eliminateAliases(GlobalValue *GV) { + // First, check whether a GlobalAlias references this definition. + // GlobalAlias MAY NOT reference declarations. + for (;;) { + // 1. Find aliases + SmallVector<GlobalAlias*,1> aliases; + Module *M = GV->getParent(); + for (Module::alias_iterator I=M->alias_begin(), E=M->alias_end(); I!=E; ++I) + if (I->getAliasee()->stripPointerCasts() == GV) + aliases.push_back(&*I); + if (aliases.empty()) + break; + // 2. Resolve aliases + for (unsigned i=0, e=aliases.size(); i<e; ++i) { + aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee()); + aliases[i]->eraseFromParent(); + } + // 3. Repeat until no more aliases found; there might + // be an alias to an alias... + } +} + +// +// DeleteGlobalInitializer - "Remove" the global variable by deleting its initializer, +// making it external. +// +void llvm::DeleteGlobalInitializer(GlobalVariable *GV) { + eliminateAliases(GV); + GV->setInitializer(nullptr); +} // DeleteFunctionBody - "Remove" the function by deleting all of its basic // blocks, making it external. // void llvm::DeleteFunctionBody(Function *F) { + eliminateAliases(F); + // delete the body of the function... F->deleteBody(); assert(F->isDeclaration() && "This didn't make the function external!"); @@ -323,10 +355,10 @@ llvm::SplitFunctionsOutOfModule(Module *M, << "' and from test function '" << TestFn->getName() << "'.\n"; exit(1); } - I.setInitializer(nullptr); // Delete the initializer to make it external + DeleteGlobalInitializer(&I); // Delete the initializer to make it external } else { // If we keep it in the safe module, then delete it in the test module - GV->setInitializer(nullptr); + DeleteGlobalInitializer(GV); } } |