Пример #1
0
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);
    );
  }
Пример #2
0
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());
  }
}
Пример #3
0
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;
}
Пример #4
0
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);
  }
}
Пример #5
0
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;
}
Пример #6
0
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 (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)) {
      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 (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI)
    MaxScatDims = std::max((*SI)->getNumScattering(), MaxScatDims);

  extendScattering(S, MaxScatDims);
  return false;
}
Пример #7
0
bool Pocc::runTransform(Scop &S) {
  Dependences *D = &getAnalysis<Dependences>();

  // Create the scop file.
  SmallString<128> TempDir;
  SmallString<128> ScopFile;
  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true, TempDir);
  ScopFile = TempDir;
  llvm::sys::path::append(ScopFile, "polly.scop");

  FILE *F = fopen(ScopFile.c_str(), "w");

  arguments.clear();

  if (!F) {
    errs() << "Cannot open file: " << TempDir.c_str() << "\n";
    errs() << "Skipping export.\n";
    return false;
  }

  ScopLib scoplib(&S);
  scoplib.print(F);
  fclose(F);

  // Execute pocc
  std::string pocc = sys::FindProgramByName("pocc");

  arguments.push_back("pocc");
  arguments.push_back("--read-scop");
  arguments.push_back(ScopFile.c_str());
  arguments.push_back("--pluto-tile-scat");
  arguments.push_back("--candl-dep-isl-simp");
  arguments.push_back("--cloogify-scheds");
  arguments.push_back("--output-scop");
  arguments.push_back("--pluto");
  arguments.push_back("--pluto-bounds");
  arguments.push_back("10");
  arguments.push_back("--pluto-fuse");

  arguments.push_back(PlutoFuse.c_str());

  if (!DisablePollyTiling)
    arguments.push_back("--pluto-tile");

  if (PollyVectorizerChoice != VECTORIZER_NONE)
    arguments.push_back("--pluto-prevector");

  arguments.push_back(0);

  PlutoStdout = TempDir;
  llvm::sys::path::append(PlutoStdout, "pluto.stdout");
  PlutoStderr = TempDir;
  llvm::sys::path::append(PlutoStderr, "pluto.stderr");

  std::vector<llvm::StringRef> Redirect;
  Redirect.push_back(0);
  Redirect.push_back(PlutoStdout.c_str());
  Redirect.push_back(PlutoStderr.c_str());

  sys::ExecuteAndWait(pocc, &arguments[0], 0,
                      (const llvm::StringRef **)&Redirect[0]);

  // Read the created scop file
  SmallString<128> NewScopFile;
  NewScopFile = TempDir;
  llvm::sys::path::append(NewScopFile, "polly.pocc.c.scop");

  FILE *poccFile = fopen(NewScopFile.c_str(), "r");
  ScopLib newScoplib(&S, poccFile, D);

  if (!newScoplib.updateScattering()) {
    errs() << "Failure when calculating the optimization with "
              "the following command: ";
    for (std::vector<const char *>::const_iterator AI = arguments.begin(),
                                                   AE = arguments.end();
         AI != AE; ++AI)
      if (*AI)
        errs() << " " << *AI;
    errs() << "\n";
    return false;
  } else
    fclose(poccFile);

  if (PollyVectorizerChoice == VECTORIZER_NONE)
    return false;

  // Find the innermost dimension that is not a constant dimension. This
  // dimension will be vectorized.
  unsigned scatterDims = S.getScatterDim();
  int lastLoop = scatterDims - 1;

  while (lastLoop) {
    bool isSingleValued = true;

    for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
      isl_map *scat = (*SI)->getScattering();
      isl_map *projected = isl_map_project_out(scat, isl_dim_out, lastLoop,
                                               scatterDims - lastLoop);

      if (!isl_map_is_bijective(projected)) {
        isSingleValued = false;
        break;
      }
    }

    if (!isSingleValued)
      break;

    lastLoop--;
  }

  // Strip mine the innermost loop.
  for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
    isl_map *scat = (*SI)->getScattering();
    int scatDims = (*SI)->getNumScattering();
    isl_space *Space = isl_space_alloc(S.getIslCtx(), S.getNumParams(),
                                       scatDims, scatDims + 1);
    isl_basic_map *map = isl_basic_map_universe(isl_space_copy(Space));
    isl_local_space *LSpace = isl_local_space_from_space(Space);

    for (int i = 0; i <= lastLoop - 1; i++) {
      isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace));

      isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
      isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);

      map = isl_basic_map_add_constraint(map, c);
    }

    for (int i = lastLoop; i < scatDims; i++) {
      isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace));

      isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
      isl_constraint_set_coefficient_si(c, isl_dim_out, i + 1, -1);

      map = isl_basic_map_add_constraint(map, c);
    }

    isl_constraint *c;

    int vectorWidth = 4;
    c = isl_inequality_alloc(isl_local_space_copy(LSpace));
    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, -vectorWidth);
    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, 1);
    map = isl_basic_map_add_constraint(map, c);

    c = isl_inequality_alloc(LSpace);
    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, vectorWidth);
    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, -1);
    isl_constraint_set_constant_si(c, vectorWidth - 1);
    map = isl_basic_map_add_constraint(map, c);

    isl_map *transform = isl_map_from_basic_map(map);
    transform = isl_map_set_tuple_name(transform, isl_dim_out, "scattering");
    transform = isl_map_set_tuple_name(transform, isl_dim_in, "scattering");

    scat = isl_map_apply_range(scat, isl_map_copy(transform));
    (*SI)->setScattering(scat);
  }

  return false;
}