Add a field to the memory access class for a related value.

The new field in the MemoryAccess allows us to track a value related
  to that access:
    - For real memory accesses the value is the loaded result or the
      stored value.
    - For straigt line scalar accesses it is the access instruction
      itself.
    - For PHI operand accesses it is the operand value.

  We use this value to simplify code which deduced information about the value
  later in the Polly pipeline and was known to be error prone.

Reviewers: grosser, Meinsersbur

Subscribers: #polly

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

llvm-svn: 245213
This commit is contained in:
Johannes Doerfert 2015-08-17 10:58:17 +00:00
parent 58fdd88751
commit d86f2157e5
5 changed files with 48 additions and 51 deletions

View File

@ -244,7 +244,15 @@ private:
ReductionType RedType = RT_NONE;
/// @brief The access instruction of this memory access.
Instruction *Inst;
Instruction *AccessInstruction;
/// @brief The value associated with this memory access.
///
/// - For real memory accesses it is the loaded result or the stored value.
/// - For straigt line scalar accesses it is the access instruction itself.
/// - For PHI operand accesses it is the operand value.
///
Value *AccessValue;
/// Updated access relation read from JSCOP file.
isl_map *newAccessRelation;
@ -377,8 +385,11 @@ public:
const std::string &getBaseName() const { return BaseName; }
/// @brief Return the access value of this memory access.
Value *getAccessValue() const { return AccessValue; }
/// @brief Return the access instruction of this memory access.
Instruction *getAccessInstruction() const { return Inst; }
Instruction *getAccessInstruction() const { return AccessInstruction; }
/// Get the stride of this memory access in the specified Schedule. Schedule
/// is a map from the statement to a schedule where the innermost dimension is

View File

@ -33,6 +33,7 @@ namespace polly {
class IRAccess {
public:
Value *BaseAddress;
Value *AccessValue;
const SCEV *Offset;
@ -58,22 +59,25 @@ public:
///
/// @param IsPHI Are we modeling special PHI node accesses?
explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset,
unsigned elemBytes, bool Affine, bool IsPHI = false)
: BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes),
Type(Type), IsAffine(Affine), IsPHI(IsPHI) {}
unsigned elemBytes, bool Affine, Value *AccessValue,
bool IsPHI = false)
: BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset),
ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(IsPHI) {}
explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset,
unsigned elemBytes, bool Affine,
SmallVector<const SCEV *, 4> Subscripts,
SmallVector<const SCEV *, 4> Sizes)
: BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes),
Type(Type), IsAffine(Affine), IsPHI(false), Subscripts(Subscripts),
Sizes(Sizes) {}
SmallVector<const SCEV *, 4> Sizes, Value *AccessValue)
: BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset),
ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(false),
Subscripts(Subscripts), Sizes(Sizes) {}
enum TypeKind getType() const { return Type; }
Value *getBase() const { return BaseAddress; }
Value *getAccessValue() const { return AccessValue; }
const SCEV *getOffset() const { return Offset; }
unsigned getElemSizeInBytes() const { return ElemBytes; }

View File

