17886bd7cSMichael Kruse //===------ FlattenSchedule.cpp --------------------------------*- C++ -*-===//
27886bd7cSMichael Kruse //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67886bd7cSMichael Kruse //
77886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
87886bd7cSMichael Kruse //
97886bd7cSMichael Kruse // Try to reduce the number of scatter dimension. Useful to make isl_union_map
107886bd7cSMichael Kruse // schedules more understandable. This is only intended for debugging and
117886bd7cSMichael Kruse // unittests, not for production use.
127886bd7cSMichael Kruse //
137886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
147886bd7cSMichael Kruse
157886bd7cSMichael Kruse #include "polly/FlattenSchedule.h"
167886bd7cSMichael Kruse #include "polly/FlattenAlgo.h"
177886bd7cSMichael Kruse #include "polly/ScopInfo.h"
187886bd7cSMichael Kruse #include "polly/ScopPass.h"
1933204859STobias Grosser #include "polly/Support/ISLOStream.h"
20c253931fSTobias Grosser #include "polly/Support/ISLTools.h"
217886bd7cSMichael Kruse #define DEBUG_TYPE "polly-flatten-schedule"
227886bd7cSMichael Kruse
237886bd7cSMichael Kruse using namespace polly;
247886bd7cSMichael Kruse using namespace llvm;
257886bd7cSMichael Kruse
267886bd7cSMichael Kruse namespace {
277886bd7cSMichael Kruse
287886bd7cSMichael Kruse /// Print a schedule to @p OS.
297886bd7cSMichael Kruse ///
307886bd7cSMichael Kruse /// Prints the schedule for each statements on a new line.
printSchedule(raw_ostream & OS,const isl::union_map & Schedule,int indent)31deaef15fSTobias Grosser void printSchedule(raw_ostream &OS, const isl::union_map &Schedule,
327886bd7cSMichael Kruse int indent) {
33c253931fSTobias Grosser for (isl::map Map : Schedule.get_map_list())
3475aa1a9aSTobias Grosser OS.indent(indent) << Map << "\n";
357886bd7cSMichael Kruse }
367886bd7cSMichael Kruse
377886bd7cSMichael Kruse /// Flatten the schedule stored in an polly::Scop.
38bd93df93SMichael Kruse class FlattenSchedule final : public ScopPass {
397886bd7cSMichael Kruse private:
407886bd7cSMichael Kruse FlattenSchedule(const FlattenSchedule &) = delete;
417886bd7cSMichael Kruse const FlattenSchedule &operator=(const FlattenSchedule &) = delete;
427886bd7cSMichael Kruse
437886bd7cSMichael Kruse std::shared_ptr<isl_ctx> IslCtx;
44deaef15fSTobias Grosser isl::union_map OldSchedule;
457886bd7cSMichael Kruse
467886bd7cSMichael Kruse public:
477886bd7cSMichael Kruse static char ID;
FlattenSchedule()487886bd7cSMichael Kruse explicit FlattenSchedule() : ScopPass(ID) {}
497886bd7cSMichael Kruse
getAnalysisUsage(AnalysisUsage & AU) const50*3f3930a4SKazu Hirata void getAnalysisUsage(AnalysisUsage &AU) const override {
517886bd7cSMichael Kruse AU.addRequiredTransitive<ScopInfoRegionPass>();
527886bd7cSMichael Kruse AU.setPreservesAll();
537886bd7cSMichael Kruse }
547886bd7cSMichael Kruse
runOnScop(Scop & S)55*3f3930a4SKazu Hirata bool runOnScop(Scop &S) override {
567886bd7cSMichael Kruse // Keep a reference to isl_ctx to ensure that it is not freed before we free
577886bd7cSMichael Kruse // OldSchedule.
587886bd7cSMichael Kruse IslCtx = S.getSharedIslCtx();
597886bd7cSMichael Kruse
60349506a9SNicola Zaghen LLVM_DEBUG(dbgs() << "Going to flatten old schedule:\n");
6161bd3a48STobias Grosser OldSchedule = S.getSchedule();
62349506a9SNicola Zaghen LLVM_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
637886bd7cSMichael Kruse
6431df6f31STobias Grosser auto Domains = S.getDomains();
6551ebda8cSTobias Grosser auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
66349506a9SNicola Zaghen LLVM_DEBUG(dbgs() << "Old schedule with domains:\n");
67349506a9SNicola Zaghen LLVM_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
687886bd7cSMichael Kruse
697886bd7cSMichael Kruse auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
707886bd7cSMichael Kruse
71349506a9SNicola Zaghen LLVM_DEBUG(dbgs() << "Flattened new schedule:\n");
72349506a9SNicola Zaghen LLVM_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
737886bd7cSMichael Kruse
7451ebda8cSTobias Grosser NewSchedule = NewSchedule.gist_domain(Domains);
75349506a9SNicola Zaghen LLVM_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
76349506a9SNicola Zaghen LLVM_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
777886bd7cSMichael Kruse
7800fd43b3SPhilip Pfaffe S.setSchedule(NewSchedule);
797886bd7cSMichael Kruse return false;
807886bd7cSMichael Kruse }
817886bd7cSMichael Kruse
printScop(raw_ostream & OS,Scop & S) const82*3f3930a4SKazu Hirata void printScop(raw_ostream &OS, Scop &S) const override {
837886bd7cSMichael Kruse OS << "Schedule before flattening {\n";
847886bd7cSMichael Kruse printSchedule(OS, OldSchedule, 4);
857886bd7cSMichael Kruse OS << "}\n\n";
867886bd7cSMichael Kruse
877886bd7cSMichael Kruse OS << "Schedule after flattening {\n";
8861bd3a48STobias Grosser printSchedule(OS, S.getSchedule(), 4);
897886bd7cSMichael Kruse OS << "}\n";
907886bd7cSMichael Kruse }
917886bd7cSMichael Kruse
releaseMemory()92*3f3930a4SKazu Hirata void releaseMemory() override {
939b41d095Spatacca OldSchedule = {};
947886bd7cSMichael Kruse IslCtx.reset();
957886bd7cSMichael Kruse }
967886bd7cSMichael Kruse };
977886bd7cSMichael Kruse
987886bd7cSMichael Kruse char FlattenSchedule::ID;
995c028081SMichael Kruse
1005c028081SMichael Kruse /// Print result from FlattenSchedule.
101bd93df93SMichael Kruse class FlattenSchedulePrinterLegacyPass final : public ScopPass {
1025c028081SMichael Kruse public:
1035c028081SMichael Kruse static char ID;
1045c028081SMichael Kruse
FlattenSchedulePrinterLegacyPass()1055c028081SMichael Kruse FlattenSchedulePrinterLegacyPass()
1065c028081SMichael Kruse : FlattenSchedulePrinterLegacyPass(outs()){};
FlattenSchedulePrinterLegacyPass(llvm::raw_ostream & OS)1075c028081SMichael Kruse explicit FlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS)
1085c028081SMichael Kruse : ScopPass(ID), OS(OS) {}
1095c028081SMichael Kruse
runOnScop(Scop & S)1105c028081SMichael Kruse bool runOnScop(Scop &S) override {
1115c028081SMichael Kruse FlattenSchedule &P = getAnalysis<FlattenSchedule>();
1125c028081SMichael Kruse
1135c028081SMichael Kruse OS << "Printing analysis '" << P.getPassName() << "' for region: '"
1145c028081SMichael Kruse << S.getRegion().getNameStr() << "' in function '"
1155c028081SMichael Kruse << S.getFunction().getName() << "':\n";
1165c028081SMichael Kruse P.printScop(OS, S);
1175c028081SMichael Kruse
1185c028081SMichael Kruse return false;
1195c028081SMichael Kruse }
1205c028081SMichael Kruse
getAnalysisUsage(AnalysisUsage & AU) const1215c028081SMichael Kruse void getAnalysisUsage(AnalysisUsage &AU) const override {
1225c028081SMichael Kruse ScopPass::getAnalysisUsage(AU);
1235c028081SMichael Kruse AU.addRequired<FlattenSchedule>();
1245c028081SMichael Kruse AU.setPreservesAll();
1255c028081SMichael Kruse }
1265c028081SMichael Kruse
1275c028081SMichael Kruse private:
1285c028081SMichael Kruse llvm::raw_ostream &OS;
1295c028081SMichael Kruse };
1305c028081SMichael Kruse
1315c028081SMichael Kruse char FlattenSchedulePrinterLegacyPass::ID = 0;
1327886bd7cSMichael Kruse } // anonymous namespace
1337886bd7cSMichael Kruse
createFlattenSchedulePass()1347886bd7cSMichael Kruse Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); }
1357886bd7cSMichael Kruse
createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream & OS)1365c028081SMichael Kruse Pass *polly::createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS) {
1375c028081SMichael Kruse return new FlattenSchedulePrinterLegacyPass(OS);
1385c028081SMichael Kruse }
1395c028081SMichael Kruse
1407886bd7cSMichael Kruse INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule",
1417886bd7cSMichael Kruse "Polly - Flatten schedule", false, false)
1427886bd7cSMichael Kruse INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule",
1437886bd7cSMichael Kruse "Polly - Flatten schedule", false, false)
1445c028081SMichael Kruse
1455c028081SMichael Kruse INITIALIZE_PASS_BEGIN(FlattenSchedulePrinterLegacyPass,
1465c028081SMichael Kruse "polly-print-flatten-schedule",
1475c028081SMichael Kruse "Polly - Print flattened schedule", false, false)
1485c028081SMichael Kruse INITIALIZE_PASS_DEPENDENCY(FlattenSchedule)
1495c028081SMichael Kruse INITIALIZE_PASS_END(FlattenSchedulePrinterLegacyPass,
1505c028081SMichael Kruse "polly-print-flatten-schedule",
1515c028081SMichael Kruse "Polly - Print flattened schedule", false, false)
152