LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMHazardRecognizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 47 49 95.9 %
Date: 2017-09-14 15:23:50 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/Target/TargetRegisterInfo.h"
      17             : using namespace llvm;
      18             : 
      19         329 : static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI,
      20             :                          const TargetRegisterInfo &TRI) {
      21             :   // FIXME: Detect integer instructions properly.
      22         329 :   const MCInstrDesc &MCID = MI->getDesc();
      23         329 :   unsigned Domain = MCID.TSFlags & ARMII::DomainMask;
      24         329 :   if (MI->mayStore())
      25             :     return false;
      26         322 :   unsigned Opcode = MCID.getOpcode();
      27         322 :   if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
      28             :     return false;
      29         290 :   if ((Domain & ARMII::DomainVFP) || (Domain & ARMII::DomainNEON))
      30         580 :     return MI->readsRegister(DefMI->getOperand(0).getReg(), &TRI);
      31             :   return false;
      32             : }
      33             : 
      34             : ScheduleHazardRecognizer::HazardType
      35       72201 : ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
      36             :   assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead");
      37             : 
      38       72201 :   MachineInstr *MI = SU->getInstr();
      39             : 
      40       72201 :   if (!MI->isDebugValue()) {
      41             :     // Look for special VMLA / VMLS hazards. A VMUL / VADD / VSUB following
      42             :     // a VMLA / VMLS will cause 4 cycle stall.
      43       72201 :     const MCInstrDesc &MCID = MI->getDesc();
      44       72201 :     if (LastMI && (MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainGeneral) {
      45       34160 :       MachineInstr *DefMI = LastMI;
      46       34160 :       const MCInstrDesc &LastMCID = LastMI->getDesc();
      47       34160 :       const MachineFunction *MF = MI->getParent()->getParent();
      48             :       const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>(
      49       34160 :                                         MF->getSubtarget().getInstrInfo());
      50             : 
      51             :       // Skip over one non-VFP / NEON instruction.
      52      102480 :       if (!LastMI->isBarrier() &&
      53       69167 :           !(TII.getSubtarget().hasMuxedUnits() && LastMI->mayLoadOrStore()) &&
      54       33747 :           (LastMCID.TSFlags & ARMII::DomainMask) == ARMII::DomainGeneral) {
      55        5620 :         MachineBasicBlock::iterator I = LastMI;
      56        8430 :         if (I != LastMI->getParent()->begin()) {
      57        2510 :           I = std::prev(I);
      58        2510 :           DefMI = &*I;
      59             :         }
      60             :       }
      61             : 
      62      102886 :       if (TII.isFpMLxInstruction(DefMI->getOpcode()) &&
      63        1141 :           (TII.canCauseFpMLxStall(MI->getOpcode()) ||
      64         329 :            hasRAWHazard(DefMI, MI, TII.getRegisterInfo()))) {
      65             :         // Try to schedule another instruction for the next 4 cycles.
      66         168 :         if (FpMLxStalls == 0)
      67          37 :           FpMLxStalls = 4;
      68             :         return Hazard;
      69             :       }
      70             :     }
      71             :   }
      72             : 
      73       72033 :   return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
      74             : }
      75             : 
      76       46342 : void ARMHazardRecognizer::Reset() {
      77       46342 :   LastMI = nullptr;
      78       46342 :   FpMLxStalls = 0;
      79       46342 :   ScoreboardHazardRecognizer::Reset();
      80       46342 : }
      81             : 
      82       46883 : void ARMHazardRecognizer::EmitInstruction(SUnit *SU) {
      83       46883 :   MachineInstr *MI = SU->getInstr();
      84       46883 :   if (!MI->isDebugValue()) {
      85       46883 :     LastMI = MI;
      86       46883 :     FpMLxStalls = 0;
      87             :   }
      88             : 
      89       46883 :   ScoreboardHazardRecognizer::EmitInstruction(SU);
      90       46883 : }
      91             : 
      92       64209 : void ARMHazardRecognizer::AdvanceCycle() {
      93       64209 :   if (FpMLxStalls && --FpMLxStalls == 0)
      94             :     // Stalled for 4 cycles but still can't schedule any other instructions.
      95          36 :     LastMI = nullptr;
      96       64209 :   ScoreboardHazardRecognizer::AdvanceCycle();
      97       64209 : }
      98             : 
      99           0 : void ARMHazardRecognizer::RecedeCycle() {
     100           0 :   llvm_unreachable("reverse ARM hazard checking unsupported");
     101             : }

Generated by: LCOV version 1.13