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) { 32*75aa1a9aSTobias Grosser Schedule.foreach_map([&OS, indent](isl::map Map) -> isl::stat { 33*75aa1a9aSTobias Grosser OS.indent(indent) << Map << "\n"; 34*75aa1a9aSTobias Grosser return isl::stat::ok; 35*75aa1a9aSTobias Grosser }); 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 617886bd7cSMichael Kruse DEBUG(dbgs() << "Going to flatten old schedule:\n"); 627886bd7cSMichael Kruse OldSchedule = give(S.getSchedule()); 637886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), OldSchedule, 2)); 647886bd7cSMichael Kruse 657886bd7cSMichael Kruse auto Domains = give(S.getDomains()); 6651ebda8cSTobias Grosser auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains); 677886bd7cSMichael Kruse DEBUG(dbgs() << "Old schedule with domains:\n"); 687886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2)); 697886bd7cSMichael Kruse 707886bd7cSMichael Kruse auto NewSchedule = flattenSchedule(RestrictedOldSchedule); 717886bd7cSMichael Kruse 727886bd7cSMichael Kruse DEBUG(dbgs() << "Flattened new schedule:\n"); 737886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), NewSchedule, 2)); 747886bd7cSMichael Kruse 7551ebda8cSTobias Grosser NewSchedule = NewSchedule.gist_domain(Domains); 767886bd7cSMichael Kruse DEBUG(dbgs() << "Gisted, flattened new schedule:\n"); 777886bd7cSMichael Kruse DEBUG(printSchedule(dbgs(), NewSchedule, 2)); 787886bd7cSMichael Kruse 797886bd7cSMichael Kruse S.setSchedule(NewSchedule.take()); 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"; 897886bd7cSMichael Kruse printSchedule(OS, give(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