Dan Gohman | 6dc75fe | 2009-02-06 17:12:10 +0000 | [diff] [blame] | 1 | //==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==// |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements the ScheduleDAGInstrs class, which implements |
| 11 | // scheduling for a MachineInstr-based dependency graph. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
Dan Gohman | 6dc75fe | 2009-02-06 17:12:10 +0000 | [diff] [blame] | 15 | #ifndef SCHEDULEDAGINSTRS_H |
| 16 | #define SCHEDULEDAGINSTRS_H |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 17 | |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/MachineDominators.h" |
| 19 | #include "llvm/CodeGen/MachineLoopInfo.h" |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/ScheduleDAG.h" |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 21 | #include "llvm/Support/Compiler.h" |
Dan Gohman | 79ce276 | 2009-01-15 19:20:50 +0000 | [diff] [blame] | 22 | #include "llvm/Target/TargetRegisterInfo.h" |
Evan Cheng | fb2e752 | 2009-09-18 21:02:19 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/DenseMap.h" |
| 24 | #include "llvm/ADT/SmallSet.h" |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 25 | #include <map> |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 26 | |
| 27 | namespace llvm { |
Dan Gohman | 3f23744 | 2008-12-16 03:25:46 +0000 | [diff] [blame] | 28 | class MachineLoopInfo; |
| 29 | class MachineDominatorTree; |
| 30 | |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 31 | /// LoopDependencies - This class analyzes loop-oriented register |
| 32 | /// dependencies, which are used to guide scheduling decisions. |
| 33 | /// For example, loop induction variable increments should be |
| 34 | /// scheduled as soon as possible after the variable's last use. |
| 35 | /// |
| 36 | class VISIBILITY_HIDDEN LoopDependencies { |
| 37 | const MachineLoopInfo &MLI; |
| 38 | const MachineDominatorTree &MDT; |
| 39 | |
| 40 | public: |
| 41 | typedef std::map<unsigned, std::pair<const MachineOperand *, unsigned> > |
| 42 | LoopDeps; |
| 43 | LoopDeps Deps; |
| 44 | |
| 45 | LoopDependencies(const MachineLoopInfo &mli, |
| 46 | const MachineDominatorTree &mdt) : |
| 47 | MLI(mli), MDT(mdt) {} |
| 48 | |
| 49 | /// VisitLoop - Clear out any previous state and analyze the given loop. |
| 50 | /// |
| 51 | void VisitLoop(const MachineLoop *Loop) { |
| 52 | Deps.clear(); |
| 53 | MachineBasicBlock *Header = Loop->getHeader(); |
| 54 | SmallSet<unsigned, 8> LoopLiveIns; |
| 55 | for (MachineBasicBlock::livein_iterator LI = Header->livein_begin(), |
| 56 | LE = Header->livein_end(); LI != LE; ++LI) |
| 57 | LoopLiveIns.insert(*LI); |
| 58 | |
| 59 | const MachineDomTreeNode *Node = MDT.getNode(Header); |
| 60 | const MachineBasicBlock *MBB = Node->getBlock(); |
| 61 | assert(Loop->contains(MBB) && |
| 62 | "Loop does not contain header!"); |
| 63 | VisitRegion(Node, MBB, Loop, LoopLiveIns); |
| 64 | } |
| 65 | |
| 66 | private: |
| 67 | void VisitRegion(const MachineDomTreeNode *Node, |
| 68 | const MachineBasicBlock *MBB, |
| 69 | const MachineLoop *Loop, |
| 70 | const SmallSet<unsigned, 8> &LoopLiveIns) { |
| 71 | unsigned Count = 0; |
| 72 | for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); |
| 73 | I != E; ++I, ++Count) { |
| 74 | const MachineInstr *MI = I; |
| 75 | for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { |
| 76 | const MachineOperand &MO = MI->getOperand(i); |
| 77 | if (!MO.isReg() || !MO.isUse()) |
| 78 | continue; |
| 79 | unsigned MOReg = MO.getReg(); |
| 80 | if (LoopLiveIns.count(MOReg)) |
| 81 | Deps.insert(std::make_pair(MOReg, std::make_pair(&MO, Count))); |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | const std::vector<MachineDomTreeNode*> &Children = Node->getChildren(); |
| 86 | for (std::vector<MachineDomTreeNode*>::const_iterator I = |
| 87 | Children.begin(), E = Children.end(); I != E; ++I) { |
| 88 | const MachineDomTreeNode *ChildNode = *I; |
| 89 | MachineBasicBlock *ChildBlock = ChildNode->getBlock(); |
| 90 | if (Loop->contains(ChildBlock)) |
| 91 | VisitRegion(ChildNode, ChildBlock, Loop, LoopLiveIns); |
| 92 | } |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of |
| 97 | /// MachineInstrs. |
| 98 | class VISIBILITY_HIDDEN ScheduleDAGInstrs : public ScheduleDAG { |
Dan Gohman | 3f23744 | 2008-12-16 03:25:46 +0000 | [diff] [blame] | 99 | const MachineLoopInfo &MLI; |
| 100 | const MachineDominatorTree &MDT; |
Evan Cheng | 38bdfc6 | 2009-10-18 19:58:47 +0000 | [diff] [blame] | 101 | const MachineFrameInfo *MFI; |
Dan Gohman | 3f23744 | 2008-12-16 03:25:46 +0000 | [diff] [blame] | 102 | |
Dan Gohman | 79ce276 | 2009-01-15 19:20:50 +0000 | [diff] [blame] | 103 | /// Defs, Uses - Remember where defs and uses of each physical register |
| 104 | /// are as we iterate upward through the instructions. This is allocated |
| 105 | /// here instead of inside BuildSchedGraph to avoid the need for it to be |
| 106 | /// initialized and destructed for each block. |
| 107 | std::vector<SUnit *> Defs[TargetRegisterInfo::FirstVirtualRegister]; |
| 108 | std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister]; |
Dale Johannesen | bfdf7f3 | 2010-03-10 22:13:47 +0000 | [diff] [blame] | 109 | |
| 110 | /// DbgValueVec - Remember DBG_VALUEs that refer to a particular |
| 111 | /// register. |
| 112 | std::vector<MachineInstr *>DbgValueVec; |
Dan Gohman | 79ce276 | 2009-01-15 19:20:50 +0000 | [diff] [blame] | 113 | |
| 114 | /// PendingLoads - Remember where unknown loads are after the most recent |
| 115 | /// unknown store, as we iterate. As with Defs and Uses, this is here |
| 116 | /// to minimize construction/destruction. |
| 117 | std::vector<SUnit *> PendingLoads; |
| 118 | |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 119 | /// LoopRegs - Track which registers are used for loop-carried dependencies. |
| 120 | /// |
| 121 | LoopDependencies LoopRegs; |
| 122 | |
| 123 | /// LoopLiveInRegs - Track which regs are live into a loop, to help guide |
| 124 | /// back-edge-aware scheduling. |
| 125 | /// |
| 126 | SmallSet<unsigned, 8> LoopLiveInRegs; |
| 127 | |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 128 | public: |
Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 129 | MachineBasicBlock::iterator Begin; // The beginning of the range to |
| 130 | // be scheduled. The range extends |
| 131 | // to InsertPos. |
| 132 | unsigned InsertPosIndex; // The index in BB of InsertPos. |
| 133 | |
Dan Gohman | 79ce276 | 2009-01-15 19:20:50 +0000 | [diff] [blame] | 134 | explicit ScheduleDAGInstrs(MachineFunction &mf, |
| 135 | const MachineLoopInfo &mli, |
| 136 | const MachineDominatorTree &mdt); |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 137 | |
| 138 | virtual ~ScheduleDAGInstrs() {} |
| 139 | |
| 140 | /// NewSUnit - Creates a new SUnit and return a ptr to it. |
| 141 | /// |
| 142 | SUnit *NewSUnit(MachineInstr *MI) { |
Dan Gohman | 361c31d | 2008-12-22 21:08:08 +0000 | [diff] [blame] | 143 | #ifndef NDEBUG |
Duncan Sands | f90fb34 | 2009-01-20 09:05:19 +0000 | [diff] [blame] | 144 | const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0]; |
Dan Gohman | 361c31d | 2008-12-22 21:08:08 +0000 | [diff] [blame] | 145 | #endif |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 146 | SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); |
Duncan Sands | f90fb34 | 2009-01-20 09:05:19 +0000 | [diff] [blame] | 147 | assert((Addr == 0 || Addr == &SUnits[0]) && |
| 148 | "SUnits std::vector reallocated on the fly!"); |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 149 | SUnits.back().OrigNode = &SUnits.back(); |
| 150 | return &SUnits.back(); |
| 151 | } |
| 152 | |
Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 153 | /// Run - perform scheduling. |
| 154 | /// |
| 155 | void Run(MachineBasicBlock *bb, |
| 156 | MachineBasicBlock::iterator begin, |
| 157 | MachineBasicBlock::iterator end, |
| 158 | unsigned endindex); |
| 159 | |
Dan Gohman | c9a5b9e | 2008-12-23 18:36:58 +0000 | [diff] [blame] | 160 | /// BuildSchedGraph - Build SUnits from the MachineBasicBlock that we are |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 161 | /// input. |
Dan Gohman | a70dca1 | 2009-10-09 23:27:56 +0000 | [diff] [blame] | 162 | virtual void BuildSchedGraph(AliasAnalysis *AA); |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 163 | |
Dan Gohman | c8c2827 | 2008-11-21 00:12:10 +0000 | [diff] [blame] | 164 | /// ComputeLatency - Compute node latency. |
| 165 | /// |
| 166 | virtual void ComputeLatency(SUnit *SU); |
| 167 | |
David Goodwin | dc4bdcd | 2009-08-19 16:08:58 +0000 | [diff] [blame] | 168 | /// ComputeOperandLatency - Override dependence edge latency using |
| 169 | /// operand use/def information |
| 170 | /// |
| 171 | virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use, |
| 172 | SDep& dep) const; |
| 173 | |
Evan Cheng | fb2e752 | 2009-09-18 21:02:19 +0000 | [diff] [blame] | 174 | virtual MachineBasicBlock* |
| 175 | EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*>*); |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 176 | |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 177 | /// StartBlock - Prepare to perform scheduling in the given block. |
| 178 | /// |
| 179 | virtual void StartBlock(MachineBasicBlock *BB); |
| 180 | |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 181 | /// Schedule - Order nodes according to selected style, filling |
| 182 | /// in the Sequence member. |
| 183 | /// |
| 184 | virtual void Schedule() = 0; |
| 185 | |
Dan Gohman | 9e64bbb | 2009-02-10 23:27:53 +0000 | [diff] [blame] | 186 | /// FinishBlock - Clean up after scheduling in the given block. |
| 187 | /// |
| 188 | virtual void FinishBlock(); |
| 189 | |
Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 190 | virtual void dumpNode(const SUnit *SU) const; |
| 191 | |
| 192 | virtual std::string getGraphNodeLabel(const SUnit *SU) const; |
| 193 | }; |
| 194 | } |
| 195 | |
| 196 | #endif |