summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Analysis
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2019-01-21 06:19:50 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2019-01-21 06:19:50 +0000
commit85c988388af46d71a9b7f44cb0feff7ee1c144ab (patch)
tree35a94fd6fd91855c073bf38274bfd72757f94250 /llvm/unittests/Analysis
parent5e8798f987b8cda8dfb2e243309456d9be00f213 (diff)
downloadbcm5719-llvm-85c988388af46d71a9b7f44cb0feff7ee1c144ab.tar.gz
bcm5719-llvm-85c988388af46d71a9b7f44cb0feff7ee1c144ab.zip
[SCEV][NFC] Introduces expression sizes estimation
This patch introduces the field `ExpressionSize` in SCEV. This field is calculated only once on SCEV creation, and it represents the complexity of this SCEV from arithmetical point of view (not from the point of the number of actual different SCEV nodes that are used in the expression). Roughly saying, it is the number of operands and operations symbols when we print this SCEV. A formal definition is following: if SCEV `X` has operands `Op1`, `Op2`, ..., `OpN`, then Size(X) = 1 + Size(Op1) + Size(Op2) + ... + Size(OpN). Size of SCEVConstant and SCEVUnknown is one. Expression size may be used as a universal way to limit SCEV transformations for huge SCEVs. Currently, we have a bunch of options that represents various limits (such as recursion depth limit) that may not make any sense from the point of view of a LLVM users who is not familiar with SCEV internals, and all these different options pursue one goal. A more general rule that may potentially allow us to get rid of this redundancy in options is "do not make transformations with SCEVs of huge size". It can apply to all SCEV traversals and transformations that may need to visit a SCEV node more than once, hence they are prone to combinatorial explosions. This patch only introduces SCEV sizes calculation as NFC, its utilization will be introduced in follow-up patches. Differential Revision: https://reviews.llvm.org/D35989 Reviewed By: reames llvm-svn: 351725
Diffstat (limited to 'llvm/unittests/Analysis')
-rw-r--r--llvm/unittests/Analysis/ScalarEvolutionTest.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 73d93aac378..c4a2113d43b 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1389,5 +1389,55 @@ TEST_F(ScalarEvolutionsTest, SCEVCacheNSW) {
EXPECT_FALSE(I->hasNoSignedWrap());
}
+// Check logic of SCEV expression size computation.
+TEST_F(ScalarEvolutionsTest, SCEVComputeExpressionSize) {
+ /*
+ * Create the following code:
+ * void func(i64 %a, i64 %b)
+ * entry:
+ * %s1 = add i64 %a, 1
+ * %s2 = udiv i64 %s1, %b
+ * br label %exit
+ * exit:
+ * ret
+ */
+
+ // Create a module.
+ Module M("SCEVComputeExpressionSize", Context);
+
+ Type *T_int64 = Type::getInt64Ty(Context);
+
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Context), { T_int64, T_int64 }, false);
+ Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+ Argument *A = &*F->arg_begin();
+ Argument *B = &*std::next(F->arg_begin());
+ ConstantInt *C = ConstantInt::get(Context, APInt(64, 1));
+
+ BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
+ BasicBlock *Exit = BasicBlock::Create(Context, "exit", F);
+
+ IRBuilder<> Builder(Entry);
+ auto *S1 = cast<Instruction>(Builder.CreateAdd(A, C, "s1"));
+ auto *S2 = cast<Instruction>(Builder.CreateUDiv(S1, B, "s2"));
+ Builder.CreateBr(Exit);
+
+ Builder.SetInsertPoint(Exit);
+ auto *R = cast<Instruction>(Builder.CreateRetVoid());
+
+ ScalarEvolution SE = buildSE(*F);
+ // Get S2 first to move it to cache.
+ const SCEV *AS = SE.getSCEV(A);
+ const SCEV *BS = SE.getSCEV(B);
+ const SCEV *CS = SE.getSCEV(C);
+ const SCEV *S1S = SE.getSCEV(S1);
+ const SCEV *S2S = SE.getSCEV(S2);
+ EXPECT_EQ(AS->getExpressionSize(), 1);
+ EXPECT_EQ(BS->getExpressionSize(), 1);
+ EXPECT_EQ(CS->getExpressionSize(), 1);
+ EXPECT_EQ(S1S->getExpressionSize(), 3);
+ EXPECT_EQ(S2S->getExpressionSize(), 5);
+}
+
} // end anonymous namespace
} // end namespace llvm
OpenPOWER on IntegriCloud