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