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" 207886bd7cSMichael Kruse #define DEBUG_TYPE "polly-flatten-schedule" 217886bd7cSMichael Kruse 227886bd7cSMichael Kruse using namespace polly; 237886bd7cSMichael Kruse using namespace llvm; 247886bd7cSMichael Kruse 257886bd7cSMichael Kruse namespace { 267886bd7cSMichael Kruse 277886bd7cSMichael Kruse /// Print a schedule to @p OS. 287886bd7cSMichael Kruse /// 297886bd7cSMichael Kruse /// Prints the schedule for each statements on a new line. 30deaef15fSTobias Grosser void printSchedule(raw_ostream &OS, const isl::union_map &Schedule, 317886bd7cSMichael Kruse int indent) { 32deaef15fSTobias Grosser foreachElt(Schedule, 33deaef15fSTobias Grosser [&OS, indent](isl::map Map) { OS.indent(indent) << Map << "\n"; }); 347886bd7cSMichael Kruse } 357886bd7cSMichael Kruse 367886bd7cSMichael Kruse /// Flatten the schedule stored in an polly::Scop. 377886bd7cSMichael Kruse class FlattenSchedule : public ScopPass { 387886bd7cSMichael Kruse private: 397886bd7cSMichael Kruse FlattenSchedule(const FlattenSchedule &) = delete; 407886bd7cSMichael Kruse const FlattenSchedule &operator=(const FlattenSchedule &) = delete; 417886bd7cSMichael Kruse 427886bd7cSMichael Kruse std::shared_ptr<isl_ctx> IslCtx; 43deaef15fSTobias Grosser isl::union_map OldSchedule; 447886bd7cSMichael Kruse 457886bd7cSMichael Kruse public: 467886bd7cSMichael Kruse static char ID; 477886bd7cSMichael Kruse explicit FlattenSchedule() : ScopPass(ID) {} 487886bd7cSMichael Kruse 497886bd7cSMichael Kruse virtual void getAnalysisUsage(AnalysisUsage &AU) const override { 507886bd7cSMichael Kruse AU.addRequiredTransitive<ScopInfoRegionPass>(); 517886bd7cSMichael Kruse AU.setPreservesAll(); 527886bd7cSMichael Kruse } 537886bd7cSMichael Kruse 547886bd7cSMichael Kruse virtual bool runOnScop(Scop &S) override { 557886bd7cSMichael Kruse // Keep a reference to isl_ctx to ensure that it is not freed before we free 567886bd7cSMichael Kruse // OldSchedule. 577886bd7cSMichael Kruse IslCtx = S.getSharedIslCtx(); 587886bd7cSMichael Kruse 597886bd7cSMichael Kruse DEBUG(dbgs() << "Going to flatten old schedule:\n"); 607886bd7cSMichael Kruse OldSchedule = give(S.getSchedule()); 617886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), OldSchedule, 2)); 627886bd7cSMichael Kruse 637886bd7cSMichael Kruse auto Domains = give(S.getDomains()); 64*51ebda8cSTobias Grosser auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains); 657886bd7cSMichael Kruse DEBUG(dbgs() << "Old schedule with domains:\n"); 667886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2)); 677886bd7cSMichael Kruse 687886bd7cSMichael Kruse auto NewSchedule = flattenSchedule(RestrictedOldSchedule); 697886bd7cSMichael Kruse 707886bd7cSMichael Kruse DEBUG(dbgs() << "Flattened new schedule:\n"); 717886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), NewSchedule, 2)); 727886bd7cSMichael Kruse 73*51ebda8cSTobias Grosser NewSchedule = NewSchedule.gist_domain(Domains); 747886bd7cSMichael Kruse DEBUG(dbgs() << "Gisted, flattened new schedule:\n"); 757886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), NewSchedule, 2)); 767886bd7cSMichael Kruse 777886bd7cSMichael Kruse S.setSchedule(NewSchedule.take()); 787886bd7cSMichael Kruse return false; 797886bd7cSMichael Kruse } 807886bd7cSMichael Kruse 817886bd7cSMichael Kruse virtual void printScop(raw_ostream &OS, Scop &S) const override { 827886bd7cSMichael Kruse OS << "Schedule before flattening {\n"; 837886bd7cSMichael Kruse printSchedule(OS, OldSchedule, 4); 847886bd7cSMichael Kruse OS << "}\n\n"; 857886bd7cSMichael Kruse 867886bd7cSMichael Kruse OS << "Schedule after flattening {\n"; 877886bd7cSMichael Kruse printSchedule(OS, give(S.getSchedule()), 4); 887886bd7cSMichael Kruse OS << "}\n"; 897886bd7cSMichael Kruse } 907886bd7cSMichael Kruse 917886bd7cSMichael Kruse virtual void releaseMemory() override { 927886bd7cSMichael Kruse OldSchedule = nullptr; 937886bd7cSMichael Kruse IslCtx.reset(); 947886bd7cSMichael Kruse } 957886bd7cSMichael Kruse }; 967886bd7cSMichael Kruse 977886bd7cSMichael Kruse char FlattenSchedule::ID; 987886bd7cSMichael Kruse } // anonymous namespace 997886bd7cSMichael Kruse 1007886bd7cSMichael Kruse Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); } 1017886bd7cSMichael Kruse 1027886bd7cSMichael Kruse INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule", 1037886bd7cSMichael Kruse "Polly - Flatten schedule", false, false) 1047886bd7cSMichael Kruse INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule", 1057886bd7cSMichael Kruse "Polly - Flatten schedule", false, false) 106