@ -447,7 +447,8 @@ __isl_give isl_map *MemoryAccess::foldAccess(const IRAccess &Access,
MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
ScopStmt *Statement, const ScopArrayInfo *SAI,
int Identifier)
: AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
: AccType(getMemoryAccessType(Access)), Statement(Statement),
AccessInstruction(AccInst), AccessValue(Access.getAccessValue()),
newAccessRelation(nullptr) {
isl_ctx *Ctx = Statement->getIslCtx();
@ -669,18 +670,6 @@ void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
Domain = NewDomain;
}
// @brief Get the data-type of the elements accessed
static Type *getAccessType(IRAccess &Access, Instruction *AccessInst) {
if (Access.isPHI())
return Access.getBase()->getType();
if (StoreInst *Store = dyn_cast<StoreInst>(AccessInst))
return Store->getValueOperand()->getType();
if (BranchInst *Branch = dyn_cast<BranchInst>(AccessInst))
return Branch->getCondition()->getType();
return AccessInst->getType();
}
void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block,
bool isApproximated) {
AccFuncSetType *AFS = tempScop.getAccessFunctions(Block);
@ -690,7 +679,7 @@ void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block,
for (auto &AccessPair : *AFS) {
IRAccess &Access = AccessPair.first;
Instruction *AccessInst = AccessPair.second;
Type *ElementType = getAccessType(Access, AccessInst);
Type *ElementType = Access.getAccessValue()->getType();
const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
Access.getBase(), ElementType, Access.Sizes, Access.isPHI());

View File

@ -135,9 +135,10 @@ void TempScopInfo::buildPHIAccesses(PHINode *PHI, Region &R,
// we have to insert a scalar dependence from the definition of OpI to
// OpBB if the definition is not in OpBB.
if (OpIBB != OpBB) {
IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true);
IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true, OpI);
AccFuncMap[OpBB].push_back(std::make_pair(ScalarRead, PHI));
IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true);
IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true,
OpI);
AccFuncMap[OpIBB].push_back(std::make_pair(ScalarWrite, OpI));
}
}
@ -147,13 +148,13 @@ void TempScopInfo::buildPHIAccesses(PHINode *PHI, Region &R,
if (!OpI)
OpI = OpBB->getTerminator();
IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true,
IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, Op,
/* IsPHI */ true);
AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI));
}
if (!OnlyNonAffineSubRegionOperands) {
IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true,
IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true, PHI,
/* IsPHI */ true);
Functions.push_back(std::make_pair(ScalarAccess, PHI));
}
@ -211,7 +212,7 @@ bool TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R,
// Do not build a read access that is not in the current SCoP
// Use the def instruction as base address of the IRAccess, so that it will
// become the name of the scalar access in the polyhedral form.
IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true);
IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true, Inst);
AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, UI));
}
@ -224,7 +225,7 @@ bool TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R,
if (R->contains(OpInst))
continue;
IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true);
IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true, Op);
AccFuncMap[Inst->getParent()].push_back(
std::make_pair(ScalarAccess, Inst));
}
@ -240,17 +241,20 @@ TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R,
const ScopDetection::BoxedLoopsSetTy *BoxedLoops) {
unsigned Size;
Type *SizeType;
Value *Val;
enum IRAccess::TypeKind Type;
if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
SizeType = Load->getType();
Size = TD->getTypeStoreSize(SizeType);
Type = IRAccess::READ;
Val = Load;
} else {
StoreInst *Store = cast<StoreInst>(Inst);
SizeType = Store->getValueOperand()->getType();
Size = TD->getTypeStoreSize(SizeType);
Type = IRAccess::MUST_WRITE;
Val = Store->getValueOperand();
}
const SCEV *AccessFunction = SE->getSCEVAtScope(getPointerOperand(*Inst), L);
@ -264,7 +268,7 @@ TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R,
if (PollyDelinearize && AccItr != InsnToMemAcc.end())
return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, true,
AccItr->second.DelinearizedSubscripts,
AccItr->second.Shape->DelinearizedSizes);
AccItr->second.Shape->DelinearizedSizes, Val);
// Check if the access depends on a loop contained in a non-affine subregion.
bool isVariantInNonAffineLoop = false;
@ -287,7 +291,7 @@ TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R,
Type = IRAccess::MAY_WRITE;
return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine,
Subscripts, Sizes);
Subscripts, Sizes, Val);
}
void TempScopInfo::buildAccessFunctions(Region &R, Region &SR) {
@ -326,7 +330,8 @@ void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
buildScalarDependences(Inst, &R, NonAffineSubRegion)) {
// If the Instruction is used outside the statement, we need to build the
// write access.
IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true);
IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true,
Inst);
Functions.push_back(std::make_pair(ScalarAccess, Inst));
}
}

View File

@ -495,21 +495,14 @@ void BlockGenerator::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB,
continue;
Instruction *Base = cast<Instruction>(MA->getBaseAddr());
Instruction *Inst = MA->getAccessInstruction();
Value *Val = MA->getAccessValue();
Value *Val = nullptr;
AllocaInst *Address = nullptr;
if (MA->getScopArrayInfo()->isPHI()) {
PHINode *BasePHI = dyn_cast<PHINode>(Base);
int PHIIdx = BasePHI->getBasicBlockIndex(BB);
assert(PHIIdx >= 0);
if (MA->getScopArrayInfo()->isPHI())
Address = getOrCreateAlloca(Base, PHIOpMap, ".phiops");
Val = BasePHI->getIncomingValue(PHIIdx);
} else {
else
Address = getOrCreateAlloca(Base, ScalarMap, ".s2a");
Val = Inst;
}
Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap);
Builder.CreateStore(Val, Address);
}
@ -1124,23 +1117,18 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB,
Instruction *ScalarBase = cast<Instruction>(MA->getBaseAddr());
Instruction *ScalarInst = MA->getAccessInstruction();
PHINode *ScalarBasePHI = dyn_cast<PHINode>(ScalarBase);
// Only generate accesses that belong to this basic block.
if (ScalarInst->getParent() != BB)
continue;
Value *Val = nullptr;
Value *Val = MA->getAccessValue();
AllocaInst *ScalarAddr = nullptr;
if (MA->getScopArrayInfo()->isPHI()) {
int PHIIdx = ScalarBasePHI->getBasicBlockIndex(BB);
if (MA->getScopArrayInfo()->isPHI())
ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops");
Val = ScalarBasePHI->getIncomingValue(PHIIdx);
} else {
else
ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a");
Val = ScalarInst;
}
Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap);
Builder.CreateStore(Val, ScalarAddr);