Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -2903,10 +2903,12 @@ /// Compute the isl representation for the SCEV @p E /// - /// @param E The SCEV that should be translated. - /// @param BB An (optional) basic block in which the isl_pw_aff is computed. - /// SCEVs known to not reference any loops in the SCoP can be - /// passed without a @p BB. + /// @param E The SCEV that should be translated. + /// @param BB An (optional) basic block in which the isl_pw_aff is + /// computed. + /// SCEVs known to not reference any loops in the SCoP can + /// be passed without a @p BB. + /// @param Domain The domain of the @p BB. /// @param NonNegative Flag to indicate the @p E has to be non-negative. /// /// Note that this function will always return a valid isl_pw_aff. However, if @@ -2914,7 +2916,7 @@ /// a dummy value of appropriate dimension is returned. This allows to bail /// for complex cases without "error handling code" needed on the users side. PWACtx getPwAff(const SCEV *E, BasicBlock *BB = nullptr, - bool NonNegative = false); + isl::set Domain = nullptr, bool NonNegative = false); /// Compute the isl representation for the SCEV @p E /// Index: include/polly/Support/SCEVAffinator.h =================================================================== --- include/polly/Support/SCEVAffinator.h +++ include/polly/Support/SCEVAffinator.h @@ -43,11 +43,13 @@ /// Translate a SCEV to an isl::pw_aff. /// - /// @param E he expression that is translated. - /// @param BB The block in which @p E is executed. + /// @param E The expression that is translated. + /// @param BB The block in which @p E is executed. + /// @param Domain The domain of the @p BB. /// /// @returns The isl representation of the SCEV @p E in @p Domain. - PWACtx getPwAff(const llvm::SCEV *E, llvm::BasicBlock *BB = nullptr); + PWACtx getPwAff(const llvm::SCEV *E, llvm::BasicBlock *BB = nullptr, + isl::set Domain = nullptr); /// Take the assumption that @p PWAC is non-negative. void takeNonNegativeAssumption(PWACtx &PWAC); Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1102,8 +1102,8 @@ isl::pw_aff MemoryAccess::getPwAff(const SCEV *E) { auto *Stmt = getStatement(); - PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock()); isl::set StmtDom = getStatement()->getDomain(); + PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock(), StmtDom); StmtDom = StmtDom.reset_tuple_id(); isl::set NewInvalidDom = StmtDom.intersect(PWAC.second); InvalidDomain = InvalidDomain.unite(NewInvalidDom); @@ -1419,28 +1419,28 @@ static __isl_give isl_set *buildConditionSet(ICmpInst::Predicate Pred, __isl_take isl_pw_aff *L, __isl_take isl_pw_aff *R, - __isl_keep isl_set *Domain) { + isl::set Domain) { isl_set *ConsequenceCondSet = buildConditionSet(Pred, L, R); - return setDimensionIds(Domain, ConsequenceCondSet); + return setDimensionIds(Domain.get(), ConsequenceCondSet); } /// Compute the isl representation for the SCEV @p E in this BB. /// /// @param S The Scop in which @p BB resides in. /// @param BB The BB for which isl representation is to be -/// computed. +/// computed. +/// @param Domain The domain of the @p BB. /// @param InvalidDomainMap A map of BB to their invalid domains. /// @param E The SCEV that should be translated. /// @param NonNegative Flag to indicate the @p E has to be non-negative. /// /// Note that this function will also adjust the invalid context accordingly. -__isl_give isl_pw_aff * -getPwAff(Scop &S, BasicBlock *BB, - DenseMap &InvalidDomainMap, const SCEV *E, - bool NonNegative = false) { - PWACtx PWAC = S.getPwAff(E, BB, NonNegative); - InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second); +__isl_give isl_pw_aff *getPwAff(Scop &S, BasicBlock *BB, isl::set Domain, + isl::set &InvalidDomain, const SCEV *E, + bool NonNegative = false) { + PWACtx PWAC = S.getPwAff(E, BB, Domain, NonNegative); + InvalidDomain = InvalidDomain.unite(PWAC.second); return PWAC.first.take(); } @@ -1450,15 +1450,14 @@ /// will be moved from @p SI to its successors. Hence, @p ConditionSets will /// have as many elements as @p SI has successors. bool buildConditionSets(Scop &S, BasicBlock *BB, SwitchInst *SI, Loop *L, - __isl_keep isl_set *Domain, - DenseMap &InvalidDomainMap, + isl::set Domain, isl::set &InvalidDomain, SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { Value *Condition = getConditionFromTerminator(SI); assert(Condition && "No condition for switch"); ScalarEvolution &SE = *S.getSE(); isl_pw_aff *LHS, *RHS; - LHS = getPwAff(S, BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L)); + LHS = getPwAff(S, BB, Domain, InvalidDomain, SE.getSCEVAtScope(Condition, L)); unsigned NumSuccessors = SI->getNumSuccessors(); ConditionSets.resize(NumSuccessors); @@ -1466,11 +1465,11 @@ unsigned Idx = Case.getSuccessorIndex(); ConstantInt *CaseValue = Case.getCaseValue(); - RHS = getPwAff(S, BB, InvalidDomainMap, SE.getSCEV(CaseValue)); + RHS = getPwAff(S, BB, Domain, InvalidDomain, SE.getSCEV(CaseValue)); isl_set *CaseConditionSet = buildConditionSet(ICmpInst::ICMP_EQ, isl_pw_aff_copy(LHS), RHS, Domain); - ConditionSets[Idx] = isl_set_coalesce( - isl_set_intersect(CaseConditionSet, isl_set_copy(Domain))); + ConditionSets[Idx] = + isl_set_coalesce(isl_set_intersect(CaseConditionSet, Domain.copy())); } assert(ConditionSets[0] == nullptr && "Default condition set was set"); @@ -1479,7 +1478,7 @@ ConditionSetUnion = isl_set_union(ConditionSetUnion, isl_set_copy(ConditionSets[u])); ConditionSets[0] = setDimensionIds( - Domain, isl_set_subtract(isl_set_copy(Domain), ConditionSetUnion)); + Domain.get(), isl_set_subtract(Domain.copy(), ConditionSetUnion)); isl_pw_aff_free(LHS); @@ -1496,16 +1495,16 @@ /// TestVal < UpperBound OR TestVal <= UpperBound __isl_give isl_set * buildUnsignedConditionSets(Scop &S, BasicBlock *BB, Value *Condition, - __isl_keep isl_set *Domain, const SCEV *SCEV_TestVal, - const SCEV *SCEV_UpperBound, - DenseMap &InvalidDomainMap, + isl::set Domain, const SCEV *SCEV_TestVal, + const SCEV *SCEV_UpperBound, isl::set &InvalidDomain, bool IsStrictUpperBound) { // Do not take NonNeg assumption on TestVal // as it might have MSB (Sign bit) set. - isl_pw_aff *TestVal = getPwAff(S, BB, InvalidDomainMap, SCEV_TestVal, false); + isl_pw_aff *TestVal = + getPwAff(S, BB, Domain, InvalidDomain, SCEV_TestVal, false); // Take NonNeg assumption on UpperBound. isl_pw_aff *UpperBound = - getPwAff(S, BB, InvalidDomainMap, SCEV_UpperBound, true); + getPwAff(S, BB, Domain, InvalidDomain, SCEV_UpperBound, true); // 0 <= TestVal isl_set *First = @@ -1522,7 +1521,7 @@ Second = isl_pw_aff_le_set(TestVal, UpperBound); isl_set *ConsequenceCondSet = isl_set_intersect(First, Second); - ConsequenceCondSet = setDimensionIds(Domain, ConsequenceCondSet); + ConsequenceCondSet = setDimensionIds(Domain.get(), ConsequenceCondSet); return ConsequenceCondSet; } @@ -1535,8 +1534,8 @@ /// context under which @p Condition is true/false will be returned as the /// new elements of @p ConditionSets. bool buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition, - TerminatorInst *TI, Loop *L, __isl_keep isl_set *Domain, - DenseMap &InvalidDomainMap, + TerminatorInst *TI, Loop *L, isl::set Domain, + isl::set Context, isl::set &InvalidDomain, SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { ScalarEvolution &SE = *S.getSE(); isl_set *ConsequenceCondSet = nullptr; @@ -1545,8 +1544,8 @@ const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L); const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType()); bool NonNeg = false; - isl_pw_aff *LHS = getPwAff(S, BB, InvalidDomainMap, LHSSCEV, NonNeg); - isl_pw_aff *RHS = getPwAff(S, BB, InvalidDomainMap, RHSSCEV, NonNeg); + isl_pw_aff *LHS = getPwAff(S, BB, Domain, InvalidDomain, LHSSCEV, NonNeg); + isl_pw_aff *RHS = getPwAff(S, BB, Domain, InvalidDomain, RHSSCEV, NonNeg); ConsequenceCondSet = buildConditionSet(ICmpInst::ICMP_SLE, LHS, RHS, Domain); } else if (auto *PHI = dyn_cast(Condition)) { @@ -1554,22 +1553,22 @@ getUniqueNonErrorValue(PHI, &S.getRegion(), *S.getLI(), *S.getDT())); if (Unique->isZero()) - ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain)); + ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain.get())); else - ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain)); + ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain.get())); } else if (auto *CCond = dyn_cast(Condition)) { if (CCond->isZero()) - ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain)); + ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain.get())); else - ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain)); + ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain.get())); } else if (BinaryOperator *BinOp = dyn_cast(Condition)) { auto Opcode = BinOp->getOpcode(); assert(Opcode == Instruction::And || Opcode == Instruction::Or); bool Valid = buildConditionSets(S, BB, BinOp->getOperand(0), TI, L, Domain, - InvalidDomainMap, ConditionSets) && + Context, InvalidDomain, ConditionSets) && buildConditionSets(S, BB, BinOp->getOperand(1), TI, L, Domain, - InvalidDomainMap, ConditionSets); + Context, InvalidDomain, ConditionSets); if (!Valid) { while (!ConditionSets.empty()) isl_set_free(ConditionSets.pop_back_val()); @@ -1609,26 +1608,26 @@ case ICmpInst::ICMP_ULT: ConsequenceCondSet = buildUnsignedConditionSets(S, BB, Condition, Domain, LeftOperand, - RightOperand, InvalidDomainMap, true); + RightOperand, InvalidDomain, true); break; case ICmpInst::ICMP_ULE: ConsequenceCondSet = buildUnsignedConditionSets(S, BB, Condition, Domain, LeftOperand, - RightOperand, InvalidDomainMap, false); + RightOperand, InvalidDomain, false); break; case ICmpInst::ICMP_UGT: ConsequenceCondSet = buildUnsignedConditionSets(S, BB, Condition, Domain, RightOperand, - LeftOperand, InvalidDomainMap, true); + LeftOperand, InvalidDomain, true); break; case ICmpInst::ICMP_UGE: ConsequenceCondSet = buildUnsignedConditionSets(S, BB, Condition, Domain, RightOperand, - LeftOperand, InvalidDomainMap, false); + LeftOperand, InvalidDomain, false); break; default: - LHS = getPwAff(S, BB, InvalidDomainMap, LeftOperand, NonNeg); - RHS = getPwAff(S, BB, InvalidDomainMap, RightOperand, NonNeg); + LHS = getPwAff(S, BB, Domain, InvalidDomain, LeftOperand, NonNeg); + RHS = getPwAff(S, BB, Domain, InvalidDomain, RightOperand, NonNeg); ConsequenceCondSet = buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain); break; @@ -1640,16 +1639,16 @@ if (!TI) ConsequenceCondSet = isl_set_params(ConsequenceCondSet); assert(ConsequenceCondSet); - ConsequenceCondSet = isl_set_coalesce( - isl_set_intersect(ConsequenceCondSet, isl_set_copy(Domain))); + ConsequenceCondSet = + isl_set_coalesce(isl_set_intersect(ConsequenceCondSet, Domain.copy())); isl_set *AlternativeCondSet = nullptr; bool TooComplex = isl_set_n_basic_set(ConsequenceCondSet) >= MaxDisjunctsInDomain; if (!TooComplex) { - AlternativeCondSet = isl_set_subtract(isl_set_copy(Domain), - isl_set_copy(ConsequenceCondSet)); + AlternativeCondSet = + isl_set_subtract(Domain.copy(), isl_set_copy(ConsequenceCondSet)); TooComplex = isl_set_n_basic_set(AlternativeCondSet) >= MaxDisjunctsInDomain; } @@ -1674,25 +1673,25 @@ /// will be moved from @p TI to its successors. Hence, @p ConditionSets will /// have as many elements as @p TI has successors. bool buildConditionSets(Scop &S, BasicBlock *BB, TerminatorInst *TI, Loop *L, - __isl_keep isl_set *Domain, - DenseMap &InvalidDomainMap, + isl::set Domain, isl::set Context, + isl::set &InvalidDomain, SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { if (SwitchInst *SI = dyn_cast(TI)) - return buildConditionSets(S, BB, SI, L, Domain, InvalidDomainMap, + return buildConditionSets(S, BB, SI, L, Domain, InvalidDomain, ConditionSets); assert(isa(TI) && "Terminator was neither branch nor switch."); if (TI->getNumSuccessors() == 1) { - ConditionSets.push_back(isl_set_copy(Domain)); + ConditionSets.push_back(Domain.copy()); return true; } Value *Condition = getConditionFromTerminator(TI); assert(Condition && "No condition for Terminator"); - return buildConditionSets(S, BB, Condition, TI, L, Domain, InvalidDomainMap, - ConditionSets); + return buildConditionSets(S, BB, Condition, TI, L, Domain, Context, + InvalidDomain, ConditionSets); } ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop, @@ -2101,11 +2100,10 @@ SmallVector ConditionSets; auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr; BasicBlock *BB = InScop ? CI->getParent() : getRegion().getEntry(); - auto *Dom = InScop ? DomainMap[BB].copy() : Context.copy(); + isl::set Dom = InScop ? DomainMap[BB] : Context; assert(Dom && "Cannot propagate a nullptr."); - bool Valid = buildConditionSets(*this, BB, Val, TI, L, Dom, - InvalidDomainMap, ConditionSets); - isl_set_free(Dom); + bool Valid = buildConditionSets(*this, BB, Val, TI, L, DomainMap[BB], Dom, + InvalidDomainMap[BB], ConditionSets); if (!Valid) continue; @@ -2836,8 +2834,8 @@ SmallVector ConditionSets; if (RN->isSubRegion()) ConditionSets.push_back(Domain.copy()); - else if (!buildConditionSets(*this, BB, TI, BBLoop, Domain.get(), - InvalidDomainMap, ConditionSets)) + else if (!buildConditionSets(*this, BB, TI, BBLoop, Domain, Context, + InvalidDomainMap[BB], ConditionSets)) return false; // Now iterate over the successors and set their initial domain based on @@ -3053,8 +3051,8 @@ else { SmallVector ConditionSets; int idx = BI->getSuccessor(0) != HeaderBB; - if (!buildConditionSets(*this, LatchBB, TI, L, LatchBBDom.get(), - InvalidDomainMap, ConditionSets)) + if (!buildConditionSets(*this, LatchBB, TI, L, LatchBBDom, Context, + InvalidDomainMap[LatchBB], ConditionSets)) return false; // Free the non back edge condition set as we do not need it. @@ -4457,14 +4455,14 @@ isl::ctx Scop::getIslCtx() const { return IslCtx.get(); } -__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB, +__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB, isl::set Domain, bool NonNegative) { // First try to use the SCEVAffinator to generate a piecewise defined // affine function from @p E in the context of @p BB. If that tasks becomes to // complex the affinator might return a nullptr. In such a case we invalidate // the SCoP and return a dummy value. This way we do not need to add error // handling code to all users of this function. - auto PWAC = Affinator.getPwAff(E, BB); + auto PWAC = Affinator.getPwAff(E, BB, Domain); if (PWAC.first) { // TODO: We could use a heuristic and either use: // SCEVAffinator::takeNonNegativeAssumption @@ -4478,7 +4476,7 @@ auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc(); invalidate(COMPLEXITY, DL, BB); - return Affinator.getPwAff(SE->getZero(E->getType()), BB); + return Affinator.getPwAff(SE->getZero(E->getType()), BB, Domain); } isl::union_set Scop::getDomains() const { Index: lib/Support/SCEVAffinator.cpp =================================================================== --- lib/Support/SCEVAffinator.cpp +++ lib/Support/SCEVAffinator.cpp @@ -112,14 +112,13 @@ return std::make_pair(PWA, isl::set::empty(isl::space(Ctx, 0, NumIterators))); } -PWACtx SCEVAffinator::getPwAff(const SCEV *Expr, BasicBlock *BB) { +PWACtx SCEVAffinator::getPwAff(const SCEV *Expr, BasicBlock *BB, + isl::set Domain) { this->BB = BB; - if (BB) { - auto *DC = S->getDomainConditions(BB).release(); - NumIterators = isl_set_n_dim(DC); - isl_set_free(DC); - } else + if (Domain) + NumIterators = isl_set_n_dim(Domain.get()); + else NumIterators = 0; return visit(Expr);