void AliasCheckGenerator::printIslExpressions(const Scop &S) { BoundsMapT BoundsMap; unsigned int numAccs = 0; for (ScopStmt *Stmt : S) { for (MemoryAccess *Acc : *Stmt) { Map Access = isl::Map(Acc->getAccessRelation()); Set Domain = isl::Set(Stmt->getDomain()); const Set MemAccs = Domain.apply(Access); if (!BoundsMap.count(MemAccs)) { BoundsMap.insert(MemAccs); ++numAccs; } } } log(Debug, 2) << "Num Accesses: " << numAccs << " -> " << binomial_coefficient(numAccs, 2) << "\n"; BoundsMapT mapcp = BoundsMap; const Set ParamCtx = Set(S.getAssumedContext()); Set Cond = Set::universe(ParamCtx.getSpace()); for (const Set &s : BoundsMap) { BoundsMapT::iterator it = mapcp.find(s); if (it != mapcp.end()) { mapcp.erase(it); if (mapcp.size() > 0) { Cond = checkPairs(Cond, s, mapcp); } } } AstBuild Builder = AstBuild::fromContext(ParamCtx); PwAff Check = Cond.indicatorFunction(); AstExpr ExprCheck = Builder.exprFromPwAff(Check); log(Debug, 4) << "if (" << ExprCheck.toStr(Format::FC) << ")\n\n"; }
/// @brief Collect information about the SCoP @p S. static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write, isl_union_map **MayWrite, isl_union_map **AccessSchedule, isl_union_map **StmtSchedule, Dependences::AnalyisLevel Level) { isl_space *Space = S.getParamSpace(); *Read = isl_union_map_empty(isl_space_copy(Space)); *Write = isl_union_map_empty(isl_space_copy(Space)); *MayWrite = isl_union_map_empty(isl_space_copy(Space)); *AccessSchedule = isl_union_map_empty(isl_space_copy(Space)); *StmtSchedule = isl_union_map_empty(Space); SmallPtrSet<const Value *, 8> ReductionBaseValues; if (UseReductions) for (ScopStmt &Stmt : S) for (MemoryAccess *MA : Stmt) if (MA->isReductionLike()) ReductionBaseValues.insert(MA->getBaseAddr()); for (ScopStmt &Stmt : S) { for (MemoryAccess *MA : Stmt) { isl_set *domcp = Stmt.getDomain(); isl_map *accdom = MA->getAccessRelation(); accdom = isl_map_intersect_domain(accdom, domcp); if (ReductionBaseValues.count(MA->getBaseAddr())) { // Wrap the access domain and adjust the schedule accordingly. // // An access domain like // Stmt[i0, i1] -> MemAcc_A[i0 + i1] // will be transformed into // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1] // // The original schedule looks like // Stmt[i0, i1] -> [0, i0, 2, i1, 0] // but as we transformed the access domain we need the schedule // to match the new access domains, thus we need // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0] isl_map *Schedule = Stmt.getSchedule(); Schedule = isl_map_apply_domain( Schedule, isl_map_reverse(isl_map_domain_map(isl_map_copy(accdom)))); accdom = isl_map_range_map(accdom); *AccessSchedule = isl_union_map_add_map(*AccessSchedule, Schedule); } else { accdom = tag(accdom, MA, Level); if (Level > Dependences::AL_Statement) { isl_map *Schedule = tag(Stmt.getSchedule(), MA, Level); *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Schedule); } } if (MA->isRead()) *Read = isl_union_map_add_map(*Read, accdom); else *Write = isl_union_map_add_map(*Write, accdom); } if (Level == Dependences::AL_Statement) *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule()); } *StmtSchedule = isl_union_map_intersect_params(*StmtSchedule, S.getAssumedContext()); *Read = isl_union_map_coalesce(*Read); *Write = isl_union_map_coalesce(*Write); *MayWrite = isl_union_map_coalesce(*MayWrite); }