17886bd7cSMichael Kruse //===------ FlattenSchedule.cpp --------------------------------*- C++ -*-===//
27886bd7cSMichael Kruse //
37886bd7cSMichael Kruse //                     The LLVM Compiler Infrastructure
47886bd7cSMichael Kruse //
57886bd7cSMichael Kruse // This file is distributed under the University of Illinois Open Source
67886bd7cSMichael Kruse // License. See LICENSE.TXT for details.
77886bd7cSMichael Kruse //
87886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
97886bd7cSMichael Kruse //
107886bd7cSMichael Kruse // Try to reduce the number of scatter dimension. Useful to make isl_union_map
117886bd7cSMichael Kruse // schedules more understandable. This is only intended for debugging and
127886bd7cSMichael Kruse // unittests, not for production use.
137886bd7cSMichael Kruse //
147886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
157886bd7cSMichael Kruse 
167886bd7cSMichael Kruse #include "polly/FlattenSchedule.h"
177886bd7cSMichael Kruse #include "polly/FlattenAlgo.h"
187886bd7cSMichael Kruse #include "polly/ScopInfo.h"
197886bd7cSMichael Kruse #include "polly/ScopPass.h"
2033204859STobias Grosser #include "polly/Support/ISLOStream.h"
21*c253931fSTobias Grosser #include "polly/Support/ISLTools.h"
227886bd7cSMichael Kruse #define DEBUG_TYPE "polly-flatten-schedule"
237886bd7cSMichael Kruse 
247886bd7cSMichael Kruse using namespace polly;
257886bd7cSMichael Kruse using namespace llvm;
267886bd7cSMichael Kruse 
277886bd7cSMichael Kruse namespace {
287886bd7cSMichael Kruse 
297886bd7cSMichael Kruse /// Print a schedule to @p OS.
307886bd7cSMichael Kruse ///
317886bd7cSMichael Kruse /// Prints the schedule for each statements on a new line.
32deaef15fSTobias Grosser void printSchedule(raw_ostream &OS, const isl::union_map &Schedule,
337886bd7cSMichael Kruse                    int indent) {
34*c253931fSTobias Grosser   for (isl::map Map : Schedule.get_map_list())
3575aa1a9aSTobias Grosser     OS.indent(indent) << Map << "\n";
367886bd7cSMichael Kruse }
377886bd7cSMichael Kruse 
387886bd7cSMichael Kruse /// Flatten the schedule stored in an polly::Scop.
397886bd7cSMichael Kruse class FlattenSchedule : public ScopPass {
407886bd7cSMichael Kruse private:
417886bd7cSMichael Kruse   FlattenSchedule(const FlattenSchedule &) = delete;
427886bd7cSMichael Kruse   const FlattenSchedule &operator=(const FlattenSchedule &) = delete;
437886bd7cSMichael Kruse 
447886bd7cSMichael Kruse   std::shared_ptr<isl_ctx> IslCtx;
45deaef15fSTobias Grosser   isl::union_map OldSchedule;
467886bd7cSMichael Kruse 
477886bd7cSMichael Kruse public:
487886bd7cSMichael Kruse   static char ID;
497886bd7cSMichael Kruse   explicit FlattenSchedule() : ScopPass(ID) {}
507886bd7cSMichael Kruse 
517886bd7cSMichael Kruse   virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
527886bd7cSMichael Kruse     AU.addRequiredTransitive<ScopInfoRegionPass>();
537886bd7cSMichael Kruse     AU.setPreservesAll();
547886bd7cSMichael Kruse   }
557886bd7cSMichael Kruse 
567886bd7cSMichael Kruse   virtual bool runOnScop(Scop &S) override {
577886bd7cSMichael Kruse     // Keep a reference to isl_ctx to ensure that it is not freed before we free
587886bd7cSMichael Kruse     // OldSchedule.
597886bd7cSMichael Kruse     IslCtx = S.getSharedIslCtx();
607886bd7cSMichael Kruse 
61349506a9SNicola Zaghen     LLVM_DEBUG(dbgs() << "Going to flatten old schedule:\n");
6261bd3a48STobias Grosser     OldSchedule = S.getSchedule();
63349506a9SNicola Zaghen     LLVM_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
647886bd7cSMichael Kruse 
6531df6f31STobias Grosser     auto Domains = S.getDomains();
6651ebda8cSTobias Grosser     auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
67349506a9SNicola Zaghen     LLVM_DEBUG(dbgs() << "Old schedule with domains:\n");
68349506a9SNicola Zaghen     LLVM_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
697886bd7cSMichael Kruse 
707886bd7cSMichael Kruse     auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
717886bd7cSMichael Kruse 
72349506a9SNicola Zaghen     LLVM_DEBUG(dbgs() << "Flattened new schedule:\n");
73349506a9SNicola Zaghen     LLVM_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
747886bd7cSMichael Kruse 
7551ebda8cSTobias Grosser     NewSchedule = NewSchedule.gist_domain(Domains);
76349506a9SNicola Zaghen     LLVM_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
77349506a9SNicola Zaghen     LLVM_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
787886bd7cSMichael Kruse 
7900fd43b3SPhilip Pfaffe     S.setSchedule(NewSchedule);
807886bd7cSMichael Kruse     return false;
817886bd7cSMichael Kruse   }
827886bd7cSMichael Kruse 
837886bd7cSMichael Kruse   virtual void printScop(raw_ostream &OS, Scop &S) const override {
847886bd7cSMichael Kruse     OS << "Schedule before flattening {\n";
857886bd7cSMichael Kruse     printSchedule(OS, OldSchedule, 4);
867886bd7cSMichael Kruse     OS << "}\n\n";
877886bd7cSMichael Kruse 
887886bd7cSMichael Kruse     OS << "Schedule after flattening {\n";
8961bd3a48STobias Grosser     printSchedule(OS, S.getSchedule(), 4);
907886bd7cSMichael Kruse     OS << "}\n";
917886bd7cSMichael Kruse   }
927886bd7cSMichael Kruse 
937886bd7cSMichael Kruse   virtual void releaseMemory() override {
947886bd7cSMichael Kruse     OldSchedule = nullptr;
957886bd7cSMichael Kruse     IslCtx.reset();
967886bd7cSMichael Kruse   }
977886bd7cSMichael Kruse };
987886bd7cSMichael Kruse 
997886bd7cSMichael Kruse char FlattenSchedule::ID;
1007886bd7cSMichael Kruse } // anonymous namespace
1017886bd7cSMichael Kruse 
1027886bd7cSMichael Kruse Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); }
1037886bd7cSMichael Kruse 
1047886bd7cSMichael Kruse INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule",
1057886bd7cSMichael Kruse                       "Polly - Flatten schedule", false, false)
1067886bd7cSMichael Kruse INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule",
1077886bd7cSMichael Kruse                     "Polly - Flatten schedule", false, false)
108