llvm.org GIT mirror llvm / f0a5715
[SCEV] Memoize visitMulExpr results in SCEVRewriteVisitor. Summary: When SCEVRewriteVisitor traverses the SCEV DAG, it may visit the same SCEV multiple times if this SCEV is referenced by multiple other SCEVs. This has exponential time complexity in the worst case. Memoizing the results will avoid re-visiting the same SCEV. Add a map to save the results, and override the visit function of SCEVVisitor. Now SCEVRewriteVisitor only visit each SCEV once and thus returns the same result for the same input SCEV. This patch fixes PR18606, PR18607. Reviewers: Sanjoy Das, Mehdi Amini, Michael Zolotukhin Differential Revision: https://reviews.llvm.org/D25810 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284868 91177308-0d34-0410-b5e6-96231b3b80d8 Li Huang 3 years ago
2 changed file(s) with 87 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
536536 T.visitAll(Root);
537537 }
538538
539 /// Recursively visits a SCEV expression and re-writes it.
539 /// This visitor recursively visits a SCEV expression and re-writes it.
540 /// The result from each visit is cached, so it will return the same
541 /// SCEV for the same input.
540542 template
541543 class SCEVRewriteVisitor : public SCEVVisitor {
542544 protected:
543545 ScalarEvolution &SE;
546 // Memoize the result of each visit so that we only compute once for
547 // the same input SCEV. This is to avoid redundant computations when
548 // a SCEV is referenced by multiple SCEVs. Without memoization, this
549 // visit algorithm would have exponential time complexity in the worst
550 // case, causing the compiler to hang on certain tests.
551 DenseMap RewriteResults;
552
544553 public:
545554 SCEVRewriteVisitor(ScalarEvolution &SE) : SE(SE) {}
555
556 const SCEV *visit(const SCEV *S) {
557 auto It = RewriteResults.find(S);
558 if (It != RewriteResults.end())
559 return It->second;
560 auto *Result = SCEVVisitor::visit(S);
561 assert(RewriteResults.insert({S, Result}).second &&
562 "Should insert a new entry");
563 return Result;
564 }
546565
547566 const SCEV *visitConstant(const SCEVConstant *Constant) {
548567 return Constant;
0 ; RUN: opt -S -indvars < %s | FileCheck %s
1
2 ; CHECK: @main
3 ; CHECK: %mul.lcssa5 = phi i32 [ %a.promoted4, %entry ], [ %mul.30, %for.body3 ]
4 ; CEHCK: %mul = mul nsw i32 %mul.lcssa5, %mul.lcssa5
5 ; CHECK: %mul.30 = mul nsw i32 %mul.29, %mul.29
6
7 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8 target triple = "x86_64-unknown-linux-gnu"
9
10 @a = local_unnamed_addr global i32 0, align 4
11 @b = local_unnamed_addr global i32 0, align 4
12
13 ; Function Attrs: norecurse nounwind uwtable
14 define i32 @main() local_unnamed_addr {
15 entry:
16 %a.promoted4 = load i32, i32* @a, align 4
17 br label %for.cond1.preheader
18
19 for.cond1.preheader: ; preds = %entry, %for.body3
20 %mul.lcssa5 = phi i32 [ %a.promoted4, %entry ], [ %mul.30, %for.body3 ]
21 %i.03 = phi i32 [ 0, %entry ], [ %inc5, %for.body3 ]
22 br label %for.body3
23
24 for.body3: ; preds = %for.cond1.preheader
25 %mul = mul nsw i32 %mul.lcssa5, %mul.lcssa5
26 %mul.1 = mul nsw i32 %mul, %mul
27 %mul.2 = mul nsw i32 %mul.1, %mul.1
28 %mul.3 = mul nsw i32 %mul.2, %mul.2
29 %mul.4 = mul nsw i32 %mul.3, %mul.3
30 %mul.5 = mul nsw i32 %mul.4, %mul.4
31 %mul.6 = mul nsw i32 %mul.5, %mul.5
32 %mul.7 = mul nsw i32 %mul.6, %mul.6
33 %mul.8 = mul nsw i32 %mul.7, %mul.7
34 %mul.9 = mul nsw i32 %mul.8, %mul.8
35 %mul.10 = mul nsw i32 %mul.9, %mul.9
36 %mul.11 = mul nsw i32 %mul.10, %mul.10
37 %mul.12 = mul nsw i32 %mul.11, %mul.11
38 %mul.13 = mul nsw i32 %mul.12, %mul.12
39 %mul.14 = mul nsw i32 %mul.13, %mul.13
40 %mul.15 = mul nsw i32 %mul.14, %mul.14
41 %mul.16 = mul nsw i32 %mul.15, %mul.15
42 %mul.17 = mul nsw i32 %mul.16, %mul.16
43 %mul.18 = mul nsw i32 %mul.17, %mul.17
44 %mul.19 = mul nsw i32 %mul.18, %mul.18
45 %mul.20 = mul nsw i32 %mul.19, %mul.19
46 %mul.21 = mul nsw i32 %mul.20, %mul.20
47 %mul.22 = mul nsw i32 %mul.21, %mul.21
48 %mul.23 = mul nsw i32 %mul.22, %mul.22
49 %mul.24 = mul nsw i32 %mul.23, %mul.23
50 %mul.25 = mul nsw i32 %mul.24, %mul.24
51 %mul.26 = mul nsw i32 %mul.25, %mul.25
52 %mul.27 = mul nsw i32 %mul.26, %mul.26
53 %mul.28 = mul nsw i32 %mul.27, %mul.27
54 %mul.29 = mul nsw i32 %mul.28, %mul.28
55 %mul.30 = mul nsw i32 %mul.29, %mul.29
56 %inc5 = add nuw nsw i32 %i.03, 1
57 %exitcond = icmp ne i32 %inc5, 10
58 br i1 %exitcond, label %for.cond1.preheader, label %for.end6
59
60 for.end6: ; preds = %for.body3
61 %mul.lcssa.lcssa = phi i32 [ %mul.30, %for.body3 ]
62 %inc.lcssa.lcssa = phi i32 [ 31, %for.body3 ]
63 store i32 %mul.lcssa.lcssa, i32* @a, align 4
64 store i32 %inc.lcssa.lcssa, i32* @b, align 4
65 ret i32 0
66 }