LLVM: lib/Target/ARM/ARMHazardRecognizer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
18
19using namespace llvm;
20
25
28
31 if (MI->mayStore())
32 return false;
33 unsigned Opcode = MCID.getOpcode();
34 if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
35 return false;
37 return MI->readsRegister(DefMI->getOperand(0).getReg(), &TRI);
38 return false;
39}
40
43 assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead");
44
46
47 if (->isDebugInstr()) {
48
49
53 const MCInstrDesc &LastMCID = LastMI->getDesc();
57
58
59 if (!LastMI->isBarrier() &&
60 !(TII.getSubtarget().hasMuxedUnits() && LastMI->mayLoadOrStore()) &&
63 if (I != LastMI->getParent()->begin()) {
66 }
67 }
68
69 if (TII.isFpMLxInstruction(DefMI->getOpcode()) &&
70 (TII.canCauseFpMLxStall(MI->getOpcode()) ||
72
73 if (FpMLxStalls == 0)
74 FpMLxStalls = 4;
76 }
77 }
78 }
80}
81
83 LastMI = nullptr;
84 FpMLxStalls = 0;
85}
86
89 if (->isDebugInstr()) {
90 LastMI = MI;
91 FpMLxStalls = 0;
92 }
93}
94
96 if (FpMLxStalls && --FpMLxStalls == 0)
97
98 LastMI = nullptr;
99}
100
104
105
106
109
110 uint64_t TSFlags = MI.getDesc().TSFlags;
112 unsigned IndexMode =
114
115
116
117
119 default:
120 return false;
122
123
124
125
126
127 BaseOp = &MI.getOperand(1);
129 ? 0
132 ? MI.getOperand(3).getImm()
133 : MI.getOperand(2).getImm();
134 return true;
136
137
138
139 BaseOp = &MI.getOperand(1);
140 Offset = MI.getOperand(2).getImm();
141 return true;
143
144 BaseOp = &MI.getOperand(2);
146 ? 0
149 ? MI.getOperand(4).getImm()
150 : MI.getOperand(3).getImm();
151 return true;
153
155
157
158 BaseOp = &MI.getOperand(1);
159 Offset = MI.getOperand(2).isImm() ? MI.getOperand(2).getImm() : 0;
160 return MI.getOperand(2).isImm();
161 }
162 return false;
163}
164
166 const ScheduleDAG *DAG, int64_t CPUBankMask, bool CPUAssumeITCMConflict)
167 : MF(DAG->MF), DL(DAG->MF.getDataLayout()),
169 : CPUBankMask),
172 : CPUAssumeITCMConflict) {
174}
175
177ARMBankConflictHazardRecognizer::CheckOffsets(unsigned O0, unsigned O1) {
178 return (((O0 ^ O1) & DataMask) != 0) ? NoHazard : Hazard;
179}
180
186
188 auto BaseVal0 = MO0->getValue();
189 auto BasePseudoVal0 = MO0->getPseudoValue();
190 int64_t Offset0 = 0;
191
192 if (!MO0->getSize().hasValue() || MO0->getSize().getValue() > 4)
194
195 bool SPvalid = false;
197 int64_t SPOffset0 = 0;
198
199 for (auto L1 : Accesses) {
200 auto MO1 = *L1->memoperands().begin();
201 auto BaseVal1 = MO1->getValue();
202 auto BasePseudoVal1 = MO1->getPseudoValue();
203 int64_t Offset1 = 0;
204
205
206 if (BaseVal0 && BaseVal1) {
207 const Value *Ptr0, *Ptr1;
210 if (Ptr0 == Ptr1 && Ptr0)
211 return CheckOffsets(Offset0, Offset1);
212 }
213
214 if (BasePseudoVal0 && BasePseudoVal1 &&
215 BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
217
220 Offset0 = MF.getFrameInfo().getObjectOffset(FS0->getFrameIndex());
221 Offset1 = MF.getFrameInfo().getObjectOffset(FS1->getFrameIndex());
222 return CheckOffsets(Offset0, Offset1);
223 }
224
225
226 if (BasePseudoVal0 && BasePseudoVal1 &&
227 BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
228 BasePseudoVal0->isConstantPool() && AssumeITCMBankConflict)
230
231
232
233
234
235
236 if (!SPvalid) {
237 if ((L0, SP, SPOffset0) || SP->getReg().id() != ARM::SP)
238 SP = nullptr;
239 SPvalid = true;
240 }
241 if (SP) {
242 int64_t SPOffset1;
245 return CheckOffsets(SPOffset0, SPOffset1);
246 }
247 }
248
250}
251
253
256 if (.mayLoad() || MI.mayStore() || MI.getNumMemOperands() != 1)
257 return;
258
259 auto MO = *MI.memoperands().begin();
262 return;
263 Accesses.push_back(&MI);
264}
265
267
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static bool getBaseOffset(const MachineInstr &MI, const MachineOperand *&BaseOp, int64_t &Offset)
Definition ARMHazardRecognizer.cpp:107
static cl::opt< int > DataBankMask("arm-data-bank-mask", cl::init(-1), cl::Hidden)
static cl::opt< bool > AssumeITCMConflict("arm-assume-itcm-bankconflict", cl::init(false), cl::Hidden)
static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI, const TargetRegisterInfo &TRI)
Definition ARMHazardRecognizer.cpp:26
Register const TargetRegisterInfo * TRI
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
Definition ARMHazardRecognizer.cpp:252
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
Definition ARMHazardRecognizer.cpp:266
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
Definition ARMHazardRecognizer.cpp:254
ARMBankConflictHazardRecognizer(const ScheduleDAG *DAG, int64_t DDM, bool ABC)
Definition ARMHazardRecognizer.cpp:165
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
Definition ARMHazardRecognizer.cpp:268
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
Definition ARMHazardRecognizer.cpp:182
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
Definition ARMHazardRecognizer.cpp:87
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
Definition ARMHazardRecognizer.cpp:101
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
Definition ARMHazardRecognizer.cpp:95
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
Definition ARMHazardRecognizer.cpp:82
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
Definition ARMHazardRecognizer.cpp:42
TypeSize getValue() const
Describe properties that are true of each instruction in the target description file.
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
unsigned getNumMemOperands() const
Return the number of memory operands.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
constexpr unsigned id() const
Scheduling unit. This is a node in the scheduling DAG.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
unsigned MaxLookAhead
MaxLookAhead - Indicate the number of cycles in the scoreboard state.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.