llvm.org GIT mirror llvm / dcf21c6
Recommit r333268: [IPSCCP] Use PredicateInfo to propagate facts from cmp instructions. This version of the patch fixes cleaning up ssa_copy intrinsics, so it does not crash for instructions in blocks that have been marked unreachable. This patch updates IPSCCP to use PredicateInfo to propagate facts to true branches predicated by EQ and to false branches predicated by NE. As a follow up, we should be able to extend it to also propagate additional facts about nonnull. Reviewers: davide, mssimpso, dberlin, efriedma Reviewed By: davide, dberlin Differential Revision: https://reviews.llvm.org/D45330 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340525 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 1 year, 28 days ago
8 changed file(s) with 158 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
2020 #ifndef LLVM_TRANSFORMS_SCALAR_SCCP_H
2121 #define LLVM_TRANSFORMS_SCALAR_SCCP_H
2222
23 #include "llvm/ADT/STLExtras.h"
2324 #include "llvm/Analysis/TargetLibraryInfo.h"
2425 #include "llvm/IR/DataLayout.h"
2526 #include "llvm/IR/Function.h"
2627 #include "llvm/IR/Module.h"
2728 #include "llvm/IR/PassManager.h"
29 #include "llvm/Transforms/Utils/PredicateInfo.h"
2830
2931 namespace llvm {
3032
3638 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
3739 };
3840
39 bool runIPSCCP(Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI);
41 bool runIPSCCP(
42 Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI,
43 function_ref(Function &)> getPredicateInfo);
4044 } // end namespace llvm
4145
4246 #endif // LLVM_TRANSFORMS_SCALAR_SCCP_H
0 #include "llvm/Transforms/IPO/SCCP.h"
1 #include "llvm/Analysis/AssumptionCache.h"
12 #include "llvm/Analysis/TargetLibraryInfo.h"
23 #include "llvm/Transforms/IPO.h"
34 #include "llvm/Transforms/Scalar/SCCP.h"
78 PreservedAnalyses IPSCCPPass::run(Module &M, ModuleAnalysisManager &AM) {
89 const DataLayout &DL = M.getDataLayout();
910 auto &TLI = AM.getResult(M);
10 if (!runIPSCCP(M, DL, &TLI))
11 auto &FAM = AM.getResult(M).getManager();
12 auto getPredicateInfo =
13 [&FAM](Function &F) -> std::unique_ptr {
14 return make_unique(F,
15 FAM.getResult(F),
16 FAM.getResult(F));
17 };
18
19 if (!runIPSCCP(M, DL, &TLI, getPredicateInfo))
1120 return PreservedAnalyses::all();
1221 return PreservedAnalyses::none();
1322 }
3342 const DataLayout &DL = M.getDataLayout();
3443 const TargetLibraryInfo *TLI =
3544 &getAnalysis().getTLI();
36 return runIPSCCP(M, DL, TLI);
45
46 auto getPredicateInfo =
47 [this](Function &F) -> std::unique_ptr {
48 return make_unique(
49 F, this->getAnalysis(F).getDomTree(),
50 this->getAnalysis().getAssumptionCache(F));
51 };
52
53 return runIPSCCP(M, DL, TLI, getPredicateInfo);
3754 }
3855
3956 void getAnalysisUsage(AnalysisUsage &AU) const override {
57 AU.addRequired();
58 AU.addRequired();
4059 AU.addRequired();
4160 }
4261 };
4867 INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp",
4968 "Interprocedural Sparse Conditional Constant Propagation",
5069 false, false)
70 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
5171 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
5272 INITIALIZE_PASS_END(IPSCCPLegacyPass, "ipsccp",
5373 "Interprocedural Sparse Conditional Constant Propagation",
5454 #include "llvm/Support/ErrorHandling.h"
5555 #include "llvm/Support/raw_ostream.h"
5656 #include "llvm/Transforms/Scalar.h"
57 #include "llvm/Transforms/Utils/PredicateInfo.h"
5758 #include
5859 #include
5960 #include
245246 using Edge = std::pair;
246247 DenseSet KnownFeasibleEdges;
247248
249 DenseMap> PredInfos;
250 DenseMap> AdditionalUsers;
251
248252 public:
253 void addPredInfo(Function &F, std::unique_ptr PI) {
254 PredInfos[&F] = std::move(PI);
255 }
256
257 const PredicateBase *getPredicateInfoFor(Instruction *I) {
258 auto PI = PredInfos.find(I->getFunction());
259 if (PI == PredInfos.end())
260 return nullptr;
261 return PI->second->getPredicateInfoFor(I);
262 }
263
249264 SCCPSolver(const DataLayout &DL, const TargetLibraryInfo *tli)
250265 : DL(DL), TLI(tli) {}
251266
555570 void OperandChangedState(Instruction *I) {
556571 if (BBExecutable.count(I->getParent())) // Inst is executable?
557572 visit(*I);
573 }
574
575 // Add U as additional user of V.
576 void addAdditionalUser(Value *V, User *U) {
577 auto Iter = AdditionalUsers.insert({V, {}});
578 Iter.first->second.insert(U);
579 }
580
581 // Mark I's users as changed, including AdditionalUsers.
582 void markUsersAsChanged(Value *I) {
583 for (User *U : I->users())
584 if (auto *UI = dyn_cast(U))
585 OperandChangedState(UI);
586
587 auto Iter = AdditionalUsers.find(I);
588 if (Iter != AdditionalUsers.end()) {
589 for (User *U : Iter->second)
590 if (auto *UI = dyn_cast(U))
591 OperandChangedState(UI);
592 }
558593 }
559594
560595 private:
11181153 Function *F = CS.getCalledFunction();
11191154 Instruction *I = CS.getInstruction();
11201155
1156 if (auto *II = dyn_cast(I)) {
1157 if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
1158 if (ValueState[I].isOverdefined())
1159 return;
1160
1161 auto *PI = getPredicateInfoFor(I);
1162 if (!PI)
1163 return;
1164
1165 auto *PBranch = dyn_cast(getPredicateInfoFor(I));
1166 if (!PBranch) {
1167 mergeInValue(ValueState[I], I, getValueState(PI->OriginalOp));
1168 return;
1169 }
1170
1171 Value *CopyOf = I->getOperand(0);
1172 Value *Cond = PBranch->Condition;
1173
1174 // Everything below relies on the condition being a comparison.
1175 auto *Cmp = dyn_cast(Cond);
1176 if (!Cmp) {
1177 mergeInValue(ValueState[I], I, getValueState(PI->OriginalOp));
1178 return;
1179 }
1180
1181 Value *CmpOp0 = Cmp->getOperand(0);
1182 Value *CmpOp1 = Cmp->getOperand(1);
1183 if (CopyOf != CmpOp0 && CopyOf != CmpOp1) {
1184 mergeInValue(ValueState[I], I, getValueState(PI->OriginalOp));
1185 return;
1186 }
1187
1188 if (CmpOp0 != CopyOf)
1189 std::swap(CmpOp0, CmpOp1);
1190
1191 LatticeVal OriginalVal = getValueState(CopyOf);
1192 LatticeVal EqVal = getValueState(CmpOp1);
1193 LatticeVal &IV = ValueState[I];
1194 if (PBranch->TrueEdge && Cmp->getPredicate() == CmpInst::ICMP_EQ) {
1195 addAdditionalUser(CmpOp1, I);
1196 if (OriginalVal.isConstant())
1197 mergeInValue(IV, I, OriginalVal);
1198 else
1199 mergeInValue(IV, I, EqVal);
1200 return;
1201 }
1202 if (!PBranch->TrueEdge && Cmp->getPredicate() == CmpInst::ICMP_NE) {
1203 addAdditionalUser(CmpOp1, I);
1204 if (OriginalVal.isConstant())
1205 mergeInValue(IV, I, OriginalVal);
1206 else
1207 mergeInValue(IV, I, EqVal);
1208 return;
1209 }
1210
1211 return (void)mergeInValue(IV, I, getValueState(PBranch->OriginalOp));
1212 }
1213 }
1214
11211215 // The common case is that we aren't tracking the callee, either because we
11221216 // are not doing interprocedural analysis or the callee is indirect, or is
11231217 // external. Handle these cases first.
12371331 // since all of its users will have already been marked as overdefined
12381332 // Update all of the users of this instruction's value.
12391333 //
1240 for (User *U : I->users())
1241 if (auto *UI = dyn_cast(U))
1242 OperandChangedState(UI);
1334 markUsersAsChanged(I);
12431335 }
12441336
12451337 // Process the instruction work list.
12561348 // Update all of the users of this instruction's value.
12571349 //
12581350 if (I->getType()->isStructTy() || !getValueState(I).isOverdefined())
1259 for (User *U : I->users())
1260 if (auto *UI = dyn_cast(U))
1261 OperandChangedState(UI);
1351 markUsersAsChanged(I);
12621352 }
12631353
12641354 // Process the basic block work list.
17971887 }
17981888 }
17991889
1800 bool llvm::runIPSCCP(Module &M, const DataLayout &DL,
1801 const TargetLibraryInfo *TLI) {
1890 bool llvm::runIPSCCP(
1891 Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI,
1892 function_ref(Function &)> getPredicateInfo) {
18021893 SCCPSolver Solver(DL, TLI);
18031894
18041895 // Loop over all functions, marking arguments to those with their addresses
18071898 if (F.isDeclaration())
18081899 continue;
18091900
1901 Solver.addPredInfo(F, getPredicateInfo(F));
18101902 // Determine if we can track the function's return values. If so, add the
18111903 // function to the solver's set of return-tracked functions.
18121904 if (canTrackReturnsInterprocedurally(&F))
19592051 F.getBasicBlockList().erase(DeadBB);
19602052 }
19612053 BlocksToErase.clear();
2054
2055 for (BasicBlock &BB : F) {
2056 for (BasicBlock::iterator BI = BB.begin(), E = BB.end(); BI != E;) {
2057 Instruction *Inst = &*BI++;
2058 if (const PredicateBase *PI = Solver.getPredicateInfoFor(Inst)) {
2059 if (auto *II = dyn_cast(Inst)) {
2060 if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
2061 Value *Op = II->getOperand(0);
2062 Inst->replaceAllUsesWith(Op);
2063 Inst->eraseFromParent();
2064 }
2065 }
2066 }
2067 }
2068 }
19622069 }
19632070
19642071 // If we inferred constant or undef return values for a function, we replaced
4040 ; CHECK-O2-NEXT: Running analysis: ProfileSummaryAnalysis
4141 ; CHECK-O2-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
4242 ; CHECK-O2-NEXT: Running pass: IPSCCPPass
43 ; CHECK-O2-DAG: Running analysis: AssumptionAnalysis on foo
44 ; CHECK-O2-DAG: Running analysis: DominatorTreeAnalysis on foo
4345 ; CHECK-O2-NEXT: Running pass: CalledValuePropagationPass
4446 ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}PostOrderFunctionAttrsPass>
4547 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}SCC
5658 ; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
5759 ; CHECK-O2-NEXT: Running pass: GlobalOptPass
5860 ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PromotePass>
59 ; CHECK-O2-NEXT: Running analysis: DominatorTreeAnalysis
60 ; CHECK-O2-NEXT: Running analysis: AssumptionAnalysis
6161 ; CHECK-O2-NEXT: Running pass: ConstantMergePass
6262 ; CHECK-O2-NEXT: Running pass: DeadArgumentEliminationPass
6363 ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
2727 ; CHECK-NEXT: Force set function attributes
2828 ; CHECK-NEXT: Infer set function attributes
2929 ; CHECK-NEXT: Interprocedural Sparse Conditional Constant Propagation
30 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
3031 ; CHECK-NEXT: Called Value Propagation
3132 ; CHECK-NEXT: Global Variable Optimizer
3233 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
275276 ; CHECK-NEXT: Simplify the CFG
276277 ; CHECK-NEXT: Module Verifier
277278 ; CHECK-NEXT: Bitcode Writer
279 ; CHECK-NEXT: Pass Arguments:
280 ; CHECK-NEXT: FunctionPass Manager
281 ; CHECK-NEXT: Dominator Tree Construction
278282 ; CHECK-NEXT: Pass Arguments:
279283 ; CHECK-NEXT: Target Library Information
280284 ; CHECK-NEXT: FunctionPass Manager
2929 ; CHECK-NEXT: FunctionPass Manager
3030 ; CHECK-NEXT: Call-site splitting
3131 ; CHECK-NEXT: Interprocedural Sparse Conditional Constant Propagation
32 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
3233 ; CHECK-NEXT: Called Value Propagation
3334 ; CHECK-NEXT: Global Variable Optimizer
3435 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
279280 ; CHECK-NEXT: Simplify the CFG
280281 ; CHECK-NEXT: Module Verifier
281282 ; CHECK-NEXT: Bitcode Writer
283 ; CHECK-NEXT: Pass Arguments:
284 ; CHECK-NEXT: FunctionPass Manager
285 ; CHECK-NEXT: Dominator Tree Construction
282286 ; CHECK-NEXT: Pass Arguments:
283287 ; CHECK-NEXT: Target Library Information
284288 ; CHECK-NEXT: FunctionPass Manager
2727 ; CHECK-NEXT: Force set function attributes
2828 ; CHECK-NEXT: Infer set function attributes
2929 ; CHECK-NEXT: Interprocedural Sparse Conditional Constant Propagation
30 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
3031 ; CHECK-NEXT: Called Value Propagation
3132 ; CHECK-NEXT: Global Variable Optimizer
3233 ; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
263264 ; CHECK-NEXT: Module Verifier
264265 ; CHECK-NEXT: Bitcode Writer
265266 ; CHECK-NEXT: Pass Arguments:
267 ; CHECK-NEXT: FunctionPass Manager
268 ; CHECK-NEXT: Dominator Tree Construction
269 ; CHECK-NEXT: Pass Arguments:
266270 ; CHECK-NEXT: Target Library Information
267271 ; CHECK-NEXT: FunctionPass Manager
268272 ; CHECK-NEXT: Dominator Tree Construction
88 %c1 = icmp eq i8 %v, 0
99 br i1 %c1, label %true, label %false
1010 true:
11 ; CHECK: %ca = musttail call i8* @side_effects(i8 %v)
11 ; CHECK: %ca = musttail call i8* @side_effects(i8 0)
1212 ; CHECK: ret i8* %ca
1313 %ca = musttail call i8* @side_effects(i8 %v)
1414 ret i8* %ca
3333 ; is always `null`.
3434 ; The call can't be removed due to `external` call above, though.
3535
36 ; CHECK: %ca = musttail call i8* @start(i8 %v)
36 ; CHECK: %ca = musttail call i8* @start(i8 0)
3737 %ca = musttail call i8* @start(i8 %v)
3838
3939 ; Thus the result must be returned anyway