[llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Dec 10 12:42:04 PST 2004
Changes in directory llvm/lib/Transforms/Scalar:
SCCP.cpp updated: 1.112 -> 1.113
---
Log message:
Fix SCCP/2004-12-10-UndefBranchBug.ll
---
Diffs of the changes: (+51 -3)
Index: llvm/lib/Transforms/Scalar/SCCP.cpp
diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.112 llvm/lib/Transforms/Scalar/SCCP.cpp:1.113
--- llvm/lib/Transforms/Scalar/SCCP.cpp:1.112 Fri Dec 10 02:02:06 2004
+++ llvm/lib/Transforms/Scalar/SCCP.cpp Fri Dec 10 14:41:50 2004
@@ -153,6 +153,13 @@
///
void Solve();
+ /// ResolveBranchesIn - While solving the dataflow for a function, we assume
+ /// that branches on undef values cannot reach any of their successors.
+ /// However, this is not a safe assumption. After we solve dataflow, this
+ /// method should be use to handle this. If this returns true, the solver
+ /// should be rerun.
+ bool ResolveBranchesIn(Function &F);
+
/// getExecutableBlocks - Once we have solved for constants, return the set of
/// blocks that is known to be executable.
std::set<BasicBlock*> &getExecutableBlocks() {
@@ -869,6 +876,36 @@
}
}
+/// ResolveBranchesIn - While solving the dataflow for a function, we assume
+/// that branches on undef values cannot reach any of their successors.
+/// However, this is not a safe assumption. After we solve dataflow, this
+/// method should be use to handle this. If this returns true, the solver
+/// should be rerun.
+bool SCCPSolver::ResolveBranchesIn(Function &F) {
+ bool BranchesResolved = false;
+ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ TerminatorInst *TI = BB->getTerminator();
+ if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
+ if (BI->isConditional()) {
+ LatticeVal &BCValue = getValueState(BI->getCondition());
+ if (BCValue.isUndefined()) {
+ BI->setCondition(ConstantBool::True);
+ BranchesResolved = true;
+ visit(BI);
+ }
+ }
+ } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
+ LatticeVal &SCValue = getValueState(SI->getCondition());
+ if (SCValue.isUndefined()) {
+ SI->setCondition(Constant::getNullValue(SI->getCondition()->getType()));
+ BranchesResolved = true;
+ visit(SI);
+ }
+ }
+ }
+ return BranchesResolved;
+}
+
namespace {
Statistic<> NumInstRemoved("sccp", "Number of instructions removed");
@@ -916,7 +953,11 @@
Values[AI].markOverdefined();
// Solve for constants.
- Solver.Solve();
+ bool ResolvedBranches = true;
+ while (ResolvedBranches) {
+ Solver.Solve();
+ ResolvedBranches = Solver.ResolveBranchesIn(F);
+ }
bool MadeChanges = false;
@@ -1037,7 +1078,14 @@
}
// Solve for constants.
- Solver.Solve();
+ bool ResolvedBranches = true;
+ while (ResolvedBranches) {
+ Solver.Solve();
+
+ ResolvedBranches = false;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ ResolvedBranches |= Solver.ResolveBranchesIn(*F);
+ }
bool MadeChanges = false;
@@ -1065,7 +1113,7 @@
if (!ExecutableBBs.count(BB)) {
DEBUG(std::cerr << " BasicBlock Dead:" << *BB);
++IPNumDeadBlocks;
-
+
// Delete the instructions backwards, as it has a reduced likelihood of
// having to update as many def-use and use-def chains.
std::vector<Instruction*> Insts;
More information about the llvm-commits
mailing list