Introduce origin/kind for exit PHI node accesses

Previously, accesses that originate from PHI nodes in the exit block
were registered as SCALAR. In some context they are treated as scalars,
but it makes a difference in others. We used to check whether the
AccessInstruction is a terminator to differentiate the cases.

This patch introduces an MemoryAccess origin EXIT_PHI and a
ScopArrayInfo kind KIND_EXIT_PHI to make this case more explicit. No
behavioural change intended.

Differential Revision: http://reviews.llvm.org/D14688

llvm-svn: 254149
This commit is contained in:
Michael Kruse 2015-11-26 12:26:06 +00:00
parent fbb6a237ba
commit cba170e4d0
3 changed files with 23 additions and 5 deletions

View File

@ -105,6 +105,10 @@ public:
// 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 @@ public:
/// #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 @@ public:
/// 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 @@ public:
/// @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; }

View File

@ -883,6 +883,8 @@ void ScopStmt::buildAccessRelations() {
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 @@ void ScopInfo::addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock,
addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(),
MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue,
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
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,

View File

@ -1201,7 +1201,7 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
ValueMapT *LocalBBMap = &BBMap;
// Implicit writes induced by PHIs must be written in the incoming blocks.
if (isa<TerminatorInst>(ScalarInst)) {
if (MA->isPHI() || MA->isExitPHI()) {
BasicBlock *ExitingBB = ScalarInst->getParent();
BasicBlock *ExitingBBCopy = BlockMap[ExitingBB];
Builder.SetInsertPoint(ExitingBBCopy->getTerminator());
@ -1217,7 +1217,7 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
Builder.CreateStore(Val, Address);
// Restore the insertion point if necessary.
if (isa<TerminatorInst>(ScalarInst))
if (MA->isPHI() || MA->isExitPHI())
Builder.SetInsertPoint(SavedInsertBB, SavedInsertionPoint);
}
}