diff options
author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-04-23 14:32:34 +0000 |
---|---|---|
committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-04-23 14:32:34 +0000 |
commit | 85676e3674fcfe1f4386ff8c5cf858b8c9238d86 (patch) | |
tree | 192ee307efb98771d99a01f95311b76cff0475b7 /polly/lib | |
parent | ac9c32e216d23d9be9751726bc440db3ac5deac9 (diff) | |
download | bcm5719-llvm-85676e3674fcfe1f4386ff8c5cf858b8c9238d86.tar.gz bcm5719-llvm-85676e3674fcfe1f4386ff8c5cf858b8c9238d86.zip |
Add an invalid domain to memory accesses
Memory accesses can have non-precisely modeled access functions that
would cause us to build incorrect execution context for hoisted loads.
This is the same issue that occurred during the domain construction for
statements and it is dealt with the same way.
llvm-svn: 267289
Diffstat (limited to 'polly/lib')
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index e3dba4bdb93..d625d41c519 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -548,6 +548,7 @@ getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) { MemoryAccess::~MemoryAccess() { isl_id_free(Id); + isl_set_free(InvalidDomain); isl_map_free(AccessRelation); isl_map_free(NewAccessRelation); } @@ -818,6 +819,10 @@ static bool isDivisible(const SCEV *Expr, unsigned Size, ScalarEvolution &SE) { void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) { assert(!AccessRelation && "AccessReltation already built"); + // Initialize the invalid domain which describes all iterations for which the + // access relation is not modeled correctly. + InvalidDomain = getStatement()->getInvalidDomain(); + isl_ctx *Ctx = isl_id_get_ctx(Id); isl_id *BaseAddrId = SAI->getBasePtrId(); @@ -866,9 +871,9 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, ArrayRef<const SCEV *> Sizes, Value *AccessValue, ScopArrayInfo::MemoryKind Kind, StringRef BaseName) : Kind(Kind), AccType(AccType), RedType(RT_NONE), Statement(Stmt), - BaseAddr(BaseAddress), BaseName(BaseName), ElementType(ElementType), - Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst), - AccessValue(AccessValue), IsAffine(Affine), + InvalidDomain(nullptr), BaseAddr(BaseAddress), BaseName(BaseName), + ElementType(ElementType), Sizes(Sizes.begin(), Sizes.end()), + AccessInstruction(AccessInst), AccessValue(AccessValue), IsAffine(Affine), Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr), NewAccessRelation(nullptr) { static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"}; @@ -881,6 +886,8 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, void MemoryAccess::realignParams() { isl_space *ParamSpace = Statement->getParent()->getParamSpace(); + InvalidDomain = + isl_set_align_params(InvalidDomain, isl_space_copy(ParamSpace)); AccessRelation = isl_map_align_params(AccessRelation, ParamSpace); } @@ -922,7 +929,9 @@ void MemoryAccess::dump() const { print(errs()); } __isl_give isl_pw_aff *MemoryAccess::getPwAff(const SCEV *E) { auto *Stmt = getStatement(); - return Stmt->getParent()->getPwAffOnly(E, Stmt->getEntryBlock()); + PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock()); + InvalidDomain = isl_set_union(InvalidDomain, PWAC.second); + return PWAC.first; } // Create a map in the size of the provided set domain, that maps from the @@ -3192,7 +3201,8 @@ const InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) const { } /// @brief Check if @p MA can always be hoisted without execution context. -static bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty) { +static bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty, + bool MAInvalidCtxIsEmpty) { LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction()); const DataLayout &DL = LInst->getParent()->getModule()->getDataLayout(); // TODO: We can provide more information for better but more expensive @@ -3203,7 +3213,7 @@ static bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty) { // If a dereferencable load is in a statement that is modeled precisely we can // hoist it. - if (StmtInvalidCtxIsEmpty) + if (StmtInvalidCtxIsEmpty && MAInvalidCtxIsEmpty) return true; // Even if the statement is not modeled precisely we can hoist the load if it @@ -3267,12 +3277,17 @@ void Scop::addInvariantLoads(ScopStmt &Stmt, MemoryAccessList &InvMAs) { Type *Ty = LInst->getType(); const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand()); + auto *MAInvalidCtx = MA->getInvalidContext(); + bool MAInvalidCtxIsEmpty = isl_set_is_empty(MAInvalidCtx); + isl_set *MACtx; // Check if we know that this pointer can be speculatively accessed. - if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty)) { + if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty, MAInvalidCtxIsEmpty)) { MACtx = isl_set_universe(isl_set_get_space(DomainCtx)); + isl_set_free(MAInvalidCtx); } else { MACtx = isl_set_copy(DomainCtx); + MACtx = isl_set_subtract(MACtx, MAInvalidCtx); MACtx = isl_set_gist_params(MACtx, getContext()); } |