1*7886bd7cSMichael Kruse //===------ FlattenSchedule.cpp --------------------------------*- C++ -*-===//
2*7886bd7cSMichael Kruse //
3*7886bd7cSMichael Kruse //                     The LLVM Compiler Infrastructure
4*7886bd7cSMichael Kruse //
5*7886bd7cSMichael Kruse // This file is distributed under the University of Illinois Open Source
6*7886bd7cSMichael Kruse // License. See LICENSE.TXT for details.
7*7886bd7cSMichael Kruse //
8*7886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
9*7886bd7cSMichael Kruse //
10*7886bd7cSMichael Kruse // Try to reduce the number of scatter dimension. Useful to make isl_union_map
11*7886bd7cSMichael Kruse // schedules more understandable. This is only intended for debugging and
12*7886bd7cSMichael Kruse // unittests, not for production use.
13*7886bd7cSMichael Kruse //
14*7886bd7cSMichael Kruse //===----------------------------------------------------------------------===//
15*7886bd7cSMichael Kruse 
16*7886bd7cSMichael Kruse #include "polly/FlattenSchedule.h"
17*7886bd7cSMichael Kruse #include "polly/FlattenAlgo.h"
18*7886bd7cSMichael Kruse #include "polly/ScopInfo.h"
19*7886bd7cSMichael Kruse #include "polly/ScopPass.h"
20*7886bd7cSMichael Kruse #define DEBUG_TYPE "polly-flatten-schedule"
21*7886bd7cSMichael Kruse 
22*7886bd7cSMichael Kruse using namespace polly;
23*7886bd7cSMichael Kruse using namespace llvm;
24*7886bd7cSMichael Kruse 
25*7886bd7cSMichael Kruse namespace {
26*7886bd7cSMichael Kruse 
27*7886bd7cSMichael Kruse /// Print a schedule to @p OS.
28*7886bd7cSMichael Kruse ///
29*7886bd7cSMichael Kruse /// Prints the schedule for each statements on a new line.
30*7886bd7cSMichael Kruse void printSchedule(raw_ostream &OS, NonowningIslPtr<isl_union_map> Schedule,
31*7886bd7cSMichael Kruse                    int indent) {
32*7886bd7cSMichael Kruse   foreachElt(Schedule, [&OS, indent](IslPtr<isl_map> Map) {
33*7886bd7cSMichael Kruse     OS.indent(indent) << Map << "\n";
34*7886bd7cSMichael Kruse   });
35*7886bd7cSMichael Kruse }
36*7886bd7cSMichael Kruse 
37*7886bd7cSMichael Kruse /// Flatten the schedule stored in an polly::Scop.
38*7886bd7cSMichael Kruse class FlattenSchedule : public ScopPass {
39*7886bd7cSMichael Kruse private:
40*7886bd7cSMichael Kruse   FlattenSchedule(const FlattenSchedule &) = delete;
41*7886bd7cSMichael Kruse   const FlattenSchedule &operator=(const FlattenSchedule &) = delete;
42*7886bd7cSMichael Kruse 
43*7886bd7cSMichael Kruse   std::shared_ptr<isl_ctx> IslCtx;
44*7886bd7cSMichael Kruse   IslPtr<isl_union_map> OldSchedule;
45*7886bd7cSMichael Kruse 
46*7886bd7cSMichael Kruse public:
47*7886bd7cSMichael Kruse   static char ID;
48*7886bd7cSMichael Kruse   explicit FlattenSchedule() : ScopPass(ID) {}
49*7886bd7cSMichael Kruse 
50*7886bd7cSMichael Kruse   virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
51*7886bd7cSMichael Kruse     AU.addRequiredTransitive<ScopInfoRegionPass>();
52*7886bd7cSMichael Kruse     AU.setPreservesAll();
53*7886bd7cSMichael Kruse   }
54*7886bd7cSMichael Kruse 
55*7886bd7cSMichael Kruse   virtual bool runOnScop(Scop &S) override {
56*7886bd7cSMichael Kruse     // Keep a reference to isl_ctx to ensure that it is not freed before we free
57*7886bd7cSMichael Kruse     // OldSchedule.
58*7886bd7cSMichael Kruse     IslCtx = S.getSharedIslCtx();
59*7886bd7cSMichael Kruse 
60*7886bd7cSMichael Kruse     DEBUG(dbgs() << "Going to flatten old schedule:\n");
61*7886bd7cSMichael Kruse     OldSchedule = give(S.getSchedule());
62*7886bd7cSMichael Kruse     DEBUG(printSchedule(dbgs(), OldSchedule, 2));
63*7886bd7cSMichael Kruse 
64*7886bd7cSMichael Kruse     auto Domains = give(S.getDomains());
65*7886bd7cSMichael Kruse     auto RestrictedOldSchedule = give(
66*7886bd7cSMichael Kruse         isl_union_map_intersect_domain(OldSchedule.copy(), Domains.copy()));
67*7886bd7cSMichael Kruse     DEBUG(dbgs() << "Old schedule with domains:\n");
68*7886bd7cSMichael Kruse     DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
69*7886bd7cSMichael Kruse 
70*7886bd7cSMichael Kruse     auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
71*7886bd7cSMichael Kruse 
72*7886bd7cSMichael Kruse     DEBUG(dbgs() << "Flattened new schedule:\n");
73*7886bd7cSMichael Kruse     DEBUG(printSchedule(dbgs(), NewSchedule, 2));
74*7886bd7cSMichael Kruse 
75*7886bd7cSMichael Kruse     NewSchedule =
76*7886bd7cSMichael Kruse         give(isl_union_map_gist_domain(NewSchedule.take(), Domains.take()));
77*7886bd7cSMichael Kruse     DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
78*7886bd7cSMichael Kruse     DEBUG(printSchedule(dbgs(), NewSchedule, 2));
79*7886bd7cSMichael Kruse 
80*7886bd7cSMichael Kruse     S.setSchedule(NewSchedule.take());
81*7886bd7cSMichael Kruse     return false;
82*7886bd7cSMichael Kruse   }
83*7886bd7cSMichael Kruse 
84*7886bd7cSMichael Kruse   virtual void printScop(raw_ostream &OS, Scop &S) const override {
85*7886bd7cSMichael Kruse     OS << "Schedule before flattening {\n";
86*7886bd7cSMichael Kruse     printSchedule(OS, OldSchedule, 4);
87*7886bd7cSMichael Kruse     OS << "}\n\n";
88*7886bd7cSMichael Kruse 
89*7886bd7cSMichael Kruse     OS << "Schedule after flattening {\n";
90*7886bd7cSMichael Kruse     printSchedule(OS, give(S.getSchedule()), 4);
91*7886bd7cSMichael Kruse     OS << "}\n";
92*7886bd7cSMichael Kruse   }
93*7886bd7cSMichael Kruse 
94*7886bd7cSMichael Kruse   virtual void releaseMemory() override {
95*7886bd7cSMichael Kruse     OldSchedule = nullptr;
96*7886bd7cSMichael Kruse     IslCtx.reset();
97*7886bd7cSMichael Kruse   }
98*7886bd7cSMichael Kruse };
99*7886bd7cSMichael Kruse 
100*7886bd7cSMichael Kruse char FlattenSchedule::ID;
101*7886bd7cSMichael Kruse } // anonymous namespace
102*7886bd7cSMichael Kruse 
103*7886bd7cSMichael Kruse Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); }
104*7886bd7cSMichael Kruse 
105*7886bd7cSMichael Kruse INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule",
106*7886bd7cSMichael Kruse                       "Polly - Flatten schedule", false, false)
107*7886bd7cSMichael Kruse INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule",
108*7886bd7cSMichael Kruse                     "Polly - Flatten schedule", false, false)
109