/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/TargetInstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- TargetInstrInfo.cpp - Target Instruction Information --------------===// |
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 | | // This file implements the TargetInstrInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/Target/TargetInstrInfo.h" |
15 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
16 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
17 | | #include "llvm/CodeGen/MachineMemOperand.h" |
18 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
19 | | #include "llvm/CodeGen/PseudoSourceValue.h" |
20 | | #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" |
21 | | #include "llvm/CodeGen/StackMaps.h" |
22 | | #include "llvm/CodeGen/TargetSchedule.h" |
23 | | #include "llvm/IR/DataLayout.h" |
24 | | #include "llvm/MC/MCAsmInfo.h" |
25 | | #include "llvm/MC/MCInstrItineraries.h" |
26 | | #include "llvm/Support/CommandLine.h" |
27 | | #include "llvm/Support/ErrorHandling.h" |
28 | | #include "llvm/Support/raw_ostream.h" |
29 | | #include "llvm/Target/TargetFrameLowering.h" |
30 | | #include "llvm/Target/TargetLowering.h" |
31 | | #include "llvm/Target/TargetMachine.h" |
32 | | #include "llvm/Target/TargetRegisterInfo.h" |
33 | | #include <cctype> |
34 | | |
35 | | using namespace llvm; |
36 | | |
37 | | static cl::opt<bool> DisableHazardRecognizer( |
38 | | "disable-sched-hazard", cl::Hidden, cl::init(false), |
39 | | cl::desc("Disable hazard detection during preRA scheduling")); |
40 | | |
41 | 28.0k | TargetInstrInfo::~TargetInstrInfo() { |
42 | 28.0k | } |
43 | | |
44 | | const TargetRegisterClass* |
45 | | TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum, |
46 | | const TargetRegisterInfo *TRI, |
47 | 63.7M | const MachineFunction &MF) const { |
48 | 63.7M | if (OpNum >= MCID.getNumOperands()) |
49 | 17.2k | return nullptr; |
50 | 63.7M | |
51 | 63.7M | short RegClass = MCID.OpInfo[OpNum].RegClass; |
52 | 63.7M | if (MCID.OpInfo[OpNum].isLookupPtrRegClass()) |
53 | 792k | return TRI->getPointerRegClass(MF, RegClass); |
54 | 62.9M | |
55 | 62.9M | // Instructions like INSERT_SUBREG do not have fixed register classes. |
56 | 62.9M | if (62.9M RegClass < 062.9M ) |
57 | 11.1M | return nullptr; |
58 | 51.8M | |
59 | 51.8M | // Otherwise just look it up normally. |
60 | 51.8M | return TRI->getRegClass(RegClass); |
61 | 51.8M | } |
62 | | |
63 | | /// insertNoop - Insert a noop into the instruction stream at the specified |
64 | | /// point. |
65 | | void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, |
66 | 0 | MachineBasicBlock::iterator MI) const { |
67 | 0 | llvm_unreachable("Target didn't implement insertNoop!"); |
68 | 0 | } |
69 | | |
70 | 57.1k | static bool isAsmComment(const char *Str, const MCAsmInfo &MAI) { |
71 | 57.1k | return strncmp(Str, MAI.getCommentString().data(), |
72 | 57.1k | MAI.getCommentString().size()) == 0; |
73 | 57.1k | } |
74 | | |
75 | | /// Measure the specified inline asm to determine an approximation of its |
76 | | /// length. |
77 | | /// Comments (which run till the next SeparatorString or newline) do not |
78 | | /// count as an instruction. |
79 | | /// Any other non-whitespace text is considered an instruction, with |
80 | | /// multiple instructions separated by SeparatorString or newlines. |
81 | | /// Variable-length instructions are not handled here; this function |
82 | | /// may be overloaded in the target code to do that. |
83 | | /// We implement a special case of the .space directive which takes only a |
84 | | /// single integer argument in base 10 that is the size in bytes. This is a |
85 | | /// restricted form of the GAS directive in that we only interpret |
86 | | /// simple--i.e. not a logical or arithmetic expression--size values without |
87 | | /// the optional fill value. This is primarily used for creating arbitrary |
88 | | /// sized inline asm blocks for testing purposes. |
89 | | unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, |
90 | 202k | const MCAsmInfo &MAI) const { |
91 | 202k | // Count the number of instructions in the asm. |
92 | 202k | bool AtInsnStart = true; |
93 | 202k | unsigned Length = 0; |
94 | 261k | for (; *Str261k ; ++Str58.3k ) { |
95 | 58.3k | if (*Str == '\n' || 58.3k strncmp(Str, MAI.getSeparatorString(), |
96 | 58.3k | strlen(MAI.getSeparatorString())) == 0) { |
97 | 1.17k | AtInsnStart = true; |
98 | 58.3k | } else if (57.1k isAsmComment(Str, MAI)57.1k ) { |
99 | 1.37k | // Stop counting as an instruction after a comment until the next |
100 | 1.37k | // separator. |
101 | 1.37k | AtInsnStart = false; |
102 | 1.37k | } |
103 | 58.3k | |
104 | 58.3k | if (AtInsnStart && 58.3k !std::isspace(static_cast<unsigned char>(*Str))6.18k ) { |
105 | 3.32k | unsigned AddLength = MAI.getMaxInstLength(); |
106 | 3.32k | if (strncmp(Str, ".space", 6) == 03.32k ) { |
107 | 93 | char *EStr; |
108 | 93 | int SpaceSize; |
109 | 93 | SpaceSize = strtol(Str + 6, &EStr, 10); |
110 | 93 | SpaceSize = SpaceSize < 0 ? 00 : SpaceSize93 ; |
111 | 93 | while (*EStr != '\n' && 93 std::isspace(static_cast<unsigned char>(*EStr))93 ) |
112 | 0 | ++EStr; |
113 | 93 | if (*EStr == '\0' || 93 *EStr == '\n'0 || |
114 | 0 | isAsmComment(EStr, MAI)) // Successfully parsed .space argument |
115 | 93 | AddLength = SpaceSize; |
116 | 93 | } |
117 | 3.32k | Length += AddLength; |
118 | 3.32k | AtInsnStart = false; |
119 | 3.32k | } |
120 | 58.3k | } |
121 | 202k | |
122 | 202k | return Length; |
123 | 202k | } |
124 | | |
125 | | /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything |
126 | | /// after it, replacing it with an unconditional branch to NewDest. |
127 | | void |
128 | | TargetInstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, |
129 | 222k | MachineBasicBlock *NewDest) const { |
130 | 222k | MachineBasicBlock *MBB = Tail->getParent(); |
131 | 222k | |
132 | 222k | // Remove all the old successors of MBB from the CFG. |
133 | 404k | while (!MBB->succ_empty()) |
134 | 181k | MBB->removeSuccessor(MBB->succ_begin()); |
135 | 222k | |
136 | 222k | // Save off the debug loc before erasing the instruction. |
137 | 222k | DebugLoc DL = Tail->getDebugLoc(); |
138 | 222k | |
139 | 222k | // Remove all the dead instructions from the end of MBB. |
140 | 222k | MBB->erase(Tail, MBB->end()); |
141 | 222k | |
142 | 222k | // If MBB isn't immediately before MBB, insert a branch to it. |
143 | 222k | if (++MachineFunction::iterator(MBB) != MachineFunction::iterator(NewDest)) |
144 | 212k | insertBranch(*MBB, NewDest, nullptr, SmallVector<MachineOperand, 0>(), DL); |
145 | 222k | MBB->addSuccessor(NewDest); |
146 | 222k | } |
147 | | |
148 | | MachineInstr *TargetInstrInfo::commuteInstructionImpl(MachineInstr &MI, |
149 | | bool NewMI, unsigned Idx1, |
150 | 385k | unsigned Idx2) const { |
151 | 385k | const MCInstrDesc &MCID = MI.getDesc(); |
152 | 385k | bool HasDef = MCID.getNumDefs(); |
153 | 385k | if (HasDef && 385k !MI.getOperand(0).isReg()357k ) |
154 | 385k | // No idea how to commute this instruction. Target should implement its own. |
155 | 0 | return nullptr; |
156 | 385k | |
157 | 385k | unsigned CommutableOpIdx1 = Idx1; (void)CommutableOpIdx1; |
158 | 385k | unsigned CommutableOpIdx2 = Idx2; (void)CommutableOpIdx2; |
159 | 385k | assert(findCommutedOpIndices(MI, CommutableOpIdx1, CommutableOpIdx2) && |
160 | 385k | CommutableOpIdx1 == Idx1 && CommutableOpIdx2 == Idx2 && |
161 | 385k | "TargetInstrInfo::CommuteInstructionImpl(): not commutable operands."); |
162 | 385k | assert(MI.getOperand(Idx1).isReg() && MI.getOperand(Idx2).isReg() && |
163 | 385k | "This only knows how to commute register operands so far"); |
164 | 385k | |
165 | 385k | unsigned Reg0 = HasDef ? MI.getOperand(0).getReg()357k : 027.9k ; |
166 | 385k | unsigned Reg1 = MI.getOperand(Idx1).getReg(); |
167 | 385k | unsigned Reg2 = MI.getOperand(Idx2).getReg(); |
168 | 385k | unsigned SubReg0 = HasDef ? MI.getOperand(0).getSubReg()357k : 027.9k ; |
169 | 385k | unsigned SubReg1 = MI.getOperand(Idx1).getSubReg(); |
170 | 385k | unsigned SubReg2 = MI.getOperand(Idx2).getSubReg(); |
171 | 385k | bool Reg1IsKill = MI.getOperand(Idx1).isKill(); |
172 | 385k | bool Reg2IsKill = MI.getOperand(Idx2).isKill(); |
173 | 385k | bool Reg1IsUndef = MI.getOperand(Idx1).isUndef(); |
174 | 385k | bool Reg2IsUndef = MI.getOperand(Idx2).isUndef(); |
175 | 385k | bool Reg1IsInternal = MI.getOperand(Idx1).isInternalRead(); |
176 | 385k | bool Reg2IsInternal = MI.getOperand(Idx2).isInternalRead(); |
177 | 385k | // If destination is tied to either of the commuted source register, then |
178 | 385k | // it must be updated. |
179 | 385k | if (HasDef && 385k Reg0 == Reg1357k && |
180 | 385k | MI.getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO) == 0811 ) { |
181 | 351 | Reg2IsKill = false; |
182 | 351 | Reg0 = Reg2; |
183 | 351 | SubReg0 = SubReg2; |
184 | 385k | } else if (384k HasDef && 384k Reg0 == Reg2356k && |
185 | 384k | MI.getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO) == 02.45k ) { |
186 | 0 | Reg1IsKill = false; |
187 | 0 | Reg0 = Reg1; |
188 | 0 | SubReg0 = SubReg1; |
189 | 0 | } |
190 | 385k | |
191 | 385k | MachineInstr *CommutedMI = nullptr; |
192 | 385k | if (NewMI385k ) { |
193 | 0 | // Create a new instruction. |
194 | 0 | MachineFunction &MF = *MI.getParent()->getParent(); |
195 | 0 | CommutedMI = MF.CloneMachineInstr(&MI); |
196 | 385k | } else { |
197 | 385k | CommutedMI = &MI; |
198 | 385k | } |
199 | 385k | |
200 | 385k | if (HasDef385k ) { |
201 | 357k | CommutedMI->getOperand(0).setReg(Reg0); |
202 | 357k | CommutedMI->getOperand(0).setSubReg(SubReg0); |
203 | 357k | } |
204 | 385k | CommutedMI->getOperand(Idx2).setReg(Reg1); |
205 | 385k | CommutedMI->getOperand(Idx1).setReg(Reg2); |
206 | 385k | CommutedMI->getOperand(Idx2).setSubReg(SubReg1); |
207 | 385k | CommutedMI->getOperand(Idx1).setSubReg(SubReg2); |
208 | 385k | CommutedMI->getOperand(Idx2).setIsKill(Reg1IsKill); |
209 | 385k | CommutedMI->getOperand(Idx1).setIsKill(Reg2IsKill); |
210 | 385k | CommutedMI->getOperand(Idx2).setIsUndef(Reg1IsUndef); |
211 | 385k | CommutedMI->getOperand(Idx1).setIsUndef(Reg2IsUndef); |
212 | 385k | CommutedMI->getOperand(Idx2).setIsInternalRead(Reg1IsInternal); |
213 | 385k | CommutedMI->getOperand(Idx1).setIsInternalRead(Reg2IsInternal); |
214 | 385k | return CommutedMI; |
215 | 385k | } |
216 | | |
217 | | MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr &MI, bool NewMI, |
218 | | unsigned OpIdx1, |
219 | 454k | unsigned OpIdx2) const { |
220 | 454k | // If OpIdx1 or OpIdx2 is not specified, then this method is free to choose |
221 | 454k | // any commutable operand, which is done in findCommutedOpIndices() method |
222 | 454k | // called below. |
223 | 454k | if ((OpIdx1 == CommuteAnyOperandIndex || 454k OpIdx2 == CommuteAnyOperandIndex34.6k ) && |
224 | 454k | !findCommutedOpIndices(MI, OpIdx1, OpIdx2)420k ) { |
225 | 1.58k | assert(MI.isCommutable() && |
226 | 1.58k | "Precondition violation: MI must be commutable."); |
227 | 1.58k | return nullptr; |
228 | 1.58k | } |
229 | 453k | return commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2); |
230 | 453k | } |
231 | | |
232 | | bool TargetInstrInfo::fixCommutedOpIndices(unsigned &ResultIdx1, |
233 | | unsigned &ResultIdx2, |
234 | | unsigned CommutableOpIdx1, |
235 | 489k | unsigned CommutableOpIdx2) { |
236 | 489k | if (ResultIdx1 == CommuteAnyOperandIndex && |
237 | 489k | ResultIdx2 == CommuteAnyOperandIndex428k ) { |
238 | 428k | ResultIdx1 = CommutableOpIdx1; |
239 | 428k | ResultIdx2 = CommutableOpIdx2; |
240 | 489k | } else if (60.4k ResultIdx1 == CommuteAnyOperandIndex60.4k ) { |
241 | 0 | if (ResultIdx2 == CommutableOpIdx1) |
242 | 0 | ResultIdx1 = CommutableOpIdx2; |
243 | 0 | else if (0 ResultIdx2 == CommutableOpIdx20 ) |
244 | 0 | ResultIdx1 = CommutableOpIdx1; |
245 | 0 | else |
246 | 0 | return false; |
247 | 60.4k | } else if (60.4k ResultIdx2 == CommuteAnyOperandIndex60.4k ) { |
248 | 13.9k | if (ResultIdx1 == CommutableOpIdx1) |
249 | 12.8k | ResultIdx2 = CommutableOpIdx2; |
250 | 1.14k | else if (1.14k ResultIdx1 == CommutableOpIdx21.14k ) |
251 | 1.07k | ResultIdx2 = CommutableOpIdx1; |
252 | 1.14k | else |
253 | 76 | return false; |
254 | 60.4k | } else |
255 | 60.4k | // Check that the result operand indices match the given commutable |
256 | 60.4k | // operand indices. |
257 | 46.5k | return (ResultIdx1 == CommutableOpIdx1 && 46.5k ResultIdx2 == CommutableOpIdx243.3k ) || |
258 | 60.4k | (ResultIdx1 == CommutableOpIdx2 && 5.58k ResultIdx2 == CommutableOpIdx1358 ); |
259 | 442k | |
260 | 442k | return true; |
261 | 442k | } |
262 | | |
263 | | bool TargetInstrInfo::findCommutedOpIndices(MachineInstr &MI, |
264 | | unsigned &SrcOpIdx1, |
265 | 261k | unsigned &SrcOpIdx2) const { |
266 | 261k | assert(!MI.isBundle() && |
267 | 261k | "TargetInstrInfo::findCommutedOpIndices() can't handle bundles"); |
268 | 261k | |
269 | 261k | const MCInstrDesc &MCID = MI.getDesc(); |
270 | 261k | if (!MCID.isCommutable()) |
271 | 9.59k | return false; |
272 | 251k | |
273 | 251k | // This assumes v0 = op v1, v2 and commuting would swap v1 and v2. If this |
274 | 251k | // is not true, then the target must implement this. |
275 | 251k | unsigned CommutableOpIdx1 = MCID.getNumDefs(); |
276 | 251k | unsigned CommutableOpIdx2 = CommutableOpIdx1 + 1; |
277 | 251k | if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, |
278 | 251k | CommutableOpIdx1, CommutableOpIdx2)) |
279 | 2.88k | return false; |
280 | 248k | |
281 | 248k | if (248k !MI.getOperand(SrcOpIdx1).isReg() || 248k !MI.getOperand(SrcOpIdx2).isReg()248k ) |
282 | 248k | // No idea. |
283 | 32 | return false; |
284 | 248k | return true; |
285 | 248k | } |
286 | | |
287 | 187M | bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { |
288 | 187M | if (!MI.isTerminator()187M ) return false93.1M ; |
289 | 94.2M | |
290 | 94.2M | // Conditional branch is a special case. |
291 | 94.2M | if (94.2M MI.isBranch() && 94.2M !MI.isBarrier()85.9M ) |
292 | 60.4M | return true; |
293 | 33.7M | if (33.7M !MI.isPredicable()33.7M ) |
294 | 33.7M | return true; |
295 | 13.1k | return !isPredicated(MI); |
296 | 13.1k | } |
297 | | |
298 | | bool TargetInstrInfo::PredicateInstruction( |
299 | 0 | MachineInstr &MI, ArrayRef<MachineOperand> Pred) const { |
300 | 0 | bool MadeChange = false; |
301 | 0 |
|
302 | 0 | assert(!MI.isBundle() && |
303 | 0 | "TargetInstrInfo::PredicateInstruction() can't handle bundles"); |
304 | 0 |
|
305 | 0 | const MCInstrDesc &MCID = MI.getDesc(); |
306 | 0 | if (!MI.isPredicable()) |
307 | 0 | return false; |
308 | 0 |
|
309 | 0 | for (unsigned j = 0, i = 0, e = MI.getNumOperands(); 0 i != e0 ; ++i0 ) { |
310 | 0 | if (MCID.OpInfo[i].isPredicate()0 ) { |
311 | 0 | MachineOperand &MO = MI.getOperand(i); |
312 | 0 | if (MO.isReg()0 ) { |
313 | 0 | MO.setReg(Pred[j].getReg()); |
314 | 0 | MadeChange = true; |
315 | 0 | } else if (0 MO.isImm()0 ) { |
316 | 0 | MO.setImm(Pred[j].getImm()); |
317 | 0 | MadeChange = true; |
318 | 0 | } else if (0 MO.isMBB()0 ) { |
319 | 0 | MO.setMBB(Pred[j].getMBB()); |
320 | 0 | MadeChange = true; |
321 | 0 | } |
322 | 0 | ++j; |
323 | 0 | } |
324 | 0 | } |
325 | 0 | return MadeChange; |
326 | 0 | } |
327 | | |
328 | | bool TargetInstrInfo::hasLoadFromStackSlot(const MachineInstr &MI, |
329 | | const MachineMemOperand *&MMO, |
330 | 9.59M | int &FrameIndex) const { |
331 | 9.59M | for (MachineInstr::mmo_iterator o = MI.memoperands_begin(), |
332 | 9.59M | oe = MI.memoperands_end(); |
333 | 11.3M | o != oe11.3M ; ++o1.75M ) { |
334 | 1.81M | if ((*o)->isLoad()1.81M ) { |
335 | 1.08M | if (const FixedStackPseudoSourceValue *Value = |
336 | 1.08M | dyn_cast_or_null<FixedStackPseudoSourceValue>( |
337 | 55.2k | (*o)->getPseudoValue())) { |
338 | 55.2k | FrameIndex = Value->getFrameIndex(); |
339 | 55.2k | MMO = *o; |
340 | 55.2k | return true; |
341 | 55.2k | } |
342 | 1.08M | } |
343 | 1.81M | } |
344 | 9.54M | return false; |
345 | 9.59M | } |
346 | | |
347 | | bool TargetInstrInfo::hasStoreToStackSlot(const MachineInstr &MI, |
348 | | const MachineMemOperand *&MMO, |
349 | 9.50M | int &FrameIndex) const { |
350 | 9.50M | for (MachineInstr::mmo_iterator o = MI.memoperands_begin(), |
351 | 9.50M | oe = MI.memoperands_end(); |
352 | 11.1M | o != oe11.1M ; ++o1.67M ) { |
353 | 1.71M | if ((*o)->isStore()1.71M ) { |
354 | 719k | if (const FixedStackPseudoSourceValue *Value = |
355 | 719k | dyn_cast_or_null<FixedStackPseudoSourceValue>( |
356 | 42.1k | (*o)->getPseudoValue())) { |
357 | 42.1k | FrameIndex = Value->getFrameIndex(); |
358 | 42.1k | MMO = *o; |
359 | 42.1k | return true; |
360 | 42.1k | } |
361 | 719k | } |
362 | 1.71M | } |
363 | 9.46M | return false; |
364 | 9.50M | } |
365 | | |
366 | | bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC, |
367 | | unsigned SubIdx, unsigned &Size, |
368 | | unsigned &Offset, |
369 | 115 | const MachineFunction &MF) const { |
370 | 115 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
371 | 115 | if (!SubIdx115 ) { |
372 | 113 | Size = TRI->getSpillSize(*RC); |
373 | 113 | Offset = 0; |
374 | 113 | return true; |
375 | 113 | } |
376 | 2 | unsigned BitSize = TRI->getSubRegIdxSize(SubIdx); |
377 | 2 | // Convert bit size to byte size to be consistent with |
378 | 2 | // MCRegisterClass::getSize(). |
379 | 2 | if (BitSize % 8) |
380 | 0 | return false; |
381 | 2 | |
382 | 2 | int BitOffset = TRI->getSubRegIdxOffset(SubIdx); |
383 | 2 | if (BitOffset < 0 || 2 BitOffset % 82 ) |
384 | 0 | return false; |
385 | 2 | |
386 | 2 | Size = BitSize /= 8; |
387 | 2 | Offset = (unsigned)BitOffset / 8; |
388 | 2 | |
389 | 2 | assert(TRI->getSpillSize(*RC) >= (Offset + Size) && "bad subregister range"); |
390 | 2 | |
391 | 2 | if (!MF.getDataLayout().isLittleEndian()2 ) { |
392 | 1 | Offset = TRI->getSpillSize(*RC) - (Offset + Size); |
393 | 1 | } |
394 | 115 | return true; |
395 | 115 | } |
396 | | |
397 | | void TargetInstrInfo::reMaterialize(MachineBasicBlock &MBB, |
398 | | MachineBasicBlock::iterator I, |
399 | | unsigned DestReg, unsigned SubIdx, |
400 | | const MachineInstr &Orig, |
401 | 904k | const TargetRegisterInfo &TRI) const { |
402 | 904k | MachineInstr *MI = MBB.getParent()->CloneMachineInstr(&Orig); |
403 | 904k | MI->substituteRegister(MI->getOperand(0).getReg(), DestReg, SubIdx, TRI); |
404 | 904k | MBB.insert(I, MI); |
405 | 904k | } |
406 | | |
407 | | bool TargetInstrInfo::produceSameValue(const MachineInstr &MI0, |
408 | | const MachineInstr &MI1, |
409 | 1.94M | const MachineRegisterInfo *MRI) const { |
410 | 1.94M | return MI0.isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs); |
411 | 1.94M | } |
412 | | |
413 | | MachineInstr &TargetInstrInfo::duplicate(MachineBasicBlock &MBB, |
414 | 1.07M | MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const { |
415 | 1.07M | assert(!Orig.isNotDuplicable() && "Instruction cannot be duplicated"); |
416 | 1.07M | MachineFunction &MF = *MBB.getParent(); |
417 | 1.07M | return MF.CloneMachineInstrBundle(MBB, InsertBefore, Orig); |
418 | 1.07M | } |
419 | | |
420 | | // If the COPY instruction in MI can be folded to a stack operation, return |
421 | | // the register class to use. |
422 | | static const TargetRegisterClass *canFoldCopy(const MachineInstr &MI, |
423 | 25.8k | unsigned FoldIdx) { |
424 | 25.8k | assert(MI.isCopy() && "MI must be a COPY instruction"); |
425 | 25.8k | if (MI.getNumOperands() != 2) |
426 | 0 | return nullptr; |
427 | 25.8k | assert(FoldIdx<2 && "FoldIdx refers no nonexistent operand"); |
428 | 25.8k | |
429 | 25.8k | const MachineOperand &FoldOp = MI.getOperand(FoldIdx); |
430 | 25.8k | const MachineOperand &LiveOp = MI.getOperand(1 - FoldIdx); |
431 | 25.8k | |
432 | 25.8k | if (FoldOp.getSubReg() || 25.8k LiveOp.getSubReg()20.7k ) |
433 | 5.15k | return nullptr; |
434 | 20.6k | |
435 | 20.6k | unsigned FoldReg = FoldOp.getReg(); |
436 | 20.6k | unsigned LiveReg = LiveOp.getReg(); |
437 | 20.6k | |
438 | 20.6k | assert(TargetRegisterInfo::isVirtualRegister(FoldReg) && |
439 | 20.6k | "Cannot fold physregs"); |
440 | 20.6k | |
441 | 20.6k | const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); |
442 | 20.6k | const TargetRegisterClass *RC = MRI.getRegClass(FoldReg); |
443 | 20.6k | |
444 | 20.6k | if (TargetRegisterInfo::isPhysicalRegister(LiveOp.getReg())) |
445 | 5.34k | return RC->contains(LiveOp.getReg()) ? 5.34k RC5.27k : nullptr69 ; |
446 | 15.3k | |
447 | 15.3k | if (15.3k RC->hasSubClassEq(MRI.getRegClass(LiveReg))15.3k ) |
448 | 14.9k | return RC; |
449 | 362 | |
450 | 362 | // FIXME: Allow folding when register classes are memory compatible. |
451 | 362 | return nullptr; |
452 | 362 | } |
453 | | |
454 | 0 | void TargetInstrInfo::getNoop(MCInst &NopInst) const { |
455 | 0 | llvm_unreachable("Not implemented"); |
456 | 0 | } |
457 | | |
458 | | static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI, |
459 | | ArrayRef<unsigned> Ops, int FrameIndex, |
460 | 233 | const TargetInstrInfo &TII) { |
461 | 233 | unsigned StartIdx = 0; |
462 | 233 | switch (MI.getOpcode()) { |
463 | 31 | case TargetOpcode::STACKMAP: { |
464 | 31 | // StackMapLiveValues are foldable |
465 | 31 | StartIdx = StackMapOpers(&MI).getVarIdx(); |
466 | 31 | break; |
467 | 233 | } |
468 | 179 | case TargetOpcode::PATCHPOINT: { |
469 | 179 | // For PatchPoint, the call args are not foldable (even if reported in the |
470 | 179 | // stackmap e.g. via anyregcc). |
471 | 179 | StartIdx = PatchPointOpers(&MI).getVarIdx(); |
472 | 179 | break; |
473 | 233 | } |
474 | 23 | case TargetOpcode::STATEPOINT: { |
475 | 23 | // For statepoints, fold deopt and gc arguments, but not call arguments. |
476 | 23 | StartIdx = StatepointOpers(&MI).getVarIdx(); |
477 | 23 | break; |
478 | 233 | } |
479 | 0 | default: |
480 | 0 | llvm_unreachable("unexpected stackmap opcode"); |
481 | 233 | } |
482 | 233 | |
483 | 233 | // Return false if any operands requested for folding are not foldable (not |
484 | 233 | // part of the stackmap's live values). |
485 | 233 | for (unsigned Op : Ops) 233 { |
486 | 233 | if (Op < StartIdx) |
487 | 118 | return nullptr; |
488 | 115 | } |
489 | 115 | |
490 | 115 | MachineInstr *NewMI = |
491 | 115 | MF.CreateMachineInstr(TII.get(MI.getOpcode()), MI.getDebugLoc(), true); |
492 | 115 | MachineInstrBuilder MIB(MF, NewMI); |
493 | 115 | |
494 | 115 | // No need to fold return, the meta data, and function arguments |
495 | 919 | for (unsigned i = 0; i < StartIdx919 ; ++i804 ) |
496 | 804 | MIB.add(MI.getOperand(i)); |
497 | 115 | |
498 | 4.25k | for (unsigned i = StartIdx; i < MI.getNumOperands()4.25k ; ++i4.13k ) { |
499 | 4.13k | MachineOperand &MO = MI.getOperand(i); |
500 | 4.13k | if (is_contained(Ops, i)4.13k ) { |
501 | 115 | unsigned SpillSize; |
502 | 115 | unsigned SpillOffset; |
503 | 115 | // Compute the spill slot size and offset. |
504 | 115 | const TargetRegisterClass *RC = |
505 | 115 | MF.getRegInfo().getRegClass(MO.getReg()); |
506 | 115 | bool Valid = |
507 | 115 | TII.getStackSlotRange(RC, MO.getSubReg(), SpillSize, SpillOffset, MF); |
508 | 115 | if (!Valid) |
509 | 0 | report_fatal_error("cannot spill patchpoint subregister operand"); |
510 | 115 | MIB.addImm(StackMaps::IndirectMemRefOp); |
511 | 115 | MIB.addImm(SpillSize); |
512 | 115 | MIB.addFrameIndex(FrameIndex); |
513 | 115 | MIB.addImm(SpillOffset); |
514 | 115 | } |
515 | 4.13k | else |
516 | 4.02k | MIB.add(MO); |
517 | 4.13k | } |
518 | 115 | return NewMI; |
519 | 233 | } |
520 | | |
521 | | /// foldMemoryOperand - Attempt to fold a load or store of the specified stack |
522 | | /// slot into the specified machine instruction for the specified operand(s). |
523 | | /// If this is possible, a new instruction is returned with the specified |
524 | | /// operand folded, otherwise NULL is returned. The client is responsible for |
525 | | /// removing the old instruction and adding the new one in the instruction |
526 | | /// stream. |
527 | | MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI, |
528 | | ArrayRef<unsigned> Ops, int FI, |
529 | 368k | LiveIntervals *LIS) const { |
530 | 368k | auto Flags = MachineMemOperand::MONone; |
531 | 743k | for (unsigned i = 0, e = Ops.size(); i != e743k ; ++i374k ) |
532 | 374k | if (374k MI.getOperand(Ops[i]).isDef()374k ) |
533 | 136k | Flags |= MachineMemOperand::MOStore; |
534 | 374k | else |
535 | 238k | Flags |= MachineMemOperand::MOLoad; |
536 | 368k | |
537 | 368k | MachineBasicBlock *MBB = MI.getParent(); |
538 | 368k | assert(MBB && "foldMemoryOperand needs an inserted instruction"); |
539 | 368k | MachineFunction &MF = *MBB->getParent(); |
540 | 368k | |
541 | 368k | // If we're not folding a load into a subreg, the size of the load is the |
542 | 368k | // size of the spill slot. But if we are, we need to figure out what the |
543 | 368k | // actual load size is. |
544 | 368k | int64_t MemSize = 0; |
545 | 368k | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
546 | 368k | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
547 | 368k | |
548 | 368k | if (Flags & MachineMemOperand::MOStore368k ) { |
549 | 136k | MemSize = MFI.getObjectSize(FI); |
550 | 368k | } else { |
551 | 237k | for (unsigned Idx : Ops) { |
552 | 237k | int64_t OpSize = MFI.getObjectSize(FI); |
553 | 237k | |
554 | 237k | if (auto SubReg237k = MI.getOperand(Idx).getSubReg()) { |
555 | 16.5k | unsigned SubRegSize = TRI->getSubRegIdxSize(SubReg); |
556 | 16.5k | if (SubRegSize > 0 && 16.5k !(SubRegSize % 8)16.5k ) |
557 | 16.5k | OpSize = SubRegSize / 8; |
558 | 16.5k | } |
559 | 237k | |
560 | 237k | MemSize = std::max(MemSize, OpSize); |
561 | 237k | } |
562 | 232k | } |
563 | 368k | |
564 | 368k | assert(MemSize && "Did not expect a zero-sized stack slot"); |
565 | 368k | |
566 | 368k | MachineInstr *NewMI = nullptr; |
567 | 368k | |
568 | 368k | if (MI.getOpcode() == TargetOpcode::STACKMAP || |
569 | 368k | MI.getOpcode() == TargetOpcode::PATCHPOINT || |
570 | 368k | MI.getOpcode() == TargetOpcode::STATEPOINT368k ) { |
571 | 118 | // Fold stackmap/patchpoint. |
572 | 118 | NewMI = foldPatchpoint(MF, MI, Ops, FI, *this); |
573 | 118 | if (NewMI) |
574 | 45 | MBB->insert(MI, NewMI); |
575 | 368k | } else { |
576 | 368k | // Ask the target to do the actual folding. |
577 | 368k | NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI, LIS); |
578 | 368k | } |
579 | 368k | |
580 | 368k | if (NewMI368k ) { |
581 | 215k | NewMI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
582 | 215k | // Add a memory operand, foldMemoryOperandImpl doesn't do that. |
583 | 215k | assert((!(Flags & MachineMemOperand::MOStore) || |
584 | 215k | NewMI->mayStore()) && |
585 | 215k | "Folded a def to a non-store!"); |
586 | 215k | assert((!(Flags & MachineMemOperand::MOLoad) || |
587 | 215k | NewMI->mayLoad()) && |
588 | 215k | "Folded a use to a non-load!"); |
589 | 215k | assert(MFI.getObjectOffset(FI) != -1); |
590 | 215k | MachineMemOperand *MMO = MF.getMachineMemOperand( |
591 | 215k | MachinePointerInfo::getFixedStack(MF, FI), Flags, MemSize, |
592 | 215k | MFI.getObjectAlignment(FI)); |
593 | 215k | NewMI->addMemOperand(MF, MMO); |
594 | 215k | |
595 | 215k | return NewMI; |
596 | 215k | } |
597 | 153k | |
598 | 153k | // Straight COPY may fold as load/store. |
599 | 153k | if (153k !MI.isCopy() || 153k Ops.size() != 125.8k ) |
600 | 127k | return nullptr; |
601 | 25.8k | |
602 | 25.8k | const TargetRegisterClass *RC = canFoldCopy(MI, Ops[0]); |
603 | 25.8k | if (!RC) |
604 | 5.58k | return nullptr; |
605 | 20.2k | |
606 | 20.2k | const MachineOperand &MO = MI.getOperand(1 - Ops[0]); |
607 | 20.2k | MachineBasicBlock::iterator Pos = MI; |
608 | 20.2k | |
609 | 20.2k | if (Flags == MachineMemOperand::MOStore) |
610 | 9.14k | storeRegToStackSlot(*MBB, Pos, MO.getReg(), MO.isKill(), FI, RC, TRI); |
611 | 20.2k | else |
612 | 11.1k | loadRegFromStackSlot(*MBB, Pos, MO.getReg(), FI, RC, TRI); |
613 | 368k | return &*--Pos; |
614 | 368k | } |
615 | | |
616 | | bool TargetInstrInfo::hasReassociableOperands( |
617 | 29.1k | const MachineInstr &Inst, const MachineBasicBlock *MBB) const { |
618 | 29.1k | const MachineOperand &Op1 = Inst.getOperand(1); |
619 | 29.1k | const MachineOperand &Op2 = Inst.getOperand(2); |
620 | 29.1k | const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); |
621 | 29.1k | |
622 | 29.1k | // We need virtual register definitions for the operands that we will |
623 | 29.1k | // reassociate. |
624 | 29.1k | MachineInstr *MI1 = nullptr; |
625 | 29.1k | MachineInstr *MI2 = nullptr; |
626 | 29.1k | if (Op1.isReg() && 29.1k TargetRegisterInfo::isVirtualRegister(Op1.getReg())29.1k ) |
627 | 29.1k | MI1 = MRI.getUniqueVRegDef(Op1.getReg()); |
628 | 29.1k | if (Op2.isReg() && 29.1k TargetRegisterInfo::isVirtualRegister(Op2.getReg())29.1k ) |
629 | 29.1k | MI2 = MRI.getUniqueVRegDef(Op2.getReg()); |
630 | 29.1k | |
631 | 29.1k | // And they need to be in the trace (otherwise, they won't have a depth). |
632 | 29.1k | return MI1 && MI229.1k && MI1->getParent() == MBB29.1k && MI2->getParent() == MBB27.8k ; |
633 | 29.1k | } |
634 | | |
635 | | bool TargetInstrInfo::hasReassociableSibling(const MachineInstr &Inst, |
636 | 24.4k | bool &Commuted) const { |
637 | 24.4k | const MachineBasicBlock *MBB = Inst.getParent(); |
638 | 24.4k | const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); |
639 | 24.4k | MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(1).getReg()); |
640 | 24.4k | MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg()); |
641 | 24.4k | unsigned AssocOpcode = Inst.getOpcode(); |
642 | 24.4k | |
643 | 24.4k | // If only one operand has the same opcode and it's the second source operand, |
644 | 24.4k | // the operands must be commuted. |
645 | 22.7k | Commuted = MI1->getOpcode() != AssocOpcode && MI2->getOpcode() == AssocOpcode; |
646 | 24.4k | if (Commuted) |
647 | 458 | std::swap(MI1, MI2); |
648 | 24.4k | |
649 | 24.4k | // 1. The previous instruction must be the same type as Inst. |
650 | 24.4k | // 2. The previous instruction must have virtual register definitions for its |
651 | 24.4k | // operands in the same basic block as Inst. |
652 | 24.4k | // 3. The previous instruction's result must only be used by Inst. |
653 | 24.4k | return MI1->getOpcode() == AssocOpcode && |
654 | 2.16k | hasReassociableOperands(*MI1, MBB) && |
655 | 2.09k | MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg()); |
656 | 24.4k | } |
657 | | |
658 | | // 1. The operation must be associative and commutative. |
659 | | // 2. The instruction must have virtual register definitions for its |
660 | | // operands in the same basic block. |
661 | | // 3. The instruction must have a reassociable sibling. |
662 | | bool TargetInstrInfo::isReassociationCandidate(const MachineInstr &Inst, |
663 | 36.2M | bool &Commuted) const { |
664 | 36.2M | return isAssociativeAndCommutative(Inst) && |
665 | 27.7k | hasReassociableOperands(Inst, Inst.getParent()) && |
666 | 24.4k | hasReassociableSibling(Inst, Commuted); |
667 | 36.2M | } |
668 | | |
669 | | // The concept of the reassociation pass is that these operations can benefit |
670 | | // from this kind of transformation: |
671 | | // |
672 | | // A = ? op ? |
673 | | // B = A op X (Prev) |
674 | | // C = B op Y (Root) |
675 | | // --> |
676 | | // A = ? op ? |
677 | | // B = X op Y |
678 | | // C = A op B |
679 | | // |
680 | | // breaking the dependency between A and B, allowing them to be executed in |
681 | | // parallel (or back-to-back in a pipeline) instead of depending on each other. |
682 | | |
683 | | // FIXME: This has the potential to be expensive (compile time) while not |
684 | | // improving the code at all. Some ways to limit the overhead: |
685 | | // 1. Track successful transforms; bail out if hit rate gets too low. |
686 | | // 2. Only enable at -O3 or some other non-default optimization level. |
687 | | // 3. Pre-screen pattern candidates here: if an operand of the previous |
688 | | // instruction is known to not increase the critical path, then don't match |
689 | | // that pattern. |
690 | | bool TargetInstrInfo::getMachineCombinerPatterns( |
691 | | MachineInstr &Root, |
692 | 36.2M | SmallVectorImpl<MachineCombinerPattern> &Patterns) const { |
693 | 36.2M | bool Commute; |
694 | 36.2M | if (isReassociationCandidate(Root, Commute)36.2M ) { |
695 | 1.17k | // We found a sequence of instructions that may be suitable for a |
696 | 1.17k | // reassociation of operands to increase ILP. Specify each commutation |
697 | 1.17k | // possibility for the Prev instruction in the sequence and let the |
698 | 1.17k | // machine combiner decide if changing the operands is worthwhile. |
699 | 1.17k | if (Commute1.17k ) { |
700 | 387 | Patterns.push_back(MachineCombinerPattern::REASSOC_AX_YB); |
701 | 387 | Patterns.push_back(MachineCombinerPattern::REASSOC_XA_YB); |
702 | 1.17k | } else { |
703 | 790 | Patterns.push_back(MachineCombinerPattern::REASSOC_AX_BY); |
704 | 790 | Patterns.push_back(MachineCombinerPattern::REASSOC_XA_BY); |
705 | 790 | } |
706 | 1.17k | return true; |
707 | 1.17k | } |
708 | 36.2M | |
709 | 36.2M | return false; |
710 | 36.2M | } |
711 | | /// Return true when a code sequence can improve loop throughput. |
712 | | bool |
713 | 410 | TargetInstrInfo::isThroughputPattern(MachineCombinerPattern Pattern) const { |
714 | 410 | return false; |
715 | 410 | } |
716 | | /// Attempt the reassociation transformation to reduce critical path length. |
717 | | /// See the above comments before getMachineCombinerPatterns(). |
718 | | void TargetInstrInfo::reassociateOps( |
719 | | MachineInstr &Root, MachineInstr &Prev, |
720 | | MachineCombinerPattern Pattern, |
721 | | SmallVectorImpl<MachineInstr *> &InsInstrs, |
722 | | SmallVectorImpl<MachineInstr *> &DelInstrs, |
723 | 1.93k | DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { |
724 | 1.93k | MachineFunction *MF = Root.getParent()->getParent(); |
725 | 1.93k | MachineRegisterInfo &MRI = MF->getRegInfo(); |
726 | 1.93k | const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); |
727 | 1.93k | const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); |
728 | 1.93k | const TargetRegisterClass *RC = Root.getRegClassConstraint(0, TII, TRI); |
729 | 1.93k | |
730 | 1.93k | // This array encodes the operand index for each parameter because the |
731 | 1.93k | // operands may be commuted. Each row corresponds to a pattern value, |
732 | 1.93k | // and each column specifies the index of A, B, X, Y. |
733 | 1.93k | unsigned OpIdx[4][4] = { |
734 | 1.93k | { 1, 1, 2, 2 }, |
735 | 1.93k | { 1, 2, 2, 1 }, |
736 | 1.93k | { 2, 1, 1, 2 }, |
737 | 1.93k | { 2, 2, 1, 1 } |
738 | 1.93k | }; |
739 | 1.93k | |
740 | 1.93k | int Row; |
741 | 1.93k | switch (Pattern) { |
742 | 790 | case MachineCombinerPattern::REASSOC_AX_BY: Row = 0; break; |
743 | 387 | case MachineCombinerPattern::REASSOC_AX_YB: Row = 1; break; |
744 | 451 | case MachineCombinerPattern::REASSOC_XA_BY: Row = 2; break; |
745 | 311 | case MachineCombinerPattern::REASSOC_XA_YB: Row = 3; break; |
746 | 0 | default: 0 llvm_unreachable0 ("unexpected MachineCombinerPattern"); |
747 | 1.93k | } |
748 | 1.93k | |
749 | 1.93k | MachineOperand &OpA = Prev.getOperand(OpIdx[Row][0]); |
750 | 1.93k | MachineOperand &OpB = Root.getOperand(OpIdx[Row][1]); |
751 | 1.93k | MachineOperand &OpX = Prev.getOperand(OpIdx[Row][2]); |
752 | 1.93k | MachineOperand &OpY = Root.getOperand(OpIdx[Row][3]); |
753 | 1.93k | MachineOperand &OpC = Root.getOperand(0); |
754 | 1.93k | |
755 | 1.93k | unsigned RegA = OpA.getReg(); |
756 | 1.93k | unsigned RegB = OpB.getReg(); |
757 | 1.93k | unsigned RegX = OpX.getReg(); |
758 | 1.93k | unsigned RegY = OpY.getReg(); |
759 | 1.93k | unsigned RegC = OpC.getReg(); |
760 | 1.93k | |
761 | 1.93k | if (TargetRegisterInfo::isVirtualRegister(RegA)) |
762 | 1.93k | MRI.constrainRegClass(RegA, RC); |
763 | 1.93k | if (TargetRegisterInfo::isVirtualRegister(RegB)) |
764 | 1.93k | MRI.constrainRegClass(RegB, RC); |
765 | 1.93k | if (TargetRegisterInfo::isVirtualRegister(RegX)) |
766 | 1.93k | MRI.constrainRegClass(RegX, RC); |
767 | 1.93k | if (TargetRegisterInfo::isVirtualRegister(RegY)) |
768 | 1.93k | MRI.constrainRegClass(RegY, RC); |
769 | 1.93k | if (TargetRegisterInfo::isVirtualRegister(RegC)) |
770 | 1.93k | MRI.constrainRegClass(RegC, RC); |
771 | 1.93k | |
772 | 1.93k | // Create a new virtual register for the result of (X op Y) instead of |
773 | 1.93k | // recycling RegB because the MachineCombiner's computation of the critical |
774 | 1.93k | // path requires a new register definition rather than an existing one. |
775 | 1.93k | unsigned NewVR = MRI.createVirtualRegister(RC); |
776 | 1.93k | InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); |
777 | 1.93k | |
778 | 1.93k | unsigned Opcode = Root.getOpcode(); |
779 | 1.93k | bool KillA = OpA.isKill(); |
780 | 1.93k | bool KillX = OpX.isKill(); |
781 | 1.93k | bool KillY = OpY.isKill(); |
782 | 1.93k | |
783 | 1.93k | // Create new instructions for insertion. |
784 | 1.93k | MachineInstrBuilder MIB1 = |
785 | 1.93k | BuildMI(*MF, Prev.getDebugLoc(), TII->get(Opcode), NewVR) |
786 | 1.93k | .addReg(RegX, getKillRegState(KillX)) |
787 | 1.93k | .addReg(RegY, getKillRegState(KillY)); |
788 | 1.93k | MachineInstrBuilder MIB2 = |
789 | 1.93k | BuildMI(*MF, Root.getDebugLoc(), TII->get(Opcode), RegC) |
790 | 1.93k | .addReg(RegA, getKillRegState(KillA)) |
791 | 1.93k | .addReg(NewVR, getKillRegState(true)); |
792 | 1.93k | |
793 | 1.93k | setSpecialOperandAttr(Root, Prev, *MIB1, *MIB2); |
794 | 1.93k | |
795 | 1.93k | // Record new instructions for insertion and old instructions for deletion. |
796 | 1.93k | InsInstrs.push_back(MIB1); |
797 | 1.93k | InsInstrs.push_back(MIB2); |
798 | 1.93k | DelInstrs.push_back(&Prev); |
799 | 1.93k | DelInstrs.push_back(&Root); |
800 | 1.93k | } |
801 | | |
802 | | void TargetInstrInfo::genAlternativeCodeSequence( |
803 | | MachineInstr &Root, MachineCombinerPattern Pattern, |
804 | | SmallVectorImpl<MachineInstr *> &InsInstrs, |
805 | | SmallVectorImpl<MachineInstr *> &DelInstrs, |
806 | 1.93k | DenseMap<unsigned, unsigned> &InstIdxForVirtReg) const { |
807 | 1.93k | MachineRegisterInfo &MRI = Root.getParent()->getParent()->getRegInfo(); |
808 | 1.93k | |
809 | 1.93k | // Select the previous instruction in the sequence based on the input pattern. |
810 | 1.93k | MachineInstr *Prev = nullptr; |
811 | 1.93k | switch (Pattern) { |
812 | 1.24k | case MachineCombinerPattern::REASSOC_AX_BY: |
813 | 1.24k | case MachineCombinerPattern::REASSOC_XA_BY: |
814 | 1.24k | Prev = MRI.getUniqueVRegDef(Root.getOperand(1).getReg()); |
815 | 1.24k | break; |
816 | 698 | case MachineCombinerPattern::REASSOC_AX_YB: |
817 | 698 | case MachineCombinerPattern::REASSOC_XA_YB: |
818 | 698 | Prev = MRI.getUniqueVRegDef(Root.getOperand(2).getReg()); |
819 | 698 | break; |
820 | 0 | default: |
821 | 0 | break; |
822 | 1.93k | } |
823 | 1.93k | |
824 | 1.93k | assert(Prev && "Unknown pattern for machine combiner"); |
825 | 1.93k | |
826 | 1.93k | reassociateOps(Root, *Prev, Pattern, InsInstrs, DelInstrs, InstIdxForVirtReg); |
827 | 1.93k | } |
828 | | |
829 | | /// foldMemoryOperand - Same as the previous version except it allows folding |
830 | | /// of any load and store from / to any address, not just from a specific |
831 | | /// stack slot. |
832 | | MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI, |
833 | | ArrayRef<unsigned> Ops, |
834 | | MachineInstr &LoadMI, |
835 | 33.7k | LiveIntervals *LIS) const { |
836 | 33.7k | assert(LoadMI.canFoldAsLoad() && "LoadMI isn't foldable!"); |
837 | | #ifndef NDEBUG |
838 | | for (unsigned i = 0, e = Ops.size(); i != e; ++i) |
839 | | assert(MI.getOperand(Ops[i]).isUse() && "Folding load into def!"); |
840 | | #endif |
841 | | MachineBasicBlock &MBB = *MI.getParent(); |
842 | 33.7k | MachineFunction &MF = *MBB.getParent(); |
843 | 33.7k | |
844 | 33.7k | // Ask the target to do the actual folding. |
845 | 33.7k | MachineInstr *NewMI = nullptr; |
846 | 33.7k | int FrameIndex = 0; |
847 | 33.7k | |
848 | 33.7k | if ((MI.getOpcode() == TargetOpcode::STACKMAP || |
849 | 33.6k | MI.getOpcode() == TargetOpcode::PATCHPOINT || |
850 | 33.6k | MI.getOpcode() == TargetOpcode::STATEPOINT) && |
851 | 33.7k | isLoadFromStackSlot(LoadMI, FrameIndex)115 ) { |
852 | 115 | // Fold stackmap/patchpoint. |
853 | 115 | NewMI = foldPatchpoint(MF, MI, Ops, FrameIndex, *this); |
854 | 115 | if (NewMI) |
855 | 70 | NewMI = &*MBB.insert(MI, NewMI); |
856 | 33.7k | } else { |
857 | 33.5k | // Ask the target to do the actual folding. |
858 | 33.5k | NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, LoadMI, LIS); |
859 | 33.5k | } |
860 | 33.7k | |
861 | 33.7k | if (!NewMI33.7k ) return nullptr29.8k ; |
862 | 3.89k | |
863 | 3.89k | // Copy the memoperands from the load to the folded instruction. |
864 | 3.89k | if (3.89k MI.memoperands_empty()3.89k ) { |
865 | 3.83k | NewMI->setMemRefs(LoadMI.memoperands_begin(), LoadMI.memoperands_end()); |
866 | 3.83k | } |
867 | 63 | else { |
868 | 63 | // Handle the rare case of folding multiple loads. |
869 | 63 | NewMI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |
870 | 63 | for (MachineInstr::mmo_iterator I = LoadMI.memoperands_begin(), |
871 | 63 | E = LoadMI.memoperands_end(); |
872 | 126 | I != E126 ; ++I63 ) { |
873 | 63 | NewMI->addMemOperand(MF, *I); |
874 | 63 | } |
875 | 63 | } |
876 | 33.7k | return NewMI; |
877 | 33.7k | } |
878 | | |
879 | | bool TargetInstrInfo::isReallyTriviallyReMaterializableGeneric( |
880 | 4.76M | const MachineInstr &MI, AliasAnalysis *AA) const { |
881 | 4.76M | const MachineFunction &MF = *MI.getParent()->getParent(); |
882 | 4.76M | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
883 | 4.76M | |
884 | 4.76M | // Remat clients assume operand 0 is the defined register. |
885 | 4.76M | if (!MI.getNumOperands() || 4.76M !MI.getOperand(0).isReg()4.76M ) |
886 | 0 | return false; |
887 | 4.76M | unsigned DefReg = MI.getOperand(0).getReg(); |
888 | 4.76M | |
889 | 4.76M | // A sub-register definition can only be rematerialized if the instruction |
890 | 4.76M | // doesn't read the other parts of the register. Otherwise it is really a |
891 | 4.76M | // read-modify-write operation on the full virtual register which cannot be |
892 | 4.76M | // moved safely. |
893 | 4.76M | if (TargetRegisterInfo::isVirtualRegister(DefReg) && |
894 | 4.76M | MI.getOperand(0).getSubReg()4.76M && MI.readsVirtualRegister(DefReg)387k ) |
895 | 17.5k | return false; |
896 | 4.74M | |
897 | 4.74M | // A load from a fixed stack slot can be rematerialized. This may be |
898 | 4.74M | // redundant with subsequent checks, but it's target-independent, |
899 | 4.74M | // simple, and a common case. |
900 | 4.74M | int FrameIdx = 0; |
901 | 4.74M | if (isLoadFromStackSlot(MI, FrameIdx) && |
902 | 28.5k | MF.getFrameInfo().isImmutableObjectIndex(FrameIdx)) |
903 | 22.0k | return true; |
904 | 4.72M | |
905 | 4.72M | // Avoid instructions obviously unsafe for remat. |
906 | 4.72M | if (4.72M MI.isNotDuplicable() || 4.72M MI.mayStore()4.72M || MI.hasUnmodeledSideEffects()4.72M ) |
907 | 21 | return false; |
908 | 4.72M | |
909 | 4.72M | // Don't remat inline asm. We have no idea how expensive it is |
910 | 4.72M | // even if it's side effect free. |
911 | 4.72M | if (4.72M MI.isInlineAsm()4.72M ) |
912 | 0 | return false; |
913 | 4.72M | |
914 | 4.72M | // Avoid instructions which load from potentially varying memory. |
915 | 4.72M | if (4.72M MI.mayLoad() && 4.72M !MI.isDereferenceableInvariantLoad(AA)46.6k ) |
916 | 38.4k | return false; |
917 | 4.68M | |
918 | 4.68M | // If any of the registers accessed are non-constant, conservatively assume |
919 | 4.68M | // the instruction is not rematerializable. |
920 | 14.2M | for (unsigned i = 0, e = MI.getNumOperands(); 4.68M i != e14.2M ; ++i9.58M ) { |
921 | 11.0M | const MachineOperand &MO = MI.getOperand(i); |
922 | 11.0M | if (!MO.isReg()11.0M ) continue4.79M ; |
923 | 6.28M | unsigned Reg = MO.getReg(); |
924 | 6.28M | if (Reg == 0) |
925 | 85.9k | continue; |
926 | 6.19M | |
927 | 6.19M | // Check for a well-behaved physical register. |
928 | 6.19M | if (6.19M TargetRegisterInfo::isPhysicalRegister(Reg)6.19M ) { |
929 | 17.3k | if (MO.isUse()17.3k ) { |
930 | 17.3k | // If the physreg has no defs anywhere, it's just an ambient register |
931 | 17.3k | // and we can freely move its uses. Alternatively, if it's allocatable, |
932 | 17.3k | // it could get allocated to something with a def during allocation. |
933 | 17.3k | if (!MRI.isConstantPhysReg(Reg)) |
934 | 1.48k | return false; |
935 | 0 | } else { |
936 | 0 | // A physreg def. We can't remat it. |
937 | 0 | return false; |
938 | 0 | } |
939 | 15.9k | continue; |
940 | 15.9k | } |
941 | 6.17M | |
942 | 6.17M | // Only allow one virtual-register def. There may be multiple defs of the |
943 | 6.17M | // same virtual register, though. |
944 | 6.17M | if (6.17M MO.isDef() && 6.17M Reg != DefReg4.68M ) |
945 | 0 | return false; |
946 | 6.17M | |
947 | 6.17M | // Don't allow any virtual-register uses. Rematting an instruction with |
948 | 6.17M | // virtual register uses would length the live ranges of the uses, which |
949 | 6.17M | // is not necessarily a good idea, certainly not "trivial". |
950 | 6.17M | if (6.17M MO.isUse()6.17M ) |
951 | 1.49M | return false; |
952 | 11.0M | } |
953 | 4.68M | |
954 | 4.68M | // Everything checked out. |
955 | 3.18M | return true; |
956 | 4.76M | } |
957 | | |
958 | 1.80k | int TargetInstrInfo::getSPAdjust(const MachineInstr &MI) const { |
959 | 1.80k | const MachineFunction *MF = MI.getParent()->getParent(); |
960 | 1.80k | const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); |
961 | 1.80k | bool StackGrowsDown = |
962 | 1.80k | TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; |
963 | 1.80k | |
964 | 1.80k | unsigned FrameSetupOpcode = getCallFrameSetupOpcode(); |
965 | 1.80k | unsigned FrameDestroyOpcode = getCallFrameDestroyOpcode(); |
966 | 1.80k | |
967 | 1.80k | if (!isFrameInstr(MI)) |
968 | 1.71k | return 0; |
969 | 88 | |
970 | 88 | int SPAdj = TFI->alignSPAdjust(getFrameSize(MI)); |
971 | 88 | |
972 | 88 | if ((!StackGrowsDown && 88 MI.getOpcode() == FrameSetupOpcode0 ) || |
973 | 88 | (StackGrowsDown && 88 MI.getOpcode() == FrameDestroyOpcode88 )) |
974 | 44 | SPAdj = -SPAdj; |
975 | 1.80k | |
976 | 1.80k | return SPAdj; |
977 | 1.80k | } |
978 | | |
979 | | /// isSchedulingBoundary - Test if the given instruction should be |
980 | | /// considered a scheduling boundary. This primarily includes labels |
981 | | /// and terminators. |
982 | | bool TargetInstrInfo::isSchedulingBoundary(const MachineInstr &MI, |
983 | | const MachineBasicBlock *MBB, |
984 | 28.9M | const MachineFunction &MF) const { |
985 | 28.9M | // Terminators and labels can't be scheduled around. |
986 | 28.9M | if (MI.isTerminator() || 28.9M MI.isPosition()24.3M ) |
987 | 4.65M | return true; |
988 | 24.2M | |
989 | 24.2M | // Don't attempt to schedule around any instruction that defines |
990 | 24.2M | // a stack-oriented pointer, as it's unlikely to be profitable. This |
991 | 24.2M | // saves compile time, because it doesn't require every single |
992 | 24.2M | // stack slot reference to depend on the instruction that does the |
993 | 24.2M | // modification. |
994 | 24.2M | const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering(); |
995 | 24.2M | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
996 | 24.2M | return MI.modifiesRegister(TLI.getStackPointerRegisterToSaveRestore(), TRI); |
997 | 24.2M | } |
998 | | |
999 | | // Provide a global flag for disabling the PreRA hazard recognizer that targets |
1000 | | // may choose to honor. |
1001 | 34.7k | bool TargetInstrInfo::usePreRAHazardRecognizer() const { |
1002 | 34.7k | return !DisableHazardRecognizer; |
1003 | 34.7k | } |
1004 | | |
1005 | | // Default implementation of CreateTargetRAHazardRecognizer. |
1006 | | ScheduleHazardRecognizer *TargetInstrInfo:: |
1007 | | CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, |
1008 | 17.6k | const ScheduleDAG *DAG) const { |
1009 | 17.6k | // Dummy hazard recognizer allows all instructions to issue. |
1010 | 17.6k | return new ScheduleHazardRecognizer(); |
1011 | 17.6k | } |
1012 | | |
1013 | | // Default implementation of CreateTargetMIHazardRecognizer. |
1014 | | ScheduleHazardRecognizer *TargetInstrInfo:: |
1015 | | CreateTargetMIHazardRecognizer(const InstrItineraryData *II, |
1016 | 1.04M | const ScheduleDAG *DAG) const { |
1017 | 1.04M | return (ScheduleHazardRecognizer *) |
1018 | 1.04M | new ScoreboardHazardRecognizer(II, DAG, "misched"); |
1019 | 1.04M | } |
1020 | | |
1021 | | // Default implementation of CreateTargetPostRAHazardRecognizer. |
1022 | | ScheduleHazardRecognizer *TargetInstrInfo:: |
1023 | | CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, |
1024 | 3.79k | const ScheduleDAG *DAG) const { |
1025 | 3.79k | return (ScheduleHazardRecognizer *) |
1026 | 3.79k | new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched"); |
1027 | 3.79k | } |
1028 | | |
1029 | | //===----------------------------------------------------------------------===// |
1030 | | // SelectionDAG latency interface. |
1031 | | //===----------------------------------------------------------------------===// |
1032 | | |
1033 | | int |
1034 | | TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, |
1035 | | SDNode *DefNode, unsigned DefIdx, |
1036 | 109k | SDNode *UseNode, unsigned UseIdx) const { |
1037 | 109k | if (!ItinData || 109k ItinData->isEmpty()107k ) |
1038 | 96.9k | return -1; |
1039 | 12.9k | |
1040 | 12.9k | if (12.9k !DefNode->isMachineOpcode()12.9k ) |
1041 | 4.07k | return -1; |
1042 | 8.84k | |
1043 | 8.84k | unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass(); |
1044 | 8.84k | if (!UseNode->isMachineOpcode()) |
1045 | 2.63k | return ItinData->getOperandCycle(DefClass, DefIdx); |
1046 | 6.20k | unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass(); |
1047 | 6.20k | return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); |
1048 | 6.20k | } |
1049 | | |
1050 | | int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, |
1051 | 13.2k | SDNode *N) const { |
1052 | 13.2k | if (!ItinData || 13.2k ItinData->isEmpty()13.2k ) |
1053 | 0 | return 1; |
1054 | 13.2k | |
1055 | 13.2k | if (13.2k !N->isMachineOpcode()13.2k ) |
1056 | 0 | return 1; |
1057 | 13.2k | |
1058 | 13.2k | return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass()); |
1059 | 13.2k | } |
1060 | | |
1061 | | //===----------------------------------------------------------------------===// |
1062 | | // MachineInstr latency interface. |
1063 | | //===----------------------------------------------------------------------===// |
1064 | | |
1065 | | unsigned TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, |
1066 | 0 | const MachineInstr &MI) const { |
1067 | 0 | if (!ItinData || 0 ItinData->isEmpty()0 ) |
1068 | 0 | return 1; |
1069 | 0 |
|
1070 | 0 | unsigned Class = MI.getDesc().getSchedClass(); |
1071 | 0 | int UOps = ItinData->Itineraries[Class].NumMicroOps; |
1072 | 0 | if (UOps >= 0) |
1073 | 0 | return UOps; |
1074 | 0 |
|
1075 | 0 | // The # of u-ops is dynamically determined. The specific target should |
1076 | 0 | // override this function to return the right number. |
1077 | 0 | return 1; |
1078 | 0 | } |
1079 | | |
1080 | | /// Return the default expected latency for a def based on it's opcode. |
1081 | | unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel &SchedModel, |
1082 | 4.09M | const MachineInstr &DefMI) const { |
1083 | 4.09M | if (DefMI.isTransient()) |
1084 | 557k | return 0; |
1085 | 3.53M | if (3.53M DefMI.mayLoad()3.53M ) |
1086 | 256k | return SchedModel.LoadLatency; |
1087 | 3.27M | if (3.27M isHighLatencyDef(DefMI.getOpcode())3.27M ) |
1088 | 1.03k | return SchedModel.HighLatency; |
1089 | 3.27M | return 1; |
1090 | 3.27M | } |
1091 | | |
1092 | 24.6k | unsigned TargetInstrInfo::getPredicationCost(const MachineInstr &) const { |
1093 | 24.6k | return 0; |
1094 | 24.6k | } |
1095 | | |
1096 | | unsigned TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, |
1097 | | const MachineInstr &MI, |
1098 | 25.0k | unsigned *PredCost) const { |
1099 | 25.0k | // Default to one cycle for no itinerary. However, an "empty" itinerary may |
1100 | 25.0k | // still have a MinLatency property, which getStageLatency checks. |
1101 | 25.0k | if (!ItinData) |
1102 | 546 | return MI.mayLoad() ? 546 233 : 1513 ; |
1103 | 24.5k | |
1104 | 24.5k | return ItinData->getStageLatency(MI.getDesc().getSchedClass()); |
1105 | 24.5k | } |
1106 | | |
1107 | | bool TargetInstrInfo::hasLowDefLatency(const TargetSchedModel &SchedModel, |
1108 | | const MachineInstr &DefMI, |
1109 | 340k | unsigned DefIdx) const { |
1110 | 340k | const InstrItineraryData *ItinData = SchedModel.getInstrItineraries(); |
1111 | 340k | if (!ItinData || 340k ItinData->isEmpty()90 ) |
1112 | 340k | return false; |
1113 | 90 | |
1114 | 90 | unsigned DefClass = DefMI.getDesc().getSchedClass(); |
1115 | 90 | int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx); |
1116 | 44 | return (DefCycle != -1 && DefCycle <= 1); |
1117 | 340k | } |
1118 | | |
1119 | | /// Both DefMI and UseMI must be valid. By default, call directly to the |
1120 | | /// itinerary. This may be overriden by the target. |
1121 | | int TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, |
1122 | | const MachineInstr &DefMI, |
1123 | | unsigned DefIdx, |
1124 | | const MachineInstr &UseMI, |
1125 | 247k | unsigned UseIdx) const { |
1126 | 247k | unsigned DefClass = DefMI.getDesc().getSchedClass(); |
1127 | 247k | unsigned UseClass = UseMI.getDesc().getSchedClass(); |
1128 | 247k | return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); |
1129 | 247k | } |
1130 | | |
1131 | | /// If we can determine the operand latency from the def only, without itinerary |
1132 | | /// lookup, do so. Otherwise return -1. |
1133 | | int TargetInstrInfo::computeDefOperandLatency( |
1134 | 0 | const InstrItineraryData *ItinData, const MachineInstr &DefMI) const { |
1135 | 0 |
|
1136 | 0 | // Let the target hook getInstrLatency handle missing itineraries. |
1137 | 0 | if (!ItinData) |
1138 | 0 | return getInstrLatency(ItinData, DefMI); |
1139 | 0 |
|
1140 | 0 | if(0 ItinData->isEmpty()0 ) |
1141 | 0 | return defaultDefLatency(ItinData->SchedModel, DefMI); |
1142 | 0 |
|
1143 | 0 | // ...operand lookup required |
1144 | 0 | return -1; |
1145 | 0 | } |
1146 | | |
1147 | | bool TargetInstrInfo::getRegSequenceInputs( |
1148 | | const MachineInstr &MI, unsigned DefIdx, |
1149 | 169k | SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const { |
1150 | 169k | assert((MI.isRegSequence() || |
1151 | 169k | MI.isRegSequenceLike()) && "Instruction do not have the proper type"); |
1152 | 169k | |
1153 | 169k | if (!MI.isRegSequence()) |
1154 | 2.25k | return getRegSequenceLikeInputs(MI, DefIdx, InputRegs); |
1155 | 167k | |
1156 | 167k | // We are looking at: |
1157 | 167k | // Def = REG_SEQUENCE v0, sub0, v1, sub1, ... |
1158 | 169k | assert(DefIdx == 0 && "REG_SEQUENCE only has one def"); |
1159 | 687k | for (unsigned OpIdx = 1, EndOpIdx = MI.getNumOperands(); OpIdx != EndOpIdx; |
1160 | 519k | OpIdx += 2519k ) { |
1161 | 519k | const MachineOperand &MOReg = MI.getOperand(OpIdx); |
1162 | 519k | const MachineOperand &MOSubIdx = MI.getOperand(OpIdx + 1); |
1163 | 519k | assert(MOSubIdx.isImm() && |
1164 | 519k | "One of the subindex of the reg_sequence is not an immediate"); |
1165 | 519k | // Record Reg:SubReg, SubIdx. |
1166 | 519k | InputRegs.push_back(RegSubRegPairAndIdx(MOReg.getReg(), MOReg.getSubReg(), |
1167 | 519k | (unsigned)MOSubIdx.getImm())); |
1168 | 519k | } |
1169 | 169k | return true; |
1170 | 169k | } |
1171 | | |
1172 | | bool TargetInstrInfo::getExtractSubregInputs( |
1173 | | const MachineInstr &MI, unsigned DefIdx, |
1174 | 3.59k | RegSubRegPairAndIdx &InputReg) const { |
1175 | 3.59k | assert((MI.isExtractSubreg() || |
1176 | 3.59k | MI.isExtractSubregLike()) && "Instruction do not have the proper type"); |
1177 | 3.59k | |
1178 | 3.59k | if (!MI.isExtractSubreg()) |
1179 | 3.59k | return getExtractSubregLikeInputs(MI, DefIdx, InputReg); |
1180 | 0 |
|
1181 | 0 | // We are looking at: |
1182 | 0 | // Def = EXTRACT_SUBREG v0.sub1, sub0. |
1183 | 3.59k | assert(DefIdx == 0 && "EXTRACT_SUBREG only has one def"); |
1184 | 0 | const MachineOperand &MOReg = MI.getOperand(1); |
1185 | 0 | const MachineOperand &MOSubIdx = MI.getOperand(2); |
1186 | 0 | assert(MOSubIdx.isImm() && |
1187 | 0 | "The subindex of the extract_subreg is not an immediate"); |
1188 | 0 |
|
1189 | 0 | InputReg.Reg = MOReg.getReg(); |
1190 | 0 | InputReg.SubReg = MOReg.getSubReg(); |
1191 | 0 | InputReg.SubIdx = (unsigned)MOSubIdx.getImm(); |
1192 | 0 | return true; |
1193 | 0 | } |
1194 | | |
1195 | | bool TargetInstrInfo::getInsertSubregInputs( |
1196 | | const MachineInstr &MI, unsigned DefIdx, |
1197 | 198k | RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const { |
1198 | 198k | assert((MI.isInsertSubreg() || |
1199 | 198k | MI.isInsertSubregLike()) && "Instruction do not have the proper type"); |
1200 | 198k | |
1201 | 198k | if (!MI.isInsertSubreg()) |
1202 | 207 | return getInsertSubregLikeInputs(MI, DefIdx, BaseReg, InsertedReg); |
1203 | 198k | |
1204 | 198k | // We are looking at: |
1205 | 198k | // Def = INSERT_SEQUENCE v0, v1, sub0. |
1206 | 198k | assert(DefIdx == 0 && "INSERT_SUBREG only has one def"); |
1207 | 198k | const MachineOperand &MOBaseReg = MI.getOperand(1); |
1208 | 198k | const MachineOperand &MOInsertedReg = MI.getOperand(2); |
1209 | 198k | const MachineOperand &MOSubIdx = MI.getOperand(3); |
1210 | 198k | assert(MOSubIdx.isImm() && |
1211 | 198k | "One of the subindex of the reg_sequence is not an immediate"); |
1212 | 198k | BaseReg.Reg = MOBaseReg.getReg(); |
1213 | 198k | BaseReg.SubReg = MOBaseReg.getSubReg(); |
1214 | 198k | |
1215 | 198k | InsertedReg.Reg = MOInsertedReg.getReg(); |
1216 | 198k | InsertedReg.SubReg = MOInsertedReg.getSubReg(); |
1217 | 198k | InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm(); |
1218 | 198k | return true; |
1219 | 198k | } |