mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +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>
|
||||
NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
|
||||
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
|
||||
/// deletes the specified instruction from the cloned module. It then runs a
|
||||
@ -272,11 +304,6 @@ llvm::SplitFunctionsOutOfModule(Module *M,
|
||||
ValueToValueMapTy 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
|
||||
std::set<Function *> TestFunctions;
|
||||
for (unsigned i = 0, e = F.size(); i != e; ++i) {
|
||||
@ -295,6 +322,27 @@ llvm::SplitFunctionsOutOfModule(Module *M,
|
||||
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
|
||||
// module if they both have static ctor/dtor functions.
|
||||
SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap);
|
||||
|
Loading…
x
Reference in New Issue
Block a user