LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMHazardRecognizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 43 45 95.6 %
Date: 2018-10-20 13:21:21 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARMHazardRecognizer.cpp - ARM postra hazard recognizer ------------===//
       2             : //
       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             : 
      10             : #include "ARMHazardRecognizer.h"
      11             : #include "ARMBaseInstrInfo.h"
      12             : #include "ARMBaseRegisterInfo.h"
      13             : #include "ARMSubtarget.h"
      14             : #include "llvm/CodeGen/MachineInstr.h"
      15             : #include "llvm/CodeGen/ScheduleDAG.h"
      16             : #include "llvm/CodeGen/TargetRegisterInfo.h"
      17             : using namespace llvm;
      18             : 
      19         429 : static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI,
      20             :                          const TargetRegisterInfo &TRI) {
      21             :   // FIXME: Detect integer instructions properly.
      22         429 :   const MCInstrDesc &MCID = MI->getDesc();
      23         429 :   unsigned Domain = MCID.TSFlags & ARMII::DomainMask;
      24         429 :   if (MI->mayStore())
      25             :     return false;
      26         426 :   unsigned Opcode = MCID.getOpcode();
      27         426 :   if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
      28             :     return false;
      29         366 :   if ((Domain & ARMII::DomainVFP) || (Domain & ARMII::DomainNEON))
      30         366 :     return MI->readsRegister(DefMI->getOperand(0).getReg(), &TRI);
      31             :   return false;
      32             : }
      33             : 
      34             : ScheduleHazardRecognizer::HazardType
      35       82438 : ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
      36             :   assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead");
      37             : 
      38       82438 :   MachineInstr *MI = SU->getInstr();
      39             : 
      40             :   if (!MI->isDebugInstr()) {
      41             :     // Look for special VMLA / VMLS hazards. A VMUL / VADD / VSUB following
      42             :     // a VMLA / VMLS will cause 4 cycle stall.
      43             :     const MCInstrDesc &MCID = MI->getDesc();
      44       82438 :     if (LastMI && (MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainGeneral) {
      45             :       MachineInstr *DefMI = LastMI;
      46       38164 :       const MCInstrDesc &LastMCID = LastMI->getDesc();
      47       38164 :       const MachineFunction *MF = MI->getParent()->getParent();
      48             :       const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>(
      49       38164 :                                         MF->getSubtarget().getInstrInfo());
      50             : 
      51             :       // Skip over one non-VFP / NEON instruction.
      52       38164 :       if (!LastMI->isBarrier() &&
      53       38164 :           !(TII.getSubtarget().hasMuxedUnits() && LastMI->mayLoadOrStore()) &&
      54       37745 :           (LastMCID.TSFlags & ARMII::DomainMask) == ARMII::DomainGeneral) {
      55        3343 :         MachineBasicBlock::iterator I = LastMI;
      56        6686 :         if (I != LastMI->getParent()->begin()) {
      57        2983 :           I = std::prev(I);
      58             :           DefMI = &*I;
      59             :         }
      60             :       }
      61             : 
      62       75842 :       if (TII.isFpMLxInstruction(DefMI->getOpcode()) &&
      63         915 :           (TII.canCauseFpMLxStall(MI->getOpcode()) ||
      64         429 :            hasRAWHazard(DefMI, MI, TII.getRegisterInfo()))) {
      65             :         // Try to schedule another instruction for the next 4 cycles.
      66         232 :         if (FpMLxStalls == 0)
      67          56 :           FpMLxStalls = 4;
      68         232 :         return Hazard;
      69             :       }
      70             :     }
      71             :   }
      72             : 
      73       82206 :   return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
      74             : }
      75             : 
      76       55563 : void ARMHazardRecognizer::Reset() {
      77       55563 :   LastMI = nullptr;
      78       55563 :   FpMLxStalls = 0;
      79       55563 :   ScoreboardHazardRecognizer::Reset();
      80       55563 : }
      81             : 
      82       56473 : void ARMHazardRecognizer::EmitInstruction(SUnit *SU) {
      83       56473 :   MachineInstr *MI = SU->getInstr();
      84             :   if (!MI->isDebugInstr()) {
      85       56473 :     LastMI = MI;
      86       56473 :     FpMLxStalls = 0;
      87             :   }
      88             : 
      89       56473 :   ScoreboardHazardRecognizer::EmitInstruction(SU);
      90       56473 : }
      91             : 
      92       78916 : void ARMHazardRecognizer::AdvanceCycle() {
      93       78916 :   if (FpMLxStalls && --FpMLxStalls == 0)
      94             :     // Stalled for 4 cycles but still can't schedule any other instructions.
      95          55 :     LastMI = nullptr;
      96       78916 :   ScoreboardHazardRecognizer::AdvanceCycle();
      97       78916 : }
      98             : 
      99           0 : void ARMHazardRecognizer::RecedeCycle() {
     100           0 :   llvm_unreachable("reverse ARM hazard checking unsupported");
     101             : }

Generated by: LCOV version 1.13