forked from OSchip/llvm-project
[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! llvm-svn: 254171
This commit is contained in:
parent
8934577171
commit
28ad2b47dd
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue