bool DeadCodeElim::runOnScop(Scop &S) { Dependences *D = &getAnalysis<Dependences>(); int Kinds = Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW; isl_union_map *Deps = D->getDependences(Kinds); isl_union_map_free(Deps); return false; }
bool IslScheduleOptimizer::runOnScop(Scop &S) { Dependences *D = &getAnalysis<Dependences>(); if (!D->hasValidDependences()) return false; isl_schedule_free(LastSchedule); LastSchedule = nullptr; // 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_constraints *ScheduleConstraints; ScheduleConstraints = isl_schedule_constraints_on_domain(Domain); ScheduleConstraints = isl_schedule_constraints_set_proximity(ScheduleConstraints, Proximity); ScheduleConstraints = isl_schedule_constraints_set_validity( ScheduleConstraints, isl_union_map_copy(Validity)); ScheduleConstraints = isl_schedule_constraints_set_coincidence(ScheduleConstraints, Validity); isl_schedule *Schedule; Schedule = isl_schedule_constraints_compute_schedule(ScheduleConstraints); 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 (ScopStmt *Stmt : S) { 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)) { StmtSchedule = isl_map_from_domain(isl_set_empty(Stmt->getDomainSpace())); 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 (ScopStmt *Stmt : S) MaxScatDims = std::max(Stmt->getNumScattering(), MaxScatDims); extendScattering(S, MaxScatDims); return false; }
bool JSONImporter::runOnScop(Scop &scop) { S = &scop; Region &R = S->getRegion(); Dependences *D = &getAnalysis<Dependences>(); std::string FileName = ImportDir + "/" + getFileName(S); std::string FunctionName = R.getEntry()->getParent()->getName(); errs() << "Reading JScop '" << R.getNameStr() << "' in function '" << FunctionName << "' from '" << FileName << "'.\n"; OwningPtr<MemoryBuffer> result; error_code ec = MemoryBuffer::getFile(FileName, result); if (ec) { errs() << "File could not be read: " << ec.message() << "\n"; return false; } Json::Reader reader; Json::Value jscop; bool parsingSuccessful = reader.parse(result->getBufferStart(), jscop); if (!parsingSuccessful) { errs() << "JSCoP file could not be parsed\n"; return false; } isl_set *OldContext = S->getContext(); isl_set *NewContext = isl_set_read_from_str(S->getIslCtx(), jscop["context"].asCString()); for (unsigned i = 0; i < isl_set_dim(OldContext, isl_dim_param); i++) { isl_id *id = isl_set_get_dim_id(OldContext, isl_dim_param, i); NewContext = isl_set_set_dim_id(NewContext, isl_dim_param, i, id); } isl_set_free(OldContext); S->setContext(NewContext); StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy()); int index = 0; for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { Json::Value schedule = jscop["statements"][index]["schedule"]; isl_map *m = isl_map_read_from_str(S->getIslCtx(), schedule.asCString()); isl_space *Space = (*SI)->getDomainSpace(); // Copy the old tuple id. This is necessary to retain the user pointer, // that stores the reference to the ScopStmt this scattering belongs to. m = isl_map_set_tuple_id(m, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set)); isl_space_free(Space); NewScattering[*SI] = m; index++; } if (!D->isValidScattering(&NewScattering)) { errs() << "JScop file contains a scattering that changes the " << "dependences. Use -disable-polly-legality to continue anyways\n"; return false; } for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; if (NewScattering.find(Stmt) != NewScattering.end()) Stmt->setScattering(NewScattering[Stmt]); } int statementIdx = 0; for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { ScopStmt *Stmt = *SI; int memoryAccessIdx = 0; for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(), ME = Stmt->memacc_end(); MI != ME; ++MI) { Json::Value accesses = jscop["statements"][statementIdx]["accesses"][ memoryAccessIdx]["relation"]; isl_map *newAccessMap = isl_map_read_from_str(S->getIslCtx(), accesses.asCString()); isl_map *currentAccessMap = (*MI)->getAccessRelation(); if (isl_map_dim(newAccessMap, isl_dim_param) != isl_map_dim(currentAccessMap, isl_dim_param)) { errs() << "JScop file changes the number of parameter dimensions\n"; isl_map_free(currentAccessMap); isl_map_free(newAccessMap); return false; } // We need to copy the isl_ids for the parameter dimensions to the new // map. Without doing this the current map would have different // ids then the new one, even though both are named identically. for (unsigned i = 0; i < isl_map_dim(currentAccessMap, isl_dim_param); i++) { isl_id *id = isl_map_get_dim_id(currentAccessMap, isl_dim_param, i); newAccessMap = isl_map_set_dim_id(newAccessMap, isl_dim_param, i, id); } // Copy the old tuple id. This is necessary to retain the user pointer, // that stores the reference to the ScopStmt this access belongs to. isl_id *Id = isl_map_get_tuple_id(currentAccessMap, isl_dim_in); newAccessMap = isl_map_set_tuple_id(newAccessMap, isl_dim_in, Id); if (!isl_map_has_equal_space(currentAccessMap, newAccessMap)) { errs() << "JScop file contains access function with incompatible " << "dimensions\n"; isl_map_free(currentAccessMap); isl_map_free(newAccessMap); return false; } if (isl_map_dim(newAccessMap, isl_dim_out) != 1) { errs() << "New access map in JScop file should be single dimensional\n"; isl_map_free(currentAccessMap); isl_map_free(newAccessMap); return false; } if (!isl_map_is_equal(newAccessMap, currentAccessMap)) { // Statistics. ++NewAccessMapFound; newAccessStrings.push_back(accesses.asCString()); (*MI)->setNewAccessRelation(newAccessMap); } else { isl_map_free(newAccessMap); } isl_map_free(currentAccessMap); memoryAccessIdx++; } statementIdx++; } return false; }