PostRASchedulerList.cpp revision b0812f114b83a32c4b90a4b553c7177c557558b5
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: 178557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ReleaseSucc(SUnit *SU, SDep *SuccEdge); 179557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ReleaseSuccessors(SUnit *SU); 180557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); 181557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin 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; 21887d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin SmallVector<TargetRegisterClass*, 4> CriticalPathRCs; 219471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (EnablePostRAScheduler.getPosition() > 0) { 220471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (!EnablePostRAScheduler) 221c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 222471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } else { 223c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng // Check that post-RA scheduling is enabled for this target. 224471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin const TargetSubtarget &ST = Fn.getTarget().getSubtarget<TargetSubtarget>(); 22587d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, CriticalPathRCs)) 226c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 227471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } 2280dad89fa94536284d51f60868326294b725a0c61David Goodwin 2294c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin // Check for antidep breaking override... 2304c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin if (EnableAntiDepBreaking.getPosition() > 0) { 2312e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : 2322e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : 2332e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin TargetSubtarget::ANTIDEP_NONE; 2344c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin } 2354c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin 236e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "PostRAScheduler\n"); 237e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 2383f23744df4809eba94284e601e81489212c974d4Dan Gohman const MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 2393f23744df4809eba94284e601e81489212c974d4Dan Gohman const MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 240d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin const InstrItineraryData &InstrItins = Fn.getTarget().getInstrItineraryData(); 2412836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? 242d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : 243d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); 2442e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreaker *ADB = 245348777110a960f0e017025dd5141cb29472c3984David Goodwin ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? 24687d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, CriticalPathRCs) : 247348777110a960f0e017025dd5141cb29472c3984David Goodwin ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? 248348777110a960f0e017025dd5141cb29472c3984David Goodwin (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); 2493f23744df4809eba94284e601e81489212c974d4Dan Gohman 2502e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); 25179ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman 252e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen // Loop over all of the basic blocks 253e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 254343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman MBB != MBBe; ++MBB) { 2551f1522839838a33e69d68656a423a244e19dffb8David Goodwin#ifndef NDEBUG 2561f1522839838a33e69d68656a423a244e19dffb8David Goodwin // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 2571f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (DebugDiv > 0) { 2581f1522839838a33e69d68656a423a244e19dffb8David Goodwin static int bbcnt = 0; 2591f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (bbcnt++ % DebugDiv != DebugMod) 2601f1522839838a33e69d68656a423a244e19dffb8David Goodwin continue; 261e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << "*** DEBUG scheduling " << Fn.getFunction()->getNameStr() << 2620ba90f3e34b826b039bdfece1415ef032c4ad3f5Dan Gohman ":BB#" << MBB->getNumber() << " ***\n"; 2631f1522839838a33e69d68656a423a244e19dffb8David Goodwin } 2641f1522839838a33e69d68656a423a244e19dffb8David Goodwin#endif 2651f1522839838a33e69d68656a423a244e19dffb8David Goodwin 2669e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Initialize register live-range state for scheduling in this block. 2679e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.StartBlock(MBB); 2689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 269f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // Schedule each sequence of instructions not interrupted by a label 270f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // or anything else that effectively needs to shut down scheduling. 2719e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman MachineBasicBlock::iterator Current = MBB->end(); 27247ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman unsigned Count = MBB->size(), CurrentCount = Count; 2739e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) { 2749e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman MachineInstr *MI = prior(I); 2759e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (isSchedulingBoundary(MI, Fn)) { 2761274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, I, Current, CurrentCount); 277fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng Scheduler.EmitSchedule(0); 2789e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Current = MI; 27947ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman CurrentCount = Count - 1; 2801274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Observe(MI, CurrentCount); 281f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman } 2829e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman I = MI; 28347ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman --Count; 28447ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman } 28547ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman assert(Count == 0 && "Instruction count mismatch!"); 2869e8bd0b362c034e629b9ee1f32e4e1adf037f529Duncan Sands assert((MBB->begin() == Current || CurrentCount != 0) && 2871274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman "Instruction count mismatch!"); 2881274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount); 289fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng Scheduler.EmitSchedule(0); 2909e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 2919e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Clean up register live-range state. 2929e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.FinishBlock(); 29388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 2945e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Update register kills 29588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin Scheduler.FixupKills(MBB); 296343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 297e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 2982e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin delete HR; 2992e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin delete ADB; 3002e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 301e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen return true; 302e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 303e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 3049e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// StartBlock - Initialize register live-range state for scheduling in 3059e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// this block. 3069e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 3079e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) { 3089e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 3099e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::StartBlock(BB); 3109e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3112e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin // Reset the hazard recognizer and anti-dep breaker. 312d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin HazardRec->Reset(); 3132e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3142e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->StartBlock(BB); 3159e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3169e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3179e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Schedule - Schedule the instruction range using list scheduling. 3189e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 319343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid SchedulePostRATDList::Schedule() { 320c9a5b9e38b442c2ae6b115213a07df3fcd14708dDan Gohman // Build the scheduling graph. 321a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman BuildSchedGraph(AA); 322343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3232e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) { 324557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin unsigned Broken = 325557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, 326557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin InsertPosIndex); 3274de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin 328557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin if (Broken != 0) { 32921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // We made changes. Update the dependency graph. 33021d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // Theoretically we could update the graph in place: 33121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // When a live range is changed to use a different register, remove 33221d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // the def's anti-dependence *and* output-dependence edges due to 33321d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // that register, and add new anti-dependence and output-dependence 33421d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // edges based on the next live range of the register. 335557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin SUnits.clear(); 336557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin Sequence.clear(); 337557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin EntrySU = SUnit(); 338557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ExitSU = SUnit(); 339557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin BuildSchedGraph(AA); 340557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin 3412e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin NumFixedAnti += Broken; 34221d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 34321d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 34421d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 345e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "********** List Scheduling **********\n"); 346d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 347d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin SUnits[su].dumpAll(this)); 348d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 349343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.initNodes(SUnits); 350557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ListScheduleTopDown(); 351343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.releaseState(); 352343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 353343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3549e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Observe - Update liveness information to account for the current 3559e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// instruction, which will not be scheduled. 3569e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 35747ac0f0c7c39289f5970688154e385be22b7f293Dan Gohmanvoid SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { 3582e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3592e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->Observe(MI, Count, InsertPosIndex); 3609e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3619e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3629e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// FinishBlock - Clean up register live-range state. 3639e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 3649e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::FinishBlock() { 3652e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3662e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->FinishBlock(); 3679e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 3699e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::FinishBlock(); 3709e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3719e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3725e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// StartBlockForKills - Initialize register live-range state for updating kills 3735e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// 3745e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwinvoid SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { 3755e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Initialize the indices to indicate that no registers are live. 376990d2857654cb80e46d207533834be3047494830David Goodwin for (unsigned i = 0; i < TRI->getNumRegs(); ++i) 377990d2857654cb80e46d207533834be3047494830David Goodwin KillIndices[i] = ~0u; 3785e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 3795e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Determine the live-out physregs for this block. 3805e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin if (!BB->empty() && BB->back().getDesc().isReturn()) { 3815e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a return block, examine the function live-out regs. 3825e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), 3835e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = MRI.liveout_end(); I != E; ++I) { 3845e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 3855e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 3865e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 3875e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 3885e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 3895e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 3905e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3915e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3925e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3935e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin else { 3945e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a non-return block, examine the live-in regs of all successors. 3955e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 3965e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin SE = BB->succ_end(); SI != SE; ++SI) { 3975e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), 3985e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = (*SI)->livein_end(); I != E; ++I) { 3995e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 4005e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 4015e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 4025e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4035e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 4045e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 4055e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4065e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4075e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4085e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 4095e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin} 4105e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 4118f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwinbool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI, 4128f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MachineOperand &MO) { 4138f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Setting kill flag... 4148f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (!MO.isKill()) { 4158f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(true); 4168f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4178f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4188f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 4198f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If MO itself is live, clear the kill flag... 4208f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[MO.getReg()] != ~0u) { 4218f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(false); 4228f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4238f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4248f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 4258f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If any subreg of MO is live, then create an imp-def for that 4268f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // subreg and keep MO marked as killed. 4278bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(false); 4288f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool AllDead = true; 4298f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin const unsigned SuperReg = MO.getReg(); 4308f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(SuperReg); 4318f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin *Subreg; ++Subreg) { 4328f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 4338f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MI->addOperand(MachineOperand::CreateReg(*Subreg, 4348f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsDef*/, 4358f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsImp*/, 4368f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsKill*/, 4378f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsDead*/)); 4388f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin AllDead = false; 4398f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4408f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4418f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 442c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman if(AllDead) 4438bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(true); 4448f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4458f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin} 4468f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 44788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// FixupKills - Fix the register kill flags, they may have been made 44888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// incorrect by instruction reordering. 44988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// 45088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwinvoid SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { 451e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "Fixup kills for BB#" << MBB->getNumber() << '\n'); 45288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 45388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin std::set<unsigned> killedRegs; 45488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin BitVector ReservedRegs = TRI->getReservedRegs(MF); 4555e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 4565e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin StartBlockForKills(MBB); 4577886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4587886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Examine block from end to start... 45988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Count = MBB->size(); 46088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (MachineBasicBlock::iterator I = MBB->end(), E = MBB->begin(); 46188a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin I != E; --Count) { 46288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineInstr *MI = --I; 463b0812f114b83a32c4b90a4b553c7177c557558b5Dale Johannesen if (MI->isDebugValue()) 464b0812f114b83a32c4b90a4b553c7177c557558b5Dale Johannesen continue; 46588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4667886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Update liveness. Registers that are defed but not used in this 4677886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // instruction are now dead. Mark register and all subregs as they 4687886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // are completely defined. 4697886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 4707886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 4717886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isReg()) continue; 4727886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 4737886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (Reg == 0) continue; 4747886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isDef()) continue; 4757886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Ignore two-addr defs. 4767886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (MI->isRegTiedToUseOperand(i)) continue; 4777886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4787886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = ~0u; 4797886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4807886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Repeat for all subregs. 4817886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4827886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 4837886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = ~0u; 4847886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 4857886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 48688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4878f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Examine all used registers and set/clear kill flag. When a 4888f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // register is used multiple times we only set the kill flag on 4898f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // the first use. 49088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.clear(); 49188a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 49288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 49388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (!MO.isReg() || !MO.isUse()) continue; 49488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Reg = MO.getReg(); 49588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 49688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4977886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin bool kill = false; 4987886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (killedRegs.find(Reg) == killedRegs.end()) { 4997886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = true; 5007886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // A register is not killed if any subregs are live... 5017886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 5027886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 5037886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 5047886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = false; 5057886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin break; 5067886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5077886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5087886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5097886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // If subreg is not live, then register is killed if it became 5107886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // live in this instruction 5117886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (kill) 5127886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = (KillIndices[Reg] == ~0u); 5137886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5147886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 51588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (MO.isKill() != kill) { 516e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "Fixing " << MO << " in "); 51715d75d9f11f877bf3716257013b563e67341b0edJakob Stoklund Olesen // Warning: ToggleKillFlag may invalidate MO. 51815d75d9f11f877bf3716257013b563e67341b0edJakob Stoklund Olesen ToggleKillFlag(MI, MO); 51988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin DEBUG(MI->dump()); 52088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5217886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 52288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.insert(Reg); 52388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5247886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 525a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // Mark any used register (that is not using undef) and subregs as 526a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // now live... 5277886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 5287886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 529a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin if (!MO.isReg() || !MO.isUse() || MO.isUndef()) continue; 5307886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 5317886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 5327886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5337886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = Count; 5347886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5357886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 5367886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 5377886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = Count; 5387886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5397886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 54088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 54188a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin} 54288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 543343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 544343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman// Top-Down Scheduling 545343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 546343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 547343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to 548343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the PendingQueue if the count reaches zero. Also update its cycle bound. 549557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { 55054e4c36a7349e94a84773afb56eccd4ca65b49e9Dan Gohman SUnit *SuccSU = SuccEdge->getSUnit(); 551c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 552343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 553c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner if (SuccSU->NumPredsLeft == 0) { 554e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << "*** Scheduling failed! ***\n"; 555343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SuccSU->dump(this); 556e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << " has been released too many times!\n"; 557c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 558343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 559343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 560c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner --SuccSU->NumPredsLeft; 561c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 562343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // Compute how many cycles it will be before this actually becomes 563343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // available. This is the max of the start time of all predecessors plus 564343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // their latencies. 565557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); 566343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 5679e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // If all the node's predecessors are scheduled, this node is ready 5689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // to be scheduled. Ignore the special ExitSU node. 5699e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 570343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.push_back(SuccSU); 5719e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 5729e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 5739e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. 574557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { 5759e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 5764de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin I != E; ++I) { 577557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSucc(SU, &*I); 5784de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin } 579343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 580343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 581343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending 582343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// count of its successors. If a successor pending count is zero, add it to 583343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the Available queue. 584557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { 585e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: "); 586343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman DEBUG(SU->dump(this)); 587343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 588343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.push_back(SU); 589557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin assert(CurCycle >= SU->getDepth() && 5904de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin "Node scheduled above its depth!"); 591557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin SU->setDepthToAtLeast(CurCycle); 592343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 593557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSuccessors(SU); 594343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SU->isScheduled = true; 595343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.ScheduledNode(SU); 596343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 597343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 598343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ListScheduleTopDown - The main loop of list scheduling for top-down 599343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// schedulers. 600557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ListScheduleTopDown() { 601343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman unsigned CurCycle = 0; 6024de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin 6034de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // We're scheduling top-down but we're visiting the regions in 6044de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // bottom-up order, so we don't know the hazards at the start of a 6054de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // region. So assume no hazards (this should usually be ok as most 6064de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // blocks are a single region). 6074de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin HazardRec->Reset(); 6084de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin 6099e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Release any successors of the special Entry node. 610557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSuccessors(&EntrySU); 6119e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 612557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin // Add all leaves to Available queue. 613343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { 614343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // It is available if it has no predecessors. 6154de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin bool available = SUnits[i].Preds.empty(); 6164de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin if (available) { 617343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(&SUnits[i]); 618343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SUnits[i].isAvailable = true; 619343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 620343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 6219e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 6222ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // In any cycle where we can't schedule any instructions, we must 6232ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // stall or emit a noop, depending on the target. 624be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer bool CycleHasInsts = false; 6252ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 626343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // While Available queue is not empty, grab the node with the highest 627343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // priority. If it is not ready put it back. Schedule the node. 6282836c283bb1c14baa50994f60769d665da608ad7Dan Gohman std::vector<SUnit*> NotReady; 629343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.reserve(SUnits.size()); 630343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman while (!AvailableQueue.empty() || !PendingQueue.empty()) { 631343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // Check to see if any of the pending instructions are ready to issue. If 632343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // so, add them to the available queue. 6333f23744df4809eba94284e601e81489212c974d4Dan Gohman unsigned MinDepth = ~0u; 634343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { 635557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin if (PendingQueue[i]->getDepth() <= CurCycle) { 636343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(PendingQueue[i]); 637343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i]->isAvailable = true; 638343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i] = PendingQueue.back(); 639343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.pop_back(); 640343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman --i; --e; 641557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin } else if (PendingQueue[i]->getDepth() < MinDepth) 642557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin MinDepth = PendingQueue[i]->getDepth(); 643343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 644c93d8373c93159c590838957b3194900caeb8a03David Goodwin 645e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "\n*** Examining Available\n"; 6467cd0118c367314308cf94765ac12f81020a56271David Goodwin LatencyPriorityQueue q = AvailableQueue; 6477cd0118c367314308cf94765ac12f81020a56271David Goodwin while (!q.empty()) { 6487cd0118c367314308cf94765ac12f81020a56271David Goodwin SUnit *su = q.pop(); 649e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << "Height " << su->getHeight() << ": "; 6507cd0118c367314308cf94765ac12f81020a56271David Goodwin su->dump(this); 6517cd0118c367314308cf94765ac12f81020a56271David Goodwin }); 652c93d8373c93159c590838957b3194900caeb8a03David Goodwin 6532836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *FoundSUnit = 0; 6542836c283bb1c14baa50994f60769d665da608ad7Dan Gohman bool HasNoopHazards = false; 6552836c283bb1c14baa50994f60769d665da608ad7Dan Gohman while (!AvailableQueue.empty()) { 6562836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *CurSUnit = AvailableQueue.pop(); 6572836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6582836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ScheduleHazardRecognizer::HazardType HT = 6592836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HazardRec->getHazardType(CurSUnit); 6602836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (HT == ScheduleHazardRecognizer::NoHazard) { 6612836c283bb1c14baa50994f60769d665da608ad7Dan Gohman FoundSUnit = CurSUnit; 6622836c283bb1c14baa50994f60769d665da608ad7Dan Gohman break; 6632836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6642836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6652836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Remember if this is a noop hazard. 6662836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard; 6672836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6682836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.push_back(CurSUnit); 6692836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6702836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6712836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Add the nodes that aren't ready back onto the available list. 6722836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (!NotReady.empty()) { 6732836c283bb1c14baa50994f60769d665da608ad7Dan Gohman AvailableQueue.push_all(NotReady); 6742836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.clear(); 6752836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6762836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6774de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // If we found a node to schedule... 678343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman if (FoundSUnit) { 6794de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // ... schedule the node... 680557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ScheduleNodeTopDown(FoundSUnit, CurCycle); 6812836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HazardRec->EmitInstruction(FoundSUnit); 682be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = true; 683343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 684d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // If we are using the target-specific hazards, then don't 685d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // advance the cycle time just because we schedule a node. If 686d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // the target allows it we can schedule multiple nodes in the 687d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin // same cycle. 688d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin if (!EnablePostRAHazardAvoidance) { 689d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops! 690d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin ++CurCycle; 691d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 6922836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } else { 693be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer if (CycleHasInsts) { 694e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Finished cycle " << CurCycle << '\n'); 6952ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 6962ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else if (!HasNoopHazards) { 6972ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have a pipeline stall, but no other problem, 6982ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // just advance the current cycle and try again. 699e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Stall in cycle " << CurCycle << '\n'); 7002ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 701557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ++NumStalls; 7022ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else { 7032ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have no instructions to issue and we have instructions 7042ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // that will fault if we don't do this right. This is the case for 7052ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // processors without pipeline interlocks and other cases. 706e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Emitting noop in cycle " << CurCycle << '\n'); 7072ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->EmitNoop(); 7082ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin Sequence.push_back(0); // NULL here means noop 709557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ++NumNoops; 7102ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } 7112ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 7122836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ++CurCycle; 713be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = false; 714343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 715343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 716343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 717343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 718a1e6d363e5efa9eb1a2e7ac21a0394c870bef5adDan Gohman VerifySchedule(/*isBottomUp=*/false); 719343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 720343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 721e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 722e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 723e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// Public Constructor Functions 724e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 725e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 726fa16354e0370fe884830286923352268b036737dEvan ChengFunctionPass *llvm::createPostRAScheduler(CodeGenOpt::Level OptLevel) { 727fa16354e0370fe884830286923352268b036737dEvan Cheng return new PostRAScheduler(OptLevel); 728e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 729