[llvm-commits] [LLVMdev] [polly] scev codegen (first step to remove the dependence on ivcanon pass)
Sebastian Pop
spop at codeaurora.org
Thu Dec 13 12:32:17 PST 2012
Ping.
Thanks,
Sebastian
Sebastian Pop wrote:
> Hi Tobi,
>
> here is the first part of removing the ivcanon pass: the two patches for llvm
> are implementing the scev apply function and the parameter rewriter (based on
> your previous code SCEVRewriter). On the Polly side the two patches are first
> collecting the LoopToScev map and using the apply function and the parameter
> rewriter.
>
> Ok to commit?
>
> Thanks,
> Sebastian
>
> Sebastian Pop wrote:
> > Hi Tobi,
> >
> > I would like to remove the SCEVRewriter code and replace it with a call to
> > SCEVAddRec::apply (see attached a patch that adds just this function). More
> > precisely I want to add another function called apply_map that applies a map
> > (loop -> expr) on a given scev. This is the apply function on a multi-variate
> > polynomial.
> >
> > So here is an overview of how I would like the scev code generator to work on an
> > example: supposing that we have a Stmt_1 that gets code generated by either
> > CLooG or ISL-codegen like this:
> >
> > Stmt_1(c1, c1+4, c1+c2);
> >
> > we will construct a map that maps the old iteration domain with 3 dimensions
> > (there are 3 arguments in Stmt_1 representing the original loop nest in which
> > Stmt_1 was located, let's call the original loop nest loop_1, loop_2, loop_3) to
> > the new expressions generated by cloog that are function of the new iteration
> > domain with 2 dimensions (c1 and c2 are the new induction variables of the code
> > generated by cloog). So the content of that map is:
> >
> > loop_1 -> c1
> > loop_2 -> c1+7
> > loop_3 -> c1+c2
> >
> > Given an access function from the original program:
> > Scev_1 = {{{0, +, 4}_1, +, 5}_2, +, 6}_3
> >
> > we will apply the map on it, and we will get a symbolic expression function of
> > the new induction variables c1, and c2:
> >
> > Scev_2 = apply (loop_1 -> c1) on Scev_1 = {{4*c1, +, 5}_2, +, 6}_3
> > Scev_3 = apply (loop_2 -> c1+7) on Scev_2 = {4*c1 + 5*(c1+7), +, 6}_3
> > Scev_4 = apply (loop_3 -> c1+c2) on Scev_3 = 4*c1 + 5*(c1+7) + 6*(c1+c2)
> >
> > We will then code generate Scev_4 and we will use this new expression for the
> > array access in the new loop nest.
> >
> > Remark that in all this process we have never referred to the original
> > "canonical induction variable". SCEV actually provides such a canonical form
> > for the induction variables without having to transform the code.
> >
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
> From 328c0cd4c246768b73dff1f8f5a3c9a089b5fa64 Mon Sep 17 00:00:00 2001
> From: Sebastian Pop <spop at codeaurora.org>
> Date: Fri, 7 Dec 2012 09:37:17 -0600
> Subject: [PATCH 1/2] add SCEVParameterRewriter
>
> ---
> include/llvm/Analysis/ScalarEvolutionExpressions.h | 104 ++++++++++++++++++++
> 1 file changed, 104 insertions(+)
>
> diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
> index b74cb33..48babff 100644
> --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
> +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
> @@ -548,6 +548,110 @@ namespace llvm {
> SCEVTraversal<SV> T(Visitor);
> T.visitAll(Root);
> }
> +
> + /// The ScevRewriter takes a scalar evolution expression and copies all its
> + /// components. The result after a rewrite is an identical SCEV.
> + struct ScevRewriter
> + : public SCEVVisitor<ScevRewriter, const SCEV*> {
> + public:
> + ScevRewriter(ScalarEvolution &S) : SE(S) {}
> +
> + virtual const SCEV *visitConstant(const SCEVConstant *Constant) {
> + return Constant;
> + }
> +
> + virtual const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
> + const SCEV *Operand = visit(Expr->getOperand());
> + return SE.getTruncateExpr(Operand, Expr->getType());
> + }
> +
> + virtual const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
> + const SCEV *Operand = visit(Expr->getOperand());
> + return SE.getZeroExtendExpr(Operand, Expr->getType());
> + }
> +
> + virtual const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
> + const SCEV *Operand = visit(Expr->getOperand());
> + return SE.getSignExtendExpr(Operand, Expr->getType());
> + }
> +
> + virtual const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> + return SE.getAddExpr(Operands);
> + }
> +
> + virtual const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> + return SE.getMulExpr(Operands);
> + }
> +
> + virtual const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
> + return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
> + }
> +
> + virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> + return SE.getAddRecExpr(Operands, Expr->getLoop(),
> + Expr->getNoWrapFlags());
> + }
> +
> + virtual const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> + return SE.getSMaxExpr(Operands);
> + }
> +
> + virtual const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> + return SE.getUMaxExpr(Operands);
> + }
> +
> + virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
> + return Expr;
> + }
> +
> + virtual const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
> + return Expr;
> + }
> +
> + protected:
> + ScalarEvolution &SE;
> + };
> +
> + typedef DenseMap<const Value*, Value*> ValueToValueMap;
> +
> + /// The ScevParameterRewriter takes a scalar evolution expression and updates
> + /// the SCEVUnknown components following the Map (Value -> Value).
> + struct ScevParameterRewriter: public ScevRewriter {
> + public:
> + static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
> + ValueToValueMap &Map) {
> + ScevParameterRewriter Rewriter(SE, Map);
> + return Rewriter.visit(Scev);
> + }
> + ScevParameterRewriter(ScalarEvolution &S, ValueToValueMap &M)
> + : ScevRewriter(S), Map(M) {}
> +
> + virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
> + Value *V = Expr->getValue();
> + if (Map.count(V))
> + return SE.getUnknown(Map[V]);
> + return Expr;
> + }
> +
> + private:
> + ValueToValueMap ⤅
> + };
> +
> }
>
> #endif
> --
> 1.7.9.5
>
> From 455451da4f213a9a6f9f12565331a7a1d86ee5e5 Mon Sep 17 00:00:00 2001
> From: Sebastian Pop <spop at codeaurora.org>
> Date: Sat, 8 Dec 2012 10:16:49 -0600
> Subject: [PATCH 2/2] add ScevApplyRewriter
>
> ---
> include/llvm/Analysis/ScalarEvolutionExpressions.h | 39 ++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
> index 48babff..f9ed59e 100644
> --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
> +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
> @@ -652,6 +652,45 @@ namespace llvm {
> ValueToValueMap ⤅
> };
>
> + typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT;
> +
> + /// The ScevApplyRewriter takes a scalar evolution expression and applies
> + /// the Map (Loop -> SCEV) to all AddRecExprs.
> + struct ScevApplyRewriter: public ScevRewriter {
> + public:
> + static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
> + ScalarEvolution &SE) {
> + ScevApplyRewriter Rewriter(SE, Map);
> + return Rewriter.visit(Scev);
> + }
> + ScevApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M)
> + : ScevRewriter(S), Map(M) {}
> +
> + virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
> + SmallVector<const SCEV *, 2> Operands;
> + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
> + Operands.push_back(visit(Expr->getOperand(i)));
> +
> + const Loop *L = Expr->getLoop();
> + const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
> +
> + if (0 == Map.count(L))
> + return Res;
> +
> + const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res;
> + return Rec->evaluateAtIteration(Map[L], SE);
> + }
> +
> + private:
> + LoopToScevMapT ⤅
> + };
> +
> +/// Applies the Map (Loop -> SCEV) to the given Scev.
> +static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map,
> + ScalarEvolution &SE) {
> + return ScevApplyRewriter::rewrite(Scev, Map, SE);
> +}
> +
> }
>
> #endif
> --
> 1.7.9.5
>
> From de79e54850b9c8433a0b28e32f51fd305737e87f Mon Sep 17 00:00:00 2001
> From: Sebastian Pop <spop at codeaurora.org>
> Date: Mon, 3 Dec 2012 11:54:43 -0600
> Subject: [PATCH 1/2] add LoopToScev maps
>
> ---
> include/polly/CodeGen/BlockGenerators.h | 19 +++++++++++++------
> lib/CodeGen/BlockGenerators.cpp | 20 ++++++++++++--------
> lib/CodeGen/CodeGeneration.cpp | 20 ++++++++++++++++++--
> lib/CodeGen/IslCodeGeneration.cpp | 23 +++++++++++++++++++----
> 4 files changed, 62 insertions(+), 20 deletions(-)
>
> diff --git a/include/polly/CodeGen/BlockGenerators.h b/include/polly/CodeGen/BlockGenerators.h
> index ed5ff3c..aad4a89 100644
> --- a/include/polly/CodeGen/BlockGenerators.h
> +++ b/include/polly/CodeGen/BlockGenerators.h
> @@ -18,6 +18,7 @@
>
> #include "llvm/IRBuilder.h"
> #include "llvm/ADT/DenseMap.h"
> +#include "llvm/Analysis/ScalarEvolutionExpressions.h"
>
> #include "isl/map.h"
>
> @@ -47,11 +48,14 @@ public:
> /// @param Stmt The statement to code generate.
> /// @param GlobalMap A map that defines for certain Values referenced from the
> /// original code new Values they should be replaced with.
> + /// @param LoopToScev Map the loops from the old code to expressions function
> + /// of the induction variables in the new code.
> /// @param P A reference to the pass this function is called from.
> /// The pass is needed to update other analysis.
> static void generate(IRBuilder<> &Builder, ScopStmt &Stmt,
> - ValueMapT &GlobalMap, Pass *P) {
> - BlockGenerator Generator(Builder, Stmt, P);
> + ValueMapT &GlobalMap, LoopToScevMapT &LoopToScev,
> + Pass *P) {
> + BlockGenerator Generator(Builder, Stmt, P, LoopToScev);
> Generator.copyBB(GlobalMap);
> }
>
> @@ -60,8 +64,10 @@ protected:
> ScopStmt &Statement;
> Pass *P;
> ScalarEvolution &SE;
> + LoopToScevMapT &LoopToScev;
>
> - BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P);
> + BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P,
> + LoopToScevMapT &LoopToScev);
>
> /// @brief Check if an instruction can be 'SCEV-ignored'
> ///
> @@ -156,8 +162,8 @@ public:
> /// The pass is needed to update other analysis.
> static void generate(IRBuilder<> &B, ScopStmt &Stmt,
> VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
> - Pass *P) {
> - VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
> + Pass *P, LoopToScevMapT <S) {
> + VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P, LTS);
> Generator.copyBB();
> }
>
> @@ -172,7 +178,8 @@ private:
> isl_set *Domain;
>
> VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
> - ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
> + ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P,
> + LoopToScevMapT <S);
>
> int getVectorWidth();
>
> diff --git a/lib/CodeGen/BlockGenerators.cpp b/lib/CodeGen/BlockGenerators.cpp
> index e8109bd..9964a3c 100644
> --- a/lib/CodeGen/BlockGenerators.cpp
> +++ b/lib/CodeGen/BlockGenerators.cpp
> @@ -342,8 +342,10 @@ Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
> }
>
>
> -BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
> - Builder(B), Statement(Stmt), P(P), SE(P->getAnalysis<ScalarEvolution>()) {}
> +BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P,
> + LoopToScevMapT <S):
> + Builder(B), Statement(Stmt), P(P), SE(P->getAnalysis<ScalarEvolution>()),
> + LoopToScev(LTS) {}
>
> bool BlockGenerator::isSCEVIgnore(const Instruction *Inst) {
> if (SCEVCodegen && SE.isSCEVable(Inst->getType()))
> @@ -562,12 +564,14 @@ void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
> }
>
> VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
> - VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
> - Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
> - Domain(Domain) {
> - assert(GlobalMaps.size() > 1 && "Only one vector lane found");
> - assert(Domain && "No statement domain provided");
> - }
> + VectorValueMapT &GlobalMaps,
> + ScopStmt &Stmt,
> + __isl_keep isl_set *Domain,
> + Pass *P, LoopToScevMapT <S)
> + : BlockGenerator(B, Stmt, P, LTS), GlobalMaps(GlobalMaps), Domain(Domain) {
> + assert(GlobalMaps.size() > 1 && "Only one vector lane found");
> + assert(Domain && "No statement domain provided");
> +}
>
> Value *VectorBlockGenerator::getVectorValue(const Value *Old,
> ValueMapT &VectorMap,
> diff --git a/lib/CodeGen/CodeGeneration.cpp b/lib/CodeGen/CodeGeneration.cpp
> index 064c828..ff1b429 100644
> --- a/lib/CodeGen/CodeGeneration.cpp
> +++ b/lib/CodeGen/CodeGeneration.cpp
> @@ -234,6 +234,20 @@ private:
> // Map the Values from the old code to their counterparts in the new code.
> ValueMapT ValueMap;
>
> + // Map the loops from the old code to expressions function of the induction
> + // variables in the new code. For example, when the code generator produces
> + // this AST:
> + //
> + // for (int c1 = 0; c1 <= 1023; c1 += 1)
> + // for (int c2 = 0; c2 <= 1023; c2 += 1)
> + // Stmt(c2 + 3, c1);
> + //
> + // the loop corresponding to the outer dimension in the old loop nest is
> + // associated to the expression obtained by code generating "c2 + 3" and the
> + // loop for the inner dimension of the original loop nest is associated to the
> + // new code generated for expression "c1".
> + LoopToScevMapT LoopToScev;
> +
> // clastVars maps from the textual representation of a clast variable to its
> // current *Value. clast variables are scheduling variables, original
> // induction variables or parameters. They are used either in loop bounds or
> @@ -377,6 +391,7 @@ void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt,
> (*VectorVMap)[VectorDim][PN] = RHS;
>
> ValueMap[PN] = RHS;
> + LoopToScev[Stmt->getLoopForDimension(Dim)] = S->getSE()->getUnknown(RHS);
> }
>
> void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
> @@ -405,7 +420,7 @@ void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
> int VectorDimensions = IVS ? IVS->size() : 1;
>
> if (VectorDimensions == 1) {
> - BlockGenerator::generate(Builder, *Statement, ValueMap, P);
> + BlockGenerator::generate(Builder, *Statement, ValueMap, LoopToScev, P);
> return;
> }
>
> @@ -422,7 +437,8 @@ void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
> }
> }
>
> - VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
> + VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P,
> + LoopToScev);
> }
>
> void ClastStmtCodeGen::codegen(const clast_block *b) {
> diff --git a/lib/CodeGen/IslCodeGeneration.cpp b/lib/CodeGen/IslCodeGeneration.cpp
> index 9bfdd1d..509ae19 100644
> --- a/lib/CodeGen/IslCodeGeneration.cpp
> +++ b/lib/CodeGen/IslCodeGeneration.cpp
> @@ -541,8 +541,8 @@ Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
>
> class IslNodeBuilder {
> public:
> - IslNodeBuilder(IRBuilder<> &Builder, Pass *P):
> - Builder(Builder), ExprBuilder(Builder, IDToValue, P), P(P) {}
> + IslNodeBuilder(IRBuilder<> &Builder, Pass *P, LoopToScevMapT <S):
> + Builder(Builder), ExprBuilder(Builder, IDToValue, P), P(P), LoopToScev(LTS) {}
>
> void addParameters(__isl_take isl_set *Context);
> void create(__isl_take isl_ast_node *Node);
> @@ -557,6 +557,20 @@ private:
> // ivs.
> std::map<isl_id *, Value*> IDToValue;
>
> + // Map the loops from the old code to expressions function of the induction
> + // variables in the new code. For example, when the code generator produces
> + // this AST:
> + //
> + // for (int c1 = 0; c1 <= 1023; c1 += 1)
> + // for (int c2 = 0; c2 <= 1023; c2 += 1)
> + // Stmt(c2 + 3, c1);
> + //
> + // the loop corresponding to the outer dimension in the old loop nest is
> + // associated to the expression obtained by code generating "c2 + 3" and the
> + // loop for the inner dimension of the original loop nest is associated to the
> + // new code generated for expression "c1".
> + LoopToScevMapT LoopToScev;
> +
> // Extract the upper bound of this loop
> //
> // The isl code generation can generate arbitrary expressions to check if the
> @@ -768,7 +782,7 @@ void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
> VMap[OldIV] = V;
> }
>
> - BlockGenerator::generate(Builder, *Stmt, VMap, P);
> + BlockGenerator::generate(Builder, *Stmt, VMap, LoopToScev, P);
>
> isl_ast_node_free(User);
> isl_id_free(Annotation);
> @@ -843,7 +857,8 @@ class IslCodeGeneration : public ScopPass {
> isl_ast_node *Ast = AstInfo.getAst();
> IRBuilder<> Builder(StartBlock->begin());
>
> - IslNodeBuilder NodeBuilder(Builder, this);
> + LoopToScevMapT LTS;
> + IslNodeBuilder NodeBuilder(Builder, this, LTS);
> NodeBuilder.addParameters(S.getContext());
> NodeBuilder.create(Ast);
> return true;
> --
> 1.7.9.5
>
> From 968c590024c4b1526e982ba2a6099d7b0c9ea3dc Mon Sep 17 00:00:00 2001
> From: Sebastian Pop <spop at codeaurora.org>
> Date: Mon, 10 Dec 2012 13:33:51 -0600
> Subject: [PATCH 2/2] use apply and ScevParameterRewriter::rewrite instead of
> SCEVRewriter
>
> ---
> lib/CodeGen/BlockGenerators.cpp | 205 +--------------------------
> test/Cloog/CodeGen/simple_vec_call_2.ll | 2 +-
> test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll | 2 +-
> 3 files changed, 6 insertions(+), 203 deletions(-)
>
> diff --git a/lib/CodeGen/BlockGenerators.cpp b/lib/CodeGen/BlockGenerators.cpp
> index 9964a3c..a0cc229 100644
> --- a/lib/CodeGen/BlockGenerators.cpp
> +++ b/lib/CodeGen/BlockGenerators.cpp
> @@ -41,204 +41,6 @@ SCEVCodegen("polly-codegen-scev",
> cl::desc("Use SCEV based code generation."), cl::Hidden,
> cl::init(false), cl::ZeroOrMore);
>
> -/// The SCEVRewriter takes a scalar evolution expression and updates the
> -/// following components:
> -///
> -/// - SCEVUnknown
> -///
> -/// Values referenced in SCEVUnknown subexpressions are looked up in
> -/// two Value to Value maps (GlobalMap and BBMap). If they are found they are
> -/// replaced by a reference to the value they map to.
> -///
> -/// - SCEVAddRecExpr
> -///
> -/// Based on a Loop -> Value map {Loop_1: %Value}, an expression
> -/// {%Base, +, %Step}<Loop_1> is rewritten to %Base + %Value * %Step.
> -/// AddRecExpr's with more than two operands can not be translated.
> -///
> -/// FIXME: The comment above is not yet reality. At the moment we derive
> -/// %Value by looking up the canonical IV of the loop and by defining
> -/// %Value = GlobalMap[%IV]. This needs to be changed to remove the need for
> -/// canonical induction variables.
> -///
> -///
> -/// How can this be used?
> -/// ====================
> -///
> -/// SCEVRewrite based code generation works on virtually independent blocks.
> -/// This means we do not run the independent blocks pass to rewrite scalar
> -/// instructions, but just ignore instructions that we can analyze with scalar
> -/// evolution. Virtually independent blocks are blocks that only reference the
> -/// following values:
> -///
> -/// o Values calculated within a basic block
> -/// o Values representable by SCEV
> -///
> -/// During code generation we can ignore all instructions:
> -///
> -/// - Ignore all instructions except:
> -/// - Load instructions
> -/// - Instructions that reference operands already calculated within the
> -/// basic block.
> -/// - Store instructions
> -struct SCEVRewriter : public SCEVVisitor<SCEVRewriter, const SCEV*> {
> -public:
> - static const SCEV *rewrite(const SCEV *scev, Scop &S, ScalarEvolution &SE,
> - ValueMapT &GlobalMap, ValueMapT &BBMap) {
> - SCEVRewriter Rewriter(S, SE, GlobalMap, BBMap);
> - return Rewriter.visit(scev);
> - }
> -
> - SCEVRewriter(Scop &S, ScalarEvolution &SE, ValueMapT &GlobalMap,
> - ValueMapT &BBMap) : S(S), SE(SE), GlobalMap(GlobalMap),
> - BBMap(BBMap) {}
> -
> - const SCEV *visit(const SCEV *Expr) {
> - // FIXME: The parameter handling is incorrect.
> - //
> - // Polly does only detect parameters in Access function and loop iteration
> - // counters, but it does not get parameters that are just used by
> - // instructions within the basic block.
> - //
> - // There are two options to solve this:
> - // o Iterate over all instructions of the SCoP and find the actual
> - // parameters.
> - // o Just check within the SCEVRewriter if Values lay outside of the SCoP
> - // and detect parameters on the fly.
> - //
> - // This is especially important for OpenMP and GPGPU code generation, as
> - // they require us to detect and possibly rewrite the corresponding
> - // parameters.
> - if (isl_id *Id = S.getIdForParam(Expr)) {
> - isl_id_free(Id);
> - return Expr;
> - }
> -
> -
> - return SCEVVisitor<SCEVRewriter, const SCEV*>::visit(Expr);
> - }
> -
> - const SCEV *visitConstant(const SCEVConstant *Constant) {
> - return Constant;
> - }
> -
> - const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
> - const SCEV *Operand = visit(Expr->getOperand());
> - return SE.getTruncateExpr(Operand, Expr->getType());
> - }
> -
> - const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
> - const SCEV *Operand = visit(Expr->getOperand());
> - return SE.getZeroExtendExpr(Operand, Expr->getType());
> - }
> -
> - const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
> - const SCEV *Operand = visit(Expr->getOperand());
> - return SE.getSignExtendExpr(Operand, Expr->getType());
> - }
> -
> - const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
> - SmallVector<const SCEV *, 2> Operands;
> - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
> - const SCEV *Operand = visit(Expr->getOperand(i));
> - Operands.push_back(Operand);
> - }
> -
> - return SE.getAddExpr(Operands);
> - }
> -
> - const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
> - SmallVector<const SCEV *, 2> Operands;
> - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
> - const SCEV *Operand = visit(Expr->getOperand(i));
> - Operands.push_back(Operand);
> - }
> -
> - return SE.getMulExpr(Operands);
> - }
> -
> - const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
> - return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
> - }
> -
> - // Return a new induction variable if the loop is within the original SCoP
> - // or NULL otherwise.
> - Value *getNewIV(const Loop *L) {
> - Value *IV = L->getCanonicalInductionVariable();
> - if (!IV)
> - return NULL;
> -
> - ValueMapT::iterator NewIV = GlobalMap.find(IV);
> -
> - if (NewIV == GlobalMap.end())
> - return NULL;
> -
> - return NewIV->second;
> - }
> -
> - const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
> - Value *IV;
> -
> - IV = getNewIV(Expr->getLoop());
> -
> - // The IV is not within the GlobalMaps. So do not rewrite it and also do
> - // not rewrite any descendants.
> - if (!IV)
> - return Expr;
> -
> - assert(Expr->getNumOperands() == 2
> - && "An AddRecExpr with more than two operands can not be rewritten.");
> -
> - const SCEV *Base, *Step, *IVExpr, *Product;
> -
> - Base = visit(Expr->getStart());
> - Step = visit(Expr->getOperand(1));
> - IVExpr = SE.getUnknown(IV);
> - IVExpr = SE.getTruncateOrSignExtend(IVExpr, Step->getType());
> - Product = SE.getMulExpr(Step, IVExpr);
> -
> - return SE.getAddExpr(Base, Product);
> - }
> -
> - const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
> - SmallVector<const SCEV *, 2> Operands;
> - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
> - const SCEV *Operand = visit(Expr->getOperand(i));
> - Operands.push_back(Operand);
> - }
> -
> - return SE.getSMaxExpr(Operands);
> - }
> -
> - const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
> - SmallVector<const SCEV *, 2> Operands;
> - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
> - const SCEV *Operand = visit(Expr->getOperand(i));
> - Operands.push_back(Operand);
> - }
> -
> - return SE.getUMaxExpr(Operands);
> - }
> -
> - const SCEV *visitUnknown(const SCEVUnknown *Expr) {
> - Value *V = Expr->getValue();
> -
> - if (GlobalMap.count(V))
> - return SE.getUnknown(GlobalMap[V]);
> -
> - if (BBMap.count(V))
> - return SE.getUnknown(BBMap[V]);
> -
> - return Expr;
> - }
> -
> -private:
> - Scop &S;
> - ScalarEvolution &SE;
> - ValueMapT &GlobalMap;
> - ValueMapT &BBMap;
> -};
> -
> // Helper class to generate memory location.
> namespace {
> class IslGenerator {
> @@ -386,9 +188,10 @@ Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
> if (SCEVCodegen && SE.isSCEVable(Old->getType()))
> if (const SCEV *Scev = SE.getSCEV(const_cast<Value*>(Old)))
> if (!isa<SCEVCouldNotCompute>(Scev)) {
> - const SCEV *NewScev = SCEVRewriter::rewrite(Scev,
> - *Statement.getParent(), SE,
> - GlobalMap, BBMap);
> + const SCEV *NewScev = apply(Scev, LoopToScev, SE);
> + ValueToValueMap VTV = GlobalMap;
> + VTV.insert(BBMap.begin(), BBMap.end());
> + NewScev = ScevParameterRewriter::rewrite(NewScev, SE, VTV);
> SCEVExpander Expander(SE, "polly");
> Value *Expanded = Expander.expandCodeFor(NewScev, Old->getType(),
> Builder.GetInsertPoint());
> diff --git a/test/Cloog/CodeGen/simple_vec_call_2.ll b/test/Cloog/CodeGen/simple_vec_call_2.ll
> index bb2a680..645599f 100644
> --- a/test/Cloog/CodeGen/simple_vec_call_2.ll
> +++ b/test/Cloog/CodeGen/simple_vec_call_2.ll
> @@ -58,4 +58,4 @@ return:
> ; CHECK-SCEV: %5 = insertelement <4 x float**> %4, float** %p_result1, i32 1
> ; CHECK-SCEV: %6 = insertelement <4 x float**> %5, float** %p_result2, i32 2
> ; CHECK-SCEV: %7 = insertelement <4 x float**> %6, float** %p_result3, i32 3
> -; CHECK-SCEV: store <4 x float**> %7, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align
> +; CHECK-SCEV: store <4 x float**> %7, <4 x float**>* bitcast (float*** getelementptr inbounds ([1024 x float**]* @B, i64 0, i64 3) to <4 x float**>*), align
> diff --git a/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll b/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll
> index d295be7..b6c6502 100644
> --- a/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll
> +++ b/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll
> @@ -37,4 +37,4 @@ return:
>
> ; CHECK-SCEV: %value_p_splat_one = load <1 x float**>* bitcast ([1024 x float**]* @A to <1 x float**>*), align 8
> ; CHECK-SCEV: %value_p_splat = shufflevector <1 x float**> %value_p_splat_one, <1 x float**> %value_p_splat_one, <4 x i32> zeroinitializer
> -; CHECK-SCEV: store <4 x float**> %value_p_splat, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align 8
> +; CHECK-SCEV: store <4 x float**> %value_p_splat, <4 x float**>* bitcast (float*** getelementptr inbounds ([1024 x float**]* @B, i64 0, i64 3) to <4 x float**>*), align
> --
> 1.7.9.5
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
More information about the llvm-commits
mailing list