blob: fba8192c01528bcea05d59a01d4ddbf5eb39f72f [file] [log] [blame]
Dan Gohmana629b482008-12-08 17:50:35 +00001//===---- ScheduleDAGInstrs.cpp - MachineInstr Rescheduling ---------------===//
Dan Gohman343f0c02008-11-19 23:18:57 +00002//
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//
Dan Gohmana629b482008-12-08 17:50:35 +000010// This implements the ScheduleDAGInstrs class, which implements re-scheduling
11// of MachineInstrs.
Dan Gohman343f0c02008-11-19 23:18:57 +000012//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "sched-instrs"
16#include "llvm/CodeGen/ScheduleDAGInstrs.h"
Dan Gohman6a9041e2008-12-04 01:35:46 +000017#include "llvm/CodeGen/PseudoSourceValue.h"
Dan Gohman343f0c02008-11-19 23:18:57 +000018#include "llvm/Target/TargetMachine.h"
19#include "llvm/Target/TargetInstrInfo.h"
20#include "llvm/Target/TargetRegisterInfo.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/Support/raw_ostream.h"
Dan Gohman6a9041e2008-12-04 01:35:46 +000023#include <map>
Dan Gohman343f0c02008-11-19 23:18:57 +000024using namespace llvm;
25
26ScheduleDAGInstrs::ScheduleDAGInstrs(MachineBasicBlock *bb,
27 const TargetMachine &tm)
28 : ScheduleDAG(0, bb, tm) {}
29
30void ScheduleDAGInstrs::BuildSchedUnits() {
31 SUnits.clear();
32 SUnits.reserve(BB->size());
Dan Gohman6a9041e2008-12-04 01:35:46 +000033 int Cost = 1; // FIXME
Dan Gohman343f0c02008-11-19 23:18:57 +000034
Dan Gohman6a9041e2008-12-04 01:35:46 +000035 // We build scheduling units by walking a block's instruction list from bottom
36 // to top.
37
38 // Remember where defs and uses of each physical register are as we procede.
Dan Gohman343f0c02008-11-19 23:18:57 +000039 SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
40 std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister] = {};
Dan Gohman6a9041e2008-12-04 01:35:46 +000041
42 // Remember where unknown loads are after the most recent unknown store
43 // as we procede.
44 std::vector<SUnit *> PendingLoads;
45
46 // Remember where a generic side-effecting instruction is as we procede. If
47 // ChainMMO is null, this is assumed to have arbitrary side-effects. If
48 // ChainMMO is non-null, then Chain makes only a single memory reference.
49 SUnit *Chain = 0;
50 MachineMemOperand *ChainMMO = 0;
51
52 // Memory references to specific known memory locations are tracked so that
53 // they can be given more precise dependencies.
54 std::map<const Value *, SUnit *> MemDefs;
55 std::map<const Value *, std::vector<SUnit *> > MemUses;
56
57 // Terminators can perform control transfers, we we need to make sure that
58 // all the work of the block is done before the terminator.
59 SUnit *Terminator = 0;
Dan Gohman343f0c02008-11-19 23:18:57 +000060
61 for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin();
62 MII != MIE; --MII) {
63 MachineInstr *MI = prior(MII);
64 SUnit *SU = NewSUnit(MI);
65
Dan Gohman6a9041e2008-12-04 01:35:46 +000066 // Add register-based dependencies (data, anti, and output).
Dan Gohman343f0c02008-11-19 23:18:57 +000067 for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
68 const MachineOperand &MO = MI->getOperand(j);
69 if (!MO.isReg()) continue;
70 unsigned Reg = MO.getReg();
71 if (Reg == 0) continue;
72
73 assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
74 std::vector<SUnit *> &UseList = Uses[Reg];
75 SUnit *&Def = Defs[Reg];
Dan Gohmanfc626b62008-11-21 19:16:58 +000076 // Optionally add output and anti dependencies.
Dan Gohman343f0c02008-11-19 23:18:57 +000077 if (Def && Def != SU)
Dan Gohmanfc626b62008-11-21 19:16:58 +000078 Def->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false,
Dan Gohmanf6b7a472008-11-21 02:38:21 +000079 /*PhyReg=*/Reg, Cost, /*isAntiDep=*/MO.isUse());
Dan Gohman343f0c02008-11-19 23:18:57 +000080 for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
81 SUnit *&Def = Defs[*Alias];
82 if (Def && Def != SU)
Dan Gohmanfc626b62008-11-21 19:16:58 +000083 Def->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false,
Dan Gohman974b5f52008-11-24 17:24:27 +000084 /*PhyReg=*/*Alias, Cost, /*isAntiDep=*/MO.isUse());
Dan Gohman343f0c02008-11-19 23:18:57 +000085 }
86
87 if (MO.isDef()) {
88 // Add any data dependencies.
89 for (unsigned i = 0, e = UseList.size(); i != e; ++i)
90 if (UseList[i] != SU)
Dan Gohmanfc626b62008-11-21 19:16:58 +000091 UseList[i]->addPred(SU, /*isCtrl=*/false, /*isArtificial=*/false,
Dan Gohman343f0c02008-11-19 23:18:57 +000092 /*PhysReg=*/Reg, Cost);
93 for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
94 std::vector<SUnit *> &UseList = Uses[*Alias];
95 for (unsigned i = 0, e = UseList.size(); i != e; ++i)
96 if (UseList[i] != SU)
Dan Gohmanfc626b62008-11-21 19:16:58 +000097 UseList[i]->addPred(SU, /*isCtrl=*/false, /*isArtificial=*/false,
Dan Gohman343f0c02008-11-19 23:18:57 +000098 /*PhysReg=*/*Alias, Cost);
99 }
100
101 UseList.clear();
102 Def = SU;
103 } else {
104 UseList.push_back(SU);
105 }
106 }
Dan Gohman6a9041e2008-12-04 01:35:46 +0000107
108 // Add chain dependencies.
109 // Note that isStoreToStackSlot and isLoadFromStackSLot are not usable
110 // after stack slots are lowered to actual addresses.
111 // TODO: Use an AliasAnalysis and do real alias-analysis queries, and
112 // produce more precise dependence information.
113 const TargetInstrDesc &TID = MI->getDesc();
114 if (TID.isCall() || TID.isReturn() || TID.isBranch() ||
115 TID.hasUnmodeledSideEffects()) {
116 new_chain:
Dan Gohmana629b482008-12-08 17:50:35 +0000117 // This is the conservative case. Add dependencies on all memory
118 // references.
Dan Gohman343f0c02008-11-19 23:18:57 +0000119 if (Chain)
Dan Gohman37d8b312008-11-21 19:17:25 +0000120 Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
Dan Gohman6a9041e2008-12-04 01:35:46 +0000121 Chain = SU;
Dan Gohman343f0c02008-11-19 23:18:57 +0000122 for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
Dan Gohman37d8b312008-11-21 19:17:25 +0000123 PendingLoads[k]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
Dan Gohman343f0c02008-11-19 23:18:57 +0000124 PendingLoads.clear();
Dan Gohman6a9041e2008-12-04 01:35:46 +0000125 for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
126 E = MemDefs.end(); I != E; ++I) {
127 I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
128 I->second = SU;
129 }
130 for (std::map<const Value *, std::vector<SUnit *> >::iterator I =
131 MemUses.begin(), E = MemUses.end(); I != E; ++I) {
132 for (unsigned i = 0, e = I->second.size(); i != e; ++i)
133 I->second[i]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
134 I->second.clear();
135 }
136 // See if it is known to just have a single memory reference.
137 MachineInstr *ChainMI = Chain->getInstr();
138 const TargetInstrDesc &ChainTID = ChainMI->getDesc();
139 if (!ChainTID.isCall() && !ChainTID.isReturn() && !ChainTID.isBranch() &&
140 !ChainTID.hasUnmodeledSideEffects() &&
141 ChainMI->hasOneMemOperand() &&
142 !ChainMI->memoperands_begin()->isVolatile() &&
143 ChainMI->memoperands_begin()->getValue())
144 // We know that the Chain accesses one specific memory location.
145 ChainMMO = &*ChainMI->memoperands_begin();
146 else
147 // Unknown memory accesses. Assume the worst.
148 ChainMMO = 0;
149 } else if (TID.mayStore()) {
150 if (MI->hasOneMemOperand() &&
151 MI->memoperands_begin()->getValue() &&
152 !MI->memoperands_begin()->isVolatile() &&
153 isa<PseudoSourceValue>(MI->memoperands_begin()->getValue())) {
154 // A store to a specific PseudoSourceValue. Add precise dependencies.
155 const Value *V = MI->memoperands_begin()->getValue();
156 // Handle the def in MemDefs, if there is one.
157 std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
158 if (I != MemDefs.end()) {
159 I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
160 I->second = SU;
161 } else {
162 MemDefs[V] = SU;
163 }
164 // Handle the uses in MemUses, if there are any.
Dan Gohmana629b482008-12-08 17:50:35 +0000165 std::map<const Value *, std::vector<SUnit *> >::iterator J =
166 MemUses.find(V);
Dan Gohman6a9041e2008-12-04 01:35:46 +0000167 if (J != MemUses.end()) {
168 for (unsigned i = 0, e = J->second.size(); i != e; ++i)
169 J->second[i]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
170 J->second.clear();
171 }
172 // Add a general dependence too, if needed.
173 if (Chain)
174 Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
175 } else
176 // Treat all other stores conservatively.
177 goto new_chain;
178 } else if (TID.mayLoad()) {
179 if (TII->isInvariantLoad(MI)) {
180 // Invariant load, no chain dependencies needed!
181 } else if (MI->hasOneMemOperand() &&
182 MI->memoperands_begin()->getValue() &&
183 !MI->memoperands_begin()->isVolatile() &&
184 isa<PseudoSourceValue>(MI->memoperands_begin()->getValue())) {
185 // A load from a specific PseudoSourceValue. Add precise dependencies.
186 const Value *V = MI->memoperands_begin()->getValue();
187 std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
188 if (I != MemDefs.end())
189 I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
190 MemUses[V].push_back(SU);
191
192 // Add a general dependence too, if needed.
193 if (Chain && (!ChainMMO ||
194 (ChainMMO->isStore() || ChainMMO->isVolatile())))
195 Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
196 } else if (MI->hasVolatileMemoryRef()) {
197 // Treat volatile loads conservatively. Note that this includes
198 // cases where memoperand information is unavailable.
199 goto new_chain;
200 } else {
201 // A normal load. Just depend on the general chain.
202 if (Chain)
203 Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
204 PendingLoads.push_back(SU);
205 }
Dan Gohman343f0c02008-11-19 23:18:57 +0000206 }
Dan Gohman6a9041e2008-12-04 01:35:46 +0000207
Dan Gohmana629b482008-12-08 17:50:35 +0000208 // Add chain edges from the terminator to ensure that all the work of the
209 // block is completed before any control transfers.
Dan Gohman343f0c02008-11-19 23:18:57 +0000210 if (Terminator && SU->Succs.empty())
Dan Gohman37d8b312008-11-21 19:17:25 +0000211 Terminator->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false);
Dan Gohman6a9041e2008-12-04 01:35:46 +0000212 if (TID.isTerminator() || MI->isLabel())
Dan Gohman343f0c02008-11-19 23:18:57 +0000213 Terminator = SU;
Dan Gohman787782f2008-11-21 01:44:51 +0000214
215 // Assign the Latency field of SU using target-provided information.
216 ComputeLatency(SU);
Dan Gohman343f0c02008-11-19 23:18:57 +0000217 }
218}
219
Dan Gohmanc8c28272008-11-21 00:12:10 +0000220void ScheduleDAGInstrs::ComputeLatency(SUnit *SU) {
221 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
222
223 // Compute the latency for the node. We use the sum of the latencies for
224 // all nodes flagged together into this SUnit.
225 SU->Latency =
226 InstrItins.getLatency(SU->getInstr()->getDesc().getSchedClass());
227}
228
Dan Gohman343f0c02008-11-19 23:18:57 +0000229void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const {
230 SU->getInstr()->dump();
231}
232
233std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
234 std::string s;
235 raw_string_ostream oss(s);
236 SU->getInstr()->print(oss);
237 return oss.str();
238}
239
240// EmitSchedule - Emit the machine code in scheduled order.
241MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
242 // For MachineInstr-based scheduling, we're rescheduling the instructions in
243 // the block, so start by removing them from the block.
244 while (!BB->empty())
245 BB->remove(BB->begin());
246
247 for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
248 SUnit *SU = Sequence[i];
249 if (!SU) {
250 // Null SUnit* is a noop.
251 EmitNoop();
252 continue;
253 }
254
255 BB->push_back(SU->getInstr());
256 }
257
258 return BB;
259}