[CVP] Require DomTree for new Pass Manager
We were previously using a DT in CVP through SimplifyQuery, but not requiring it in the new pass manager. Hence it would crash if DT was not already available. This now gets DT directly and plumbs it through to where it is used (instead of using it through SQ). llvm-svn: 332836
This commit is contained in:
parent
563d0b9cb9
commit
8ceab61c75
|
@ -136,7 +136,7 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
|
||||||
/// -->
|
/// -->
|
||||||
/// %r = %x
|
/// %r = %x
|
||||||
static bool simplifyCommonValuePhi(PHINode *P, LazyValueInfo *LVI,
|
static bool simplifyCommonValuePhi(PHINode *P, LazyValueInfo *LVI,
|
||||||
const SimplifyQuery &SQ) {
|
DominatorTree *DT) {
|
||||||
// Collect incoming constants and initialize possible common value.
|
// Collect incoming constants and initialize possible common value.
|
||||||
SmallVector<std::pair<Constant *, unsigned>, 4> IncomingConstants;
|
SmallVector<std::pair<Constant *, unsigned>, 4> IncomingConstants;
|
||||||
Value *CommonValue = nullptr;
|
Value *CommonValue = nullptr;
|
||||||
|
@ -159,7 +159,7 @@ static bool simplifyCommonValuePhi(PHINode *P, LazyValueInfo *LVI,
|
||||||
// The common value must be valid in all incoming blocks.
|
// The common value must be valid in all incoming blocks.
|
||||||
BasicBlock *ToBB = P->getParent();
|
BasicBlock *ToBB = P->getParent();
|
||||||
if (auto *CommonInst = dyn_cast<Instruction>(CommonValue))
|
if (auto *CommonInst = dyn_cast<Instruction>(CommonValue))
|
||||||
if (!SQ.DT->dominates(CommonInst, ToBB))
|
if (!DT->dominates(CommonInst, ToBB))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// We have a phi with exactly 1 variable incoming value and 1 or more constant
|
// We have a phi with exactly 1 variable incoming value and 1 or more constant
|
||||||
|
@ -180,7 +180,7 @@ static bool simplifyCommonValuePhi(PHINode *P, LazyValueInfo *LVI,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool processPHI(PHINode *P, LazyValueInfo *LVI,
|
static bool processPHI(PHINode *P, LazyValueInfo *LVI, DominatorTree *DT,
|
||||||
const SimplifyQuery &SQ) {
|
const SimplifyQuery &SQ) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ static bool processPHI(PHINode *P, LazyValueInfo *LVI,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Changed)
|
if (!Changed)
|
||||||
Changed = simplifyCommonValuePhi(P, LVI, SQ);
|
Changed = simplifyCommonValuePhi(P, LVI, DT);
|
||||||
|
|
||||||
if (Changed)
|
if (Changed)
|
||||||
++NumPhis;
|
++NumPhis;
|
||||||
|
@ -669,7 +669,8 @@ static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
|
||||||
ConstantInt::getFalse(C->getContext());
|
ConstantInt::getFalse(C->getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
|
static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
|
||||||
|
const SimplifyQuery &SQ) {
|
||||||
bool FnChanged = false;
|
bool FnChanged = false;
|
||||||
// Visiting in a pre-order depth-first traversal causes us to simplify early
|
// Visiting in a pre-order depth-first traversal causes us to simplify early
|
||||||
// blocks before querying later blocks (which require us to analyze early
|
// blocks before querying later blocks (which require us to analyze early
|
||||||
|
@ -685,7 +686,7 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
|
||||||
BBChanged |= processSelect(cast<SelectInst>(II), LVI);
|
BBChanged |= processSelect(cast<SelectInst>(II), LVI);
|
||||||
break;
|
break;
|
||||||
case Instruction::PHI:
|
case Instruction::PHI:
|
||||||
BBChanged |= processPHI(cast<PHINode>(II), LVI, SQ);
|
BBChanged |= processPHI(cast<PHINode>(II), LVI, DT, SQ);
|
||||||
break;
|
break;
|
||||||
case Instruction::ICmp:
|
case Instruction::ICmp:
|
||||||
case Instruction::FCmp:
|
case Instruction::FCmp:
|
||||||
|
@ -750,14 +751,17 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
|
LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
|
||||||
return runImpl(F, LVI, getBestSimplifyQuery(*this, F));
|
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||||
|
|
||||||
|
return runImpl(F, LVI, DT, getBestSimplifyQuery(*this, F));
|
||||||
}
|
}
|
||||||
|
|
||||||
PreservedAnalyses
|
PreservedAnalyses
|
||||||
CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) {
|
CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||||
|
|
||||||
LazyValueInfo *LVI = &AM.getResult<LazyValueAnalysis>(F);
|
LazyValueInfo *LVI = &AM.getResult<LazyValueAnalysis>(F);
|
||||||
bool Changed = runImpl(F, LVI, getBestSimplifyQuery(AM, F));
|
DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
|
||||||
|
|
||||||
|
bool Changed = runImpl(F, LVI, DT, getBestSimplifyQuery(AM, F));
|
||||||
|
|
||||||
if (!Changed)
|
if (!Changed)
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes="correlated-propagation" -S | FileCheck %s
|
||||||
|
|
||||||
define i8* @simplify_phi_common_value_op0(i8* %ptr, i32* %b) {
|
define i8* @simplify_phi_common_value_op0(i8* %ptr, i32* %b) {
|
||||||
; CHECK-LABEL: @simplify_phi_common_value_op0(
|
; CHECK-LABEL: @simplify_phi_common_value_op0(
|
||||||
|
@ -92,3 +93,33 @@ return:
|
||||||
ret i8 %r
|
ret i8 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i8* @simplify_phi_common_value_from_instruction(i8* %ptr_op, i32* %b, i32 %i) {
|
||||||
|
; CHECK-LABEL: @simplify_phi_common_value_from_instruction(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: [[PTR:%.*]] = getelementptr i8, i8* [[PTR_OP:%.*]], i32 [[I:%.*]]
|
||||||
|
; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i8* [[PTR]], null
|
||||||
|
; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]
|
||||||
|
; CHECK: else:
|
||||||
|
; CHECK-NEXT: [[LB:%.*]] = load i32, i32* [[B:%.*]]
|
||||||
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LB]], 1
|
||||||
|
; CHECK-NEXT: store i32 [[ADD]], i32* [[B]]
|
||||||
|
; CHECK-NEXT: br label [[RETURN]]
|
||||||
|
; CHECK: return:
|
||||||
|
; CHECK-NEXT: ret i8* [[PTR]]
|
||||||
|
;
|
||||||
|
entry:
|
||||||
|
%ptr = getelementptr i8, i8* %ptr_op, i32 %i
|
||||||
|
%isnull = icmp eq i8* %ptr, null
|
||||||
|
br i1 %isnull, label %return, label %else
|
||||||
|
|
||||||
|
else:
|
||||||
|
%lb = load i32, i32* %b
|
||||||
|
%add = add nsw i32 %lb, 1
|
||||||
|
store i32 %add, i32* %b
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return:
|
||||||
|
%r = phi i8* [ %ptr, %else ], [ null, %entry ]
|
||||||
|
ret i8* %r
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue