From 9d10fffa3310fd97d51d67631bf3f55faea6368a Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 15 Feb 2013 20:55:59 +0000 Subject: [PATCH] add LoopToScev maps llvm-svn: 175295 --- polly/include/polly/CodeGen/BlockGenerators.h | 51 +++++++++++++----- polly/lib/CodeGen/BlockGenerators.cpp | 78 +++++++++++++++------------ polly/lib/CodeGen/CodeGeneration.cpp | 39 +++++++++++--- polly/lib/CodeGen/IslCodeGeneration.cpp | 27 ++++++---- 4 files changed, 131 insertions(+), 64 deletions(-) diff --git a/polly/include/polly/CodeGen/BlockGenerators.h b/polly/include/polly/CodeGen/BlockGenerators.h index 17e68ef..e2518f2 100644 --- a/polly/include/polly/CodeGen/BlockGenerators.h +++ b/polly/include/polly/CodeGen/BlockGenerators.h @@ -18,6 +18,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "isl/map.h" @@ -50,9 +51,9 @@ public: /// @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) { + ValueMapT &GlobalMap, LoopToScevMapT <S, Pass *P) { BlockGenerator Generator(Builder, Stmt, P); - Generator.copyBB(GlobalMap); + Generator.copyBB(GlobalMap, LTS); } protected: @@ -77,36 +78,42 @@ protected: /// @param GlobalMap A mapping from old values to their new values /// (for values recalculated in the new ScoP, but not /// within this basic block). + /// @param LTS A mapping from loops virtual canonical induction + /// variable to their new values + /// (for values recalculated in the new ScoP, but not + /// within this basic block). /// /// @returns o The old value, if it is still valid. /// o The new value, if available. /// o NULL, if no value is found. - Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap); + Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap, + LoopToScevMapT <S); void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); /// @brief Get the memory access offset to be added to the base address std::vector getMemoryAccessIndex(__isl_keep isl_map *AccessRelation, Value *BaseAddress, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, + LoopToScevMapT <S); /// @brief Get the new operand address according to the changed access in /// JSCOP file. Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation, Value *BaseAddress, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); /// @brief Generate the operand address Value *generateLocationAccessed(const Instruction *Inst, const Value *Pointer, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); /// @brief Copy a single Instruction. /// @@ -119,7 +126,7 @@ protected: /// (for values recalculated in the new ScoP, but not /// within this basic block). void copyInstruction(const Instruction *Inst, ValueMapT &BBMap, - ValueMapT &GlobalMap); + ValueMapT &GlobalMap, LoopToScevMapT <S); /// @brief Copy the basic block. /// @@ -129,7 +136,7 @@ protected: /// @param GlobalMap A mapping from old values to their new values /// (for values recalculated in the new ScoP, but not /// within this basic block). - void copyBB(ValueMapT &GlobalMap); + void copyBB(ValueMapT &GlobalMap, LoopToScevMapT <S); }; /// @brief Generate a new vector basic block for a polyhedral statement. @@ -159,9 +166,10 @@ public: /// The pass is needed to update other analysis. static void generate(IRBuilder<> &B, ScopStmt &Stmt, VectorValueMapT &GlobalMaps, + std::vector &VLTS, __isl_keep isl_map *Schedule, Pass *P) { - VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Schedule, P); + VectorBlockGenerator Generator(B, GlobalMaps, VLTS, Stmt, Schedule, P); Generator.copyBB(); } @@ -173,11 +181,30 @@ private: // all referenes to the old instructions with their recalculated values. VectorValueMapT &GlobalMaps; + // This is a vector of loop->scev maps. The first map is used for the first + // vector lane, ... + // Each map, contains information about Instructions in the old ScoP, which + // are recalculated in the new SCoP. When copying the basic block, we replace + // all referenes to the old instructions with their recalculated values. + // + // For example, when the code generator produces this AST: + // + // for (int c1 = 0; c1 <= 1023; c1 += 1) + // for (int c2 = 0; c2 <= 1023; c2 += VF) + // for (int lane = 0; lane <= VF; lane += 1) + // Stmt(c2 + lane + 3, c1); + // + // VLTS[lane] contains a map: + // "outer loop in the old loop nest" -> SCEV("c2 + lane + 3"), + // "inner loop in the old loop nest" -> SCEV("c1"). + std::vector &VLTS; + // A map from the statement to a schedule where the innermost dimension is the // dimension of the innermost loop containing the statemenet. isl_map *Schedule; VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps, + std::vector &VLTS, ScopStmt &Stmt, __isl_keep isl_map *Schedule, Pass *P); diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 132f1f8..d70cc20 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -355,7 +355,7 @@ bool BlockGenerator::isSCEVIgnore(const Instruction *Inst) { } Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, LoopToScevMapT <S) { // We assume constants never change. // This avoids map lookups for many calls to this function. if (isa(Old)) @@ -403,7 +403,7 @@ Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap, } void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, LoopToScevMapT <S) { Instruction *NewInst = Inst->clone(); // Replace old operands with the new ones. @@ -411,7 +411,7 @@ void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap, OE = Inst->op_end(); OI != OE; ++OI) { Value *OldOperand = *OI; - Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap); + Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap, LTS); if (!NewOperand) { assert(!isa(NewInst) && @@ -432,7 +432,7 @@ void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap, std::vector BlockGenerator::getMemoryAccessIndex( __isl_keep isl_map *AccessRelation, Value *BaseAddress, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, LoopToScevMapT <S) { assert((isl_map_dim(AccessRelation, isl_dim_out) == 1) && "Only single dimensional access functions supported"); @@ -440,7 +440,7 @@ std::vector BlockGenerator::getMemoryAccessIndex( std::vector IVS; for (unsigned i = 0; i < Statement.getNumIterators(); ++i) { const Value *OriginalIV = Statement.getInductionVariableForDimension(i); - Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap); + Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap, LTS); IVS.push_back(NewIV); } @@ -460,9 +460,10 @@ std::vector BlockGenerator::getMemoryAccessIndex( Value *BlockGenerator::getNewAccessOperand( __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, LoopToScevMapT <S) { std::vector IndexArray = - getMemoryAccessIndex(NewAccessRelation, BaseAddress, BBMap, GlobalMap); + getMemoryAccessIndex(NewAccessRelation, BaseAddress, BBMap, GlobalMap, + LTS); Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray, "p_newarrayidx_"); return NewOperand; @@ -470,7 +471,7 @@ Value *BlockGenerator::getNewAccessOperand( Value *BlockGenerator::generateLocationAccessed( const Instruction *Inst, const Value *Pointer, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, LoopToScevMapT <S) { MemoryAccess &Access = Statement.getAccessFor(Inst); isl_map *CurrentAccessRelation = Access.getAccessRelation(); isl_map *NewAccessRelation = Access.getNewAccessRelation(); @@ -481,11 +482,12 @@ Value *BlockGenerator::generateLocationAccessed( Value *NewPointer; if (!NewAccessRelation) { - NewPointer = getNewValue(Pointer, BBMap, GlobalMap); + NewPointer = getNewValue(Pointer, BBMap, GlobalMap, LTS); } else { Value *BaseAddress = const_cast(Access.getBaseAddr()); NewPointer = - getNewAccessOperand(NewAccessRelation, BaseAddress, BBMap, GlobalMap); + getNewAccessOperand(NewAccessRelation, BaseAddress, BBMap, GlobalMap, + LTS); } isl_map_free(CurrentAccessRelation); @@ -494,27 +496,32 @@ Value *BlockGenerator::generateLocationAccessed( } Value *BlockGenerator::generateScalarLoad( - const LoadInst *Load, ValueMapT &BBMap, ValueMapT &GlobalMap) { + const LoadInst *Load, ValueMapT &BBMap, ValueMapT &GlobalMap, + LoopToScevMapT <S) { const Value *Pointer = Load->getPointerOperand(); const Instruction *Inst = dyn_cast(Load); - Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap); + Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap, + LTS); Value *ScalarLoad = Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_"); return ScalarLoad; } Value *BlockGenerator::generateScalarStore( - const StoreInst *Store, ValueMapT &BBMap, ValueMapT &GlobalMap) { + const StoreInst *Store, ValueMapT &BBMap, ValueMapT &GlobalMap, + LoopToScevMapT <S) { const Value *Pointer = Store->getPointerOperand(); Value *NewPointer = - generateLocationAccessed(Store, Pointer, BBMap, GlobalMap); - Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap); + generateLocationAccessed(Store, Pointer, BBMap, GlobalMap, LTS); + Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap, + LTS); return Builder.CreateStore(ValueOperand, NewPointer); } void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap, - ValueMapT &GlobalMap) { + ValueMapT &GlobalMap, + LoopToScevMapT <S) { // Terminator instructions control the control flow. They are explicitly // expressed in the clast and do not need to be copied. if (Inst->isTerminator()) @@ -524,19 +531,19 @@ void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap, return; if (const LoadInst *Load = dyn_cast(Inst)) { - BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap); + BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap, LTS); return; } if (const StoreInst *Store = dyn_cast(Inst)) { - BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap); + BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap, LTS); return; } - copyInstScalar(Inst, BBMap, GlobalMap); + copyInstScalar(Inst, BBMap, GlobalMap, LTS); } -void BlockGenerator::copyBB(ValueMapT &GlobalMap) { +void BlockGenerator::copyBB(ValueMapT &GlobalMap, LoopToScevMapT <S) { BasicBlock *BB = Statement.getBasicBlock(); BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P); @@ -547,13 +554,14 @@ void BlockGenerator::copyBB(ValueMapT &GlobalMap) { for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) - copyInstruction(II, BBMap, GlobalMap); + copyInstruction(II, BBMap, GlobalMap, LTS); } VectorBlockGenerator::VectorBlockGenerator( - IRBuilder<> &B, VectorValueMapT &GlobalMaps, ScopStmt &Stmt, - __isl_keep isl_map *Schedule, Pass *P) - : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps), Schedule(Schedule) { + IRBuilder<> &B, VectorValueMapT &GlobalMaps, std::vector &VLTS, + ScopStmt &Stmt, __isl_keep isl_map *Schedule, Pass *P) + : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps), VLTS(VLTS), + Schedule(Schedule) { assert(GlobalMaps.size() > 1 && "Only one vector lane found"); assert(Schedule && "No statement domain provided"); } @@ -569,8 +577,8 @@ Value *VectorBlockGenerator::getVectorValue( for (int Lane = 0; Lane < Width; Lane++) Vector = Builder.CreateInsertElement( - Vector, getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane]), - Builder.getInt32(Lane)); + Vector, getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane], + VLTS[Lane]), Builder.getInt32(Lane)); VectorMap[Old] = Vector; @@ -591,7 +599,7 @@ Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap) { const Value *Pointer = Load->getPointerOperand(); Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth()); - Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]); + Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0]); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); LoadInst *VecLoad = @@ -606,7 +614,7 @@ Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap) { const Value *Pointer = Load->getPointerOperand(); Type *VectorPtrType = getVectorPtrTy(Pointer, 1); - Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]); + Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0]); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, Load->getName() + "_p_vec_p"); LoadInst *ScalarLoad = @@ -633,7 +641,8 @@ Value *VectorBlockGenerator::generateUnknownStrideLoad( Value *Vector = UndefValue::get(VectorType); for (int i = 0; i < VectorWidth; i++) { - Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]); + Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i], + VLTS[i]); Value *ScalarLoad = Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_"); Vector = Builder.CreateInsertElement( @@ -649,7 +658,7 @@ void VectorBlockGenerator::generateLoad( !VectorType::isValidElementType(Load->getType())) { for (int i = 0; i < getVectorWidth(); i++) ScalarMaps[i][Load] = - generateScalarLoad(Load, ScalarMaps[i], GlobalMaps[i]); + generateScalarLoad(Load, ScalarMaps[i], GlobalMaps[i], VLTS[i]); return; } @@ -707,7 +716,8 @@ void VectorBlockGenerator::copyStore( if (Access.isStrideOne(isl_map_copy(Schedule))) { Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth); - Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]); + Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0], + VLTS[0]); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); @@ -718,7 +728,8 @@ void VectorBlockGenerator::copyStore( } else { for (unsigned i = 0; i < ScalarMaps.size(); i++) { Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i)); - Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]); + Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i], + VLTS[i]); Builder.CreateStore(Scalar, NewPointer); } } @@ -776,7 +787,8 @@ void VectorBlockGenerator::copyInstScalarized(const Instruction *Inst, HasVectorOperand = extractScalarValues(Inst, VectorMap, ScalarMaps); for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++) - copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]); + copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane], + VLTS[VectorLane]); if (!VectorType::isValidElementType(Inst->getType()) || !HasVectorOperand) return; diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 8398c41..c639c7e 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -225,6 +225,19 @@ 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); + // + // LoopToScev is a map associating: + // "outer loop in the old loop nest" -> SCEV("c2 + 3"), + // "inner loop in the old loop nest" -> SCEV("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 @@ -249,11 +262,13 @@ private: void codegen(const clast_assignment *a, ScopStmt *Statement, unsigned Dimension, int vectorDim, - std::vector *VectorVMap = 0); + std::vector *VectorVMap = 0, + std::vector *VLTS = 0); void codegenSubstitutions(const clast_stmt *Assignment, ScopStmt *Statement, int vectorDim = 0, - std::vector *VectorVMap = 0); + std::vector *VectorVMap = 0, + std::vector *VLTS = 0); void codegen(const clast_user_stmt *u, std::vector *IVS = NULL, const char *iterator = NULL, isl_set *scatteringDomain = 0); @@ -353,7 +368,8 @@ void ClastStmtCodeGen::codegen(const clast_assignment *a) { void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt, unsigned Dim, int VectorDim, - std::vector *VectorVMap) { + std::vector *VectorVMap, + std::vector *VLTS) { const PHINode *PN; Value *RHS; @@ -366,19 +382,24 @@ void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt, if (VectorVMap) (*VectorVMap)[VectorDim][PN] = RHS; + const llvm::SCEV *URHS = S->getSE()->getUnknown(RHS); + if (VLTS) + (*VLTS)[VectorDim][Stmt->getLoopForDimension(Dim)] = URHS; + ValueMap[PN] = RHS; + LoopToScev[Stmt->getLoopForDimension(Dim)] = URHS; } void ClastStmtCodeGen::codegenSubstitutions( const clast_stmt *Assignment, ScopStmt *Statement, int vectorDim, - std::vector *VectorVMap) { + std::vector *VectorVMap, std::vector *VLTS) { int Dimension = 0; while (Assignment) { assert(CLAST_STMT_IS_A(Assignment, stmt_ass) && "Substitions are expected to be assignments"); codegen((const clast_assignment *)Assignment, Statement, Dimension, - vectorDim, VectorVMap); + vectorDim, VectorVMap, VLTS); Assignment = Assignment->next; Dimension++; } @@ -409,11 +430,12 @@ 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; } VectorValueMapT VectorMap(VectorDimensions); + std::vector VLTS(VectorDimensions); if (IVS) { assert(u->substitutions && "Substitutions expected!"); @@ -421,13 +443,14 @@ void ClastStmtCodeGen::codegen(const clast_user_stmt *u, for (std::vector::iterator II = IVS->begin(), IE = IVS->end(); II != IE; ++II) { ClastVars[iterator] = *II; - codegenSubstitutions(u->substitutions, Statement, i, &VectorMap); + codegenSubstitutions(u->substitutions, Statement, i, &VectorMap, &VLTS); i++; } } isl_map *Schedule = extractPartialSchedule(Statement, Domain); - VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Schedule, P); + VectorBlockGenerator::generate(Builder, *Statement, VectorMap, VLTS, Schedule, + P); isl_map_free(Schedule); } diff --git a/polly/lib/CodeGen/IslCodeGeneration.cpp b/polly/lib/CodeGen/IslCodeGeneration.cpp index b9837f9..a87a6a5 100644 --- a/polly/lib/CodeGen/IslCodeGeneration.cpp +++ b/polly/lib/CodeGen/IslCodeGeneration.cpp @@ -584,11 +584,11 @@ private: void createForSequential(__isl_take isl_ast_node *For); void createSubstitutions(__isl_take isl_pw_multi_aff *PMA, __isl_take isl_ast_build *Context, ScopStmt *Stmt, - ValueMapT &VMap); + ValueMapT &VMap, LoopToScevMapT <S); void createSubstitutionsVector( __isl_take isl_pw_multi_aff *PMA, __isl_take isl_ast_build *Context, - ScopStmt *Stmt, VectorValueMapT &VMap, std::vector &IVS, - __isl_take isl_id *IteratorID); + ScopStmt *Stmt, VectorValueMapT &VMap, std::vector &VLTS, + std::vector &IVS, __isl_take isl_id *IteratorID); void createIf(__isl_take isl_ast_node *If); void createUserVector( __isl_take isl_ast_node *User, std::vector &IVS, @@ -679,6 +679,7 @@ void IslNodeBuilder::createUserVector( isl_id *Id = isl_pw_multi_aff_get_tuple_id(Info->PMA, isl_dim_out); ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id); VectorValueMapT VectorMap(IVS.size()); + std::vector VLTS(IVS.size()); isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain()); Schedule = isl_union_map_intersect_domain(Schedule, Domain); @@ -686,8 +687,8 @@ void IslNodeBuilder::createUserVector( createSubstitutionsVector(isl_pw_multi_aff_copy(Info->PMA), isl_ast_build_copy(Info->Context), Stmt, VectorMap, - IVS, IteratorID); - VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, S, P); + VLTS, IVS, IteratorID); + VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, VLTS, S, P); isl_map_free(S); isl_id_free(Annotation); @@ -886,7 +887,8 @@ void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) { void IslNodeBuilder::createSubstitutions(__isl_take isl_pw_multi_aff *PMA, __isl_take isl_ast_build *Context, - ScopStmt *Stmt, ValueMapT &VMap) { + ScopStmt *Stmt, ValueMapT &VMap, + LoopToScevMapT <S) { for (unsigned i = 0; i < isl_pw_multi_aff_dim(PMA, isl_dim_out); ++i) { isl_pw_aff *Aff; isl_ast_expr *Expr; @@ -903,6 +905,8 @@ void IslNodeBuilder::createSubstitutions(__isl_take isl_pw_multi_aff *PMA, // (because we calculate a value of the original induction variable). V = Builder.CreateIntCast(V, OldIV->getType(), true); VMap[OldIV] = V; + ScalarEvolution *SE = Stmt->getParent()->getSE(); + LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V); } isl_pw_multi_aff_free(PMA); @@ -911,8 +915,8 @@ void IslNodeBuilder::createSubstitutions(__isl_take isl_pw_multi_aff *PMA, void IslNodeBuilder::createSubstitutionsVector( __isl_take isl_pw_multi_aff *PMA, __isl_take isl_ast_build *Context, - ScopStmt *Stmt, VectorValueMapT &VMap, std::vector &IVS, - __isl_take isl_id *IteratorID) { + ScopStmt *Stmt, VectorValueMapT &VMap, std::vector &VLTS, + std::vector &IVS, __isl_take isl_id *IteratorID) { int i = 0; Value *OldValue = IDToValue[IteratorID]; @@ -920,7 +924,7 @@ void IslNodeBuilder::createSubstitutionsVector( II != IE; ++II) { IDToValue[IteratorID] = *II; createSubstitutions(isl_pw_multi_aff_copy(PMA), isl_ast_build_copy(Context), - Stmt, VMap[i]); + Stmt, VMap[i], VLTS[i]); i++; } @@ -932,6 +936,7 @@ void IslNodeBuilder::createSubstitutionsVector( void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) { ValueMapT VMap; + LoopToScevMapT LTS; struct IslAstUser *Info; isl_id *Annotation, *Id; ScopStmt *Stmt; @@ -946,9 +951,9 @@ void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) { Stmt = (ScopStmt *)isl_id_get_user(Id); createSubstitutions(isl_pw_multi_aff_copy(Info->PMA), - isl_ast_build_copy(Info->Context), Stmt, VMap); + isl_ast_build_copy(Info->Context), Stmt, VMap, LTS); - BlockGenerator::generate(Builder, *Stmt, VMap, P); + BlockGenerator::generate(Builder, *Stmt, VMap, LTS, P); isl_ast_node_free(User); isl_id_free(Annotation); -- 2.7.4