[llvm] r254171 - [bugpoint] Fix "Alias must point to a definition" problems
Hal Finkel via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 26 11:23:50 PST 2015
Author: hfinkel
Date: Thu Nov 26 13:23:49 2015
New Revision: 254171
URL: http://llvm.org/viewvc/llvm-project?rev=254171&view=rev
Log:
[bugpoint] Fix "Alias must point to a definition" problems
GlobalAliases may reference function definitions, but not function declarations.
bugpoint would sometimes create invalid IR by deleting a function's body (thus
mutating a function definition into a declaration) without first 'fixing' any
GlobalAliases that reference that function definition.
This change iteratively prevents that issue. Before deleting a function's body,
it scans the module for GlobalAliases which reference that function. When
found, it eliminates them using replaceAllUsesWith.
Fixes PR20788.
Patch by Nick Johnson!
Modified:
llvm/trunk/tools/bugpoint/BugDriver.h
llvm/trunk/tools/bugpoint/CrashDebugger.cpp
llvm/trunk/tools/bugpoint/ExtractFunction.cpp
Modified: llvm/trunk/tools/bugpoint/BugDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.h?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/BugDriver.h (original)
+++ llvm/trunk/tools/bugpoint/BugDriver.h Thu Nov 26 13:23:49 2015
@@ -321,6 +321,11 @@ void PrintFunctionList(const std::vector
///
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.
//
Modified: llvm/trunk/tools/bugpoint/CrashDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/CrashDebugger.cpp?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/CrashDebugger.cpp (original)
+++ llvm/trunk/tools/bugpoint/CrashDebugger.cpp Thu Nov 26 13:23:49 2015
@@ -162,7 +162,7 @@ ReduceCrashingGlobalVariables::TestGloba
// 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;
}
Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original)
+++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Thu Nov 26 13:23:49 2015
@@ -179,11 +179,43 @@ std::unique_ptr<Module> BugDriver::extra
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 *
<< "' 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);
}
}
More information about the llvm-commits
mailing list