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