summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-15 20:02:12 +0000
committerChris Lattner <sabre@nondot.org>2009-11-15 20:02:12 +0000
commit773587859185937b683951a8d6285a52bf78cc9d (patch)
tree44a1da88c87c1b88f6256128ac9d6c6613ede8b4 /llvm/lib/Analysis/LazyValueInfo.cpp
parentb0c0a0df3e08639b3ac8e668cff1dda7161bc868 (diff)
downloadbcm5719-llvm-773587859185937b683951a8d6285a52bf78cc9d.tar.gz
bcm5719-llvm-773587859185937b683951a8d6285a52bf78cc9d.zip
teach LVI to infer edge information from switch instructions.
This allows JT to eliminate a ton of infeasible edges when handling code like the templates in PatternMatch.h llvm-svn: 88869
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 3148acaac4e..1f7f1933913 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -403,8 +403,10 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
}
-/// getEdgeValue - This method
+/// getEdgeValue - This method attempts to infer more complex
LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) {
+ // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we
+ // know that v != 0.
if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) {
// If this is a conditional branch and only one successor goes to BBTo, then
// we maybe able to infer something from the condition.
@@ -433,11 +435,27 @@ LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) {
}
}
}
-
- // TODO: Info from switch.
-
- // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we
- // know that v != 0.
+
+ // If the edge was formed by a switch on the value, then we may know exactly
+ // what it is.
+ if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) {
+ // If BBTo is the default destination of the switch, we don't know anything.
+ // Given a more powerful range analysis we could know stuff.
+ if (SI->getCondition() == Val && SI->getDefaultDest() != BBTo) {
+ // We only know something if there is exactly one value that goes from
+ // BBFrom to BBTo.
+ unsigned NumEdges = 0;
+ ConstantInt *EdgeVal = 0;
+ for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
+ if (SI->getSuccessor(i) != BBTo) continue;
+ if (NumEdges++) break;
+ EdgeVal = SI->getCaseValue(i);
+ }
+ assert(EdgeVal && "Missing successor?");
+ if (NumEdges == 1)
+ return LVILatticeVal::get(EdgeVal);
+ }
+ }
// Otherwise see if the value is known in the block.
return getBlockValue(BBFrom);
OpenPOWER on IntegriCloud