22#define DEBUG_TYPE "pre-RA-sched"
24bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(
SUnit *SU) {
26 if (isBCTRAfterSet(SU))
38 for (
unsigned i = 0, ie = (
unsigned) SU->
Preds.size(); i != ie; ++i) {
40 if (!PredMCID || !PredMCID->
mayStore())
43 if (!SU->
Preds[i].isNormalMemory() && !SU->
Preds[i].isBarrier())
46 for (
unsigned j = 0, je = CurGroup.size(); j != je; ++j)
47 if (SU->
Preds[i].getSUnit() == CurGroup[j])
54bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(
SUnit *SU) {
55 const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
64 for (
unsigned i = 0, ie = (
unsigned) SU->
Preds.size(); i != ie; ++i) {
65 const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->
Preds[i].getSUnit());
66 if (!PredMCID || PredMCID->
getSchedClass() != PPC::Sched::IIC_SprMTSPR)
69 if (SU->
Preds[i].isCtrl())
72 for (
unsigned j = 0, je = CurGroup.size(); j != je; ++j)
73 if (SU->
Preds[i].getSUnit() == CurGroup[j])
89bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(
const MCInstrDesc *
MCID,
94 unsigned IIC =
MCID->getSchedClass();
99 case PPC::Sched::IIC_IntDivW:
100 case PPC::Sched::IIC_IntDivD:
101 case PPC::Sched::IIC_LdStLoadUpd:
102 case PPC::Sched::IIC_LdStLDU:
103 case PPC::Sched::IIC_LdStLFDU:
104 case PPC::Sched::IIC_LdStLFDUX:
105 case PPC::Sched::IIC_LdStLHA:
106 case PPC::Sched::IIC_LdStLHAU:
107 case PPC::Sched::IIC_LdStLWA:
108 case PPC::Sched::IIC_LdStSTU:
109 case PPC::Sched::IIC_LdStSTFDU:
112 case PPC::Sched::IIC_LdStLoadUpdX:
113 case PPC::Sched::IIC_LdStLDUX:
114 case PPC::Sched::IIC_LdStLHAUX:
115 case PPC::Sched::IIC_LdStLWARX:
116 case PPC::Sched::IIC_LdStLDARX:
117 case PPC::Sched::IIC_LdStSTUX:
118 case PPC::Sched::IIC_LdStSTDCX:
119 case PPC::Sched::IIC_LdStSTWCX:
120 case PPC::Sched::IIC_BrMCRX:
134 case PPC::Sched::IIC_BrCR:
135 case PPC::Sched::IIC_SprMFCR:
136 case PPC::Sched::IIC_SprMFCRF:
137 case PPC::Sched::IIC_SprMTSPR:
144 if (Stalls == 0 && isLoadAfterStore(SU))
153 if (
MCID && mustComeFirst(
MCID, NSlots) && CurSlots)
163 if (isLoadAfterStore(SU) && CurSlots < 6) {
181 if (CurSlots == 5 || (
MCID->isBranch() && CurBranches == 1)) {
183 CurSlots = CurBranches = 0;
189 bool MustBeFirst = mustComeFirst(
MCID, NSlots);
193 if (MustBeFirst && CurSlots) {
194 CurSlots = CurBranches = 0;
199 CurGroup.push_back(SU);
201 if (
MCID->isBranch())
219 CurSlots = CurBranches = 0;
233 CurSlots = CurBranches = 0;
235 CurGroup.push_back(
nullptr);
271void PPCHazardRecognizer970::EndDispatchGroup() {
282PPCHazardRecognizer970::GetInstrType(
unsigned Opcode,
283 bool &isFirst,
bool &isSingle,
301bool PPCHazardRecognizer970::
302isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
303 const Value *LoadValue)
const {
304 for (
unsigned i = 0, e = NumStores; i !=
e; ++i) {
306 if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
311 if (StoreValue[i] == LoadValue) {
314 if (StoreOffset[i] < LoadOffset) {
315 if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset)
return true;
317 if (int64_t(LoadOffset+LoadSize) > StoreOffset[i])
return true;
330 assert(Stalls == 0 &&
"PPC hazards don't support scoreboard lookahead");
334 if (
MI->isDebugInstr())
337 unsigned Opcode =
MI->getOpcode();
340 GetInstrType(Opcode, isFirst, isSingle, isCracked,
346 if (NumIssued != 0 && (isFirst || isSingle))
352 if (isCracked && NumIssued > 2)
363 if (NumIssued == 4)
return Hazard;
367 if (NumIssued >= 2)
return Hazard;
374 if (HasCTRSet && Opcode == PPC::BCTRL)
379 if (
isLoad && NumStores && !
MI->memoperands_empty()) {
393 if (
MI->isDebugInstr())
396 unsigned Opcode =
MI->getOpcode();
399 GetInstrType(Opcode, isFirst, isSingle, isCracked,
404 if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet =
true;
407 if (
isStore && NumStores < 4 && !MI->memoperands_empty() &&
408 (*
MI->memoperands_begin())->getSize().hasValue()) {
411 StoreOffset[NumStores] = MO->
getOffset();
412 StoreValue[NumStores] = MO->
getValue();
430 assert(NumIssued < 5 &&
"Illegal dispatch group!");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isLoad(int Opcode)
static bool isStore(int Opcode)
TypeSize getValue() const
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
unsigned getOpcode() const
Return the opcode number for this descriptor.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Representation of each machine instruction.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
unsigned PreEmitNoops(SUnit *SU) override
PreEmitNoops - This callback is invoked prior to emitting an instruction.
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
bool ShouldPreferAnother(SUnit *SU) override
ShouldPreferAnother - This callback may be invoked if getHazardType returns NoHazard.
void EmitNoop() override
EmitNoop - This callback is invoked when a noop was added to the instruction stream.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
PPCHazardRecognizer970(const ScheduleDAG &DAG)
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - We return hazard for any non-branch instruction that would terminate the dispatch gro...
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
Scheduling unit. This is a node in the scheduling DAG.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
const MCInstrDesc * getInstrDesc(const SUnit *SU) const
Returns the MCInstrDesc of this SUnit.
const TargetInstrInfo * TII
Target instruction information.
virtual bool ShouldPreferAnother(SUnit *)
ShouldPreferAnother - This callback may be invoked if getHazardType returns NoHazard.
virtual unsigned PreEmitNoops(SUnit *)
PreEmitNoops - This callback is invoked prior to emitting an instruction.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
InstrType
This represents what is and is not supported when finding similarity in Instructions.
@ PPC970_Pseudo
These are the various PPC970 execution unit pipelines.
@ PPC970_First
PPC970_First - This instruction starts a new dispatch group, so it will always be the first one in th...
@ PPC970_Cracked
PPC970_Cracked - This instruction is cracked into two pieces, requiring two dispatch pipes to be avai...
@ PPC970_Single
PPC970_Single - This instruction starts a new dispatch group and terminates it, so it will be the sol...
Define some predicates that are used for node matching.
int32_t getNonRecordFormOpcode(uint32_t)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.