static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI,
const TargetRegisterInfo &TRI) {
// FIXME: Detect integer instructions properly.
- const TargetInstrDesc &TID = MI->getDesc();
- unsigned Domain = TID.TSFlags & ARMII::DomainMask;
- if (TID.mayStore())
+ const MCInstrDesc &MCID = MI->getDesc();
+ unsigned Domain = MCID.TSFlags & ARMII::DomainMask;
+ if (MI->mayStore())
return false;
- unsigned Opcode = TID.getOpcode();
+ unsigned Opcode = MCID.getOpcode();
if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
return false;
if ((Domain & ARMII::DomainVFP) || (Domain & ARMII::DomainNEON))
MachineInstr *MI = SU->getInstr();
if (!MI->isDebugValue()) {
- if (ITBlockSize && MI != ITBlockMIs[ITBlockSize-1])
- return Hazard;
-
// Look for special VMLA / VMLS hazards. A VMUL / VADD / VSUB following
// a VMLA / VMLS will cause 4 cycle stall.
- const TargetInstrDesc &TID = MI->getDesc();
- if (LastMI && (TID.TSFlags & ARMII::DomainMask) != ARMII::DomainGeneral) {
+ const MCInstrDesc &MCID = MI->getDesc();
+ if (LastMI && (MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainGeneral) {
MachineInstr *DefMI = LastMI;
- const TargetInstrDesc &LastTID = LastMI->getDesc();
+ const MCInstrDesc &LastMCID = LastMI->getDesc();
+ const TargetMachine &TM =
+ MI->getParent()->getParent()->getTarget();
+ const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
+
// Skip over one non-VFP / NEON instruction.
- if (!LastTID.isBarrier() &&
- (LastTID.TSFlags & ARMII::DomainMask) == ARMII::DomainGeneral) {
+ if (!LastMI->isBarrier() &&
+ // On A9, AGU and NEON/FPU are muxed.
+ !(TII.getSubtarget().isLikeA9() &&
+ (LastMI->mayLoad() || LastMI->mayStore())) &&
+ (LastMCID.TSFlags & ARMII::DomainMask) == ARMII::DomainGeneral) {
MachineBasicBlock::iterator I = LastMI;
if (I != LastMI->getParent()->begin()) {
- I = llvm::prior(I);
+ I = std::prev(I);
DefMI = &*I;
}
}
if (TII.isFpMLxInstruction(DefMI->getOpcode()) &&
(TII.canCauseFpMLxStall(MI->getOpcode()) ||
- hasRAWHazard(DefMI, MI, TRI))) {
+ hasRAWHazard(DefMI, MI, TII.getRegisterInfo()))) {
// Try to schedule another instruction for the next 4 cycles.
if (FpMLxStalls == 0)
FpMLxStalls = 4;
}
void ARMHazardRecognizer::Reset() {
- LastMI = 0;
+ LastMI = nullptr;
FpMLxStalls = 0;
- ITBlockSize = 0;
ScoreboardHazardRecognizer::Reset();
}
void ARMHazardRecognizer::EmitInstruction(SUnit *SU) {
MachineInstr *MI = SU->getInstr();
- unsigned Opcode = MI->getOpcode();
- if (ITBlockSize) {
- --ITBlockSize;
- } else if (Opcode == ARM::t2IT) {
- unsigned Mask = MI->getOperand(1).getImm();
- unsigned NumTZ = CountTrailingZeros_32(Mask);
- assert(NumTZ <= 3 && "Invalid IT mask!");
- ITBlockSize = 4 - NumTZ;
- MachineBasicBlock::iterator I = MI;
- for (unsigned i = 0; i < ITBlockSize; ++i) {
- // Advance to the next instruction, skipping any dbg_value instructions.
- do {
- ++I;
- } while (I->isDebugValue());
- ITBlockMIs[ITBlockSize-1-i] = &*I;
- }
- }
-
if (!MI->isDebugValue()) {
LastMI = MI;
FpMLxStalls = 0;
void ARMHazardRecognizer::AdvanceCycle() {
if (FpMLxStalls && --FpMLxStalls == 0)
// Stalled for 4 cycles but still can't schedule any other instructions.
- LastMI = 0;
+ LastMI = nullptr;
ScoreboardHazardRecognizer::AdvanceCycle();
}