[llvm] r318377 - [SCEV][NFC] Introduce isSafeToExpandAt function to SCEVExpander
Max Kazantsev via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 15 21:10:56 PST 2017
Author: mkazantsev
Date: Wed Nov 15 21:10:56 2017
New Revision: 318377
URL: http://llvm.org/viewvc/llvm-project?rev=318377&view=rev
Log:
[SCEV][NFC] Introduce isSafeToExpandAt function to SCEVExpander
This function checks that:
1) It is safe to expand a SCEV;
2) It is OK to materialize it at the specified location.
For example, attempt to expand a loop's AddRec to the same loop's preheader should fail.
Differential Revision: https://reviews.llvm.org/D39236
Modified:
llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h
llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp
Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=318377&r1=318376&r2=318377&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Wed Nov 15 21:10:56 2017
@@ -27,9 +27,16 @@ namespace llvm {
class TargetTransformInfo;
/// Return true if the given expression is safe to expand in the sense that
- /// all materialized values are safe to speculate.
+ /// all materialized values are safe to speculate anywhere their operands are
+ /// defined.
bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
+ /// Return true if the given expression is safe to expand in the sense that
+ /// all materialized values are defined and safe to speculate at the specified
+ /// location and their operands are defined at this location.
+ bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
+ ScalarEvolution &SE);
+
/// This class uses information about analyze scalars to rewrite expressions
/// in canonical form.
///
Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=318377&r1=318376&r2=318377&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Nov 15 21:10:56 2017
@@ -2293,4 +2293,9 @@ bool isSafeToExpand(const SCEV *S, Scala
visitAll(S, Search);
return !Search.IsUnsafe;
}
+
+bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
+ ScalarEvolution &SE) {
+ return isSafeToExpand(S, SE) && SE.dominates(S, InsertionPoint->getParent());
+}
}
Modified: llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp?rev=318377&r1=318376&r2=318377&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp Wed Nov 15 21:10:56 2017
@@ -1113,5 +1113,76 @@ TEST_F(ScalarEvolutionsTest, SCEVFoldSum
EXPECT_EQ(Expr, ZeroConst);
}
+// Check that we can correctly identify the points at which the SCEV of the
+// AddRec can be expanded.
+TEST_F(ScalarEvolutionsTest, SCEVExpanderIsSafeToExpandAt) {
+ /*
+ * Create the following code:
+ * func(i64 addrspace(10)* %arg)
+ * top:
+ * br label %L.ph
+ * L.ph:
+ * br label %L
+ * L:
+ * %phi = phi i64 [i64 0, %L.ph], [ %add, %L2 ]
+ * %add = add i64 %phi2, 1
+ * %cond = icmp slt i64 %add, 1000; then becomes 2000.
+ * br i1 %cond, label %post, label %L2
+ * post:
+ * ret void
+ *
+ */
+
+ // Create a module with non-integral pointers in it's datalayout
+ Module NIM("nonintegral", Context);
+ std::string DataLayout = M.getDataLayoutStr();
+ if (!DataLayout.empty())
+ DataLayout += "-";
+ DataLayout += "ni:10";
+ NIM.setDataLayout(DataLayout);
+
+ Type *T_int64 = Type::getInt64Ty(Context);
+ Type *T_pint64 = T_int64->getPointerTo(10);
+
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
+ Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+
+ BasicBlock *Top = BasicBlock::Create(Context, "top", F);
+ BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
+ BasicBlock *L = BasicBlock::Create(Context, "L", F);
+ BasicBlock *Post = BasicBlock::Create(Context, "post", F);
+
+ IRBuilder<> Builder(Top);
+ Builder.CreateBr(LPh);
+
+ Builder.SetInsertPoint(LPh);
+ Builder.CreateBr(L);
+
+ Builder.SetInsertPoint(L);
+ PHINode *Phi = Builder.CreatePHI(T_int64, 2);
+ auto *Add = cast<Instruction>(
+ Builder.CreateAdd(Phi, ConstantInt::get(T_int64, 1), "add"));
+ auto *Limit = ConstantInt::get(T_int64, 1000);
+ auto *Cond = cast<Instruction>(
+ Builder.CreateICmp(ICmpInst::ICMP_SLT, Add, Limit, "cond"));
+ Builder.CreateCondBr(Cond, L, Post);
+ Phi->addIncoming(ConstantInt::get(T_int64, 0), LPh);
+ Phi->addIncoming(Add, L);
+
+ Builder.SetInsertPoint(Post);
+ Builder.CreateRetVoid();
+
+ ScalarEvolution SE = buildSE(*F);
+ const SCEV *S = SE.getSCEV(Phi);
+ EXPECT_TRUE(isa<SCEVAddRecExpr>(S));
+ const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(S);
+ EXPECT_TRUE(AR->isAffine());
+ EXPECT_FALSE(isSafeToExpandAt(AR, Top->getTerminator(), SE));
+ EXPECT_FALSE(isSafeToExpandAt(AR, LPh->getTerminator(), SE));
+ EXPECT_TRUE(isSafeToExpandAt(AR, L->getTerminator(), SE));
+ EXPECT_TRUE(isSafeToExpandAt(AR, Post->getTerminator(), SE));
+}
+
} // end anonymous namespace
} // end namespace llvm
More information about the llvm-commits
mailing list