llvm.org GIT mirror llvm / a0b59f6
Add a prototype of a new peephole optimizing pass that uses LazyValue info to simplify PHIs and select's. This pass addresses the missed optimizations from PR2581 and PR4420. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112325 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 10 years ago
6 changed file(s) with 165 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
148148 (void) llvm::createLintPass();
149149 (void) llvm::createSinkingPass();
150150 (void) llvm::createLowerAtomicPass();
151 (void) llvm::createValuePropagationPass();
151152
152153 (void)new llvm::IntervalPartition();
153154 (void)new llvm::FindUsedTypes();
342342 //
343343 Pass *createLowerAtomicPass();
344344
345 //===----------------------------------------------------------------------===//
346 //
347 // ValuePropagation - Propagate CFG-derived value information
348 //
349 Pass *createValuePropagationPass();
350
345351 } // End llvm namespace
346352
347353 #endif
0 //===- ValuePropagation.cpp - Propagate information derived control flow --===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Value Propagation pass.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "value-propagation"
14 #include "llvm/Transforms/Scalar.h"
15 #include "llvm/Function.h"
16 #include "llvm/Instructions.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Analysis/LazyValueInfo.h"
19 #include "llvm/Transforms/Utils/Local.h"
20 using namespace llvm;
21
22 namespace {
23 class ValuePropagation : public FunctionPass {
24 LazyValueInfo *LVI;
25
26 bool processSelect(SelectInst *SI);
27 bool processPHI(PHINode *P);
28
29 public:
30 static char ID;
31 ValuePropagation(): FunctionPass(ID) { }
32
33 bool runOnFunction(Function &F);
34
35 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
36 AU.addRequired();
37 }
38 };
39 }
40
41 char ValuePropagation::ID = 0;
42 INITIALIZE_PASS(ValuePropagation, "value-propagation",
43 "Value Propagation", false, false);
44
45 // Public interface to the Value Propagation pass
46 Pass *llvm::createValuePropagationPass() {
47 return new ValuePropagation();
48 }
49
50 bool ValuePropagation::processSelect(SelectInst *S) {
51 Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
52 if (!C) return false;
53
54 ConstantInt *CI = dyn_cast(C);
55 if (!CI) return false;
56
57 if (CI->isZero()) {
58 S->replaceAllUsesWith(S->getOperand(2));
59 S->eraseFromParent();
60 } else if (CI->isOne()) {
61 S->replaceAllUsesWith(S->getOperand(1));
62 S->eraseFromParent();
63 } else {
64 assert(0 && "Select on constant is neither 0 nor 1?");
65 }
66
67 return true;
68 }
69
70 bool ValuePropagation::processPHI(PHINode *P) {
71 bool changed = false;
72
73 BasicBlock *BB = P->getParent();
74 for (unsigned i = 0; i < P->getNumIncomingValues(); ++i) {
75 Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i),
76 P->getIncomingBlock(i),
77 BB);
78 if (!C || C == P->getIncomingValue(i)) continue;
79
80 P->setIncomingValue(i, C);
81 changed = true;
82 }
83
84 if (Value *ConstVal = P->hasConstantValue()) {
85 P->replaceAllUsesWith(ConstVal);
86 P->eraseFromParent();
87 changed = true;
88 }
89
90 return changed;
91 }
92
93 bool ValuePropagation::runOnFunction(Function &F) {
94 LVI = &getAnalysis();
95
96 bool changed = false;
97
98 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
99 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
100 Instruction *II = BI++;
101 if (SelectInst *SI = dyn_cast(II))
102 changed |= processSelect(SI);
103 else if (PHINode *P = dyn_cast(II))
104 changed |= processPHI(P);
105 }
106
107 if (changed)
108 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
109 SimplifyInstructionsInBlock(FI);
110
111 return changed;
112 }
0 load_lib llvm.exp
1
2 RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]]
0 ; RUN: opt < %s -value-propagation -S | FileCheck %s
1 ; PR2581
2
3 ; CHECK: @run
4 define i32 @run(i1 %C) nounwind {
5 br i1 %C, label %exit, label %body
6
7 body: ; preds = %0
8 ; CHECK-NOT: select
9 %A = select i1 %C, i32 10, i32 11 ; [#uses=1]
10 ; CHECK: ret i32 11
11 ret i32 %A
12
13 exit: ; preds = %0
14 ; CHECK: ret i32 10
15 ret i32 10
16 }
0 ; RUN: opt < %s -value-propagation -S | FileCheck %s
1 ; PR4420
2
3 declare i1 @ext()
4 ; CHECK: @foo
5 define i1 @foo() {
6 entry:
7 %cond = tail call i1 @ext() ; [#uses=2]
8 br i1 %cond, label %bb1, label %bb2
9
10 bb1: ; preds = %entry
11 %cond2 = tail call i1 @ext() ; [#uses=1]
12 br i1 %cond2, label %bb3, label %bb2
13
14 bb2: ; preds = %bb1, %entry
15 ; CHECK-NOT: phi i1
16 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ] ; [#uses=1]
17 ; CHECK: ret i1 false
18 ret i1 %cond_merge
19
20 bb3: ; preds = %bb1
21 %res = tail call i1 @ext() ; [#uses=1]
22 ; CHECK: ret i1 %res
23 ret i1 %res
24 }