PostRASchedulerList.cpp revision 0ba90f3e34b826b039bdfece1415ef032c4ad3f5
172f159640382a16e036b63dcb9c0b427e6d5dc0aDale Johannesen//===----- SchedulePostRAList.cpp - list scheduler ------------------------===// 2e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 3e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// The LLVM Compiler Infrastructure 4e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 8e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 9e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 10e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// This implements a top-down list scheduler, using standard algorithms. 11e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// The basic approach uses a priority queue of available nodes to schedule. 12e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// One at a time, nodes are taken from the priority queue (thus in priority 13e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// order), checked for legality to schedule, and emitted if legal. 14e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 15e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// Nodes may not be legal to schedule either due to structural hazards (e.g. 16e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// pipeline or resource constraints) or because an input to the instruction has 17e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// not completed execution. 18e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// 19e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 20e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 21e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#define DEBUG_TYPE "post-RA-sched" 2282c7248518a8b759a567fbb4b3176542ad2cf414David Goodwin#include "AntiDepBreaker.h" 23348777110a960f0e017025dd5141cb29472c3984David Goodwin#include "AggressiveAntiDepBreaker.h" 242e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin#include "CriticalAntiDepBreaker.h" 25d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin#include "ExactHazardRecognizer.h" 26d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin#include "SimpleHazardRecognizer.h" 276dc75fe5279e2c12bda13dcc4a1a13908de8596fDan Gohman#include "ScheduleDAGInstrs.h" 28e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/CodeGen/Passes.h" 29343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/CodeGen/LatencyPriorityQueue.h" 30343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/CodeGen/SchedulerRegistry.h" 313f23744df4809eba94284e601e81489212c974d4Dan Gohman#include "llvm/CodeGen/MachineDominators.h" 32c7951f8e09a65e07626e7b9a272ce9911b249472David Goodwin#include "llvm/CodeGen/MachineFrameInfo.h" 33e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/CodeGen/MachineFunctionPass.h" 343f23744df4809eba94284e601e81489212c974d4Dan Gohman#include "llvm/CodeGen/MachineLoopInfo.h" 3521d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/CodeGen/MachineRegisterInfo.h" 362836c283bb1c14baa50994f60769d665da608ad7Dan Gohman#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 37a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman#include "llvm/Analysis/AliasAnalysis.h" 38bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman#include "llvm/Target/TargetLowering.h" 3979ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman#include "llvm/Target/TargetMachine.h" 4021d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/Target/TargetInstrInfo.h" 4121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/Target/TargetRegisterInfo.h" 420dad89fa94536284d51f60868326294b725a0c61David Goodwin#include "llvm/Target/TargetSubtarget.h" 43e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin#include "llvm/Support/CommandLine.h" 44e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/Support/Debug.h" 45c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 463a5f0d444cf21e2b90d5eb965bb677c7ce098546David Goodwin#include "llvm/Support/raw_ostream.h" 472e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin#include "llvm/ADT/BitVector.h" 48343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/ADT/Statistic.h" 4921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include <map> 5088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin#include <set> 51e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesenusing namespace llvm; 52e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 532836c283bb1c14baa50994f60769d665da608ad7Dan GohmanSTATISTIC(NumNoops, "Number of noops inserted"); 54343f0c046702831a4a6aec951b6a297a23241a55Dan GohmanSTATISTIC(NumStalls, "Number of pipeline stalls"); 552e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid GoodwinSTATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); 56343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 57471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin// Post-RA scheduling is enabled with 58471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin// TargetSubtarget.enablePostRAScheduler(). This flag can be used to 59471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin// override the target. 60471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwinstatic cl::opt<bool> 61471850ab84301dd47cab2bf8d694fcb5766c1169David GoodwinEnablePostRAScheduler("post-RA-scheduler", 62471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin cl::desc("Enable scheduling after register allocation"), 639843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin cl::init(false), cl::Hidden); 642e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwinstatic cl::opt<std::string> 6521d9003087c9a707e6cd95460136b499df358fb8Dan GohmanEnableAntiDepBreaking("break-anti-dependencies", 662e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin cl::desc("Break post-RA scheduling anti-dependencies: " 672e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin "\"critical\", \"all\", or \"none\""), 682e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin cl::init("none"), cl::Hidden); 692836c283bb1c14baa50994f60769d665da608ad7Dan Gohmanstatic cl::opt<bool> 702836c283bb1c14baa50994f60769d665da608ad7Dan GohmanEnablePostRAHazardAvoidance("avoid-hazards", 71d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin cl::desc("Enable exact hazard avoidance"), 725e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin cl::init(true), cl::Hidden); 732836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 741f1522839838a33e69d68656a423a244e19dffb8David Goodwin// If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 751f1522839838a33e69d68656a423a244e19dffb8David Goodwinstatic cl::opt<int> 761f1522839838a33e69d68656a423a244e19dffb8David GoodwinDebugDiv("postra-sched-debugdiv", 771f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::desc("Debug control MBBs that are scheduled"), 781f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::init(0), cl::Hidden); 791f1522839838a33e69d68656a423a244e19dffb8David Goodwinstatic cl::opt<int> 801f1522839838a33e69d68656a423a244e19dffb8David GoodwinDebugMod("postra-sched-debugmod", 811f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::desc("Debug control MBBs that are scheduled"), 821f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::init(0), cl::Hidden); 831f1522839838a33e69d68656a423a244e19dffb8David Goodwin 84ada0ef86d98df4ac36808e4a0f0098250bf1a842David GoodwinAntiDepBreaker::~AntiDepBreaker() { } 85ada0ef86d98df4ac36808e4a0f0098250bf1a842David Goodwin 86e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesennamespace { 876726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class PostRAScheduler : public MachineFunctionPass { 88a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman AliasAnalysis *AA; 89fa16354e0370fe884830286923352268b036737dEvan Cheng CodeGenOpt::Level OptLevel; 90a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman 91e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen public: 92e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen static char ID; 93fa16354e0370fe884830286923352268b036737dEvan Cheng PostRAScheduler(CodeGenOpt::Level ol) : 94fa16354e0370fe884830286923352268b036737dEvan Cheng MachineFunctionPass(&ID), OptLevel(ol) {} 9521d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 963f23744df4809eba94284e601e81489212c974d4Dan Gohman void getAnalysisUsage(AnalysisUsage &AU) const { 97845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesCFG(); 98a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman AU.addRequired<AliasAnalysis>(); 993f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addRequired<MachineDominatorTree>(); 1003f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addPreserved<MachineDominatorTree>(); 1013f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addRequired<MachineLoopInfo>(); 1023f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addPreserved<MachineLoopInfo>(); 1033f23744df4809eba94284e601e81489212c974d4Dan Gohman MachineFunctionPass::getAnalysisUsage(AU); 1043f23744df4809eba94284e601e81489212c974d4Dan Gohman } 1053f23744df4809eba94284e601e81489212c974d4Dan Gohman 106343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman const char *getPassName() const { 10721d9003087c9a707e6cd95460136b499df358fb8Dan Gohman return "Post RA top-down list latency scheduler"; 108343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 109343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 110343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman bool runOnMachineFunction(MachineFunction &Fn); 111343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman }; 112343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman char PostRAScheduler::ID = 0; 113343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 1146726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class SchedulePostRATDList : public ScheduleDAGInstrs { 115343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// AvailableQueue - The priority queue to use for the available SUnits. 116c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 117343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman LatencyPriorityQueue AvailableQueue; 118343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 119343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// PendingQueue - This contains all of the instructions whose operands have 120343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// been issued, but their results are not ready yet (due to the latency of 121343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// the operation). Once the operands becomes available, the instruction is 122343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// added to the AvailableQueue. 123343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman std::vector<SUnit*> PendingQueue; 124343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 12521d9003087c9a707e6cd95460136b499df358fb8Dan Gohman /// Topo - A topological ordering for SUnits. 12621d9003087c9a707e6cd95460136b499df358fb8Dan Gohman ScheduleDAGTopologicalSort Topo; 127e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 128c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// HazardRec - The hazard recognizer to use. 129c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman ScheduleHazardRecognizer *HazardRec; 130c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman 1312e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// AntiDepBreak - Anti-dependence breaking object, or NULL if none 1322e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreaker *AntiDepBreak; 1332e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 134c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// AA - AliasAnalysis for making memory reference queries. 135c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman AliasAnalysis *AA; 136480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 137c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// KillIndices - The index of the most recent kill (proceding bottom-up), 138c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// or ~0u if the register is not live. 1399e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; 1409e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 14121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman public: 14279ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman SchedulePostRATDList(MachineFunction &MF, 1433f23744df4809eba94284e601e81489212c974d4Dan Gohman const MachineLoopInfo &MLI, 1442836c283bb1c14baa50994f60769d665da608ad7Dan Gohman const MachineDominatorTree &MDT, 145a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman ScheduleHazardRecognizer *HR, 1462e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreaker *ADB, 1472e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AliasAnalysis *aa) 14879ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), 1492e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} 1502836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 1512836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ~SchedulePostRATDList() { 1522836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 153343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 1549e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// StartBlock - Initialize register live-range state for scheduling in 1559e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// this block. 1569e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// 1579e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman void StartBlock(MachineBasicBlock *BB); 1589e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 159480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin /// Schedule - Schedule the instruction range using list scheduling. 1609e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// 161480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin void Schedule(); 162480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 163c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// Observe - Update liveness information to account for the current 164c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// instruction, which will not be scheduled. 165c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 166c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman void Observe(MachineInstr *MI, unsigned Count); 167480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 168c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// FinishBlock - Clean up register live-range state. 169c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 170c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman void FinishBlock(); 171480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 1722e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// FixupKills - Fix register kill flags that have been made 1732e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// invalid due to scheduling 1742e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// 1752e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin void FixupKills(MachineBasicBlock *MBB); 1762e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 177c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman private: 17854e4c36a7349e94a84773afb56eccd4ca65b49e9Dan Gohman void ReleaseSucc(SUnit *SU, SDep *SuccEdge); 1799e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman void ReleaseSuccessors(SUnit *SU); 180343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); 181343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman void ListScheduleTopDown(); 1825e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin void StartBlockForKills(MachineBasicBlock *BB); 1838f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 1848f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // ToggleKillFlag - Toggle a register operand kill flag. Other 1858f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // adjustments may be made to the instruction if necessary. Return 1868f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // true if the operand has been deleted, false if not. 1878f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool ToggleKillFlag(MachineInstr *MI, MachineOperand &MO); 188e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen }; 189e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 190e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 1919e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// isSchedulingBoundary - Test if the given instruction should be 1929e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// considered a scheduling boundary. This primarily includes labels 1939e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// and terminators. 1949e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 1959e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanstatic bool isSchedulingBoundary(const MachineInstr *MI, 1969e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman const MachineFunction &MF) { 1979e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Terminators and labels can't be scheduled around. 1989e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (MI->getDesc().isTerminator() || MI->isLabel()) 1999e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman return true; 2009e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 201bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman // Don't attempt to schedule around any instruction that modifies 202bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman // a stack-oriented pointer, as it's unlikely to be profitable. This 203bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman // saves compile time, because it doesn't require every single 204bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman // stack slot reference to depend on the instruction that does the 205bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman // modification. 206bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman const TargetLowering &TLI = *MF.getTarget().getTargetLowering(); 207bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman if (MI->modifiesRegister(TLI.getStackPointerRegisterToSaveRestore())) 208bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman return true; 209bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman 2109e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman return false; 2119e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 2129e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 213343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanbool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { 2145bf7c2a34679b6afe46ba4f605f1921da950a66bDan Gohman AA = &getAnalysis<AliasAnalysis>(); 2155bf7c2a34679b6afe46ba4f605f1921da950a66bDan Gohman 216471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin // Check for explicit enable/disable of post-ra scheduling. 2174c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE; 218471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (EnablePostRAScheduler.getPosition() > 0) { 219471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (!EnablePostRAScheduler) 220c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 221471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } else { 222c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng // Check that post-RA scheduling is enabled for this target. 223471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin const TargetSubtarget &ST = Fn.getTarget().getSubtarget<TargetSubtarget>(); 2244c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode)) 225c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 226471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } 2270dad89fa94536284d51f60868326294b725a0c61David Goodwin 2284c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin // Check for antidep breaking override... 2294c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin if (EnableAntiDepBreaking.getPosition() > 0) { 2302e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : 2312e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : 2322e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin TargetSubtarget::ANTIDEP_NONE; 2334c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin } 2344c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin 2353a5f0d444cf21e2b90d5eb965bb677c7ce098546David Goodwin DEBUG(errs() << "PostRAScheduler\n"); 236e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 2373f23744df4809eba94284e601e81489212c974d4Dan Gohman const MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 2383f23744df4809eba94284e601e81489212c974d4Dan Gohman const MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 239d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin const InstrItineraryData &InstrItins = Fn.getTarget().getInstrItineraryData(); 2402836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? 241d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : 242d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); 2432e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreaker *ADB = 244348777110a960f0e017025dd5141cb29472c3984David Goodwin ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? 245348777110a960f0e017025dd5141cb29472c3984David Goodwin (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : 246348777110a960f0e017025dd5141cb29472c3984David Goodwin ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? 247348777110a960f0e017025dd5141cb29472c3984David Goodwin (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); 2483f23744df4809eba94284e601e81489212c974d4Dan Gohman 2492e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); 25079ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman 251e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen // Loop over all of the basic blocks 252e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 253343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman MBB != MBBe; ++MBB) { 2541f1522839838a33e69d68656a423a244e19dffb8David Goodwin#ifndef NDEBUG 2551f1522839838a33e69d68656a423a244e19dffb8David Goodwin // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 2561f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (DebugDiv > 0) { 2571f1522839838a33e69d68656a423a244e19dffb8David Goodwin static int bbcnt = 0; 2581f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (bbcnt++ % DebugDiv != DebugMod) 2591f1522839838a33e69d68656a423a244e19dffb8David Goodwin continue; 2601f1522839838a33e69d68656a423a244e19dffb8David Goodwin errs() << "*** DEBUG scheduling " << Fn.getFunction()->getNameStr() << 2610ba90f3e34b826b039bdfece1415ef032c4ad3f5Dan Gohman ":BB#" << MBB->getNumber() << " ***\n"; 2621f1522839838a33e69d68656a423a244e19dffb8David Goodwin } 2631f1522839838a33e69d68656a423a244e19dffb8David Goodwin#endif 2641f1522839838a33e69d68656a423a244e19dffb8David Goodwin 2659e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Initialize register live-range state for scheduling in this block. 2669e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.StartBlock(MBB); 2679e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 268f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // Schedule each sequence of instructions not interrupted by a label 269f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // or anything else that effectively needs to shut down scheduling. 2709e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman MachineBasicBlock::iterator Current = MBB->end(); 27147ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman unsigned Count = MBB->size(), CurrentCount = Count; 2729e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) { 2739e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman MachineInstr *MI = prior(I); 2749e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (isSchedulingBoundary(MI, Fn)) { 2751274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, I, Current, CurrentCount); 276fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng Scheduler.EmitSchedule(0); 2779e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Current = MI; 27847ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman CurrentCount = Count - 1; 2791274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Observe(MI, CurrentCount); 280f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman } 2819e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman I = MI; 28247ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman --Count; 28347ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman } 28447ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman assert(Count == 0 && "Instruction count mismatch!"); 2859e8bd0b362c034e629b9ee1f32e4e1adf037f529Duncan Sands assert((MBB->begin() == Current || CurrentCount != 0) && 2861274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman "Instruction count mismatch!"); 2871274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount); 288fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng Scheduler.EmitSchedule(0); 2899e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 2909e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Clean up register live-range state. 2919e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.FinishBlock(); 29288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 2935e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Update register kills 29488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin Scheduler.FixupKills(MBB); 295343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 296e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 2972e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin delete HR; 2982e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin delete ADB; 2992e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 300e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen return true; 301e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 302e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 3039e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// StartBlock - Initialize register live-range state for scheduling in 3049e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// this block. 3059e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 3069e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) { 3079e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 3089e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::StartBlock(BB); 3099e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3102e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin // Reset the hazard recognizer and anti-dep breaker. 311d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin HazardRec->Reset(); 3122e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3132e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->StartBlock(BB); 3149e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3159e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3169e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Schedule - Schedule the instruction range using list scheduling. 3179e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 318343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid SchedulePostRATDList::Schedule() { 319c9a5b9e38b442c2ae6b115213a07df3fcd14708dDan Gohman // Build the scheduling graph. 320a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman BuildSchedGraph(AA); 321343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3222e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) { 323e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin for (unsigned i = 0, Trials = AntiDepBreak->GetMaxTrials(); 324e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin i < Trials; ++i) { 325e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin DEBUG(errs() << "********** Break Anti-Deps, Trial " << 326e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin i << " **********\n"); 327e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin unsigned Broken = 328e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, 329e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin InsertPosIndex); 330e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin if (Broken == 0) 331e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin break; 332e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin 33321d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // We made changes. Update the dependency graph. 33421d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // Theoretically we could update the graph in place: 33521d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // When a live range is changed to use a different register, remove 33621d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // the def's anti-dependence *and* output-dependence edges due to 33721d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // that register, and add new anti-dependence and output-dependence 33821d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // edges based on the next live range of the register. 33921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman SUnits.clear(); 3409e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman EntrySU = SUnit(); 3419e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ExitSU = SUnit(); 342a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman BuildSchedGraph(AA); 3432e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 3442e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin NumFixedAnti += Broken; 34521d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 34621d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 34721d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 348e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin DEBUG(errs() << "********** List Scheduling **********\n"); 349e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin 350d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 351d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin SUnits[su].dumpAll(this)); 352d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 353343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.initNodes(SUnits); 35421d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 355343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman ListScheduleTopDown(); 356343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 357343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.releaseState(); 358343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 359343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3609e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Observe - Update liveness information to account for the current 3619e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// instruction, which will not be scheduled. 3629e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 36347ac0f0c7c39289f5970688154e385be22b7f293Dan Gohmanvoid SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { 3642e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3652e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->Observe(MI, Count, InsertPosIndex); 3669e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3679e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// FinishBlock - Clean up register live-range state. 3699e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 3709e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::FinishBlock() { 3712e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3722e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->FinishBlock(); 3739e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3749e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 3759e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::FinishBlock(); 3769e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3779e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3785e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// StartBlockForKills - Initialize register live-range state for updating kills 3795e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// 3805e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwinvoid SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { 3815e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Initialize the indices to indicate that no registers are live. 3825e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin std::fill(KillIndices, array_endof(KillIndices), ~0u); 3835e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 3845e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Determine the live-out physregs for this block. 3855e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin if (!BB->empty() && BB->back().getDesc().isReturn()) { 3865e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a return block, examine the function live-out regs. 3875e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), 3885e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = MRI.liveout_end(); I != E; ++I) { 3895e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 3905e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 3915e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 3925e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 3935e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 3945e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 3955e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3965e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3975e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3985e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin else { 3995e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a non-return block, examine the live-in regs of all successors. 4005e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 4015e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin SE = BB->succ_end(); SI != SE; ++SI) { 4025e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), 4035e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = (*SI)->livein_end(); I != E; ++I) { 4045e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 4055e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 4065e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 4075e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4085e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 4095e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 4105e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4115e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4125e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4135e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4145e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin} 4155e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 4168f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwinbool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI, 4178f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MachineOperand &MO) { 4188f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Setting kill flag... 4198f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (!MO.isKill()) { 4208f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(true); 4218f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4228f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4238f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 4248f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If MO itself is live, clear the kill flag... 4258f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[MO.getReg()] != ~0u) { 4268f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(false); 4278f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4288f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4298f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 4308f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If any subreg of MO is live, then create an imp-def for that 4318f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // subreg and keep MO marked as killed. 4328bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(false); 4338f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool AllDead = true; 4348f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin const unsigned SuperReg = MO.getReg(); 4358f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(SuperReg); 4368f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin *Subreg; ++Subreg) { 4378f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 4388f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MI->addOperand(MachineOperand::CreateReg(*Subreg, 4398f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsDef*/, 4408f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsImp*/, 4418f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsKill*/, 4428f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsDead*/)); 4438f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin AllDead = false; 4448f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4458f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4468f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 447c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman if(AllDead) 4488bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(true); 4498f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4508f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin} 4518f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 45288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// FixupKills - Fix the register kill flags, they may have been made 45388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// incorrect by instruction reordering. 45488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// 45588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwinvoid SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { 4560ba90f3e34b826b039bdfece1415ef032c4ad3f5Dan Gohman DEBUG(errs() << "Fixup kills for BB#" << MBB->getNumber() << '\n'); 45788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 45888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin std::set<unsigned> killedRegs; 45988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin BitVector ReservedRegs = TRI->getReservedRegs(MF); 4605e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 4615e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin StartBlockForKills(MBB); 4627886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4637886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Examine block from end to start... 46488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Count = MBB->size(); 46588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (MachineBasicBlock::iterator I = MBB->end(), E = MBB->begin(); 46688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin I != E; --Count) { 46788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineInstr *MI = --I; 46888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4697886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Update liveness. Registers that are defed but not used in this 4707886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // instruction are now dead. Mark register and all subregs as they 4717886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // are completely defined. 4727886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 4737886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 4747886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isReg()) continue; 4757886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 4767886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (Reg == 0) continue; 4777886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isDef()) continue; 4787886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Ignore two-addr defs. 4797886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (MI->isRegTiedToUseOperand(i)) continue; 4807886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4817886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = ~0u; 4827886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4837886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Repeat for all subregs. 4847886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4857886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 4867886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = ~0u; 4877886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 4887886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 48988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4908f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Examine all used registers and set/clear kill flag. When a 4918f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // register is used multiple times we only set the kill flag on 4928f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // the first use. 49388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.clear(); 49488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 49588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 49688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (!MO.isReg() || !MO.isUse()) continue; 49788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Reg = MO.getReg(); 49888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 49988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 5007886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin bool kill = false; 5017886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (killedRegs.find(Reg) == killedRegs.end()) { 5027886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = true; 5037886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // A register is not killed if any subregs are live... 5047886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 5057886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 5067886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 5077886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = false; 5087886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin break; 5097886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5107886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5117886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5127886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // If subreg is not live, then register is killed if it became 5137886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // live in this instruction 5147886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (kill) 5157886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = (KillIndices[Reg] == ~0u); 5167886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5177886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 51888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (MO.isKill() != kill) { 5198f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool removed = ToggleKillFlag(MI, MO); 5208f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (removed) { 5218f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin DEBUG(errs() << "Fixed <removed> in "); 5228f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } else { 5238f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin DEBUG(errs() << "Fixed " << MO << " in "); 5248f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 52588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin DEBUG(MI->dump()); 52688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5277886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 52888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.insert(Reg); 52988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5307886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 531a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // Mark any used register (that is not using undef) and subregs as 532a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // now live... 5337886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 5347886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 535a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin if (!MO.isReg() || !MO.isUse() || MO.isUndef()) continue; 5367886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 5377886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 5387886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5397886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = Count; 5407886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5417886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 5427886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 5437886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = Count; 5447886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5457886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 54688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 54788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin} 54888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 549343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 550343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman// Top-Down Scheduling 551343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 552343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 553343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to 554343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the PendingQueue if the count reaches zero. Also update its cycle bound. 55554e4c36a7349e94a84773afb56eccd4ca65b49e9Dan Gohmanvoid SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { 55654e4c36a7349e94a84773afb56eccd4ca65b49e9Dan Gohman SUnit *SuccSU = SuccEdge->getSUnit(); 557c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 558343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 559c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner if (SuccSU->NumPredsLeft == 0) { 560103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner errs() << "*** Scheduling failed! ***\n"; 561343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SuccSU->dump(this); 562103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner errs() << " has been released too many times!\n"; 563c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 564343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 565343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 566c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner --SuccSU->NumPredsLeft; 567c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 568343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // Compute how many cycles it will be before this actually becomes 569343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // available. This is the max of the start time of all predecessors plus 570343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // their latencies. 5713f23744df4809eba94284e601e81489212c974d4Dan Gohman SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); 572343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 5739e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // If all the node's predecessors are scheduled, this node is ready 5749e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // to be scheduled. Ignore the special ExitSU node. 5759e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 576343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.push_back(SuccSU); 5779e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 5789e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 5799e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. 5809e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { 5819e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 5829e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman I != E; ++I) 5839e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ReleaseSucc(SU, &*I); 584343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 585343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 586343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending 587343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// count of its successors. If a successor pending count is zero, add it to 588343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the Available queue. 589343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { 5903a5f0d444cf21e2b90d5eb965bb677c7ce098546David Goodwin DEBUG(errs() << "*** Scheduling [" << CurCycle << "]: "); 591343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman DEBUG(SU->dump(this)); 592343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 593343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.push_back(SU); 5943f23744df4809eba94284e601e81489212c974d4Dan Gohman assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!"); 5953f23744df4809eba94284e601e81489212c974d4Dan Gohman SU->setDepthToAtLeast(CurCycle); 596343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 5979e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ReleaseSuccessors(SU); 598343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SU->isScheduled = true; 599343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.ScheduledNode(SU); 600343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 601343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 602343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ListScheduleTopDown - The main loop of list scheduling for top-down 603343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// schedulers. 604343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid SchedulePostRATDList::ListScheduleTopDown() { 605343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman unsigned CurCycle = 0; 606343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 6079e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Release any successors of the special Entry node. 6089e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ReleaseSuccessors(&EntrySU); 6099e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 610343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // All leaves to Available queue. 611343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { 612343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // It is available if it has no predecessors. 613343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman if (SUnits[i].Preds.empty()) { 614343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(&SUnits[i]); 615343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SUnits[i].isAvailable = true; 616343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 617343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 6189e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 6192ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // In any cycle where we can't schedule any instructions, we must 6202ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // stall or emit a noop, depending on the target. 621be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer bool CycleHasInsts = false; 6222ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 623343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // While Available queue is not empty, grab the node with the highest 624343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // priority. If it is not ready put it back. Schedule the node. 6252836c283bb1c14baa50994f60769d665da608ad7Dan Gohman std::vector<SUnit*> NotReady; 626343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.reserve(SUnits.size()); 627343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman while (!AvailableQueue.empty() || !PendingQueue.empty()) { 628343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // Check to see if any of the pending instructions are ready to issue. If 629343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // so, add them to the available queue. 6303f23744df4809eba94284e601e81489212c974d4Dan Gohman unsigned MinDepth = ~0u; 631343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { 6323f23744df4809eba94284e601e81489212c974d4Dan Gohman if (PendingQueue[i]->getDepth() <= CurCycle) { 633343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(PendingQueue[i]); 634343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i]->isAvailable = true; 635343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i] = PendingQueue.back(); 636343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.pop_back(); 637343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman --i; --e; 6383f23744df4809eba94284e601e81489212c974d4Dan Gohman } else if (PendingQueue[i]->getDepth() < MinDepth) 6393f23744df4809eba94284e601e81489212c974d4Dan Gohman MinDepth = PendingQueue[i]->getDepth(); 640343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 641c93d8373c93159c590838957b3194900caeb8a03David Goodwin 6427cd0118c367314308cf94765ac12f81020a56271David Goodwin DEBUG(errs() << "\n*** Examining Available\n"; 6437cd0118c367314308cf94765ac12f81020a56271David Goodwin LatencyPriorityQueue q = AvailableQueue; 6447cd0118c367314308cf94765ac12f81020a56271David Goodwin while (!q.empty()) { 6457cd0118c367314308cf94765ac12f81020a56271David Goodwin SUnit *su = q.pop(); 6467cd0118c367314308cf94765ac12f81020a56271David Goodwin errs() << "Height " << su->getHeight() << ": "; 6477cd0118c367314308cf94765ac12f81020a56271David Goodwin su->dump(this); 6487cd0118c367314308cf94765ac12f81020a56271David Goodwin }); 649c93d8373c93159c590838957b3194900caeb8a03David Goodwin 6502836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *FoundSUnit = 0; 6512836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6522836c283bb1c14baa50994f60769d665da608ad7Dan Gohman bool HasNoopHazards = false; 6532836c283bb1c14baa50994f60769d665da608ad7Dan Gohman while (!AvailableQueue.empty()) { 6542836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *CurSUnit = AvailableQueue.pop(); 6552836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6562836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ScheduleHazardRecognizer::HazardType HT = 6572836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HazardRec->getHazardType(CurSUnit); 6582836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (HT == ScheduleHazardRecognizer::NoHazard) { 6592836c283bb1c14baa50994f60769d665da608ad7Dan Gohman FoundSUnit = CurSUnit; 6602836c283bb1c14baa50994f60769d665da608ad7Dan Gohman break; 6612836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6622836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6632836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Remember if this is a noop hazard. 6642836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard; 6652836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6662836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.push_back(CurSUnit); 6672836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6682836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6692836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Add the nodes that aren't ready back onto the available list. 6702836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (!NotReady.empty()) { 6712836c283bb1c14baa50994f60769d665da608ad7Dan Gohman AvailableQueue.push_all(NotReady); 6722836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.clear(); 6732836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6742836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 675343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // If we found a node to schedule, do it now. 676343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman if (FoundSUnit) { 677343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman ScheduleNodeTopDown(FoundSUnit, CurCycle); 6782836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HazardRec->EmitInstruction(FoundSUnit); 679be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = true; 680343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 681d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // If we are using the target-specific hazards, then don't 682d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // advance the cycle time just because we schedule a node. If 683d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // the target allows it we can schedule multiple nodes in the 684d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // same cycle. 685d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin if (!EnablePostRAHazardAvoidance) { 686d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops! 687d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin ++CurCycle; 688d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 6892836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } else { 690be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer if (CycleHasInsts) { 6912ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin DEBUG(errs() << "*** Finished cycle " << CurCycle << '\n'); 6922ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 6932ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else if (!HasNoopHazards) { 6942ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have a pipeline stall, but no other problem, 6952ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // just advance the current cycle and try again. 6962ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin DEBUG(errs() << "*** Stall in cycle " << CurCycle << '\n'); 6972ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 6982ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin ++NumStalls; 6992ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else { 7002ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have no instructions to issue and we have instructions 7012ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // that will fault if we don't do this right. This is the case for 7022ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // processors without pipeline interlocks and other cases. 7032ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin DEBUG(errs() << "*** Emitting noop in cycle " << CurCycle << '\n'); 7042ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->EmitNoop(); 7052ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin Sequence.push_back(0); // NULL here means noop 7062ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin ++NumNoops; 7072ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } 7082ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 7092836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ++CurCycle; 710be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = false; 711343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 712343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 713343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 714343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 715a1e6d363e5efa9eb1a2e7ac21a0394c870bef5adDan Gohman VerifySchedule(/*isBottomUp=*/false); 716343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 717343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 718e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 719e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 720e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// Public Constructor Functions 721e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 722e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 723fa16354e0370fe884830286923352268b036737dEvan ChengFunctionPass *llvm::createPostRAScheduler(CodeGenOpt::Level OptLevel) { 724fa16354e0370fe884830286923352268b036737dEvan Cheng return new PostRAScheduler(OptLevel); 725e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 726