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