Index: polly/trunk/include/polly/ScopDetection.h =================================================================== --- polly/trunk/include/polly/ScopDetection.h +++ polly/trunk/include/polly/ScopDetection.h @@ -164,6 +164,10 @@ /// @brief Loads that need to be invariant during execution. InvariantLoadsSetTy RequiredILS; + /// @brief Map to memory access description for the corresponding LLVM + /// instructions. + MapInsnToMemAcc InsnToMemAcc; + /// @brief Initialize a DetectionContext from scratch. DetectionContext(Region &R, AliasAnalysis &AA, bool Verify) : CurRegion(R), AST(AA), Verifying(Verify), Log(&R), hasLoads(false), @@ -501,6 +505,10 @@ /// @brief Return the set of loops in non-affine subregions for @p R. const BoxedLoopsSetTy *getBoxedLoops(const Region *R) const; + /// @brief Get the instruction to memory access mapping of the current + /// function for @p R. + const MapInsnToMemAcc *getInsnToMemAccMap(const Region *R) const; + /// @brief Return the set of required invariant loads for @p R. const InvariantLoadsSetTy *getRequiredInvariantLoads(const Region *R) const; Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -2045,11 +2045,13 @@ /// @param R The region on which to build the data access dictionary. /// @param BoxedLoops The set of loops that are overapproximated in @p R. /// @param ScopRIL The required invariant loads equivalence classes. + /// @param InsnToMemAcc The Instruction to MemoryAccess mapping /// @returns True if the access could be built, False otherwise. bool buildAccessMultiDimParam(MemAccInst Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL); + const InvariantLoadsSetTy &ScopRIL, + const MapInsnToMemAcc &InsnToMemAcc); /// @brief Build a single-dimensional parameteric sized MemoryAccess /// from the Load/Store instruction. @@ -2070,9 +2072,11 @@ /// @param R The region on which to build the data access dictionary. /// @param BoxedLoops The set of loops that are overapproximated in @p R. /// @param ScopRIL The required invariant loads equivalence classes. + /// @param InsnToMemAcc The Instruction to MemoryAccess mapping. void buildMemoryAccess(MemAccInst Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL); + const InvariantLoadsSetTy &ScopRIL, + const MapInsnToMemAcc &InsnToMemAcc); /// @brief Analyze and extract the cross-BB scalar dependences (or, /// dataflow dependencies) of an instruction. @@ -2098,9 +2102,11 @@ /// @brief Build the access functions for the subregion @p SR. /// - /// @param R The SCoP region. - /// @param SR A subregion of @p R. - void buildAccessFunctions(Region &R, Region &SR); + /// @param R The SCoP region. + /// @param SR A subregion of @p R. + /// @param InsnToMemAcc The Instruction to MemoryAccess mapping. + void buildAccessFunctions(Region &R, Region &SR, + const MapInsnToMemAcc &InsnToMemAcc); /// @brief Create ScopStmt for all BBs and non-affine subregions of @p SR. /// @@ -2115,9 +2121,11 @@ /// /// @param R The SCoP region. /// @param BB A basic block in @p R. + /// @param InsnToMemAcc The Instruction to MemoryAccess mapping. /// @param NonAffineSubRegion The non affine sub-region @p BB is in. /// @param IsExitBlock Flag to indicate that @p BB is in the exit BB. void buildAccessFunctions(Region &R, BasicBlock &BB, + const MapInsnToMemAcc &InsnToMemAcc, Region *NonAffineSubRegion = nullptr, bool IsExitBlock = false); Index: polly/trunk/lib/Analysis/ScopDetection.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopDetection.cpp +++ polly/trunk/lib/Analysis/ScopDetection.cpp @@ -501,8 +501,6 @@ return true; } -MapInsnToMemAcc InsnToMemAcc; - /// @brief Remove smax of smax(0, size) expressions from a SCEV expression and /// register the '...' components. /// @@ -732,7 +730,8 @@ } if (!BasePtrHasNonAffine) - InsnToMemAcc.insert(TempMemoryAccesses.begin(), TempMemoryAccesses.end()); + Context.InsnToMemAcc.insert(TempMemoryAccesses.begin(), + TempMemoryAccesses.end()); return true; } @@ -1400,6 +1399,13 @@ return &DC->BoxedLoopsSet; } +const MapInsnToMemAcc * +ScopDetection::getInsnToMemAccMap(const Region *R) const { + const DetectionContext *DC = getDetectionContext(R); + assert(DC && "ScopR is no valid region!"); + return &DC->InsnToMemAcc; +} + const InvariantLoadsSetTy * ScopDetection::getRequiredInvariantLoads(const Region *R) const { const DetectionContext *DC = getDetectionContext(R); @@ -1442,7 +1448,6 @@ void ScopDetection::releaseMemory() { RejectLogs.clear(); ValidRegions.clear(); - InsnToMemAcc.clear(); DetectionContextMap.clear(); // Do not clear the invalid function set. Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -3745,8 +3745,6 @@ } } -extern MapInsnToMemAcc InsnToMemAcc; - bool ScopInfo::buildAccessMultiDimFixed( MemAccInst Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, @@ -3806,7 +3804,7 @@ bool ScopInfo::buildAccessMultiDimParam( MemAccInst Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { + const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) { Value *Address = Inst.getPointerOperand(); Value *Val = Inst.getValueOperand(); Type *SizeType = Val->getType(); @@ -3892,30 +3890,31 @@ void ScopInfo::buildMemoryAccess( MemAccInst Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { + const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) { if (buildAccessMultiDimFixed(Inst, L, R, BoxedLoops, ScopRIL)) return; - if (buildAccessMultiDimParam(Inst, L, R, BoxedLoops, ScopRIL)) + if (buildAccessMultiDimParam(Inst, L, R, BoxedLoops, ScopRIL, InsnToMemAcc)) return; buildAccessSingleDim(Inst, L, R, BoxedLoops, ScopRIL); } -void ScopInfo::buildAccessFunctions(Region &R, Region &SR) { +void ScopInfo::buildAccessFunctions(Region &R, Region &SR, + const MapInsnToMemAcc &InsnToMemAcc) { if (SD->isNonAffineSubRegion(&SR, &R)) { for (BasicBlock *BB : SR.blocks()) - buildAccessFunctions(R, *BB, &SR); + buildAccessFunctions(R, *BB, InsnToMemAcc, &SR); return; } for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I) if (I->isSubRegion()) - buildAccessFunctions(R, *I->getNodeAs()); + buildAccessFunctions(R, *I->getNodeAs(), InsnToMemAcc); else - buildAccessFunctions(R, *I->getNodeAs()); + buildAccessFunctions(R, *I->getNodeAs(), InsnToMemAcc); } void ScopInfo::buildStmts(Region &R, Region &SR) { @@ -3933,6 +3932,7 @@ } void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, + const MapInsnToMemAcc &InsnToMemAcc, Region *NonAffineSubRegion, bool IsExitBlock) { // We do not build access functions for error blocks, as they may contain @@ -3962,7 +3962,7 @@ // there might be other invariant accesses that will be hoisted and // that would allow to make a non-affine access affine. if (auto MemInst = MemAccInst::dyn_cast(Inst)) - buildMemoryAccess(MemInst, L, &R, BoxedLoops, ScopRIL); + buildMemoryAccess(MemInst, L, &R, BoxedLoops, ScopRIL, InsnToMemAcc); if (isIgnoredIntrinsic(&Inst)) continue; @@ -4140,7 +4140,7 @@ scop.reset(new Scop(R, *SE, ctx, MaxLoopDepth)); buildStmts(R, R); - buildAccessFunctions(R, R); + buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R)); // In case the region does not have an exiting block we will later (during // code generation) split the exit block. This will move potential PHI nodes @@ -4150,7 +4150,8 @@ // accesses. Note that we do not model anything in the exit block if we have // an exiting block in the region, as there will not be any splitting later. if (!R.getExitingBlock()) - buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); + buildAccessFunctions(R, *R.getExit(), *SD->getInsnToMemAccMap(&R), nullptr, + /* IsExitBlock */ true); scop->init(*AA, AC, *SD, *DT, *LI); }