mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Improve handling of blockaddresses in bugpoint when splitting a module. Patch by Daniel Reynaud.
llvm-svn: 151115
This commit is contained in:
parent
a6003dae39
commit
87b4f40d41
@ -47,7 +47,39 @@ namespace {
|
|||||||
cl::opt<bool, true>
|
cl::opt<bool, true>
|
||||||
NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
|
NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
|
||||||
cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
|
cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
|
||||||
}
|
|
||||||
|
Function* globalInitUsesExternalBA(GlobalVariable* GV) {
|
||||||
|
if (!GV->hasInitializer())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Constant *I = GV->getInitializer();
|
||||||
|
|
||||||
|
// walk the values used by the initializer
|
||||||
|
// (and recurse into things like ConstantExpr)
|
||||||
|
std::vector<Constant*> Todo;
|
||||||
|
std::set<Constant*> Done;
|
||||||
|
Todo.push_back(I);
|
||||||
|
|
||||||
|
while (!Todo.empty()) {
|
||||||
|
Constant* V = Todo.back();
|
||||||
|
Todo.pop_back();
|
||||||
|
Done.insert(V);
|
||||||
|
|
||||||
|
if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) {
|
||||||
|
Function *F = BA->getFunction();
|
||||||
|
if (F->isDeclaration())
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) {
|
||||||
|
Constant *C = dyn_cast<Constant>(*i);
|
||||||
|
if (C && !isa<GlobalValue>(C) && !Done.count(C))
|
||||||
|
Todo.push_back(C);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
/// deleteInstructionFromProgram - This method clones the current Program and
|
/// deleteInstructionFromProgram - This method clones the current Program and
|
||||||
/// deletes the specified instruction from the cloned module. It then runs a
|
/// deletes the specified instruction from the cloned module. It then runs a
|
||||||
@ -272,11 +304,6 @@ llvm::SplitFunctionsOutOfModule(Module *M,
|
|||||||
ValueToValueMapTy NewVMap;
|
ValueToValueMapTy NewVMap;
|
||||||
Module *New = CloneModule(M, NewVMap);
|
Module *New = CloneModule(M, NewVMap);
|
||||||
|
|
||||||
// Make sure global initializers exist only in the safe module (CBE->.so)
|
|
||||||
for (Module::global_iterator I = New->global_begin(), E = New->global_end();
|
|
||||||
I != E; ++I)
|
|
||||||
I->setInitializer(0); // Delete the initializer to make it external
|
|
||||||
|
|
||||||
// Remove the Test functions from the Safe module
|
// Remove the Test functions from the Safe module
|
||||||
std::set<Function *> TestFunctions;
|
std::set<Function *> TestFunctions;
|
||||||
for (unsigned i = 0, e = F.size(); i != e; ++i) {
|
for (unsigned i = 0, e = F.size(); i != e; ++i) {
|
||||||
@ -295,6 +322,27 @@ llvm::SplitFunctionsOutOfModule(Module *M,
|
|||||||
DeleteFunctionBody(I);
|
DeleteFunctionBody(I);
|
||||||
|
|
||||||
|
|
||||||
|
// Try to split the global initializers evenly
|
||||||
|
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
|
||||||
|
I != E; ++I) {
|
||||||
|
GlobalVariable *GV = cast<GlobalVariable>(NewVMap[I]);
|
||||||
|
if (Function *TestFn = globalInitUsesExternalBA(I)) {
|
||||||
|
if (Function *SafeFn = globalInitUsesExternalBA(GV)) {
|
||||||
|
errs() << "*** Error: when reducing functions, encountered "
|
||||||
|
"the global '";
|
||||||
|
WriteAsOperand(errs(), GV, false);
|
||||||
|
errs() << "' with an initializer that references blockaddresses "
|
||||||
|
"from safe function '" << SafeFn->getName()
|
||||||
|
<< "' and from test function '" << TestFn->getName() << "'.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
I->setInitializer(0); // 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(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that there is a global ctor/dtor array in both halves of the
|
// Make sure that there is a global ctor/dtor array in both halves of the
|
||||||
// module if they both have static ctor/dtor functions.
|
// module if they both have static ctor/dtor functions.
|
||||||
SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap);
|
SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user