PostRASchedulerList.cpp revision 5b1b4489cf3a0f56f8be0673fc5cc380a32d277b
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" 25fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen#include "RegisterClassInfo.h" 266dc75fe5279e2c12bda13dcc4a1a13908de8596fDan Gohman#include "ScheduleDAGInstrs.h" 27e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/CodeGen/Passes.h" 28343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/CodeGen/LatencyPriorityQueue.h" 29343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/CodeGen/SchedulerRegistry.h" 303f23744df4809eba94284e601e81489212c974d4Dan Gohman#include "llvm/CodeGen/MachineDominators.h" 31c7951f8e09a65e07626e7b9a272ce9911b249472David Goodwin#include "llvm/CodeGen/MachineFrameInfo.h" 32e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/CodeGen/MachineFunctionPass.h" 333f23744df4809eba94284e601e81489212c974d4Dan Gohman#include "llvm/CodeGen/MachineLoopInfo.h" 3421d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/CodeGen/MachineRegisterInfo.h" 352836c283bb1c14baa50994f60769d665da608ad7Dan Gohman#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 36a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman#include "llvm/Analysis/AliasAnalysis.h" 37bed353d0163a6b17beecc20c23b67de9b06e7b5cDan Gohman#include "llvm/Target/TargetLowering.h" 3879ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman#include "llvm/Target/TargetMachine.h" 3921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/Target/TargetInstrInfo.h" 4021d9003087c9a707e6cd95460136b499df358fb8Dan Gohman#include "llvm/Target/TargetRegisterInfo.h" 415b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng#include "llvm/Target/TargetSubtargetInfo.h" 42e10deca33e74a7c70ab585f78eee3fb52937f668David Goodwin#include "llvm/Support/CommandLine.h" 43e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen#include "llvm/Support/Debug.h" 44c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 453a5f0d444cf21e2b90d5eb965bb677c7ce098546David Goodwin#include "llvm/Support/raw_ostream.h" 462e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin#include "llvm/ADT/BitVector.h" 47343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#include "llvm/ADT/Statistic.h" 4888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin#include <set> 49e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesenusing namespace llvm; 50e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 512836c283bb1c14baa50994f60769d665da608ad7Dan GohmanSTATISTIC(NumNoops, "Number of noops inserted"); 52343f0c046702831a4a6aec951b6a297a23241a55Dan GohmanSTATISTIC(NumStalls, "Number of pipeline stalls"); 532e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid GoodwinSTATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); 54343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 55471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin// Post-RA scheduling is enabled with 565b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng// TargetSubtargetInfo.enablePostRAScheduler(). This flag can be used to 57471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin// override the target. 58471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwinstatic cl::opt<bool> 59471850ab84301dd47cab2bf8d694fcb5766c1169David GoodwinEnablePostRAScheduler("post-RA-scheduler", 60471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin cl::desc("Enable scheduling after register allocation"), 619843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin cl::init(false), cl::Hidden); 622e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwinstatic cl::opt<std::string> 6321d9003087c9a707e6cd95460136b499df358fb8Dan GohmanEnableAntiDepBreaking("break-anti-dependencies", 642e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin cl::desc("Break post-RA scheduling anti-dependencies: " 652e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin "\"critical\", \"all\", or \"none\""), 662e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin cl::init("none"), cl::Hidden); 672836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 681f1522839838a33e69d68656a423a244e19dffb8David Goodwin// If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 691f1522839838a33e69d68656a423a244e19dffb8David Goodwinstatic cl::opt<int> 701f1522839838a33e69d68656a423a244e19dffb8David GoodwinDebugDiv("postra-sched-debugdiv", 711f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::desc("Debug control MBBs that are scheduled"), 721f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::init(0), cl::Hidden); 731f1522839838a33e69d68656a423a244e19dffb8David Goodwinstatic cl::opt<int> 741f1522839838a33e69d68656a423a244e19dffb8David GoodwinDebugMod("postra-sched-debugmod", 751f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::desc("Debug control MBBs that are scheduled"), 761f1522839838a33e69d68656a423a244e19dffb8David Goodwin cl::init(0), cl::Hidden); 771f1522839838a33e69d68656a423a244e19dffb8David Goodwin 78ada0ef86d98df4ac36808e4a0f0098250bf1a842David GoodwinAntiDepBreaker::~AntiDepBreaker() { } 79ada0ef86d98df4ac36808e4a0f0098250bf1a842David Goodwin 80e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesennamespace { 816726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class PostRAScheduler : public MachineFunctionPass { 82a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman AliasAnalysis *AA; 8386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng const TargetInstrInfo *TII; 84fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen RegisterClassInfo RegClassInfo; 85fa16354e0370fe884830286923352268b036737dEvan Cheng CodeGenOpt::Level OptLevel; 86a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman 87e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen public: 88e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen static char ID; 89fa16354e0370fe884830286923352268b036737dEvan Cheng PostRAScheduler(CodeGenOpt::Level ol) : 9090c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson MachineFunctionPass(ID), OptLevel(ol) {} 9121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 923f23744df4809eba94284e601e81489212c974d4Dan Gohman void getAnalysisUsage(AnalysisUsage &AU) const { 93845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesCFG(); 94a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman AU.addRequired<AliasAnalysis>(); 953f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addRequired<MachineDominatorTree>(); 963f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addPreserved<MachineDominatorTree>(); 973f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addRequired<MachineLoopInfo>(); 983f23744df4809eba94284e601e81489212c974d4Dan Gohman AU.addPreserved<MachineLoopInfo>(); 993f23744df4809eba94284e601e81489212c974d4Dan Gohman MachineFunctionPass::getAnalysisUsage(AU); 1003f23744df4809eba94284e601e81489212c974d4Dan Gohman } 1013f23744df4809eba94284e601e81489212c974d4Dan Gohman 102343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman const char *getPassName() const { 10321d9003087c9a707e6cd95460136b499df358fb8Dan Gohman return "Post RA top-down list latency scheduler"; 104343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 105343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 106343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman bool runOnMachineFunction(MachineFunction &Fn); 107343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman }; 108343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman char PostRAScheduler::ID = 0; 109343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 1106726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class SchedulePostRATDList : public ScheduleDAGInstrs { 111343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// AvailableQueue - The priority queue to use for the available SUnits. 112c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 113343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman LatencyPriorityQueue AvailableQueue; 1149001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 115343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// PendingQueue - This contains all of the instructions whose operands have 116343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// been issued, but their results are not ready yet (due to the latency of 117343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// the operation). Once the operands becomes available, the instruction is 118343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman /// added to the AvailableQueue. 119343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman std::vector<SUnit*> PendingQueue; 120343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 12121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman /// Topo - A topological ordering for SUnits. 12221d9003087c9a707e6cd95460136b499df358fb8Dan Gohman ScheduleDAGTopologicalSort Topo; 123e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 124c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// HazardRec - The hazard recognizer to use. 125c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman ScheduleHazardRecognizer *HazardRec; 126c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman 1272e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// AntiDepBreak - Anti-dependence breaking object, or NULL if none 1282e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreaker *AntiDepBreak; 1292e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 130c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// AA - AliasAnalysis for making memory reference queries. 131c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman AliasAnalysis *AA; 132480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 133c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// KillIndices - The index of the most recent kill (proceding bottom-up), 134c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// or ~0u if the register is not live. 13524173da61db2725bf91b0edf57cfa554ac105e9dBill Wendling std::vector<unsigned> KillIndices; 1369e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 13721d9003087c9a707e6cd95460136b499df358fb8Dan Gohman public: 1382da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick SchedulePostRATDList( 1392da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, 140fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen AliasAnalysis *AA, const RegisterClassInfo&, 1415b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng TargetSubtargetInfo::AntiDepBreakMode AntiDepMode, 1422da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick SmallVectorImpl<TargetRegisterClass*> &CriticalPathRCs); 1432da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 1442da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick ~SchedulePostRATDList(); 145343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 1469e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// StartBlock - Initialize register live-range state for scheduling in 1479e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// this block. 1489e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// 1499e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman void StartBlock(MachineBasicBlock *BB); 1509e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 151480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin /// Schedule - Schedule the instruction range using list scheduling. 1529e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman /// 153480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin void Schedule(); 1549001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 155c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// Observe - Update liveness information to account for the current 156c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// instruction, which will not be scheduled. 157c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 158c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman void Observe(MachineInstr *MI, unsigned Count); 159480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 160c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// FinishBlock - Clean up register live-range state. 161c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman /// 162c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman void FinishBlock(); 163480c529e026942f28e1a792d2cec6d6b5bc0edbaDavid Goodwin 1642e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// FixupKills - Fix register kill flags that have been made 1652e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// invalid due to scheduling 1662e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin /// 1672e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin void FixupKills(MachineBasicBlock *MBB); 1682e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin 169c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman private: 170557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ReleaseSucc(SUnit *SU, SDep *SuccEdge); 171557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ReleaseSuccessors(SUnit *SU); 172557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); 173557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin void ListScheduleTopDown(); 1745e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin void StartBlockForKills(MachineBasicBlock *BB); 1759001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 1768f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // ToggleKillFlag - Toggle a register operand kill flag. Other 1778f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // adjustments may be made to the instruction if necessary. Return 1788f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // true if the operand has been deleted, false if not. 1798f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool ToggleKillFlag(MachineInstr *MI, MachineOperand &MO); 180e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen }; 181e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 182e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 1832da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickSchedulePostRATDList::SchedulePostRATDList( 1842da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, 185fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen AliasAnalysis *AA, const RegisterClassInfo &RCI, 1865b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng TargetSubtargetInfo::AntiDepBreakMode AntiDepMode, 1872da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick SmallVectorImpl<TargetRegisterClass*> &CriticalPathRCs) 1882da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), AA(AA), 1892da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick KillIndices(TRI->getNumRegs()) 1902da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick{ 1912da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const TargetMachine &TM = MF.getTarget(); 1922da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const InstrItineraryData *InstrItins = TM.getInstrItineraryData(); 1932da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick HazardRec = 1942da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins, this); 1952da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick AntiDepBreak = 1965b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_ALL) ? 197fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen (AntiDepBreaker *)new AggressiveAntiDepBreaker(MF, RCI, CriticalPathRCs) : 1985b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_CRITICAL) ? 199fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen (AntiDepBreaker *)new CriticalAntiDepBreaker(MF, RCI) : NULL)); 2002da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick} 2012da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 2022da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickSchedulePostRATDList::~SchedulePostRATDList() { 2032da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick delete HazardRec; 2042da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick delete AntiDepBreak; 2052da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick} 2062da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 207343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanbool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { 20886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng TII = Fn.getTarget().getInstrInfo(); 2092da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 2102da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 2112da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick AliasAnalysis *AA = &getAnalysis<AliasAnalysis>(); 212fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen RegClassInfo.runOnMachineFunction(Fn); 2135bf7c2a34679b6afe46ba4f605f1921da950a66bDan Gohman 214471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin // Check for explicit enable/disable of post-ra scheduling. 2155b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng TargetSubtargetInfo::AntiDepBreakMode AntiDepMode = TargetSubtargetInfo::ANTIDEP_NONE; 21687d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin SmallVector<TargetRegisterClass*, 4> CriticalPathRCs; 217471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (EnablePostRAScheduler.getPosition() > 0) { 218471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin if (!EnablePostRAScheduler) 219c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 220471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } else { 221c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng // Check that post-RA scheduling is enabled for this target. 2222da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // This may upgrade the AntiDepMode. 2235b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng const TargetSubtargetInfo &ST = Fn.getTarget().getSubtarget<TargetSubtargetInfo>(); 22487d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, CriticalPathRCs)) 225c83da2f9e389332b9cf8eae9d823f745be5624b8Evan Cheng return false; 226471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin } 2270dad89fa94536284d51f60868326294b725a0c61David Goodwin 2284c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin // Check for antidep breaking override... 2294c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin if (EnableAntiDepBreaking.getPosition() > 0) { 2305b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng AntiDepMode = (EnableAntiDepBreaking == "all") 2315b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng ? TargetSubtargetInfo::ANTIDEP_ALL 2325b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng : ((EnableAntiDepBreaking == "critical") 2335b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng ? TargetSubtargetInfo::ANTIDEP_CRITICAL 2345b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng : TargetSubtargetInfo::ANTIDEP_NONE); 2354c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin } 2364c3715c2e5e17d7216a96ac2baf9720630f04408David Goodwin 237e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "PostRAScheduler\n"); 238e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 239fa796dd720f1b34596a043f17f098fac18ecc028Jakob Stoklund Olesen SchedulePostRATDList Scheduler(Fn, MLI, MDT, AA, RegClassInfo, AntiDepMode, 2402da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick CriticalPathRCs); 24179ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman 242e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen // Loop over all of the basic blocks 243e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 244343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman MBB != MBBe; ++MBB) { 2451f1522839838a33e69d68656a423a244e19dffb8David Goodwin#ifndef NDEBUG 2461f1522839838a33e69d68656a423a244e19dffb8David Goodwin // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 2471f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (DebugDiv > 0) { 2481f1522839838a33e69d68656a423a244e19dffb8David Goodwin static int bbcnt = 0; 2491f1522839838a33e69d68656a423a244e19dffb8David Goodwin if (bbcnt++ % DebugDiv != DebugMod) 2501f1522839838a33e69d68656a423a244e19dffb8David Goodwin continue; 251e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << "*** DEBUG scheduling " << Fn.getFunction()->getNameStr() << 2520ba90f3e34b826b039bdfece1415ef032c4ad3f5Dan Gohman ":BB#" << MBB->getNumber() << " ***\n"; 2531f1522839838a33e69d68656a423a244e19dffb8David Goodwin } 2541f1522839838a33e69d68656a423a244e19dffb8David Goodwin#endif 2551f1522839838a33e69d68656a423a244e19dffb8David Goodwin 2569e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Initialize register live-range state for scheduling in this block. 2579e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.StartBlock(MBB); 2589e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 259f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // Schedule each sequence of instructions not interrupted by a label 260f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman // or anything else that effectively needs to shut down scheduling. 2619e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman MachineBasicBlock::iterator Current = MBB->end(); 26247ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman unsigned Count = MBB->size(), CurrentCount = Count; 2639e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) { 26486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MachineInstr *MI = llvm::prior(I); 26586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (TII->isSchedulingBoundary(MI, MBB, Fn)) { 2661274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, I, Current, CurrentCount); 267af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman Scheduler.EmitSchedule(); 2689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Current = MI; 26947ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman CurrentCount = Count - 1; 2701274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Observe(MI, CurrentCount); 271f7119393a97c2a10757084b6bc186380f8c19a73Dan Gohman } 2729e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman I = MI; 27347ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman --Count; 27447ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman } 27547ac0f0c7c39289f5970688154e385be22b7f293Dan Gohman assert(Count == 0 && "Instruction count mismatch!"); 2769e8bd0b362c034e629b9ee1f32e4e1adf037f529Duncan Sands assert((MBB->begin() == Current || CurrentCount != 0) && 2771274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman "Instruction count mismatch!"); 2781274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90Dan Gohman Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount); 279af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman Scheduler.EmitSchedule(); 2809e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 2819e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Clean up register live-range state. 2829e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman Scheduler.FinishBlock(); 28388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 2845e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Update register kills 28588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin Scheduler.FixupKills(MBB); 286343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 287e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 288e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen return true; 289e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 2909001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 2919e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// StartBlock - Initialize register live-range state for scheduling in 2929e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// this block. 2939e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 2949e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) { 2959e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 2969e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::StartBlock(BB); 2979e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 2982e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin // Reset the hazard recognizer and anti-dep breaker. 299d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin HazardRec->Reset(); 3002e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3012e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->StartBlock(BB); 3029e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3039e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3049e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Schedule - Schedule the instruction range using list scheduling. 3059e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 306343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid SchedulePostRATDList::Schedule() { 307c9a5b9e38b442c2ae6b115213a07df3fcd14708dDan Gohman // Build the scheduling graph. 308a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman BuildSchedGraph(AA); 309343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3102e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) { 3119001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach unsigned Broken = 312557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, 313e29e8e100ea38be1771e5f010a5511cbb990d515Devang Patel InsertPosIndex, DbgValues); 3149001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 315557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin if (Broken != 0) { 31621d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // We made changes. Update the dependency graph. 31721d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // Theoretically we could update the graph in place: 31821d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // When a live range is changed to use a different register, remove 31921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // the def's anti-dependence *and* output-dependence edges due to 32021d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // that register, and add new anti-dependence and output-dependence 32121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman // edges based on the next live range of the register. 322557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin SUnits.clear(); 323557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin Sequence.clear(); 324557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin EntrySU = SUnit(); 325557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ExitSU = SUnit(); 326557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin BuildSchedGraph(AA); 3279001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 3282e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin NumFixedAnti += Broken; 32921d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 33021d9003087c9a707e6cd95460136b499df358fb8Dan Gohman } 33121d9003087c9a707e6cd95460136b499df358fb8Dan Gohman 332e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "********** List Scheduling **********\n"); 333d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 334d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin SUnits[su].dumpAll(this)); 335d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 336343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.initNodes(SUnits); 337557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ListScheduleTopDown(); 338343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.releaseState(); 339343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 340343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 3419e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// Observe - Update liveness information to account for the current 3429e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// instruction, which will not be scheduled. 3439e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 34447ac0f0c7c39289f5970688154e385be22b7f293Dan Gohmanvoid SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { 3452e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3462e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->Observe(MI, Count, InsertPosIndex); 3479e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3489e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3499e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// FinishBlock - Clean up register live-range state. 3509e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// 3519e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohmanvoid SchedulePostRATDList::FinishBlock() { 3522e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin if (AntiDepBreak != NULL) 3532e7be612d5d0eb42ee3ae08194dbb03b750cc6bfDavid Goodwin AntiDepBreak->FinishBlock(); 3549e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3559e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Call the superclass. 3569e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman ScheduleDAGInstrs::FinishBlock(); 3579e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 3589e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 3595e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// StartBlockForKills - Initialize register live-range state for updating kills 3605e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin/// 3615e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwinvoid SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { 3625e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Initialize the indices to indicate that no registers are live. 363990d2857654cb80e46d207533834be3047494830David Goodwin for (unsigned i = 0; i < TRI->getNumRegs(); ++i) 364990d2857654cb80e46d207533834be3047494830David Goodwin KillIndices[i] = ~0u; 3655e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 3665e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Determine the live-out physregs for this block. 3675e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin if (!BB->empty() && BB->back().getDesc().isReturn()) { 3685e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a return block, examine the function live-out regs. 3695e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), 3705e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = MRI.liveout_end(); I != E; ++I) { 3715e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 3725e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 3735e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 3745e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 3755e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 3765e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 3775e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3785e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3795e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3805e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin else { 3815e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // In a non-return block, examine the live-in regs of all successors. 3825e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 3835e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin SE = BB->succ_end(); SI != SE; ++SI) { 3845e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), 3855e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin E = (*SI)->livein_end(); I != E; ++I) { 3865e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin unsigned Reg = *I; 3875e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[Reg] = BB->size(); 3885e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin // Repeat, for all subregs. 3895e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 3905e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin *Subreg; ++Subreg) { 3915e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin KillIndices[*Subreg] = BB->size(); 3925e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3935e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3945e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3955e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin } 3965e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin} 3975e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 3988f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwinbool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI, 3998f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MachineOperand &MO) { 4008f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Setting kill flag... 4018f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (!MO.isKill()) { 4028f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(true); 4038f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4048f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4059001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 4068f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If MO itself is live, clear the kill flag... 4078f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[MO.getReg()] != ~0u) { 4088f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MO.setIsKill(false); 4098f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4108f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4118f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 4128f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // If any subreg of MO is live, then create an imp-def for that 4138f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // subreg and keep MO marked as killed. 4148bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(false); 4158f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin bool AllDead = true; 4168f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin const unsigned SuperReg = MO.getReg(); 4178f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(SuperReg); 4188f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin *Subreg; ++Subreg) { 4198f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 4208f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin MI->addOperand(MachineOperand::CreateReg(*Subreg, 4218f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsDef*/, 4228f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin true /*IsImp*/, 4238f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsKill*/, 4248f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin false /*IsDead*/)); 4258f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin AllDead = false; 4268f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4278f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin } 4288f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 429c1ae8c9b8f426b74215abf0f7e46bffecc6f52d9Dan Gohman if(AllDead) 4308bff4af61219031345e7dae0c1840315e6bfab7fBenjamin Kramer MO.setIsKill(true); 4318f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin return false; 4328f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin} 4338f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin 43488a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// FixupKills - Fix the register kill flags, they may have been made 43588a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// incorrect by instruction reordering. 43688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin/// 43788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwinvoid SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { 438e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "Fixup kills for BB#" << MBB->getNumber() << '\n'); 43988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 44088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin std::set<unsigned> killedRegs; 44188a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin BitVector ReservedRegs = TRI->getReservedRegs(MF); 4425e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin 4435e41178a6ee9a0faa2c031811d32543d7e9d0affDavid Goodwin StartBlockForKills(MBB); 4449001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 4457886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Examine block from end to start... 44688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Count = MBB->size(); 44788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (MachineBasicBlock::iterator I = MBB->end(), E = MBB->begin(); 44888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin I != E; --Count) { 44988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineInstr *MI = --I; 450b0812f114b83a32c4b90a4b553c7177c557558b5Dale Johannesen if (MI->isDebugValue()) 451b0812f114b83a32c4b90a4b553c7177c557558b5Dale Johannesen continue; 45288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4537886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Update liveness. Registers that are defed but not used in this 4547886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // instruction are now dead. Mark register and all subregs as they 4557886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // are completely defined. 4567886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 4577886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 4587886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isReg()) continue; 4597886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 4607886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (Reg == 0) continue; 4617886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (!MO.isDef()) continue; 4627886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Ignore two-addr defs. 4637886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (MI->isRegTiedToUseOperand(i)) continue; 4649001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 4657886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = ~0u; 4669001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 4677886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // Repeat for all subregs. 4687886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4697886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 4707886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = ~0u; 4717886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 4727886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 47388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4748f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // Examine all used registers and set/clear kill flag. When a 4758f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // register is used multiple times we only set the kill flag on 4768f909345bcabd0cbcb99d01d23f1d77b8b1518ecDavid Goodwin // the first use. 47788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.clear(); 47888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 47988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 48088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (!MO.isReg() || !MO.isUse()) continue; 48188a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin unsigned Reg = MO.getReg(); 48288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 48388a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 4847886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin bool kill = false; 4857886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (killedRegs.find(Reg) == killedRegs.end()) { 4867886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = true; 4877886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // A register is not killed if any subregs are live... 4887886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 4897886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 4907886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (KillIndices[*Subreg] != ~0u) { 4917886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = false; 4927886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin break; 4937886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 4947886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 4957886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 4967886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // If subreg is not live, then register is killed if it became 4977886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin // live in this instruction 4987886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if (kill) 4997886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin kill = (KillIndices[Reg] == ~0u); 5007886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5019001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 50288a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin if (MO.isKill() != kill) { 503e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "Fixing " << MO << " in "); 50415d75d9f11f877bf3716257013b563e67341b0edJakob Stoklund Olesen // Warning: ToggleKillFlag may invalidate MO. 50515d75d9f11f877bf3716257013b563e67341b0edJakob Stoklund Olesen ToggleKillFlag(MI, MO); 50688a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin DEBUG(MI->dump()); 50788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5089001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 50988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin killedRegs.insert(Reg); 51088a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 5119001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 512a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // Mark any used register (that is not using undef) and subregs as 513a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin // now live... 5147886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 5157886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin MachineOperand &MO = MI->getOperand(i); 516a3251db21a474affaca945e3fc53f22d30d20f00David Goodwin if (!MO.isReg() || !MO.isUse() || MO.isUndef()) continue; 5177886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin unsigned Reg = MO.getReg(); 5187886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin if ((Reg == 0) || ReservedRegs.test(Reg)) continue; 5197886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin 5207886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[Reg] = Count; 5219001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 5227886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin for (const unsigned *Subreg = TRI->getSubRegisters(Reg); 5237886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin *Subreg; ++Subreg) { 5247886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin KillIndices[*Subreg] = Count; 5257886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 5267886cd85b21db4498ff042a4e42aded7bf3272eeDavid Goodwin } 52788a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin } 52888a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin} 52988a589c4b39830bbeed23654521ef2f77bb87abeDavid Goodwin 530343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 531343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman// Top-Down Scheduling 532343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman//===----------------------------------------------------------------------===// 533343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 534343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to 535343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the PendingQueue if the count reaches zero. Also update its cycle bound. 536557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { 53754e4c36a7349e94a84773afb56eccd4ca65b49e9Dan Gohman SUnit *SuccSU = SuccEdge->getSUnit(); 538c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 539343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 540c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner if (SuccSU->NumPredsLeft == 0) { 541e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << "*** Scheduling failed! ***\n"; 542343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SuccSU->dump(this); 543e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene dbgs() << " has been released too many times!\n"; 544c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 545343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 546343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 547c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner --SuccSU->NumPredsLeft; 548c277ab08a24d2dbe9b4ff1a9154ea6115ed6a4e3Reid Kleckner 54989fd43778e47b0698582f906e3dac900c376102eAndrew Trick // Standard scheduler algorithms will recompute the depth of the successor 55015ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // here as such: 55115ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); 55215ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // 55315ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // However, we lazily compute node depth instead. Note that 55415ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // ScheduleNodeTopDown has already updated the depth of this node which causes 55515ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // all descendents to be marked dirty. Setting the successor depth explicitly 55615ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // here would cause depth to be recomputed for all its ancestors. If the 55715ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // successor is not yet ready (because of a transitively redundant edge) then 55815ab3594eba495ffd1f070207a4aceeae9492c11Andrew Trick // this causes depth computation to be quadratic in the size of the DAG. 5599001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 5609e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // If all the node's predecessors are scheduled, this node is ready 5619e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // to be scheduled. Ignore the special ExitSU node. 5629e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 563343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.push_back(SuccSU); 5649e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman} 5659e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 5669e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman/// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. 567557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { 5689e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 5694de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin I != E; ++I) { 570557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSucc(SU, &*I); 5714de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin } 572343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 573343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 574343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending 575343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// count of its successors. If a successor pending count is zero, add it to 576343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// the Available queue. 577557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { 578e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: "); 579343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman DEBUG(SU->dump(this)); 5809001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 581343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.push_back(SU); 5829001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach assert(CurCycle >= SU->getDepth() && 5834de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin "Node scheduled above its depth!"); 584557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin SU->setDepthToAtLeast(CurCycle); 585343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 586557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSuccessors(SU); 587343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SU->isScheduled = true; 588343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.ScheduledNode(SU); 589343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 590343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 591343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// ListScheduleTopDown - The main loop of list scheduling for top-down 592343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman/// schedulers. 593557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwinvoid SchedulePostRATDList::ListScheduleTopDown() { 594343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman unsigned CurCycle = 0; 5959001303a3fc3e901c1e5e8b5daea56e55989c114Jim Grosbach 5964de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // We're scheduling top-down but we're visiting the regions in 5974de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // bottom-up order, so we don't know the hazards at the start of a 5984de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // region. So assume no hazards (this should usually be ok as most 5994de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // blocks are a single region). 6004de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin HazardRec->Reset(); 6014de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin 6029e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman // Release any successors of the special Entry node. 603557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ReleaseSuccessors(&EntrySU); 6049e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 605557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin // Add all leaves to Available queue. 606343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { 607343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // It is available if it has no predecessors. 6084de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin bool available = SUnits[i].Preds.empty(); 6094de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin if (available) { 610343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(&SUnits[i]); 611343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman SUnits[i].isAvailable = true; 612343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 613343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 6149e64bbb322417c09f27afdf08e3946287c9df5aaDan Gohman 6152ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // In any cycle where we can't schedule any instructions, we must 6162ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // stall or emit a noop, depending on the target. 617be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer bool CycleHasInsts = false; 6182ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 619343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // While Available queue is not empty, grab the node with the highest 620343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // priority. If it is not ready put it back. Schedule the node. 6212836c283bb1c14baa50994f60769d665da608ad7Dan Gohman std::vector<SUnit*> NotReady; 622343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman Sequence.reserve(SUnits.size()); 623343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman while (!AvailableQueue.empty() || !PendingQueue.empty()) { 624343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // Check to see if any of the pending instructions are ready to issue. If 625343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman // so, add them to the available queue. 6263f23744df4809eba94284e601e81489212c974d4Dan Gohman unsigned MinDepth = ~0u; 627343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { 628557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin if (PendingQueue[i]->getDepth() <= CurCycle) { 629343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman AvailableQueue.push(PendingQueue[i]); 630343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i]->isAvailable = true; 631343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue[i] = PendingQueue.back(); 632343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman PendingQueue.pop_back(); 633343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman --i; --e; 634557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin } else if (PendingQueue[i]->getDepth() < MinDepth) 635557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin MinDepth = PendingQueue[i]->getDepth(); 636343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 637c93d8373c93159c590838957b3194900caeb8a03David Goodwin 6382da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick DEBUG(dbgs() << "\n*** Examining Available\n"; AvailableQueue.dump(this)); 639c93d8373c93159c590838957b3194900caeb8a03David Goodwin 6402836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *FoundSUnit = 0; 6412836c283bb1c14baa50994f60769d665da608ad7Dan Gohman bool HasNoopHazards = false; 6422836c283bb1c14baa50994f60769d665da608ad7Dan Gohman while (!AvailableQueue.empty()) { 6432836c283bb1c14baa50994f60769d665da608ad7Dan Gohman SUnit *CurSUnit = AvailableQueue.pop(); 6442836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6452836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ScheduleHazardRecognizer::HazardType HT = 6462da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); 6472836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (HT == ScheduleHazardRecognizer::NoHazard) { 6482836c283bb1c14baa50994f60769d665da608ad7Dan Gohman FoundSUnit = CurSUnit; 6492836c283bb1c14baa50994f60769d665da608ad7Dan Gohman break; 6502836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6512836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6522836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Remember if this is a noop hazard. 6532836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard; 6542836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6552836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.push_back(CurSUnit); 6562836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6572836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6582836c283bb1c14baa50994f60769d665da608ad7Dan Gohman // Add the nodes that aren't ready back onto the available list. 6592836c283bb1c14baa50994f60769d665da608ad7Dan Gohman if (!NotReady.empty()) { 6602836c283bb1c14baa50994f60769d665da608ad7Dan Gohman AvailableQueue.push_all(NotReady); 6612836c283bb1c14baa50994f60769d665da608ad7Dan Gohman NotReady.clear(); 6622836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } 6632836c283bb1c14baa50994f60769d665da608ad7Dan Gohman 6644de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // If we found a node to schedule... 665343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman if (FoundSUnit) { 6664de099d8ca651e00fa5fac22bace4f4dba2d0292David Goodwin // ... schedule the node... 667557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ScheduleNodeTopDown(FoundSUnit, CurCycle); 6682836c283bb1c14baa50994f60769d665da608ad7Dan Gohman HazardRec->EmitInstruction(FoundSUnit); 669be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = true; 670cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick if (HazardRec->atIssueLimit()) { 671cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick DEBUG(dbgs() << "*** Max instructions per cycle " << CurCycle << '\n'); 672cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick HazardRec->AdvanceCycle(); 673cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick ++CurCycle; 674cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick CycleHasInsts = false; 675cf9aa284b332bc2613def3612b80c5883d4b9985Andrew Trick } 6762836c283bb1c14baa50994f60769d665da608ad7Dan Gohman } else { 677be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer if (CycleHasInsts) { 678e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Finished cycle " << CurCycle << '\n'); 6792ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 6802ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else if (!HasNoopHazards) { 6812ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have a pipeline stall, but no other problem, 6822ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // just advance the current cycle and try again. 683e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Stall in cycle " << CurCycle << '\n'); 6842ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->AdvanceCycle(); 685557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ++NumStalls; 6862ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } else { 6872ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // Otherwise, we have no instructions to issue and we have instructions 6882ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // that will fault if we don't do this right. This is the case for 6892ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin // processors without pipeline interlocks and other cases. 690e1b2129471e994cfb7d34cc5134eb99dd1ae39f2David Greene DEBUG(dbgs() << "*** Emitting noop in cycle " << CurCycle << '\n'); 6912ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin HazardRec->EmitNoop(); 6922ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin Sequence.push_back(0); // NULL here means noop 693557bbe6b5d13faaec38f85a266db457c7cb09ff2David Goodwin ++NumNoops; 6942ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin } 6952ffb0ce7dce2d5c243b90493807308af6fab0528David Goodwin 6962836c283bb1c14baa50994f60769d665da608ad7Dan Gohman ++CurCycle; 697be441c0f348a1c02a3632718832f6e2d42c4f8f0Benjamin Kramer CycleHasInsts = false; 698343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 699343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman } 700343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman 701343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#ifndef NDEBUG 702a1e6d363e5efa9eb1a2e7ac21a0394c870bef5adDan Gohman VerifySchedule(/*isBottomUp=*/false); 703343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman#endif 704343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman} 705e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 706e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 707e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen// Public Constructor Functions 708e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen//===----------------------------------------------------------------------===// 709e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen 710fa16354e0370fe884830286923352268b036737dEvan ChengFunctionPass *llvm::createPostRAScheduler(CodeGenOpt::Level OptLevel) { 711fa16354e0370fe884830286923352268b036737dEvan Cheng return new PostRAScheduler(OptLevel); 712e7e7d0d7e39d0c7c659d26b97e8081fce0fcd749Dale Johannesen} 713