mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-02 00:51:56 +00:00
teach various passes about blockaddress. We no longer
crash on any clang tests. llvm-svn: 85465
This commit is contained in:
parent
2dcd23d6f7
commit
a0e35cae82
@ -191,13 +191,13 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
|
||||
|
||||
void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) {
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
|
||||
GlobalIsNeeded(GV);
|
||||
else {
|
||||
// Loop over all of the operands of the constant, adding any globals they
|
||||
// use to the list of needed globals.
|
||||
for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I)
|
||||
MarkUsedGlobalsAsNeeded(cast<Constant>(*I));
|
||||
}
|
||||
return GlobalIsNeeded(GV);
|
||||
|
||||
// Loop over all of the operands of the constant, adding any globals they
|
||||
// use to the list of needed globals.
|
||||
for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I)
|
||||
if (Constant *OpC = dyn_cast<Constant>(*I))
|
||||
MarkUsedGlobalsAsNeeded(OpC);
|
||||
}
|
||||
|
||||
// RemoveUnusedGlobalValue - Loop over all of the uses of the specified
|
||||
|
@ -448,10 +448,16 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
|
||||
Succs[BCValue.getConstant() == ConstantInt::getFalse(*Context)] = true;
|
||||
}
|
||||
}
|
||||
} else if (isa<InvokeInst>(&TI)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isa<InvokeInst>(&TI)) {
|
||||
// Invoke instructions successors are always executable.
|
||||
Succs[0] = Succs[1] = true;
|
||||
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
|
||||
LatticeVal &SCValue = getValueState(SI->getCondition());
|
||||
if (SCValue.isOverdefined() || // Overdefined condition?
|
||||
(SCValue.isConstant() && !isa<ConstantInt>(SCValue.getConstant()))) {
|
||||
@ -459,9 +465,20 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
|
||||
Succs.assign(TI.getNumSuccessors(), true);
|
||||
} else if (SCValue.isConstant())
|
||||
Succs[SI->findCaseValue(cast<ConstantInt>(SCValue.getConstant()))] = true;
|
||||
} else {
|
||||
llvm_unreachable("SCCP: Don't know how to handle this terminator!");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: This could be improved if the operand is a [cast of a] BlockAddress.
|
||||
if (isa<IndirectBrInst>(&TI)) {
|
||||
// Just mark all destinations executable!
|
||||
Succs.assign(TI.getNumSuccessors(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
errs() << "Unknown terminator instruction: " << TI << '\n';
|
||||
#endif
|
||||
llvm_unreachable("SCCP: Don't know how to handle this terminator!");
|
||||
}
|
||||
|
||||
|
||||
@ -479,25 +496,27 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
|
||||
if (BI->isUnconditional())
|
||||
return true;
|
||||
else {
|
||||
LatticeVal &BCValue = getValueState(BI->getCondition());
|
||||
if (BCValue.isOverdefined()) {
|
||||
// Overdefined condition variables mean the branch could go either way.
|
||||
return true;
|
||||
} else if (BCValue.isConstant()) {
|
||||
// Not branching on an evaluatable constant?
|
||||
if (!isa<ConstantInt>(BCValue.getConstant())) return true;
|
||||
|
||||
LatticeVal &BCValue = getValueState(BI->getCondition());
|
||||
if (BCValue.isOverdefined()) {
|
||||
// Overdefined condition variables mean the branch could go either way.
|
||||
return true;
|
||||
} else if (BCValue.isConstant()) {
|
||||
// Not branching on an evaluatable constant?
|
||||
if (!isa<ConstantInt>(BCValue.getConstant())) return true;
|
||||
|
||||
// Constant condition variables mean the branch can only go a single way
|
||||
return BI->getSuccessor(BCValue.getConstant() ==
|
||||
ConstantInt::getFalse(*Context)) == To;
|
||||
}
|
||||
return false;
|
||||
// Constant condition variables mean the branch can only go a single way
|
||||
return BI->getSuccessor(BCValue.getConstant() ==
|
||||
ConstantInt::getFalse(*Context)) == To;
|
||||
}
|
||||
} else if (isa<InvokeInst>(TI)) {
|
||||
// Invoke instructions successors are always executable.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Invoke instructions successors are always executable.
|
||||
if (isa<InvokeInst>(TI))
|
||||
return true;
|
||||
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
||||
|
||||
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
||||
LatticeVal &SCValue = getValueState(SI->getCondition());
|
||||
if (SCValue.isOverdefined()) { // Overdefined condition?
|
||||
// All destinations are executable!
|
||||
@ -517,12 +536,17 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
|
||||
return SI->getDefaultDest() == To;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
errs() << "Unknown terminator instruction: " << *TI << '\n';
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
|
||||
// Just mark all destinations executable!
|
||||
// TODO: This could be improved if the operand is a [cast of a] BlockAddress.
|
||||
if (isa<IndirectBrInst>(&TI))
|
||||
return true;
|
||||
|
||||
#ifndef NDEBUG
|
||||
errs() << "Unknown terminator instruction: " << *TI << '\n';
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
|
||||
// visit Implementations - Something changed in this instruction... Either an
|
||||
|
@ -113,8 +113,8 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
|
||||
|
||||
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
|
||||
Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
|
||||
BasicBlock *BB = cast<BasicBlock>(MapValue(BA->getBasicBlock(), VM));
|
||||
return VM[V] = BlockAddress::get(F, BB);
|
||||
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
|
||||
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
|
||||
}
|
||||
|
||||
llvm_unreachable("Unknown type of constant!");
|
||||
|
Loading…
Reference in New Issue
Block a user