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