static bool isSendMsgTraceDataOrGDS(const SIInstrInfo &TII, const MachineInstr &MI) { if (TII.isAlwaysGDS(MI.getOpcode())) return true; switch (MI.getOpcode()) { case AMDGPU::S_SENDMSG: case AMDGPU::S_SENDMSGHALT: case AMDGPU::S_TTRACEDATA: return true; // These DS opcodes don't support GDS. case AMDGPU::DS_NOP: case AMDGPU::DS_PERMUTE_B32: case AMDGPU::DS_BPERMUTE_B32: return false; default: if (TII.isDS(MI.getOpcode())) { int GDS = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::gds); if (MI.getOperand(GDS).getImm()) return true; } return false; } }
static bool hasAnyNonFlatUseOfReg(const MachineRegisterInfo &MRI, const SIInstrInfo &TII, unsigned Reg) { for (const MachineOperand &UseOp : MRI.reg_operands(Reg)) { if (!UseOp.isImplicit() || !TII.isFLAT(*UseOp.getParent())) return true; } return false; }
// These are only terminators to get correct spill code placement during // register allocation, so turn them back into normal instructions. Only one of // these is expected per block. static bool removeTerminatorBit(const SIInstrInfo &TII, MachineInstr &MI) { switch (MI.getOpcode()) { case AMDGPU::S_MOV_B64_term: { MI.setDesc(TII.get(AMDGPU::COPY)); return true; } case AMDGPU::S_XOR_B64_term: { // This is only a terminator to get the correct spill code placement during // register allocation. MI.setDesc(TII.get(AMDGPU::S_XOR_B64)); return true; } case AMDGPU::S_ANDN2_B64_term: { // This is only a terminator to get the correct spill code placement during // register allocation. MI.setDesc(TII.get(AMDGPU::S_ANDN2_B64)); return true; } default: return false; } }
void apply(ScheduleDAGInstrs *DAGInstrs) override { ScheduleDAGMI *DAG = static_cast<ScheduleDAGMI*>(DAGInstrs); SUnit *SUa = nullptr; // Search for two consequent memory operations and link them // to prevent scheduler from moving them apart. // In DAG pre-process SUnits are in the original order of // the instructions before scheduling. for (SUnit &SU : DAG->SUnits) { MachineInstr &MI2 = *SU.getInstr(); if (!MI2.mayLoad() && !MI2.mayStore()) { SUa = nullptr; continue; } if (!SUa) { SUa = &SU; continue; } MachineInstr &MI1 = *SUa->getInstr(); if ((TII->isVMEM(MI1) && TII->isVMEM(MI2)) || (TII->isFLAT(MI1) && TII->isFLAT(MI2)) || (TII->isSMRD(MI1) && TII->isSMRD(MI2)) || (TII->isDS(MI1) && TII->isDS(MI2))) { SU.addPredBarrier(SUa); for (const SDep &SI : SU.Preds) { if (SI.getSUnit() != SUa) SUa->addPred(SDep(SI.getSUnit(), SDep::Artificial)); } if (&SU != &DAG->ExitSU) { for (const SDep &SI : SUa->Succs) { if (SI.getSUnit() != &SU) SI.getSUnit()->addPred(SDep(&SU, SDep::Artificial)); } } } SUa = &SU; } }