/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ARMHazardRecognizer.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI, |
20 | 1.27k | const TargetRegisterInfo &TRI) { |
21 | 1.27k | // FIXME: Detect integer instructions properly. |
22 | 1.27k | const MCInstrDesc &MCID = MI->getDesc(); |
23 | 1.27k | unsigned Domain = MCID.TSFlags & ARMII::DomainMask; |
24 | 1.27k | if (MI->mayStore()) |
25 | 7 | return false; |
26 | 1.26k | unsigned Opcode = MCID.getOpcode(); |
27 | 1.26k | if (Opcode == ARM::VMOVRS || 1.26k Opcode == ARM::VMOVRRD1.13k ) |
28 | 144 | return false; |
29 | 1.12k | if (1.12k (Domain & ARMII::DomainVFP) || 1.12k (Domain & ARMII::DomainNEON)21 ) |
30 | 1.12k | return MI->readsRegister(DefMI->getOperand(0).getReg(), &TRI); |
31 | 0 | return false; |
32 | 0 | } |
33 | | |
34 | | ScheduleHazardRecognizer::HazardType |
35 | 213k | ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { |
36 | 213k | assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead"); |
37 | 213k | |
38 | 213k | MachineInstr *MI = SU->getInstr(); |
39 | 213k | |
40 | 213k | if (!MI->isDebugValue()213k ) { |
41 | 213k | // Look for special VMLA / VMLS hazards. A VMUL / VADD / VSUB following |
42 | 213k | // a VMLA / VMLS will cause 4 cycle stall. |
43 | 213k | const MCInstrDesc &MCID = MI->getDesc(); |
44 | 213k | if (LastMI && 213k (MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainGeneral167k ) { |
45 | 49.1k | MachineInstr *DefMI = LastMI; |
46 | 49.1k | const MCInstrDesc &LastMCID = LastMI->getDesc(); |
47 | 49.1k | const MachineFunction *MF = MI->getParent()->getParent(); |
48 | 49.1k | const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>( |
49 | 49.1k | MF->getSubtarget().getInstrInfo()); |
50 | 49.1k | |
51 | 49.1k | // Skip over one non-VFP / NEON instruction. |
52 | 49.1k | if (!LastMI->isBarrier() && |
53 | 49.1k | !(TII.getSubtarget().hasMuxedUnits() && 49.1k LastMI->mayLoadOrStore()1.26k ) && |
54 | 49.1k | (LastMCID.TSFlags & ARMII::DomainMask) == ARMII::DomainGeneral48.7k ) { |
55 | 4.95k | MachineBasicBlock::iterator I = LastMI; |
56 | 4.95k | if (I != LastMI->getParent()->begin()4.95k ) { |
57 | 4.51k | I = std::prev(I); |
58 | 4.51k | DefMI = &*I; |
59 | 4.51k | } |
60 | 4.95k | } |
61 | 49.1k | |
62 | 49.1k | if (TII.isFpMLxInstruction(DefMI->getOpcode()) && |
63 | 1.52k | (TII.canCauseFpMLxStall(MI->getOpcode()) || |
64 | 49.1k | hasRAWHazard(DefMI, MI, TII.getRegisterInfo())1.27k )) { |
65 | 434 | // Try to schedule another instruction for the next 4 cycles. |
66 | 434 | if (FpMLxStalls == 0) |
67 | 98 | FpMLxStalls = 4; |
68 | 434 | return Hazard; |
69 | 434 | } |
70 | 213k | } |
71 | 213k | } |
72 | 213k | |
73 | 213k | return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); |
74 | 213k | } |
75 | | |
76 | 152k | void ARMHazardRecognizer::Reset() { |
77 | 152k | LastMI = nullptr; |
78 | 152k | FpMLxStalls = 0; |
79 | 152k | ScoreboardHazardRecognizer::Reset(); |
80 | 152k | } |
81 | | |
82 | 172k | void ARMHazardRecognizer::EmitInstruction(SUnit *SU) { |
83 | 172k | MachineInstr *MI = SU->getInstr(); |
84 | 172k | if (!MI->isDebugValue()172k ) { |
85 | 172k | LastMI = MI; |
86 | 172k | FpMLxStalls = 0; |
87 | 172k | } |
88 | 172k | |
89 | 172k | ScoreboardHazardRecognizer::EmitInstruction(SU); |
90 | 172k | } |
91 | | |
92 | 153k | void ARMHazardRecognizer::AdvanceCycle() { |
93 | 153k | if (FpMLxStalls && 153k --FpMLxStalls == 0363 ) |
94 | 153k | // Stalled for 4 cycles but still can't schedule any other instructions. |
95 | 90 | LastMI = nullptr; |
96 | 153k | ScoreboardHazardRecognizer::AdvanceCycle(); |
97 | 153k | } |
98 | | |
99 | 0 | void ARMHazardRecognizer::RecedeCycle() { |
100 | 0 | llvm_unreachable("reverse ARM hazard checking unsupported"); |
101 | 0 | } |