mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 22:28:18 +00:00
Walk down the dominator tree instead of the control flow graph. That means
that we can't modify the CFG any more, at least not until it's possible to update the dominator tree (PR217). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30469 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -48,10 +48,6 @@ namespace {
|
|||||||
NumVarsReplaced("predsimplify", "Number of argument substitutions");
|
NumVarsReplaced("predsimplify", "Number of argument substitutions");
|
||||||
Statistic<>
|
Statistic<>
|
||||||
NumInstruction("predsimplify", "Number of instructions removed");
|
NumInstruction("predsimplify", "Number of instructions removed");
|
||||||
Statistic<>
|
|
||||||
NumSwitchCases("predsimplify", "Number of switch cases removed");
|
|
||||||
Statistic<>
|
|
||||||
NumBranches("predsimplify", "Number of branches made unconditional");
|
|
||||||
|
|
||||||
/// Returns true if V1 is a better choice than V2. Note that it is
|
/// Returns true if V1 is a better choice than V2. Note that it is
|
||||||
/// not a total ordering.
|
/// not a total ordering.
|
||||||
@@ -126,21 +122,18 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ElemTy &getLeader(iterator I) {
|
ElemTy &getLeader(iterator I) {
|
||||||
assert(I != 0 && "Element zero is out of range.");
|
assert(I && I <= leaders.size() && "Illegal leader to get.");
|
||||||
assert(I <= leaders.size() && "Invalid iterator.");
|
|
||||||
return leaders[I-1];
|
return leaders[I-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ElemTy &getLeader(const_iterator I) const {
|
const ElemTy &getLeader(const_iterator I) const {
|
||||||
assert(I != 0 && "Element zero is out of range.");
|
assert(I && I <= leaders.size() && "Illegal leaders to get.");
|
||||||
return leaders[I-1];
|
return leaders[I-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void debug(std::ostream &os) const {
|
void debug(std::ostream &os) const {
|
||||||
std::set<Value *> Unique;
|
|
||||||
for (unsigned i = 1, e = leaders.size()+1; i != e; ++i) {
|
for (unsigned i = 1, e = leaders.size()+1; i != e; ++i) {
|
||||||
Unique.insert(getLeader(i));
|
|
||||||
os << i << ". " << *getLeader(i) << ": [";
|
os << i << ". " << *getLeader(i) << ": [";
|
||||||
for (std::map<Value *, unsigned>::const_iterator
|
for (std::map<Value *, unsigned>::const_iterator
|
||||||
I = mapping.begin(), E = mapping.end(); I != E; ++I) {
|
I = mapping.begin(), E = mapping.end(); I != E; ++I) {
|
||||||
@@ -150,14 +143,6 @@ namespace {
|
|||||||
}
|
}
|
||||||
os << "]\n";
|
os << "]\n";
|
||||||
}
|
}
|
||||||
assert(Unique.size() == leaders.size() && "Duplicate leaders.");
|
|
||||||
|
|
||||||
for (typename std::map<ElemTy, unsigned>::const_iterator
|
|
||||||
I = mapping.begin(), E = mapping.end(); I != E; ++I) {
|
|
||||||
assert(I->second != 0 && "Zero iterator in mapping.");
|
|
||||||
assert(I->second <= leaders.size() &&
|
|
||||||
"Invalid iterator found in mapping.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -263,7 +248,6 @@ namespace {
|
|||||||
order(V1, V2);
|
order(V1, V2);
|
||||||
if (isa<Constant>(V2)) return; // refuse to set false == true.
|
if (isa<Constant>(V2)) return; // refuse to set false == true.
|
||||||
|
|
||||||
DEBUG(std::cerr << "equal: " << *V1 << " and " << *V2 << "\n");
|
|
||||||
SynonymIterator deleted = union_find.unionSets(V1, V2);
|
SynonymIterator deleted = union_find.unionSets(V1, V2);
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
SynonymIterator replacement = union_find.findLeader(V1);
|
SynonymIterator replacement = union_find.findLeader(V1);
|
||||||
@@ -286,7 +270,6 @@ namespace {
|
|||||||
// For example, %x = setne int 0, 0 causes "0 != 0".
|
// For example, %x = setne int 0, 0 causes "0 != 0".
|
||||||
if (isa<Constant>(V1) && isa<Constant>(V2)) return;
|
if (isa<Constant>(V1) && isa<Constant>(V2)) return;
|
||||||
|
|
||||||
DEBUG(std::cerr << "not equal: " << *V1 << " and " << *V2 << "\n");
|
|
||||||
if (findProperty(NE, V1, V2) != Properties.end())
|
if (findProperty(NE, V1, V2) != Properties.end())
|
||||||
return; // found.
|
return; // found.
|
||||||
|
|
||||||
@@ -450,8 +433,6 @@ namespace {
|
|||||||
E = Properties.end(); I != E; ++I) {
|
E = Properties.end(); I != E; ++I) {
|
||||||
os << (*I).I1 << " " << OpcodeTable[(*I).Opcode] << " "
|
os << (*I).I1 << " " << OpcodeTable[(*I).Opcode] << " "
|
||||||
<< (*I).I2 << "\n";
|
<< (*I).I2 << "\n";
|
||||||
assert((*I).I1 <= size && "Invalid property.");
|
|
||||||
assert((*I).I2 <= size && "Invalid property.");
|
|
||||||
}
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
@@ -478,25 +459,24 @@ namespace {
|
|||||||
// Used by terminator instructions to proceed from the current basic
|
// Used by terminator instructions to proceed from the current basic
|
||||||
// block to the next. Verifies that "current" dominates "next",
|
// block to the next. Verifies that "current" dominates "next",
|
||||||
// then calls visitBasicBlock.
|
// then calls visitBasicBlock.
|
||||||
void proceedToSuccessor(PropertySet &CurrentPS, PropertySet &NextPS,
|
void proceedToSuccessor(TerminatorInst *TI, unsigned edge,
|
||||||
DTNodeType *Current, DTNodeType *Next);
|
PropertySet &CurrentPS, PropertySet &NextPS);
|
||||||
void proceedToSuccessor(PropertySet &CurrentPS,
|
void proceedToSuccessors(PropertySet &CurrentPS, BasicBlock *Current);
|
||||||
DTNodeType *Current, DTNodeType *Next);
|
|
||||||
|
|
||||||
// Visits each instruction in the basic block.
|
// Visits each instruction in the basic block.
|
||||||
void visitBasicBlock(DTNodeType *DTNode, PropertySet &KnownProperties);
|
void visitBasicBlock(BasicBlock *Block, PropertySet &KnownProperties);
|
||||||
|
|
||||||
// Tries to simplify each Instruction and add new properties to
|
// Tries to simplify each Instruction and add new properties to
|
||||||
// the PropertySet. Returns true if it erase the instruction.
|
// the PropertySet. Returns true if it erase the instruction.
|
||||||
void visitInstruction(Instruction *I, DTNodeType *, PropertySet &);
|
void visitInstruction(Instruction *I, PropertySet &);
|
||||||
// For each instruction, add the properties to KnownProperties.
|
// For each instruction, add the properties to KnownProperties.
|
||||||
|
|
||||||
void visit(TerminatorInst *TI, DTNodeType *, PropertySet &);
|
void visit(TerminatorInst *TI, PropertySet &);
|
||||||
void visit(BranchInst *BI, DTNodeType *, PropertySet &);
|
void visit(BranchInst *BI, PropertySet &);
|
||||||
void visit(SwitchInst *SI, DTNodeType *, PropertySet);
|
void visit(SwitchInst *SI, PropertySet);
|
||||||
void visit(LoadInst *LI, DTNodeType *, PropertySet &);
|
void visit(LoadInst *LI, PropertySet &);
|
||||||
void visit(StoreInst *SI, DTNodeType *, PropertySet &);
|
void visit(StoreInst *SI, PropertySet &);
|
||||||
void visit(BinaryOperator *BO, DTNodeType *, PropertySet &);
|
void visit(BinaryOperator *BO, PropertySet &);
|
||||||
|
|
||||||
DominatorTree *DT;
|
DominatorTree *DT;
|
||||||
bool modified;
|
bool modified;
|
||||||
@@ -515,12 +495,13 @@ bool PredicateSimplifier::runOnFunction(Function &F) {
|
|||||||
|
|
||||||
modified = false;
|
modified = false;
|
||||||
PropertySet KnownProperties;
|
PropertySet KnownProperties;
|
||||||
visitBasicBlock(DT->getRootNode(), KnownProperties);
|
visitBasicBlock(DT->getRootNode()->getBlock(), KnownProperties);
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::getAnalysisUsage(AnalysisUsage &AU) const {
|
void PredicateSimplifier::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<DominatorTree>();
|
AU.addRequired<DominatorTree>();
|
||||||
|
AU.setPreservesCFG();
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve catches cases addProperty won't because it wasn't used as a
|
// resolve catches cases addProperty won't because it wasn't used as a
|
||||||
@@ -611,8 +592,6 @@ Value *PredicateSimplifier::resolve(Value *V, const PropertySet &KP) {
|
|||||||
|
|
||||||
V = KP.canonicalize(V);
|
V = KP.canonicalize(V);
|
||||||
|
|
||||||
DEBUG(std::cerr << "peering into " << *V << "\n");
|
|
||||||
|
|
||||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
|
||||||
return resolve(BO, KP);
|
return resolve(BO, KP);
|
||||||
else if (SelectInst *SI = dyn_cast<SelectInst>(V))
|
else if (SelectInst *SI = dyn_cast<SelectInst>(V))
|
||||||
@@ -621,24 +600,17 @@ Value *PredicateSimplifier::resolve(Value *V, const PropertySet &KP) {
|
|||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visitBasicBlock(DTNodeType *DTNode,
|
void PredicateSimplifier::visitBasicBlock(BasicBlock *BB,
|
||||||
PropertySet &KnownProperties) {
|
PropertySet &KnownProperties) {
|
||||||
BasicBlock *BB = DTNode->getBlock();
|
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
|
||||||
visitInstruction(I++, DTNode, KnownProperties);
|
visitInstruction(I++, KnownProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visitInstruction(Instruction *I,
|
void PredicateSimplifier::visitInstruction(Instruction *I,
|
||||||
DTNodeType *DTNode,
|
|
||||||
PropertySet &KnownProperties) {
|
PropertySet &KnownProperties) {
|
||||||
|
|
||||||
DEBUG(std::cerr << "Considering instruction " << *I << "\n");
|
|
||||||
DEBUG(KnownProperties.debug(std::cerr));
|
|
||||||
|
|
||||||
// Try to replace the whole instruction.
|
// Try to replace the whole instruction.
|
||||||
Value *V = resolve(I, KnownProperties);
|
Value *V = resolve(I, KnownProperties);
|
||||||
assert(V->getType() == I->getType() && "Instruction type mutated!");
|
|
||||||
if (V != I) {
|
if (V != I) {
|
||||||
modified = true;
|
modified = true;
|
||||||
++NumInstruction;
|
++NumInstruction;
|
||||||
@@ -651,7 +623,6 @@ void PredicateSimplifier::visitInstruction(Instruction *I,
|
|||||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
||||||
Value *Oper = I->getOperand(i);
|
Value *Oper = I->getOperand(i);
|
||||||
Value *V = resolve(Oper, KnownProperties);
|
Value *V = resolve(Oper, KnownProperties);
|
||||||
assert(V->getType() == Oper->getType() && "Operand type mutated!");
|
|
||||||
if (V != Oper) {
|
if (V != Oper) {
|
||||||
modified = true;
|
modified = true;
|
||||||
++NumVarsReplaced;
|
++NumVarsReplaced;
|
||||||
@@ -662,54 +633,60 @@ void PredicateSimplifier::visitInstruction(Instruction *I,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I))
|
if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I))
|
||||||
visit(TI, DTNode, KnownProperties);
|
visit(TI, KnownProperties);
|
||||||
else if (LoadInst *LI = dyn_cast<LoadInst>(I))
|
else if (LoadInst *LI = dyn_cast<LoadInst>(I))
|
||||||
visit(LI, DTNode, KnownProperties);
|
visit(LI, KnownProperties);
|
||||||
else if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
else if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
||||||
visit(SI, DTNode, KnownProperties);
|
visit(SI, KnownProperties);
|
||||||
else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I))
|
else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I))
|
||||||
visit(BO, DTNode, KnownProperties);
|
visit(BO, KnownProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::proceedToSuccessor(PropertySet &CurrentPS,
|
// The basic block on the target of the specified edge must be known
|
||||||
PropertySet &NextPS,
|
// to be immediately dominated by the parent of the TerminatorInst.
|
||||||
DTNodeType *Current,
|
void PredicateSimplifier::proceedToSuccessor(TerminatorInst *TI,
|
||||||
DTNodeType *Next) {
|
unsigned edge,
|
||||||
if (Next->getBlock()->getSinglePredecessor() == Current->getBlock())
|
PropertySet &CurrentPS,
|
||||||
proceedToSuccessor(NextPS, Current, Next);
|
PropertySet &NextPS) {
|
||||||
|
assert(edge < TI->getNumSuccessors() && "Invalid index for edge.");
|
||||||
|
|
||||||
|
BasicBlock *BB = TI->getParent(),
|
||||||
|
*BBNext = TI->getSuccessor(edge);
|
||||||
|
|
||||||
|
if (BBNext->getSinglePredecessor() == BB)
|
||||||
|
visitBasicBlock(BBNext, NextPS);
|
||||||
else
|
else
|
||||||
proceedToSuccessor(CurrentPS, Current, Next);
|
visitBasicBlock(BBNext, CurrentPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::proceedToSuccessor(PropertySet &KP,
|
void PredicateSimplifier::proceedToSuccessors(PropertySet &KP,
|
||||||
DTNodeType *Current,
|
BasicBlock *BBCurrent) {
|
||||||
DTNodeType *Next) {
|
DTNodeType *Current = DT->getNode(BBCurrent);
|
||||||
if (Current->properlyDominates(Next))
|
for (DTNodeType::iterator I = Current->begin(), E = Current->end();
|
||||||
visitBasicBlock(Next, KP);
|
I != E; ++I) {
|
||||||
|
PropertySet Copy(KP);
|
||||||
|
visitBasicBlock((*I)->getBlock(), Copy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(TerminatorInst *TI, DTNodeType *Node,
|
void PredicateSimplifier::visit(TerminatorInst *TI, PropertySet &KP) {
|
||||||
PropertySet &KP) {
|
|
||||||
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
|
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
|
||||||
visit(BI, Node, KP);
|
visit(BI, KP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
||||||
visit(SI, Node, KP);
|
visit(SI, KP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, E = TI->getNumSuccessors(); i != E; ++i) {
|
proceedToSuccessors(KP, TI->getParent());
|
||||||
BasicBlock *BB = TI->getSuccessor(i);
|
|
||||||
PropertySet KPcopy(KP);
|
|
||||||
proceedToSuccessor(KPcopy, Node, DT->getNode(TI->getSuccessor(i)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(BranchInst *BI, DTNodeType *Node,
|
void PredicateSimplifier::visit(BranchInst *BI, PropertySet &KP) {
|
||||||
PropertySet &KP) {
|
BasicBlock *BB = BI->getParent();
|
||||||
|
|
||||||
if (BI->isUnconditional()) {
|
if (BI->isUnconditional()) {
|
||||||
proceedToSuccessor(KP, Node, DT->getNode(BI->getSuccessor(0)));
|
proceedToSuccessors(KP, BB);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,110 +695,73 @@ void PredicateSimplifier::visit(BranchInst *BI, DTNodeType *Node,
|
|||||||
BasicBlock *TrueDest = BI->getSuccessor(0),
|
BasicBlock *TrueDest = BI->getSuccessor(0),
|
||||||
*FalseDest = BI->getSuccessor(1);
|
*FalseDest = BI->getSuccessor(1);
|
||||||
|
|
||||||
if (Condition == ConstantBool::True) {
|
if (Condition == ConstantBool::True || TrueDest == FalseDest) {
|
||||||
FalseDest->removePredecessor(BI->getParent());
|
proceedToSuccessors(KP, BB);
|
||||||
BI->setUnconditionalDest(TrueDest);
|
|
||||||
modified = true;
|
|
||||||
++NumBranches;
|
|
||||||
proceedToSuccessor(KP, Node, DT->getNode(TrueDest));
|
|
||||||
return;
|
return;
|
||||||
} else if (Condition == ConstantBool::False) {
|
} else if (Condition == ConstantBool::False) {
|
||||||
TrueDest->removePredecessor(BI->getParent());
|
proceedToSuccessors(KP, BB);
|
||||||
BI->setUnconditionalDest(FalseDest);
|
|
||||||
modified = true;
|
|
||||||
++NumBranches;
|
|
||||||
proceedToSuccessor(KP, Node, DT->getNode(FalseDest));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertySet TrueProperties(KP), FalseProperties(KP);
|
DTNodeType *Node = DT->getNode(BB);
|
||||||
DEBUG(std::cerr << "true set:\n");
|
for (DTNodeType::iterator I = Node->begin(), E = Node->end(); I != E; ++I) {
|
||||||
TrueProperties.addEqual(ConstantBool::True, Condition);
|
if ((*I)->getBlock() == TrueDest) {
|
||||||
DEBUG(TrueProperties.debug(std::cerr));
|
PropertySet TrueProperties(KP);
|
||||||
DEBUG(std::cerr << "false set:\n");
|
TrueProperties.addEqual(ConstantBool::True, Condition);
|
||||||
FalseProperties.addEqual(ConstantBool::False, Condition);
|
proceedToSuccessor(BI, 0, KP, TrueProperties);
|
||||||
DEBUG(FalseProperties.debug(std::cerr));
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PropertySet KPcopy(KP);
|
if ((*I)->getBlock() == FalseDest) {
|
||||||
proceedToSuccessor(KP, TrueProperties, Node, DT->getNode(TrueDest));
|
PropertySet FalseProperties(KP);
|
||||||
proceedToSuccessor(KPcopy, FalseProperties, Node, DT->getNode(FalseDest));
|
FalseProperties.addEqual(ConstantBool::False, Condition);
|
||||||
|
proceedToSuccessor(BI, 1, KP, FalseProperties);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitBasicBlock((*I)->getBlock(), KP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(SwitchInst *SI, DTNodeType *DTNode,
|
void PredicateSimplifier::visit(SwitchInst *SI, PropertySet KP) {
|
||||||
PropertySet KP) {
|
|
||||||
Value *Condition = SI->getCondition();
|
Value *Condition = SI->getCondition();
|
||||||
assert(Condition == KP.canonicalize(Condition) &&
|
|
||||||
"Instruction wasn't already canonicalized?");
|
|
||||||
|
|
||||||
// If there's an NEProperty covering this SwitchInst, we may be able to
|
|
||||||
// eliminate one of the cases.
|
|
||||||
for (PropertySet::ConstPropertyIterator I = KP.Properties.begin(),
|
|
||||||
E = KP.Properties.end(); I != E; ++I) {
|
|
||||||
if (I->Opcode != PropertySet::NE) continue;
|
|
||||||
Value *V1 = KP.union_find.getLeader(I->I1),
|
|
||||||
*V2 = KP.union_find.getLeader(I->I2);
|
|
||||||
|
|
||||||
// Find a Property with a ConstantInt on one side and our
|
|
||||||
// Condition on the other.
|
|
||||||
ConstantInt *CI = NULL;
|
|
||||||
if (V1 == Condition)
|
|
||||||
CI = dyn_cast<ConstantInt>(V2);
|
|
||||||
else if (V2 == Condition)
|
|
||||||
CI = dyn_cast<ConstantInt>(V1);
|
|
||||||
|
|
||||||
if (!CI) continue;
|
|
||||||
|
|
||||||
unsigned i = SI->findCaseValue(CI);
|
|
||||||
if (i != 0) { // zero is reserved for the default case.
|
|
||||||
SI->getSuccessor(i)->removePredecessor(SI->getParent());
|
|
||||||
SI->removeCase(i);
|
|
||||||
modified = true;
|
|
||||||
++NumSwitchCases;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the EQProperty in each of the cases BBs,
|
// Set the EQProperty in each of the cases BBs,
|
||||||
// and the NEProperties in the default BB.
|
// and the NEProperties in the default BB.
|
||||||
PropertySet DefaultProperties(KP);
|
PropertySet DefaultProperties(KP);
|
||||||
|
|
||||||
DTNodeType *Node = DT->getNode(SI->getParent()),
|
DTNodeType *Node = DT->getNode(SI->getParent());
|
||||||
*DefaultNode = DT->getNode(SI->getSuccessor(0));
|
for (DTNodeType::iterator I = Node->begin(), E = Node->end(); I != E; ++I) {
|
||||||
if (!Node->dominates(DefaultNode)) DefaultNode = NULL;
|
BasicBlock *BB = (*I)->getBlock();
|
||||||
|
|
||||||
for (unsigned I = 1, E = SI->getNumCases(); I < E; ++I) {
|
PropertySet Copy(KP);
|
||||||
ConstantInt *CI = SI->getCaseValue(I);
|
|
||||||
|
|
||||||
BasicBlock *SuccBB = SI->getSuccessor(I);
|
if (BB == SI->getDefaultDest()) {
|
||||||
PropertySet copy(KP);
|
PropertySet NewProperties(KP);
|
||||||
if (SuccBB->getSinglePredecessor()) {
|
for (unsigned i = 1, e = SI->getNumCases(); i < e; ++i)
|
||||||
|
NewProperties.addNotEqual(Condition, SI->getCaseValue(i));
|
||||||
|
|
||||||
|
proceedToSuccessor(SI, 0, Copy, NewProperties);
|
||||||
|
} else if (ConstantInt *CI = SI->findCaseDest(BB)) {
|
||||||
PropertySet NewProperties(KP);
|
PropertySet NewProperties(KP);
|
||||||
NewProperties.addEqual(Condition, CI);
|
NewProperties.addEqual(Condition, CI);
|
||||||
proceedToSuccessor(copy, NewProperties, DTNode, DT->getNode(SuccBB));
|
proceedToSuccessor(SI, SI->findCaseValue(CI), Copy, NewProperties);
|
||||||
} else
|
} else
|
||||||
proceedToSuccessor(copy, DTNode, DT->getNode(SuccBB));
|
visitBasicBlock(BB, Copy);
|
||||||
|
|
||||||
if (DefaultNode)
|
|
||||||
DefaultProperties.addNotEqual(Condition, CI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DefaultNode)
|
|
||||||
proceedToSuccessor(DefaultProperties, DTNode, DefaultNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(LoadInst *LI, DTNodeType *,
|
void PredicateSimplifier::visit(LoadInst *LI, PropertySet &KP) {
|
||||||
PropertySet &KP) {
|
|
||||||
Value *Ptr = LI->getPointerOperand();
|
Value *Ptr = LI->getPointerOperand();
|
||||||
KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
|
KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(StoreInst *SI, DTNodeType *,
|
void PredicateSimplifier::visit(StoreInst *SI, PropertySet &KP) {
|
||||||
PropertySet &KP) {
|
|
||||||
Value *Ptr = SI->getPointerOperand();
|
Value *Ptr = SI->getPointerOperand();
|
||||||
KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
|
KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PredicateSimplifier::visit(BinaryOperator *BO, DTNodeType *,
|
void PredicateSimplifier::visit(BinaryOperator *BO, PropertySet &KP) {
|
||||||
PropertySet &KP) {
|
|
||||||
Instruction::BinaryOps ops = BO->getOpcode();
|
Instruction::BinaryOps ops = BO->getOpcode();
|
||||||
|
|
||||||
switch (ops) {
|
switch (ops) {
|
||||||
|
Reference in New Issue
Block a user