Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -105,6 +105,10 @@ // Scalar references used to model PHI nodes KIND_PHI, + // Like KIND_PHI, but for PHIs in the exit node. Depending on context, these + // are handled like KIND_SCALAR. + KIND_EXIT_PHI, + // References to (multi-dimensional) arrays KIND_ARRAY, }; @@ -324,7 +328,7 @@ /// #AccessValue is also the llvm::Value itself. /// /// - /// * Accesses to emulate PHI nodes + /// * Accesses to emulate PHI nodes within the SCoP /// /// PHIInst instructions such as /// @@ -359,7 +363,15 @@ /// Note that there can also be a scalar write access for %PHI if used in a /// different BasicBlock, i.e. there can be a %PHI.phiops as well as a /// %PHI.s2a. - enum AccessOrigin { EXPLICIT, SCALAR, PHI }; + /// + /// + /// * Accesses to emulate PHI nodes that are in the SCoP's exit block + /// + /// Like the previous, but the PHI itself is not located in the SCoP itself. + /// There will be no READ type MemoryAccess for such values. The PHINode's + /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses write + /// directly to the escaping value's ".s2a" alloca. + enum AccessOrigin { EXPLICIT, SCALAR, PHI, EXIT_PHI }; /// @brief The access type of a memory access /// @@ -671,6 +683,10 @@ /// @brief Is this MemoryAccess modeling special PHI node accesses? bool isPHI() const { return Origin == PHI; } + /// @brief Is this MemoryAccess modeling the accesses of a PHI node in the + /// SCoP's exit block? + bool isExitPHI() const { return Origin == EXIT_PHI; } + /// @brief Get the statement that contains this memory access. ScopStmt *getStatement() const { return Statement; } Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -883,6 +883,8 @@ ScopArrayInfo::ARRAYKIND Ty; if (Access->isPHI()) Ty = ScopArrayInfo::KIND_PHI; + else if (Access->isExitPHI()) + Ty = ScopArrayInfo::KIND_EXIT_PHI; else if (Access->isImplicit()) Ty = ScopArrayInfo::KIND_SCALAR; else @@ -3932,7 +3934,7 @@ addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(), MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue, ArrayRef(), ArrayRef(), - IsExitBlock ? MemoryAccess::SCALAR : MemoryAccess::PHI); + IsExitBlock ? MemoryAccess::EXIT_PHI : MemoryAccess::PHI); } void ScopInfo::addPHIReadAccess(PHINode *PHI) { addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI, Index: polly/trunk/lib/CodeGen/BlockGenerators.cpp =================================================================== --- polly/trunk/lib/CodeGen/BlockGenerators.cpp +++ polly/trunk/lib/CodeGen/BlockGenerators.cpp @@ -1201,7 +1201,7 @@ ValueMapT *LocalBBMap = &BBMap; // Implicit writes induced by PHIs must be written in the incoming blocks. - if (isa(ScalarInst)) { + if (MA->isPHI() || MA->isExitPHI()) { BasicBlock *ExitingBB = ScalarInst->getParent(); BasicBlock *ExitingBBCopy = BlockMap[ExitingBB]; Builder.SetInsertPoint(ExitingBBCopy->getTerminator()); @@ -1217,7 +1217,7 @@ Builder.CreateStore(Val, Address); // Restore the insertion point if necessary. - if (isa(ScalarInst)) + if (MA->isPHI() || MA->isExitPHI()) Builder.SetInsertPoint(SavedInsertBB, SavedInsertionPoint); } }