bool Interchange::runOnScop(Scop &S) { if (std::distance(S.begin(), S.end()) != 2) // One statement besides the final statement return false; for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; if (!Stmt->isReduction()) continue; isl_map *Scattering = isl_map_copy(Stmt->getScattering()); const std::string MapString = "{scattering[i0, i1, i2, i3, i4] -> scattering[i0, i3, i2, i1, i4]}"; isl_map *Map = isl_map_read_from_str(Stmt->getIslContext(), MapString.c_str(), -1); isl_map_add_dims(Map, isl_dim_param, Stmt->getNumParams()); Scattering = isl_map_apply_range(Scattering, Map); Stmt->setScattering(Scattering); DEBUG( isl_printer *p = isl_printer_to_str(S.getCtx()); isl_printer_print_map(p, Scattering); dbgs() << isl_printer_get_str(p) << '\n'; isl_printer_flush(p); isl_printer_free(p); ); }
void Dependences::collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write, isl_union_map **MayWrite, isl_union_map **Schedule) { 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)); *Schedule = isl_union_map_empty(Space); for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(), ME = Stmt->memacc_end(); MI != ME; ++MI) { isl_set *domcp = Stmt->getDomain(); isl_map *accdom = (*MI)->getAccessRelation(); accdom = isl_map_intersect_domain(accdom, domcp); if ((*MI)->isRead()) *Read = isl_union_map_add_map(*Read, accdom); else *Write = isl_union_map_add_map(*Write, accdom); } *Schedule = isl_union_map_add_map(*Schedule, Stmt->getScattering()); } }
isl_union_map *getCombinedScheduleForSpace(Scop *scop, unsigned dimLevel) { isl_space *Space = scop->getParamSpace(); isl_union_map *schedule = isl_union_map_empty(Space); for (Scop::iterator SI = scop->begin(), SE = scop->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; unsigned remainingDimensions = Stmt->getNumScattering() - dimLevel; isl_map *Scattering = isl_map_project_out( Stmt->getScattering(), isl_dim_out, dimLevel, remainingDimensions); schedule = isl_union_map_add_map(schedule, Scattering); } return schedule; }
__isl_give isl_union_map *IslAst::getSchedule() { isl_union_map *Schedule = isl_union_map_empty(S->getParamSpace()); for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; isl_map *StmtSchedule = Stmt->getScattering(); StmtSchedule = isl_map_intersect_domain(StmtSchedule, Stmt->getDomain()); Schedule = isl_union_map_union(Schedule, isl_union_map_from_map(StmtSchedule)); } return Schedule; }
bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) { Scop &S = getCurScop(); if (LegalityCheckDisabled) return true; isl_union_map *Dependences = getDependences(TYPE_ALL); isl_space *Space = S.getParamSpace(); isl_union_map *Scattering = isl_union_map_empty(Space); isl_space *ScatteringSpace = 0; for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; isl_map *StmtScat; if (NewScattering->find(*SI) == NewScattering->end()) StmtScat = Stmt->getScattering(); else StmtScat = isl_map_copy((*NewScattering)[Stmt]); if (!ScatteringSpace) ScatteringSpace = isl_space_range(isl_map_get_space(StmtScat)); Scattering = isl_union_map_add_map(Scattering, StmtScat); } Dependences = isl_union_map_apply_domain(Dependences, isl_union_map_copy(Scattering)); Dependences = isl_union_map_apply_range(Dependences, Scattering); isl_set *Zero = isl_set_universe(isl_space_copy(ScatteringSpace)); for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++) Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0); isl_union_set *UDeltas = isl_union_map_deltas(Dependences); isl_set *Deltas = isl_union_set_extract_set(UDeltas, ScatteringSpace); isl_union_set_free(UDeltas); isl_map *NonPositive = isl_set_lex_le_set(Deltas, Zero); bool IsValid = isl_map_is_empty(NonPositive); isl_map_free(NonPositive); return IsValid; }
CloogUnionDomain *Cloog::buildCloogUnionDomain() { CloogUnionDomain *DU = cloog_union_domain_alloc(S->getNumParams()); for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; CloogScattering *Scattering; CloogDomain *Domain; Scattering = cloog_scattering_from_isl_map(Stmt->getScattering()); Domain = cloog_domain_from_isl_set(Stmt->getDomain()); std::string entryName = Stmt->getBaseName(); DU = cloog_union_domain_add_domain(DU, entryName.c_str(), Domain, Scattering, Stmt); } return DU; }
void IslScheduleOptimizer::extendScattering(Scop &S, unsigned NewDimensions) { for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; unsigned OldDimensions = Stmt->getNumScattering(); isl_space *Space; isl_map *Map, *New; Space = isl_space_alloc(Stmt->getIslCtx(), 0, OldDimensions, NewDimensions); Map = isl_map_universe(Space); for (unsigned i = 0; i < OldDimensions; i++) Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i); for (unsigned i = OldDimensions; i < NewDimensions; i++) Map = isl_map_fix_si(Map, isl_dim_out, i, 0); Map = isl_map_align_params(Map, S.getParamSpace()); New = isl_map_apply_range(Stmt->getScattering(), Map); Stmt->setScattering(New); } }
CloogUnionDomain *Cloog::buildCloogUnionDomain() { CloogUnionDomain *DU = cloog_union_domain_alloc(S->getNumParams()); for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; if (Stmt->isFinalRead()) continue; CloogScattering *Scattering= cloog_scattering_from_isl_map(isl_map_copy(Stmt->getScattering())); CloogDomain *Domain = cloog_domain_from_isl_set(isl_set_copy(Stmt->getDomain())); std::string entryName = Stmt->getBaseName(); char *Name = (char*)malloc(sizeof(char) * (entryName.size() + 1)); strcpy(Name, entryName.c_str()); DU = cloog_union_domain_add_domain(DU, Name, Domain, Scattering, Stmt); } return DU; }
bool IslScheduleOptimizer::runOnScop(Scop &S) { Dependences *D = &getAnalysis<Dependences>(); isl_schedule_free(LastSchedule); LastSchedule = NULL; // Build input data. int ValidityKinds = Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW; int ProximityKinds; if (OptimizeDeps == "all") ProximityKinds = Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW; else if (OptimizeDeps == "raw") ProximityKinds = Dependences::TYPE_RAW; else { errs() << "Do not know how to optimize for '" << OptimizeDeps << "'" << " Falling back to optimizing all dependences.\n"; ProximityKinds = Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW; } isl_union_set *Domain = S.getDomains(); if (!Domain) return false; isl_union_map *Validity = D->getDependences(ValidityKinds); isl_union_map *Proximity = D->getDependences(ProximityKinds); // Simplify the dependences by removing the constraints introduced by the // domains. This can speed up the scheduling time significantly, as large // constant coefficients will be removed from the dependences. The // introduction of some additional dependences reduces the possible // transformations, but in most cases, such transformation do not seem to be // interesting anyway. In some cases this option may stop the scheduler to // find any schedule. if (SimplifyDeps == "yes") { Validity = isl_union_map_gist_domain(Validity, isl_union_set_copy(Domain)); Validity = isl_union_map_gist_range(Validity, isl_union_set_copy(Domain)); Proximity = isl_union_map_gist_domain(Proximity, isl_union_set_copy(Domain)); Proximity = isl_union_map_gist_range(Proximity, isl_union_set_copy(Domain)); } else if (SimplifyDeps != "no") { errs() << "warning: Option -polly-opt-simplify-deps should either be 'yes' " "or 'no'. Falling back to default: 'yes'\n"; } DEBUG(dbgs() << "\n\nCompute schedule from: "); DEBUG(dbgs() << "Domain := "; isl_union_set_dump(Domain); dbgs() << ";\n"); DEBUG(dbgs() << "Proximity := "; isl_union_map_dump(Proximity); dbgs() << ";\n"); DEBUG(dbgs() << "Validity := "; isl_union_map_dump(Validity); dbgs() << ";\n"); int IslFusionStrategy; if (FusionStrategy == "max") { IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX; } else if (FusionStrategy == "min") { IslFusionStrategy = ISL_SCHEDULE_FUSE_MIN; } else { errs() << "warning: Unknown fusion strategy. Falling back to maximal " "fusion.\n"; IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX; } int IslMaximizeBands; if (MaximizeBandDepth == "yes") { IslMaximizeBands = 1; } else if (MaximizeBandDepth == "no") { IslMaximizeBands = 0; } else { errs() << "warning: Option -polly-opt-maximize-bands should either be 'yes'" " or 'no'. Falling back to default: 'yes'\n"; IslMaximizeBands = 1; } isl_options_set_schedule_fuse(S.getIslCtx(), IslFusionStrategy); isl_options_set_schedule_maximize_band_depth(S.getIslCtx(), IslMaximizeBands); isl_options_set_schedule_max_constant_term(S.getIslCtx(), MaxConstantTerm); isl_options_set_schedule_max_coefficient(S.getIslCtx(), MaxCoefficient); isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE); isl_schedule *Schedule; Schedule = isl_union_set_compute_schedule(Domain, Validity, Proximity); isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT); // In cases the scheduler is not able to optimize the code, we just do not // touch the schedule. if (!Schedule) return false; DEBUG(dbgs() << "Schedule := "; isl_schedule_dump(Schedule); dbgs() << ";\n"); isl_union_map *ScheduleMap = getScheduleMap(Schedule); for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; isl_map *StmtSchedule; isl_set *Domain = Stmt->getDomain(); isl_union_map *StmtBand; StmtBand = isl_union_map_intersect_domain(isl_union_map_copy(ScheduleMap), isl_union_set_from_set(Domain)); if (isl_union_map_is_empty(StmtBand)) { // Statements with an empty iteration domain may not have a schedule // assigned by the isl schedule optimizer. As Polly expects each statement // to have a schedule, we keep the old schedule for this statement. As // there are zero iterations to execute, the content of the schedule does // not matter. // // TODO: Consider removing such statements when constructing the scop. StmtSchedule = Stmt->getScattering(); StmtSchedule = isl_map_set_tuple_id(StmtSchedule, isl_dim_out, NULL); isl_union_map_free(StmtBand); } else { assert(isl_union_map_n_map(StmtBand) == 1); StmtSchedule = isl_map_from_union_map(StmtBand); } Stmt->setScattering(StmtSchedule); } isl_union_map_free(ScheduleMap); LastSchedule = Schedule; unsigned MaxScatDims = 0; for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) MaxScatDims = std::max((*SI)->getNumScattering(), MaxScatDims); extendScattering(S, MaxScatDims); return false; }