llvm.org GIT mirror llvm / 413e39f
Recommit r333268: [IPSCCP] Use PredicateInfo to propagate facts from cmp instructions. r337828 resolves a PredicateInfo issue with unnamed types. Original message: 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337904 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 1 year, 1 month ago
8 changed file(s) with 161 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 continue;
2065 }
2066 }
2067 Inst->replaceAllUsesWith(PI->OriginalOp);
2068 Inst->eraseFromParent();
2069 }
2070 }
2071 }
19622072 }
19632073
19642074 // 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()
269270 ; CHECK-NEXT: Module Verifier
270271 ; CHECK-NEXT: Bitcode Writer
271272 ; CHECK-NEXT: Pass Arguments:
273 ; CHECK-NEXT: FunctionPass Manager
274 ; CHECK-NEXT: Dominator Tree Construction
275 ; CHECK-NEXT: Pass Arguments:
272276 ; CHECK-NEXT: Target Library Information
273277 ; CHECK-NEXT: FunctionPass Manager
274278 ; CHECK-NEXT: Dominator Tree Construction
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()
273274 ; CHECK-NEXT: Module Verifier
274275 ; CHECK-NEXT: Bitcode Writer
275276 ; CHECK-NEXT: Pass Arguments:
277 ; CHECK-NEXT: FunctionPass Manager
278 ; CHECK-NEXT: Dominator Tree Construction
279 ; CHECK-NEXT: Pass Arguments:
276280 ; CHECK-NEXT: Target Library Information
277281 ; CHECK-NEXT: FunctionPass Manager
278282 ; CHECK-NEXT: Dominator Tree Construction
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()
256257 ; CHECK-NEXT: Module Verifier
257258 ; CHECK-NEXT: Bitcode Writer
258259 ; CHECK-NEXT: Pass Arguments:
260 ; CHECK-NEXT: FunctionPass Manager
261 ; CHECK-NEXT: Dominator Tree Construction
262 ; CHECK-NEXT: Pass Arguments:
259263 ; CHECK-NEXT: Target Library Information
260264 ; CHECK-NEXT: FunctionPass Manager
261265 ; 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