llvm.org GIT mirror llvm / dc4bdcd
Use the schedule itinerary operand use/def cycle information to adjust dependence edge latency for post-RA scheduling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79425 91177308-0d34-0410-b5e6-96231b3b80d8 David Goodwin 10 years ago
6 changed file(s) with 107 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
494494 ///
495495 virtual void ComputeLatency(SUnit *SU) = 0;
496496
497 /// ComputeOperandLatency - Override dependence edge latency using
498 /// operand use/def information
499 ///
500 virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use,
501 SDep& dep) const { };
502
497503 /// Schedule - Order nodes according to selected style, filling
498504 /// in the Sequence member.
499505 ///
102102 /// isEmpty - Returns true if there are no itineraries.
103103 ///
104104 bool isEmpty() const { return Itineratries == 0; }
105
105
106106 /// beginStage - Return the first stage of the itinerary.
107107 ///
108108 const InstrStage *beginStage(unsigned ItinClassIndx) const {
117117 return Stages + StageIdx;
118118 }
119119
120 /// getLatency - Return the scheduling latency of the given class. A
121 /// simple latency value for an instruction is an over-simplification
122 /// for some architectures, but it's a reasonable first approximation.
120 /// getStageLatency - Return the total stage latency of the given
121 /// class. The latency is the maximum completion time for any stage
122 /// in the itinerary.
123123 ///
124 unsigned getLatency(unsigned ItinClassIndx) const {
125 // If the target doesn't provide latency information, use a simple
126 // non-zero default value for all instructions.
124 unsigned getStageLatency(unsigned ItinClassIndx) const {
125 // If the target doesn't provide itinerary information, use a
126 // simple non-zero default value for all instructions.
127127 if (isEmpty())
128128 return 1;
129129
130 // Caclulate the maximum completion time for any stage. The
131 // assumption is that all inputs are consumed at the start of the
132 // first stage and that all outputs are produced at the end of the
133 // latest completing last stage.
130 // Calculate the maximum completion time for any stage.
134131 unsigned Latency = 0, StartCycle = 0;
135132 for (const InstrStage *IS = beginStage(ItinClassIndx),
136133 *E = endStage(ItinClassIndx); IS != E; ++IS) {
140137
141138 return Latency;
142139 }
140
141 /// getOperandCycle - Return the cycle for the given class and
142 /// operand. Return -1 if no cycle is specified for the operand.
143 ///
144 int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
145 if (isEmpty())
146 return -1;
147
148 unsigned FirstIdx = Itineratries[ItinClassIndx].FirstOperandCycle;
149 unsigned LastIdx = Itineratries[ItinClassIndx].LastOperandCycle;
150 if ((FirstIdx + OperandIdx) >= LastIdx)
151 return -1;
152
153 return (int)OperandCycles[FirstIdx + OperandIdx];
154 }
143155 };
144156
145157
1616 namespace llvm {
1717
1818 class SDep;
19 class SUnit;
1920
2021 //===----------------------------------------------------------------------===//
2122 ///
3940
4041 // adjustSchedDependency - Perform target specific adjustments to
4142 // the latency of a schedule dependency.
42 virtual void adjustSchedDependency(SDep&) const { };
43 virtual void adjustSchedDependency(SUnit *def, SUnit *use,
44 SDep& dep) const { };
4345 };
4446
4547 } // End llvm namespace
209209 // Optionally add in a special extra latency for nodes that
210210 // feed addresses.
211211 // TODO: Do this for register aliases too.
212 // TODO: Perhaps we should get rid of
213 // SpecialAddressLatency and just move this into
214 // adjustSchedDependency for the targets that care about
215 // it.
212216 if (SpecialAddressLatency != 0 && !UnitLatencies) {
213217 MachineInstr *UseMI = UseSU->getInstr();
214218 const TargetInstrDesc &UseTID = UseMI->getDesc();
219223 UseTID.OpInfo[RegUseIndex].isLookupPtrRegClass())
220224 LDataLatency += SpecialAddressLatency;
221225 }
226 // Adjust the dependence latency using operand def/use
227 // information (if any), and then allow the target to
228 // perform its own adjustments.
222229 const SDep& dep = SDep(SU, SDep::Data, LDataLatency, Reg);
223 ST.adjustSchedDependency((SDep &)dep);
230 if (!UnitLatencies) {
231 ComputeOperandLatency(SU, UseSU, (SDep &)dep);
232 ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
233 }
224234 UseSU->addPred(dep);
225235 }
226236 }
230240 SUnit *UseSU = UseList[i];
231241 if (UseSU != SU) {
232242 const SDep& dep = SDep(SU, SDep::Data, DataLatency, *Alias);
233 ST.adjustSchedDependency((SDep &)dep);
243 if (!UnitLatencies) {
244 ComputeOperandLatency(SU, UseSU, (SDep &)dep);
245 ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
246 }
234247 UseSU->addPred(dep);
235248 }
236249 }
409422
410423 // Compute the latency for the node.
411424 SU->Latency =
412 InstrItins.getLatency(SU->getInstr()->getDesc().getSchedClass());
425 InstrItins.getStageLatency(SU->getInstr()->getDesc().getSchedClass());
413426
414427 // Simplistic target-independent heuristic: assume that loads take
415428 // extra time.
416429 if (InstrItins.isEmpty())
417430 if (SU->getInstr()->getDesc().mayLoad())
418431 SU->Latency += 2;
432 }
433
434 void ScheduleDAGInstrs::ComputeOperandLatency(SUnit *Def, SUnit *Use,
435 SDep& dep) const {
436 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
437 if (InstrItins.isEmpty())
438 return;
439
440 // For a data dependency with a known register...
441 if ((dep.getKind() != SDep::Data) || (dep.getReg() == 0))
442 return;
443
444 const unsigned Reg = dep.getReg();
445
446 // ... find the definition of the register in the defining
447 // instruction
448 MachineInstr *DefMI = Def->getInstr();
449 int DefIdx = DefMI->findRegisterDefOperandIdx(Reg);
450 if (DefIdx != -1) {
451 int DefCycle = InstrItins.getOperandCycle(DefMI->getDesc().getSchedClass(), DefIdx);
452 if (DefCycle >= 0) {
453 MachineInstr *UseMI = Use->getInstr();
454 const unsigned UseClass = UseMI->getDesc().getSchedClass();
455
456 // For all uses of the register, calculate the maxmimum latency
457 int Latency = -1;
458 for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
459 const MachineOperand &MO = UseMI->getOperand(i);
460 if (!MO.isReg() || !MO.isUse())
461 continue;
462 unsigned MOReg = MO.getReg();
463 if (MOReg != Reg)
464 continue;
465
466 int UseCycle = InstrItins.getOperandCycle(UseClass, i);
467 if (UseCycle >= 0)
468 Latency = std::max(Latency, DefCycle - UseCycle + 1);
469 }
470
471 // If we found a latency, then replace the existing dependence latency.
472 if (Latency >= 0)
473 dep.setLatency(Latency);
474 }
475 }
419476 }
420477
421478 void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const {
159159 ///
160160 virtual void ComputeLatency(SUnit *SU);
161161
162 /// ComputeOperandLatency - Override dependence edge latency using
163 /// operand use/def information
164 ///
165 virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use,
166 SDep& dep) const;
167
162168 virtual MachineBasicBlock *EmitSchedule();
163169
164170 /// StartBlock - Prepare to perform scheduling in the given block.
153153
154154 void ScheduleDAGSDNodes::AddSchedEdges() {
155155 const TargetSubtarget &ST = TM.getSubtarget();
156
157 // Check to see if the scheduler cares about latencies.
158 bool UnitLatencies = ForceUnitLatencies();
156159
157160 // Pass 2: add the preds, succs, etc.
158161 for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
211214
212215 const SDep& dep = SDep(OpSU, isChain ? SDep::Order : SDep::Data,
213216 OpSU->Latency, PhysReg);
214 if (!isChain)
215 ST.adjustSchedDependency((SDep &)dep);
217 if (!isChain && !UnitLatencies) {
218 ComputeOperandLatency(OpSU, SU, (SDep &)dep);
219 ST.adjustSchedDependency(OpSU, SU, (SDep &)dep);
220 }
216221
217222 SU->addPred(dep);
218223 }
241246 for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
242247 if (N->isMachineOpcode()) {
243248 SawMachineOpcode = true;
244 SU->Latency +=
245 InstrItins.getLatency(TII->get(N->getMachineOpcode()).getSchedClass());
249 SU->Latency += InstrItins.
250 getStageLatency(TII->get(N->getMachineOpcode()).getSchedClass());
246251 }
247252 }
248253