LLVM 24.0.0git
HexagonInstrInfo.cpp
Go to the documentation of this file.
1//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the Hexagon implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "HexagonInstrInfo.h"
16#include "HexagonRegisterInfo.h"
17#include "HexagonSubtarget.h"
18#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/StringRef.h"
42#include "llvm/IR/DebugLoc.h"
44#include "llvm/MC/MCAsmInfo.h"
46#include "llvm/MC/MCInstrDesc.h"
50#include "llvm/Support/Debug.h"
55#include <cassert>
56#include <cstdint>
57#include <cstring>
58#include <iterator>
59#include <optional>
60#include <string>
61#include <utility>
62
63using namespace llvm;
64
65#define DEBUG_TYPE "hexagon-instrinfo"
66
67#define GET_INSTRINFO_CTOR_DTOR
68#define GET_INSTRMAP_INFO
70#include "HexagonGenDFAPacketizer.inc"
71#include "HexagonGenInstrInfo.inc"
72
73cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
74 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
75 "packetization boundary."));
76
77static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
78 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
79
81 "disable-hexagon-nv-schedule", cl::Hidden,
82 cl::desc("Disable schedule adjustment for new value stores."));
83
85 "enable-timing-class-latency", cl::Hidden, cl::init(false),
86 cl::desc("Enable timing class latency"));
87
89 "enable-alu-forwarding", cl::Hidden, cl::init(true),
90 cl::desc("Enable vec alu forwarding"));
91
93 "enable-acc-forwarding", cl::Hidden, cl::init(true),
94 cl::desc("Enable vec acc forwarding"));
95
96static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
97 cl::init(true), cl::Hidden,
98 cl::desc("branch relax asm"));
99
100static cl::opt<bool>
101 UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,
102 cl::desc("Use the DFA based hazard recognizer."));
103
104/// Constants for Hexagon instructions.
105const int Hexagon_MEMW_OFFSET_MAX = 4095;
106const int Hexagon_MEMW_OFFSET_MIN = -4096;
107const int Hexagon_MEMD_OFFSET_MAX = 8191;
108const int Hexagon_MEMD_OFFSET_MIN = -8192;
109const int Hexagon_MEMH_OFFSET_MAX = 2047;
110const int Hexagon_MEMH_OFFSET_MIN = -2048;
111const int Hexagon_MEMB_OFFSET_MAX = 1023;
112const int Hexagon_MEMB_OFFSET_MIN = -1024;
113const int Hexagon_ADDI_OFFSET_MAX = 32767;
114const int Hexagon_ADDI_OFFSET_MIN = -32768;
115
116// Pin the vtable to this file.
117void HexagonInstrInfo::anchor() {}
118
120 : HexagonGenInstrInfo(ST, RegInfo, Hexagon::ADJCALLSTACKDOWN,
121 Hexagon::ADJCALLSTACKUP),
122 RegInfo(ST.getHwMode()), Subtarget(ST) {}
123
124namespace llvm {
125namespace HexagonFUnits {
126 bool isSlot0Only(unsigned units);
127}
128}
129
131 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
132 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
133}
134
136 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&
137 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));
138}
139
140/// Calculate number of instructions excluding the debug instructions.
143 unsigned Count = 0;
144 for (; MIB != MIE; ++MIB) {
145 if (!MIB->isDebugInstr())
146 ++Count;
147 }
148 return Count;
149}
150
151// Check if the A2_tfrsi instruction is cheap or not. If the operand has
152// to be constant-extendend it is not cheap since it occupies two slots
153// in a packet.
155 // Enable the following steps only at Os/Oz
156 if (!(MI.getMF()->getFunction().hasOptSize()))
157 return MI.isAsCheapAsAMove();
158
159 if (MI.getOpcode() == Hexagon::A2_tfrsi) {
160 auto Op = MI.getOperand(1);
161 // If the instruction has a global address as operand, it is not cheap
162 // since the operand will be constant extended.
163 if (Op.isGlobal())
164 return false;
165 // If the instruction has an operand of size > 16bits, its will be
166 // const-extended and hence, it is not cheap.
167 if (Op.isImm()) {
168 int64_t Imm = Op.getImm();
169 if (!isInt<16>(Imm))
170 return false;
171 }
172 }
173 return MI.isAsCheapAsAMove();
174}
175
176// Do not sink floating point instructions that updates USR register.
177// Example:
178// feclearexcept
179// F2_conv_w2sf
180// fetestexcept
181// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.
182// TODO: On some of these floating point instructions, USR is marked as Use.
183// In reality, these instructions also Def the USR. If USR is marked as Def,
184// some of the assumptions in assembler packetization are broken.
186 // Assumption: A floating point instruction that reads the USR will write
187 // the USR as well.
188 if (isFloat(MI) && MI.hasRegisterImplicitUseOperand(Hexagon::USR))
189 return false;
190 return true;
191}
192
193/// Find the hardware loop instruction used to set-up the specified loop.
194/// On Hexagon, we have two instructions used to set-up the hardware loop
195/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
196/// to indicate the end of a loop.
198 unsigned EndLoopOp, MachineBasicBlock *TargetBB,
200 unsigned LOOPi;
201 unsigned LOOPr;
202 if (EndLoopOp == Hexagon::ENDLOOP0) {
203 LOOPi = Hexagon::J2_loop0i;
204 LOOPr = Hexagon::J2_loop0r;
205 } else { // EndLoopOp == Hexagon::EndLOOP1
206 LOOPi = Hexagon::J2_loop1i;
207 LOOPr = Hexagon::J2_loop1r;
208 }
209
210 // The loop set-up instruction will be in a predecessor block
211 for (MachineBasicBlock *PB : BB->predecessors()) {
212 // If this has been visited, already skip it.
213 if (!Visited.insert(PB).second)
214 continue;
215 if (PB == BB)
216 continue;
217 for (MachineInstr &I : llvm::reverse(PB->instrs())) {
218 unsigned Opc = I.getOpcode();
219 if (Opc == LOOPi || Opc == LOOPr)
220 return &I;
221 // We've reached a different loop, which means the loop01 has been
222 // removed.
223 if (Opc == EndLoopOp && I.getOperand(0).getMBB() != TargetBB)
224 return nullptr;
225 }
226 // Check the predecessors for the LOOP instruction.
227 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
228 return Loop;
229 }
230 return nullptr;
231}
232
233/// Gather register def/uses from MI.
234/// This treats possible (predicated) defs as actually happening ones
235/// (conservatively).
236static inline void parseOperands(const MachineInstr &MI,
238 Defs.clear();
239 Uses.clear();
240
241 for (const MachineOperand &MO : MI.operands()) {
242 if (!MO.isReg())
243 continue;
244
245 Register Reg = MO.getReg();
246 if (!Reg)
247 continue;
248
249 if (MO.isUse())
250 Uses.push_back(MO.getReg());
251
252 if (MO.isDef())
253 Defs.push_back(MO.getReg());
254 }
255}
256
257// Position dependent, so check twice for swap.
258static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
259 switch (Ga) {
261 default:
262 return false;
264 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
266 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
267 Gb == HexagonII::HSIG_A);
269 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
272 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
273 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
274 Gb == HexagonII::HSIG_A);
276 return (Gb == HexagonII::HSIG_A);
278 return (Gb == HexagonII::HSIG_Compound);
279 }
280 return false;
281}
282
283/// isLoadFromStackSlot - If the specified machine instruction is a direct
284/// load from a stack slot, return the virtual or physical register number of
285/// the destination along with the FrameIndex of the loaded stack slot. If
286/// not, return 0. This predicate must return 0 if the instruction has
287/// any side effects other than loading from the stack slot.
289 int &FrameIndex) const {
290 switch (MI.getOpcode()) {
291 default:
292 break;
293 case Hexagon::L2_loadri_io:
294 case Hexagon::L2_loadrd_io:
295 case Hexagon::V6_vL32b_ai:
296 case Hexagon::V6_vL32b_nt_ai:
297 case Hexagon::V6_vL32Ub_ai:
298 case Hexagon::LDriw_pred:
299 case Hexagon::LDriw_ctr:
300 case Hexagon::PS_vloadrq_ai:
301 case Hexagon::PS_vloadrw_ai:
302 case Hexagon::PS_vloadrw_nt_ai: {
303 const MachineOperand OpFI = MI.getOperand(1);
304 if (!OpFI.isFI())
305 return 0;
306 const MachineOperand OpOff = MI.getOperand(2);
307 if (!OpOff.isImm() || OpOff.getImm() != 0)
308 return 0;
309 FrameIndex = OpFI.getIndex();
310 return MI.getOperand(0).getReg();
311 }
312
313 case Hexagon::L2_ploadrit_io:
314 case Hexagon::L2_ploadrif_io:
315 case Hexagon::L2_ploadrdt_io:
316 case Hexagon::L2_ploadrdf_io: {
317 const MachineOperand OpFI = MI.getOperand(2);
318 if (!OpFI.isFI())
319 return 0;
320 const MachineOperand OpOff = MI.getOperand(3);
321 if (!OpOff.isImm() || OpOff.getImm() != 0)
322 return 0;
323 FrameIndex = OpFI.getIndex();
324 return MI.getOperand(0).getReg();
325 }
326 }
327
328 return 0;
329}
330
331/// isStoreToStackSlot - If the specified machine instruction is a direct
332/// store to a stack slot, return the virtual or physical register number of
333/// the source reg along with the FrameIndex of the loaded stack slot. If
334/// not, return 0. This predicate must return 0 if the instruction has
335/// any side effects other than storing to the stack slot.
337 int &FrameIndex) const {
338 switch (MI.getOpcode()) {
339 default:
340 break;
341 case Hexagon::S2_storerb_io:
342 case Hexagon::S2_storerh_io:
343 case Hexagon::S2_storeri_io:
344 case Hexagon::S2_storerd_io:
345 case Hexagon::V6_vS32b_ai:
346 case Hexagon::V6_vS32Ub_ai:
347 case Hexagon::STriw_pred:
348 case Hexagon::STriw_ctr:
349 case Hexagon::PS_vstorerq_ai:
350 case Hexagon::PS_vstorerw_ai: {
351 const MachineOperand &OpFI = MI.getOperand(0);
352 if (!OpFI.isFI())
353 return 0;
354 const MachineOperand &OpOff = MI.getOperand(1);
355 if (!OpOff.isImm() || OpOff.getImm() != 0)
356 return 0;
357 FrameIndex = OpFI.getIndex();
358 return MI.getOperand(2).getReg();
359 }
360
361 case Hexagon::S2_pstorerbt_io:
362 case Hexagon::S2_pstorerbf_io:
363 case Hexagon::S2_pstorerht_io:
364 case Hexagon::S2_pstorerhf_io:
365 case Hexagon::S2_pstorerit_io:
366 case Hexagon::S2_pstorerif_io:
367 case Hexagon::S2_pstorerdt_io:
368 case Hexagon::S2_pstorerdf_io: {
369 const MachineOperand &OpFI = MI.getOperand(1);
370 if (!OpFI.isFI())
371 return 0;
372 const MachineOperand &OpOff = MI.getOperand(2);
373 if (!OpOff.isImm() || OpOff.getImm() != 0)
374 return 0;
375 FrameIndex = OpFI.getIndex();
376 return MI.getOperand(3).getReg();
377 }
378 }
379
380 return 0;
381}
382
383/// This function checks if the instruction or bundle of instructions
384/// has load from stack slot and returns frameindex and machine memory
385/// operand of that instruction if true.
387 const MachineInstr &MI,
389 if (MI.isBundle()) {
390 const MachineBasicBlock *MBB = MI.getParent();
392 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
394 return true;
395 return false;
396 }
397
399}
400
401/// This function checks if the instruction or bundle of instructions
402/// has store to stack slot and returns frameindex and machine memory
403/// operand of that instruction if true.
405 const MachineInstr &MI,
407 if (MI.isBundle()) {
408 const MachineBasicBlock *MBB = MI.getParent();
410 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
412 return true;
413 return false;
414 }
415
417}
418
419/// This function can analyze one/two way branching only and should (mostly) be
420/// called by target independent side.
421/// First entry is always the opcode of the branching instruction, except when
422/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a
423/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
424/// e.g. Jump_c p will have
425/// Cond[0] = Jump_c
426/// Cond[1] = p
427/// HW-loop ENDLOOP:
428/// Cond[0] = ENDLOOP
429/// Cond[1] = MBB
430/// New value jump:
431/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
432/// Cond[1] = R
433/// Cond[2] = Imm
436 MachineBasicBlock *&FBB,
438 bool AllowModify) const {
439 TBB = nullptr;
440 FBB = nullptr;
441 Cond.clear();
442
443 // If the block has no terminators, it just falls into the block after it.
445 if (I == MBB.instr_begin())
446 return false;
447
448 // A basic block may looks like this:
449 //
450 // [ insn
451 // EH_LABEL
452 // insn
453 // insn
454 // insn
455 // EH_LABEL
456 // insn ]
457 //
458 // It has two succs but does not have a terminator
459 // Don't know how to handle it.
460 do {
461 --I;
462 if (I->isEHLabel())
463 // Don't analyze EH branches.
464 return true;
465 } while (I != MBB.instr_begin());
466
467 I = MBB.instr_end();
468 --I;
469
470 while (I->isDebugInstr()) {
471 if (I == MBB.instr_begin())
472 return false;
473 --I;
474 }
475
476 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
477 I->getOperand(0).isMBB();
478 // Delete the J2_jump if it's equivalent to a fall-through.
479 if (AllowModify && JumpToBlock &&
480 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
481 LLVM_DEBUG(dbgs() << "\nErasing the jump to successor block\n";);
482 I->eraseFromParent();
483 I = MBB.instr_end();
484 if (I == MBB.instr_begin())
485 return false;
486 --I;
487 }
488 if (!isUnpredicatedTerminator(*I))
489 return false;
490
491 // Get the last instruction in the block.
492 MachineInstr *LastInst = &*I;
493 MachineInstr *SecondLastInst = nullptr;
494 // Find one more terminator if present.
495 while (true) {
496 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
497 if (!SecondLastInst)
498 SecondLastInst = &*I;
499 else
500 // This is a third branch.
501 return true;
502 }
503 if (I == MBB.instr_begin())
504 break;
505 --I;
506 }
507
508 int LastOpcode = LastInst->getOpcode();
509 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
510 // If the branch target is not a basic block, it could be a tail call.
511 // (It is, if the target is a function.)
512 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
513 return true;
514 if (SecLastOpcode == Hexagon::J2_jump &&
515 !SecondLastInst->getOperand(0).isMBB())
516 return true;
517
518 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
519 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);
520
521 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
522 return true;
523
524 // If there is only one terminator instruction, process it.
525 if (LastInst && !SecondLastInst) {
526 if (LastOpcode == Hexagon::J2_jump) {
527 TBB = LastInst->getOperand(0).getMBB();
528 return false;
529 }
530 if (isEndLoopN(LastOpcode)) {
531 TBB = LastInst->getOperand(0).getMBB();
532 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
533 Cond.push_back(LastInst->getOperand(0));
534 return false;
535 }
536 if (LastOpcodeHasJMP_c) {
537 TBB = LastInst->getOperand(1).getMBB();
538 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
539 Cond.push_back(LastInst->getOperand(0));
540 return false;
541 }
542 // Only supporting rr/ri versions of new-value jumps.
543 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
544 TBB = LastInst->getOperand(2).getMBB();
545 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
546 Cond.push_back(LastInst->getOperand(0));
547 Cond.push_back(LastInst->getOperand(1));
548 return false;
549 }
550 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
551 << " with one jump\n";);
552 // Otherwise, don't know what this is.
553 return true;
554 }
555
556 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
557 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);
558 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
559 if (!SecondLastInst->getOperand(1).isMBB())
560 return true;
561 TBB = SecondLastInst->getOperand(1).getMBB();
562 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
563 Cond.push_back(SecondLastInst->getOperand(0));
564 FBB = LastInst->getOperand(0).getMBB();
565 return false;
566 }
567
568 // Only supporting rr/ri versions of new-value jumps.
569 if (SecLastOpcodeHasNVJump &&
570 (SecondLastInst->getNumExplicitOperands() == 3) &&
571 (LastOpcode == Hexagon::J2_jump)) {
572 TBB = SecondLastInst->getOperand(2).getMBB();
573 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
574 Cond.push_back(SecondLastInst->getOperand(0));
575 Cond.push_back(SecondLastInst->getOperand(1));
576 FBB = LastInst->getOperand(0).getMBB();
577 return false;
578 }
579
580 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
581 // executed, so remove it.
582 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
583 TBB = SecondLastInst->getOperand(0).getMBB();
584 I = LastInst->getIterator();
585 if (AllowModify)
586 I->eraseFromParent();
587 return false;
588 }
589
590 // If the block ends with an ENDLOOP, and J2_jump, handle it.
591 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
592 TBB = SecondLastInst->getOperand(0).getMBB();
593 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
594 Cond.push_back(SecondLastInst->getOperand(0));
595 FBB = LastInst->getOperand(0).getMBB();
596 return false;
597 }
598 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
599 << " with two jumps";);
600 // Otherwise, can't handle this.
601 return true;
602}
603
605 int *BytesRemoved) const {
606 assert(!BytesRemoved && "code size not handled");
607
608 LLVM_DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));
610 unsigned Count = 0;
611 while (I != MBB.begin()) {
612 --I;
613 if (I->isDebugInstr())
614 continue;
615 // Only removing branches from end of MBB.
616 if (!I->isBranch())
617 return Count;
618 if (Count && (I->getOpcode() == Hexagon::J2_jump))
619 llvm_unreachable("Malformed basic block: unconditional branch not last");
620 MBB.erase(&MBB.back());
621 I = MBB.end();
622 ++Count;
623 }
624 return Count;
625}
626
631 const DebugLoc &DL,
632 int *BytesAdded) const {
633 unsigned BOpc = Hexagon::J2_jump;
634 unsigned BccOpc = Hexagon::J2_jumpt;
635 assert(validateBranchCond(Cond) && "Invalid branching condition");
636 assert(TBB && "insertBranch must not be told to insert a fallthrough");
637 assert(!BytesAdded && "code size not handled");
638
639 // Check if reverseBranchCondition has asked to reverse this branch
640 // If we want to reverse the branch an odd number of times, we want
641 // J2_jumpf.
642 if (!Cond.empty() && Cond[0].isImm())
643 BccOpc = Cond[0].getImm();
644
645 if (!FBB) {
646 if (Cond.empty()) {
647 // Due to a bug in TailMerging/CFG Optimization, we need to add a
648 // special case handling of a predicated jump followed by an
649 // unconditional jump. If not, Tail Merging and CFG Optimization go
650 // into an infinite loop.
651 MachineBasicBlock *NewTBB, *NewFBB;
653 auto Term = MBB.getFirstTerminator();
654 if (Term != MBB.end() && isPredicated(*Term) &&
655 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&
656 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {
659 return insertBranch(MBB, TBB, nullptr, Cond, DL);
660 }
661 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
662 } else if (isEndLoopN(Cond[0].getImm())) {
663 int EndLoopOp = Cond[0].getImm();
664 assert(Cond[1].isMBB());
665 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
666 // Check for it, and change the BB target if needed.
668 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
669 VisitedBBs);
670 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
671 Loop->getOperand(0).setMBB(TBB);
672 // Add the ENDLOOP after the finding the LOOP0.
673 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
674 } else if (isNewValueJump(Cond[0].getImm())) {
675 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
676 // New value jump
677 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
678 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
679 RegState Flags1 = getUndefRegState(Cond[1].isUndef());
680 LLVM_DEBUG(dbgs() << "\nInserting NVJump for "
682 if (Cond[2].isReg()) {
683 RegState Flags2 = getUndefRegState(Cond[2].isUndef());
684 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
685 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
686 } else if(Cond[2].isImm()) {
687 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
688 addImm(Cond[2].getImm()).addMBB(TBB);
689 } else
690 llvm_unreachable("Invalid condition for branching");
691 } else {
692 assert((Cond.size() == 2) && "Malformed cond vector");
693 const MachineOperand &RO = Cond[1];
694 RegState Flags = getUndefRegState(RO.isUndef());
695 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
696 }
697 return 1;
698 }
699 assert((!Cond.empty()) &&
700 "Cond. cannot be empty when multiple branchings are required");
701 assert((!isNewValueJump(Cond[0].getImm())) &&
702 "NV-jump cannot be inserted with another branch");
703 // Special case for hardware loops. The condition is a basic block.
704 if (isEndLoopN(Cond[0].getImm())) {
705 int EndLoopOp = Cond[0].getImm();
706 assert(Cond[1].isMBB());
707 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
708 // Check for it, and change the BB target if needed.
710 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
711 VisitedBBs);
712 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
713 Loop->getOperand(0).setMBB(TBB);
714 // Add the ENDLOOP after the finding the LOOP0.
715 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
716 } else {
717 const MachineOperand &RO = Cond[1];
718 RegState Flags = getUndefRegState(RO.isUndef());
719 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
720 }
721 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
722
723 return 2;
724}
725
726namespace {
727class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
728 MachineInstr *Loop, *EndLoop;
729 MachineFunction *MF;
730 const HexagonInstrInfo *TII;
731 int64_t TripCount;
732 Register LoopCount;
733 DebugLoc DL;
734
735public:
736 HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)
737 : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),
738 TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()),
739 DL(Loop->getDebugLoc()) {
740 // Inspect the Loop instruction up-front, as it may be deleted when we call
741 // createTripCountGreaterCondition.
742 TripCount = Loop->getOpcode() == Hexagon::J2_loop0r
743 ? -1
744 : Loop->getOperand(1).getImm();
745 if (TripCount == -1)
746 LoopCount = Loop->getOperand(1).getReg();
747 }
748
749 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
750 // Only ignore the terminator.
751 return MI == EndLoop;
752 }
753
754 std::optional<bool> createTripCountGreaterCondition(
755 int TC, MachineBasicBlock &MBB,
756 SmallVectorImpl<MachineOperand> &Cond) override {
757 if (TripCount == -1) {
758 // Check if we're done with the loop.
759 Register Done = TII->createVR(MF, MVT::i1);
760 MachineInstr *NewCmp = BuildMI(&MBB, DL,
761 TII->get(Hexagon::C2_cmpgtui), Done)
762 .addReg(LoopCount)
763 .addImm(TC);
764 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
765 Cond.push_back(NewCmp->getOperand(0));
766 return {};
767 }
768
769 return TripCount > TC;
770 }
771
772 void setPreheader(MachineBasicBlock *NewPreheader) override {
773 NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),
774 Loop);
775 }
776
777 void adjustTripCount(int TripCountAdjust) override {
778 // If the loop trip count is a compile-time value, then just change the
779 // value.
780 if (Loop->getOpcode() == Hexagon::J2_loop0i ||
781 Loop->getOpcode() == Hexagon::J2_loop1i) {
782 int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;
783 assert(TripCount > 0 && "Can't create an empty or negative loop!");
784 Loop->getOperand(1).setImm(TripCount);
785 return;
786 }
787
788 // The loop trip count is a run-time value. We generate code to subtract
789 // one from the trip count, and update the loop instruction.
790 Register LoopCount = Loop->getOperand(1).getReg();
791 Register NewLoopCount = TII->createVR(MF, MVT::i32);
792 BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),
793 TII->get(Hexagon::A2_addi), NewLoopCount)
794 .addReg(LoopCount)
795 .addImm(TripCountAdjust);
796 Loop->getOperand(1).setReg(NewLoopCount);
797 }
798
799 void disposed(LiveIntervals *LIS) override {
800 if (LIS)
802 Loop->eraseFromParent();
803 }
804};
805} // namespace
806
807std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
809 // We really "analyze" only hardware loops right now.
811
812 if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {
814 MachineInstr *LoopInst = findLoopInstr(
815 LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);
816 if (LoopInst)
817 return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);
818 }
819 return nullptr;
820}
821
823 unsigned NumCycles, unsigned ExtraPredCycles,
824 BranchProbability Probability) const {
825 return nonDbgBBSize(&MBB) <= 3;
826}
827
829 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
830 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
831 const {
832 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
833}
834
836 unsigned NumInstrs, BranchProbability Probability) const {
837 return NumInstrs <= 4;
838}
839
840static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
842 const MachineBasicBlock &B = *MI.getParent();
843 Regs.addLiveIns(B);
844 auto E = MachineBasicBlock::const_iterator(MI.getIterator());
845 for (auto I = B.begin(); I != E; ++I) {
846 Clobbers.clear();
847 Regs.stepForward(*I, Clobbers);
848 }
849}
850
851static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
852 const MachineBasicBlock &B = *MI.getParent();
853 Regs.addLiveOuts(B);
854 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();
855 for (auto I = B.rbegin(); I != E; ++I)
856 Regs.stepBackward(*I);
857}
858
861 const DebugLoc &DL, Register DestReg,
862 Register SrcReg, bool KillSrc,
863 bool RenamableDest,
864 bool RenamableSrc) const {
865 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
866 RegState KillFlag = getKillRegState(KillSrc);
867
868 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
869 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
870 .addReg(SrcReg, KillFlag);
871 return;
872 }
873 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
874 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
875 .addReg(SrcReg, KillFlag);
876 return;
877 }
878 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
879 // Map Pd = Ps to Pd = or(Ps, Ps).
880 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
881 .addReg(SrcReg).addReg(SrcReg, KillFlag);
882 return;
883 }
884 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
885 Hexagon::IntRegsRegClass.contains(SrcReg)) {
886 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
887 .addReg(SrcReg, KillFlag);
888 return;
889 }
890 if (Hexagon::IntRegsRegClass.contains(DestReg) &&
891 Hexagon::CtrRegsRegClass.contains(SrcReg)) {
892 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
893 .addReg(SrcReg, KillFlag);
894 return;
895 }
896 if (Hexagon::ModRegsRegClass.contains(DestReg) &&
897 Hexagon::IntRegsRegClass.contains(SrcReg)) {
898 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
899 .addReg(SrcReg, KillFlag);
900 return;
901 }
902 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
903 Hexagon::IntRegsRegClass.contains(DestReg)) {
904 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
905 .addReg(SrcReg, KillFlag);
906 return;
907 }
908 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
909 Hexagon::PredRegsRegClass.contains(DestReg)) {
910 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
911 .addReg(SrcReg, KillFlag);
912 return;
913 }
914 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
915 Hexagon::IntRegsRegClass.contains(DestReg)) {
916 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
917 .addReg(SrcReg, KillFlag);
918 return;
919 }
920 if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {
921 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
922 addReg(SrcReg, KillFlag);
923 return;
924 }
925 if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {
926 LivePhysRegs LiveAtMI(HRI);
927 getLiveInRegsAt(LiveAtMI, *I);
928 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
929 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
930 RegState UndefLo = getUndefRegState(!LiveAtMI.contains(SrcLo));
931 RegState UndefHi = getUndefRegState(!LiveAtMI.contains(SrcHi));
932 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
933 .addReg(SrcHi, KillFlag | UndefHi)
934 .addReg(SrcLo, KillFlag | UndefLo);
935 return;
936 }
937 if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {
938 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
939 .addReg(SrcReg)
940 .addReg(SrcReg, KillFlag);
941 return;
942 }
943 if (Hexagon::HvxQRRegClass.contains(SrcReg) &&
944 Hexagon::HvxVRRegClass.contains(DestReg)) {
945 llvm_unreachable("Unimplemented pred to vec");
946 return;
947 }
948 if (Hexagon::HvxQRRegClass.contains(DestReg) &&
949 Hexagon::HvxVRRegClass.contains(SrcReg)) {
950 llvm_unreachable("Unimplemented vec to pred");
951 return;
952 }
953
954#ifndef NDEBUG
955 // Show the invalid registers to ease debugging.
956 dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "
957 << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';
958#endif
959 llvm_unreachable("Unimplemented");
960}
961
964 Register SrcReg, bool isKill, int FI,
965 const TargetRegisterClass *RC,
966 Register VReg,
967 MachineInstr::MIFlag Flags) const {
968 DebugLoc DL = MBB.findDebugLoc(I);
969 MachineFunction &MF = *MBB.getParent();
970 MachineFrameInfo &MFI = MF.getFrameInfo();
971 RegState KillFlag = getKillRegState(isKill);
972
975 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
976
977 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
978 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
979 .addFrameIndex(FI).addImm(0)
980 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
981 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
982 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
983 .addFrameIndex(FI).addImm(0)
984 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
985 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
986 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
987 .addFrameIndex(FI).addImm(0)
988 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
989 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
990 BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))
991 .addFrameIndex(FI).addImm(0)
992 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
993 } else if (Hexagon::CircRegsRegClass.hasSubClassEq(RC)) {
994 BuildMI(MBB, I, DL, get(Hexagon::STriw_circ))
995 .addFrameIndex(FI)
996 .addReg(SrcReg, KillFlag)
997 .addMemOperand(MMO);
998 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
999 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
1000 .addFrameIndex(FI).addImm(0)
1001 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1002 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1003 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
1004 .addFrameIndex(FI).addImm(0)
1005 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1006 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1007 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
1008 .addFrameIndex(FI).addImm(0)
1009 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1010 } else {
1011 llvm_unreachable("Unimplemented");
1012 }
1013}
1014
1017 Register DestReg, int FI,
1018 const TargetRegisterClass *RC,
1019 Register VReg, unsigned SubReg,
1020 MachineInstr::MIFlag Flags) const {
1021 DebugLoc DL = MBB.findDebugLoc(I);
1022 MachineFunction &MF = *MBB.getParent();
1023 MachineFrameInfo &MFI = MF.getFrameInfo();
1024
1027 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
1028
1029 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
1030 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
1031 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1032 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
1033 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
1034 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1035 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
1036 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
1037 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1038 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
1039 BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)
1040 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1041 } else if (Hexagon::CircRegsRegClass.hasSubClassEq(RC)) {
1042 BuildMI(MBB, I, DL, get(Hexagon::LDriw_circ), DestReg)
1043 .addFrameIndex(FI)
1044 .addMemOperand(MMO);
1045 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
1046 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
1047 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1048 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1049 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)
1050 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1051 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1052 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)
1053 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1054 } else {
1055 llvm_unreachable("Can't store this register to stack slot");
1056 }
1057}
1058
1059/// expandPostRAPseudo - This function is called for all pseudo instructions
1060/// that remain after register allocation. Many pseudo instructions are
1061/// created to help register allocation. This is the place to convert them
1062/// into real instructions. The target can edit MI in place, or it can insert
1063/// new instructions and erase MI. The function should return true if
1064/// anything was changed.
1066 MachineBasicBlock &MBB = *MI.getParent();
1067 MachineFunction &MF = *MBB.getParent();
1069 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1070 LivePhysRegs LiveIn(HRI), LiveOut(HRI);
1071 DebugLoc DL = MI.getDebugLoc();
1072 unsigned Opc = MI.getOpcode();
1073
1074 auto RealCirc = [&](unsigned Opc, bool HasImm, unsigned MxOp) {
1075 Register M_CSx = MI.getOperand(MxOp).getReg();
1076 Register Mx = HRI.getSubReg(M_CSx, Hexagon::isub_hi);
1077 unsigned CSOp = HasImm ? 5 : 4;
1078 auto MIB = BuildMI(MBB, MI, DL, get(Opc));
1079 for (unsigned i = 0; i != CSOp; ++i)
1080 if (i == MxOp)
1081 MIB.addReg(Mx);
1082 else
1083 MIB.add(MI.getOperand(i));
1084 Register CSx = (M_CSx == Hexagon::CS_M0 ? Hexagon::CS0 : Hexagon::CS1);
1085 MIB.addReg(CSx, RegState::Implicit);
1086 MBB.erase(MI);
1087 return true;
1088 };
1089
1090 auto UseAligned = [&](const MachineInstr &MI, Align NeedAlign) {
1091 if (MI.memoperands().empty())
1092 return false;
1093 return all_of(MI.memoperands(), [NeedAlign](const MachineMemOperand *MMO) {
1094 return MMO->getAlign() >= NeedAlign;
1095 });
1096 };
1097
1098 switch (Opc) {
1099 case Hexagon::PS_call_instrprof_custom: {
1100 auto Op0 = MI.getOperand(0);
1101 assert(Op0.isGlobal() &&
1102 "First operand must be a global containing handler name.");
1103 const GlobalValue *NameVar = Op0.getGlobal();
1104 const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);
1105 auto *Arr = cast<ConstantDataArray>(GV->getInitializer());
1106 StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
1107
1108 MachineOperand &Op1 = MI.getOperand(1);
1109 // Set R0 with the imm value to be passed to the custom profiling handler.
1110 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)
1111 .addImm(Op1.getImm());
1112 // The call to the custom handler is being treated as a special one as the
1113 // callee is responsible for saving and restoring all the registers
1114 // (including caller saved registers) it needs to modify. This is
1115 // done to reduce the impact of instrumentation on the code being
1116 // instrumented/profiled.
1117 // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers
1118 // are in the Def list of the Hexagon::PS_call_instrprof_custom and
1119 // therefore will be handled appropriately duing register allocation.
1120
1121 // TODO: It may be a good idea to add a separate pseudo instruction for
1122 // static relocation which doesn't need to reserve r14, r15 and r28.
1123
1124 auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))
1126 .addDef(Hexagon::R29, RegState::ImplicitDefine)
1127 .addDef(Hexagon::R30, RegState::ImplicitDefine)
1128 .addDef(Hexagon::R14, RegState::ImplicitDefine)
1129 .addDef(Hexagon::R15, RegState::ImplicitDefine)
1130 .addDef(Hexagon::R28, RegState::ImplicitDefine);
1131 const char *cstr = MF.createExternalSymbolName(NameStr);
1132 MIB.addExternalSymbol(cstr);
1133 MBB.erase(MI);
1134 return true;
1135 }
1136 case TargetOpcode::COPY: {
1137 MachineOperand &MD = MI.getOperand(0);
1138 MachineOperand &MS = MI.getOperand(1);
1139 MachineBasicBlock::iterator MBBI = MI.getIterator();
1140 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
1141 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
1142 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
1143 }
1144 MBB.erase(MBBI);
1145 return true;
1146 }
1147 case Hexagon::PS_aligna:
1148 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
1149 .addReg(HRI.getFrameRegister())
1150 .addImm(-MI.getOperand(1).getImm());
1151 MBB.erase(MI);
1152 return true;
1153 case Hexagon::V6_vassignp: {
1154 Register SrcReg = MI.getOperand(1).getReg();
1155 Register DstReg = MI.getOperand(0).getReg();
1156 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1157 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1158 getLiveInRegsAt(LiveIn, MI);
1159 RegState UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));
1160 RegState UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));
1161 RegState Kill = getKillRegState(MI.getOperand(1).isKill());
1162 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)
1163 .addReg(SrcHi, UndefHi)
1164 .addReg(SrcLo, Kill | UndefLo);
1165 MBB.erase(MI);
1166 return true;
1167 }
1168 case Hexagon::V6_lo: {
1169 Register SrcReg = MI.getOperand(1).getReg();
1170 Register DstReg = MI.getOperand(0).getReg();
1171 Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1172 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
1173 MBB.erase(MI);
1174 return true;
1175 }
1176 case Hexagon::V6_hi: {
1177 Register SrcReg = MI.getOperand(1).getReg();
1178 Register DstReg = MI.getOperand(0).getReg();
1179 Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1180 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
1181 MBB.erase(MI);
1182 return true;
1183 }
1184 case Hexagon::PS_vloadrv_ai: {
1185 Register DstReg = MI.getOperand(0).getReg();
1186 const MachineOperand &BaseOp = MI.getOperand(1);
1187 assert(BaseOp.getSubReg() == 0);
1188 int Offset = MI.getOperand(2).getImm();
1189 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1190 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1191 : Hexagon::V6_vL32Ub_ai;
1192 BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
1193 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1194 .addImm(Offset)
1195 .cloneMemRefs(MI);
1196 MBB.erase(MI);
1197 return true;
1198 }
1199 case Hexagon::PS_vloadrw_ai: {
1200 Register DstReg = MI.getOperand(0).getReg();
1201 const MachineOperand &BaseOp = MI.getOperand(1);
1202 assert(BaseOp.getSubReg() == 0);
1203 int Offset = MI.getOperand(2).getImm();
1204 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1205 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1206 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1207 : Hexagon::V6_vL32Ub_ai;
1208 BuildMI(MBB, MI, DL, get(NewOpc),
1209 HRI.getSubReg(DstReg, Hexagon::vsub_lo))
1210 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1211 .addImm(Offset)
1212 .cloneMemRefs(MI);
1213 BuildMI(MBB, MI, DL, get(NewOpc),
1214 HRI.getSubReg(DstReg, Hexagon::vsub_hi))
1215 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1216 .addImm(Offset + VecOffset)
1217 .cloneMemRefs(MI);
1218 MBB.erase(MI);
1219 return true;
1220 }
1221 case Hexagon::PS_vstorerv_ai: {
1222 const MachineOperand &SrcOp = MI.getOperand(2);
1223 assert(SrcOp.getSubReg() == 0);
1224 const MachineOperand &BaseOp = MI.getOperand(0);
1225 assert(BaseOp.getSubReg() == 0);
1226 int Offset = MI.getOperand(1).getImm();
1227 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1228 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1229 : Hexagon::V6_vS32Ub_ai;
1230 BuildMI(MBB, MI, DL, get(NewOpc))
1231 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1232 .addImm(Offset)
1234 .cloneMemRefs(MI);
1235 MBB.erase(MI);
1236 return true;
1237 }
1238 case Hexagon::PS_vstorerw_ai: {
1239 Register SrcReg = MI.getOperand(2).getReg();
1240 const MachineOperand &BaseOp = MI.getOperand(0);
1241 assert(BaseOp.getSubReg() == 0);
1242 int Offset = MI.getOperand(1).getImm();
1243 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1244 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1245 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1246 : Hexagon::V6_vS32Ub_ai;
1247 BuildMI(MBB, MI, DL, get(NewOpc))
1248 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1249 .addImm(Offset)
1250 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))
1251 .cloneMemRefs(MI);
1252 BuildMI(MBB, MI, DL, get(NewOpc))
1253 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1254 .addImm(Offset + VecOffset)
1255 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))
1256 .cloneMemRefs(MI);
1257 MBB.erase(MI);
1258 return true;
1259 }
1260 case Hexagon::PS_true: {
1261 Register Reg = MI.getOperand(0).getReg();
1262 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1263 .addReg(Reg, RegState::Undef)
1264 .addReg(Reg, RegState::Undef);
1265 MBB.erase(MI);
1266 return true;
1267 }
1268 case Hexagon::PS_false: {
1269 Register Reg = MI.getOperand(0).getReg();
1270 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1271 .addReg(Reg, RegState::Undef)
1272 .addReg(Reg, RegState::Undef);
1273 MBB.erase(MI);
1274 return true;
1275 }
1276 case Hexagon::PS_qtrue: {
1277 BuildMI(MBB, MI, DL, get(Hexagon::V6_veqw), MI.getOperand(0).getReg())
1278 .addReg(Hexagon::V0, RegState::Undef)
1279 .addReg(Hexagon::V0, RegState::Undef);
1280 MBB.erase(MI);
1281 return true;
1282 }
1283 case Hexagon::PS_qfalse: {
1284 BuildMI(MBB, MI, DL, get(Hexagon::V6_vgtw), MI.getOperand(0).getReg())
1285 .addReg(Hexagon::V0, RegState::Undef)
1286 .addReg(Hexagon::V0, RegState::Undef);
1287 MBB.erase(MI);
1288 return true;
1289 }
1290 case Hexagon::PS_vdd0: {
1291 Register Vd = MI.getOperand(0).getReg();
1292 BuildMI(MBB, MI, DL, get(Hexagon::V6_vsubw_dv), Vd)
1294 .addReg(Vd, RegState::Undef);
1295 MBB.erase(MI);
1296 return true;
1297 }
1298 case Hexagon::PS_vmulw: {
1299 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
1300 Register DstReg = MI.getOperand(0).getReg();
1301 Register Src1Reg = MI.getOperand(1).getReg();
1302 Register Src2Reg = MI.getOperand(2).getReg();
1303 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1304 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1305 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1306 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1307 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1308 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1309 .addReg(Src1SubHi)
1310 .addReg(Src2SubHi);
1311 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1312 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1313 .addReg(Src1SubLo)
1314 .addReg(Src2SubLo);
1315 MBB.erase(MI);
1316 return true;
1317 }
1318 case Hexagon::PS_vmulw_acc: {
1319 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
1320 Register DstReg = MI.getOperand(0).getReg();
1321 Register Src1Reg = MI.getOperand(1).getReg();
1322 Register Src2Reg = MI.getOperand(2).getReg();
1323 Register Src3Reg = MI.getOperand(3).getReg();
1324 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1325 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1326 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1327 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1328 Register Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);
1329 Register Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);
1330 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1331 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1332 .addReg(Src1SubHi)
1333 .addReg(Src2SubHi)
1334 .addReg(Src3SubHi);
1335 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1336 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1337 .addReg(Src1SubLo)
1338 .addReg(Src2SubLo)
1339 .addReg(Src3SubLo);
1340 MBB.erase(MI);
1341 return true;
1342 }
1343 case Hexagon::PS_pselect: {
1344 const MachineOperand &Op0 = MI.getOperand(0);
1345 const MachineOperand &Op1 = MI.getOperand(1);
1346 const MachineOperand &Op2 = MI.getOperand(2);
1347 const MachineOperand &Op3 = MI.getOperand(3);
1348 Register Rd = Op0.getReg();
1349 Register Pu = Op1.getReg();
1350 Register Rs = Op2.getReg();
1351 Register Rt = Op3.getReg();
1352 DebugLoc DL = MI.getDebugLoc();
1353 RegState K1 = getKillRegState(Op1.isKill());
1354 RegState K2 = getKillRegState(Op2.isKill());
1355 RegState K3 = getKillRegState(Op3.isKill());
1356 if (Rd != Rs)
1357 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1358 .addReg(Pu, (Rd == Rt) ? K1 : RegState::NoFlags)
1359 .addReg(Rs, K2);
1360 if (Rd != Rt)
1361 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1362 .addReg(Pu, K1)
1363 .addReg(Rt, K3);
1364 MBB.erase(MI);
1365 return true;
1366 }
1367 case Hexagon::PS_vselect: {
1368 const MachineOperand &Op0 = MI.getOperand(0);
1369 const MachineOperand &Op1 = MI.getOperand(1);
1370 const MachineOperand &Op2 = MI.getOperand(2);
1371 const MachineOperand &Op3 = MI.getOperand(3);
1372 getLiveOutRegsAt(LiveOut, MI);
1373 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1374 Register PReg = Op1.getReg();
1375 assert(Op1.getSubReg() == 0);
1376 RegState PState = getRegState(Op1);
1377
1378 if (Op0.getReg() != Op2.getReg()) {
1379 RegState S =
1380 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1381 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
1382 .add(Op0)
1383 .addReg(PReg, S)
1384 .add(Op2);
1385 if (IsDestLive)
1386 T.addReg(Op0.getReg(), RegState::Implicit);
1387 IsDestLive = true;
1388 }
1389 if (Op0.getReg() != Op3.getReg()) {
1390 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
1391 .add(Op0)
1392 .addReg(PReg, PState)
1393 .add(Op3);
1394 if (IsDestLive)
1395 T.addReg(Op0.getReg(), RegState::Implicit);
1396 }
1397 MBB.erase(MI);
1398 return true;
1399 }
1400 case Hexagon::PS_wselect: {
1401 MachineOperand &Op0 = MI.getOperand(0);
1402 MachineOperand &Op1 = MI.getOperand(1);
1403 MachineOperand &Op2 = MI.getOperand(2);
1404 MachineOperand &Op3 = MI.getOperand(3);
1405 getLiveOutRegsAt(LiveOut, MI);
1406 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1407 Register PReg = Op1.getReg();
1408 assert(Op1.getSubReg() == 0);
1409 RegState PState = getRegState(Op1);
1410
1411 if (Op0.getReg() != Op2.getReg()) {
1412 RegState S =
1413 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1414 Register SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);
1415 Register SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);
1416 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
1417 .add(Op0)
1418 .addReg(PReg, S)
1419 .addReg(SrcHi)
1420 .addReg(SrcLo);
1421 if (IsDestLive)
1422 T.addReg(Op0.getReg(), RegState::Implicit);
1423 IsDestLive = true;
1424 }
1425 if (Op0.getReg() != Op3.getReg()) {
1426 Register SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);
1427 Register SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);
1428 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
1429 .add(Op0)
1430 .addReg(PReg, PState)
1431 .addReg(SrcHi)
1432 .addReg(SrcLo);
1433 if (IsDestLive)
1434 T.addReg(Op0.getReg(), RegState::Implicit);
1435 }
1436 MBB.erase(MI);
1437 return true;
1438 }
1439
1440 case Hexagon::PS_crash: {
1441 // Generate a misaligned load that is guaranteed to cause a crash.
1442 class CrashPseudoSourceValue : public PseudoSourceValue {
1443 public:
1444 CrashPseudoSourceValue(const TargetMachine &TM)
1445 : PseudoSourceValue(TargetCustom, TM) {}
1446
1447 bool isConstant(const MachineFrameInfo *) const override {
1448 return false;
1449 }
1450 bool isAliased(const MachineFrameInfo *) const override {
1451 return false;
1452 }
1453 bool mayAlias(const MachineFrameInfo *) const override {
1454 return false;
1455 }
1456 void printCustom(raw_ostream &OS) const override {
1457 OS << "MisalignedCrash";
1458 }
1459 };
1460
1461 static const CrashPseudoSourceValue CrashPSV(MF.getTarget());
1463 MachinePointerInfo(&CrashPSV),
1465 Align(1));
1466 BuildMI(MBB, MI, DL, get(Hexagon::PS_loadrdabs), Hexagon::D13)
1467 .addImm(0xBADC0FEE) // Misaligned load.
1468 .addMemOperand(MMO);
1469 MBB.erase(MI);
1470 return true;
1471 }
1472
1473 case Hexagon::PS_tailcall_i:
1474 MI.setDesc(get(Hexagon::J2_jump));
1475 return true;
1476 case Hexagon::PS_tailcall_r:
1477 case Hexagon::PS_jmpret:
1478 MI.setDesc(get(Hexagon::J2_jumpr));
1479 return true;
1480 case Hexagon::PS_jmprett:
1481 MI.setDesc(get(Hexagon::J2_jumprt));
1482 return true;
1483 case Hexagon::PS_jmpretf:
1484 MI.setDesc(get(Hexagon::J2_jumprf));
1485 return true;
1486 case Hexagon::PS_jmprettnewpt:
1487 MI.setDesc(get(Hexagon::J2_jumprtnewpt));
1488 return true;
1489 case Hexagon::PS_jmpretfnewpt:
1490 MI.setDesc(get(Hexagon::J2_jumprfnewpt));
1491 return true;
1492 case Hexagon::PS_jmprettnew:
1493 MI.setDesc(get(Hexagon::J2_jumprtnew));
1494 return true;
1495 case Hexagon::PS_jmpretfnew:
1496 MI.setDesc(get(Hexagon::J2_jumprfnew));
1497 return true;
1498
1499 case Hexagon::PS_loadrub_pci:
1500 return RealCirc(Hexagon::L2_loadrub_pci, /*HasImm*/true, /*MxOp*/4);
1501 case Hexagon::PS_loadrb_pci:
1502 return RealCirc(Hexagon::L2_loadrb_pci, /*HasImm*/true, /*MxOp*/4);
1503 case Hexagon::PS_loadruh_pci:
1504 return RealCirc(Hexagon::L2_loadruh_pci, /*HasImm*/true, /*MxOp*/4);
1505 case Hexagon::PS_loadrh_pci:
1506 return RealCirc(Hexagon::L2_loadrh_pci, /*HasImm*/true, /*MxOp*/4);
1507 case Hexagon::PS_loadri_pci:
1508 return RealCirc(Hexagon::L2_loadri_pci, /*HasImm*/true, /*MxOp*/4);
1509 case Hexagon::PS_loadrd_pci:
1510 return RealCirc(Hexagon::L2_loadrd_pci, /*HasImm*/true, /*MxOp*/4);
1511 case Hexagon::PS_loadrub_pcr:
1512 return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm*/false, /*MxOp*/3);
1513 case Hexagon::PS_loadrb_pcr:
1514 return RealCirc(Hexagon::L2_loadrb_pcr, /*HasImm*/false, /*MxOp*/3);
1515 case Hexagon::PS_loadruh_pcr:
1516 return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm*/false, /*MxOp*/3);
1517 case Hexagon::PS_loadrh_pcr:
1518 return RealCirc(Hexagon::L2_loadrh_pcr, /*HasImm*/false, /*MxOp*/3);
1519 case Hexagon::PS_loadri_pcr:
1520 return RealCirc(Hexagon::L2_loadri_pcr, /*HasImm*/false, /*MxOp*/3);
1521 case Hexagon::PS_loadrd_pcr:
1522 return RealCirc(Hexagon::L2_loadrd_pcr, /*HasImm*/false, /*MxOp*/3);
1523 case Hexagon::PS_storerb_pci:
1524 return RealCirc(Hexagon::S2_storerb_pci, /*HasImm*/true, /*MxOp*/3);
1525 case Hexagon::PS_storerh_pci:
1526 return RealCirc(Hexagon::S2_storerh_pci, /*HasImm*/true, /*MxOp*/3);
1527 case Hexagon::PS_storerf_pci:
1528 return RealCirc(Hexagon::S2_storerf_pci, /*HasImm*/true, /*MxOp*/3);
1529 case Hexagon::PS_storeri_pci:
1530 return RealCirc(Hexagon::S2_storeri_pci, /*HasImm*/true, /*MxOp*/3);
1531 case Hexagon::PS_storerd_pci:
1532 return RealCirc(Hexagon::S2_storerd_pci, /*HasImm*/true, /*MxOp*/3);
1533 case Hexagon::PS_storerb_pcr:
1534 return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm*/false, /*MxOp*/2);
1535 case Hexagon::PS_storerh_pcr:
1536 return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm*/false, /*MxOp*/2);
1537 case Hexagon::PS_storerf_pcr:
1538 return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm*/false, /*MxOp*/2);
1539 case Hexagon::PS_storeri_pcr:
1540 return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm*/false, /*MxOp*/2);
1541 case Hexagon::PS_storerd_pcr:
1542 return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm*/false, /*MxOp*/2);
1543 }
1544
1545 return false;
1546}
1547
1550 MachineBasicBlock &MBB = *MI.getParent();
1551 const DebugLoc &DL = MI.getDebugLoc();
1552 unsigned Opc = MI.getOpcode();
1554
1555 switch (Opc) {
1556 case Hexagon::V6_vgather_vscatter_mh_pseudo:
1557 // This is mainly a place holder. It will be extended.
1558 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1559 .add(MI.getOperand(2))
1560 .add(MI.getOperand(3))
1561 .add(MI.getOperand(4));
1562 BuildMI(MBB, MI, DL, get(Hexagon::V6_vscattermh))
1563 .add(MI.getOperand(2))
1564 .add(MI.getOperand(3))
1565 .add(MI.getOperand(4))
1566 .addReg(Hexagon::VTMP);
1567 MBB.erase(MI);
1568 return First.getInstrIterator();
1569 case Hexagon::V6_vgathermh_pseudo:
1570 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1571 .add(MI.getOperand(2))
1572 .add(MI.getOperand(3))
1573 .add(MI.getOperand(4));
1574 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1575 .add(MI.getOperand(0))
1576 .addImm(MI.getOperand(1).getImm())
1577 .addReg(Hexagon::VTMP);
1578 MBB.erase(MI);
1579 return First.getInstrIterator();
1580
1581 case Hexagon::V6_vgathermw_pseudo:
1582 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))
1583 .add(MI.getOperand(2))
1584 .add(MI.getOperand(3))
1585 .add(MI.getOperand(4));
1586 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1587 .add(MI.getOperand(0))
1588 .addImm(MI.getOperand(1).getImm())
1589 .addReg(Hexagon::VTMP);
1590 MBB.erase(MI);
1591 return First.getInstrIterator();
1592
1593 case Hexagon::V6_vgathermhw_pseudo:
1594 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))
1595 .add(MI.getOperand(2))
1596 .add(MI.getOperand(3))
1597 .add(MI.getOperand(4));
1598 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1599 .add(MI.getOperand(0))
1600 .addImm(MI.getOperand(1).getImm())
1601 .addReg(Hexagon::VTMP);
1602 MBB.erase(MI);
1603 return First.getInstrIterator();
1604
1605 case Hexagon::V6_vgathermhq_pseudo:
1606 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))
1607 .add(MI.getOperand(2))
1608 .add(MI.getOperand(3))
1609 .add(MI.getOperand(4))
1610 .add(MI.getOperand(5));
1611 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1612 .add(MI.getOperand(0))
1613 .addImm(MI.getOperand(1).getImm())
1614 .addReg(Hexagon::VTMP);
1615 MBB.erase(MI);
1616 return First.getInstrIterator();
1617
1618 case Hexagon::V6_vgathermwq_pseudo:
1619 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))
1620 .add(MI.getOperand(2))
1621 .add(MI.getOperand(3))
1622 .add(MI.getOperand(4))
1623 .add(MI.getOperand(5));
1624 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1625 .add(MI.getOperand(0))
1626 .addImm(MI.getOperand(1).getImm())
1627 .addReg(Hexagon::VTMP);
1628 MBB.erase(MI);
1629 return First.getInstrIterator();
1630
1631 case Hexagon::V6_vgathermhwq_pseudo:
1632 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))
1633 .add(MI.getOperand(2))
1634 .add(MI.getOperand(3))
1635 .add(MI.getOperand(4))
1636 .add(MI.getOperand(5));
1637 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1638 .add(MI.getOperand(0))
1639 .addImm(MI.getOperand(1).getImm())
1640 .addReg(Hexagon::VTMP);
1641 MBB.erase(MI);
1642 return First.getInstrIterator();
1643 }
1644
1645 return MI.getIterator();
1646}
1647
1648// We indicate that we want to reverse the branch by
1649// inserting the reversed branching opcode.
1652 if (Cond.empty())
1653 return true;
1654 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1655 unsigned opcode = Cond[0].getImm();
1656 //unsigned temp;
1657 assert(get(opcode).isBranch() && "Should be a branching condition.");
1658 if (isEndLoopN(opcode))
1659 return true;
1660 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1661 Cond[0].setImm(NewOpcode);
1662 return false;
1663}
1664
1670
1674
1676 unsigned BasePos, OffsetPos;
1677 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
1678 return false;
1679 return isPostIncrement(MI) && MI.getOperand(OffsetPos).isImm();
1680}
1681
1682// Returns true if an instruction is predicated irrespective of the predicate
1683// sense. For example, all of the following will return true.
1684// if (p0) R1 = add(R2, R3)
1685// if (!p0) R1 = add(R2, R3)
1686// if (p0.new) R1 = add(R2, R3)
1687// if (!p0.new) R1 = add(R2, R3)
1688// Note: New-value stores are not included here as in the current
1689// implementation, we don't need to check their predicate sense.
1691 const uint64_t F = MI.getDesc().TSFlags;
1693}
1694
1697 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1698 isEndLoopN(Cond[0].getImm())) {
1699 LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
1700 return false;
1701 }
1702 int Opc = MI.getOpcode();
1703 assert (isPredicable(MI) && "Expected predicable instruction");
1704 bool invertJump = predOpcodeHasNot(Cond);
1705
1706 // We have to predicate MI "in place", i.e. after this function returns,
1707 // MI will need to be transformed into a predicated form. To avoid com-
1708 // plicated manipulations with the operands (handling tied operands,
1709 // etc.), build a new temporary instruction, then overwrite MI with it.
1710
1711 MachineBasicBlock &B = *MI.getParent();
1712 DebugLoc DL = MI.getDebugLoc();
1713 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1714 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
1715 unsigned NOp = 0, NumOps = MI.getNumOperands();
1716 while (NOp < NumOps) {
1717 MachineOperand &Op = MI.getOperand(NOp);
1718 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1719 break;
1720 T.add(Op);
1721 NOp++;
1722 }
1723
1724 Register PredReg;
1725 unsigned PredRegPos;
1726 RegState PredRegFlags = {};
1727 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1728 (void)GotPredReg;
1729 assert(GotPredReg);
1730 T.addReg(PredReg, PredRegFlags);
1731 while (NOp < NumOps)
1732 T.add(MI.getOperand(NOp++));
1733
1734 MI.setDesc(get(PredOpc));
1735 while (unsigned n = MI.getNumOperands())
1736 MI.removeOperand(n-1);
1737 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
1738 MI.addOperand(T->getOperand(i));
1739
1740 MachineBasicBlock::instr_iterator TI = T->getIterator();
1741 B.erase(TI);
1742
1743 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1744 MRI.clearKillFlags(PredReg);
1745 return true;
1746}
1747
1749 ArrayRef<MachineOperand> Pred2) const {
1750 // TODO: Fix this
1751 return false;
1752}
1753
1755 std::vector<MachineOperand> &Pred,
1756 bool SkipDead) const {
1757 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1758
1759 for (const MachineOperand &MO : MI.operands()) {
1760 if (MO.isReg()) {
1761 if (!MO.isDef())
1762 continue;
1763 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1764 if (RC == &Hexagon::PredRegsRegClass) {
1765 Pred.push_back(MO);
1766 return true;
1767 }
1768 continue;
1769 } else if (MO.isRegMask()) {
1770 for (Register PR : Hexagon::PredRegsRegClass) {
1771 if (!MI.modifiesRegister(PR, &HRI))
1772 continue;
1773 Pred.push_back(MO);
1774 return true;
1775 }
1776 }
1777 }
1778 return false;
1779}
1780
1782 if (!MI.getDesc().isPredicable())
1783 return false;
1784
1785 if (MI.isCall() || isTailCall(MI)) {
1786 if (!Subtarget.usePredicatedCalls())
1787 return false;
1788 }
1789
1790 // HVX loads are not predicable on v60, but are on v62.
1791 if (!Subtarget.hasV62Ops()) {
1792 switch (MI.getOpcode()) {
1793 case Hexagon::V6_vL32b_ai:
1794 case Hexagon::V6_vL32b_pi:
1795 case Hexagon::V6_vL32b_ppu:
1796 case Hexagon::V6_vL32b_cur_ai:
1797 case Hexagon::V6_vL32b_cur_pi:
1798 case Hexagon::V6_vL32b_cur_ppu:
1799 case Hexagon::V6_vL32b_nt_ai:
1800 case Hexagon::V6_vL32b_nt_pi:
1801 case Hexagon::V6_vL32b_nt_ppu:
1802 case Hexagon::V6_vL32b_tmp_ai:
1803 case Hexagon::V6_vL32b_tmp_pi:
1804 case Hexagon::V6_vL32b_tmp_ppu:
1805 case Hexagon::V6_vL32b_nt_cur_ai:
1806 case Hexagon::V6_vL32b_nt_cur_pi:
1807 case Hexagon::V6_vL32b_nt_cur_ppu:
1808 case Hexagon::V6_vL32b_nt_tmp_ai:
1809 case Hexagon::V6_vL32b_nt_tmp_pi:
1810 case Hexagon::V6_vL32b_nt_tmp_ppu:
1811 return false;
1812 }
1813 }
1814 return true;
1815}
1816
1818 bool Invert) const {
1819 if (Invert)
1820 return false;
1821
1822 switch (Inst.getOpcode()) {
1823 // TODO: Add more instructions to be handled by MachineCombiner.
1824 case Hexagon::F2_sfadd:
1826 default:
1827 return false;
1828 }
1829}
1830
1832 const MachineBasicBlock *MBB,
1833 const MachineFunction &MF) const {
1834 // Debug info is never a scheduling boundary. It's necessary to be explicit
1835 // due to the special treatment of IT instructions below, otherwise a
1836 // dbg_value followed by an IT will result in the IT instruction being
1837 // considered a scheduling hazard, which is wrong. It should be the actual
1838 // instruction preceding the dbg_value instruction(s), just like it is
1839 // when debug info is not present.
1840 if (MI.isDebugInstr())
1841 return false;
1842
1843 // Throwing call is a boundary.
1844 if (MI.isCall()) {
1845 // Don't mess around with no return calls.
1846 if (doesNotReturn(MI))
1847 return true;
1848 // If any of the block's successors is a landing pad, this could be a
1849 // throwing call.
1850 for (auto *I : MBB->successors())
1851 if (I->isEHPad())
1852 return true;
1853 }
1854
1855 // Terminators and labels can't be scheduled around.
1856 if (MI.getDesc().isTerminator() || MI.isPosition())
1857 return true;
1858
1859 // INLINEASM_BR can jump to another block
1860 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
1861 return true;
1862
1863 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1864 return true;
1865
1866 return false;
1867}
1868
1869/// Measure the specified inline asm to determine an approximation of its
1870/// length.
1871/// Comments (which run till the next SeparatorString or newline) do not
1872/// count as an instruction.
1873/// Any other non-whitespace text is considered an instruction, with
1874/// multiple instructions separated by SeparatorString or newlines.
1875/// Variable-length instructions are not handled here; this function
1876/// may be overloaded in the target code to do that.
1877/// Hexagon counts the number of ##'s and adjust for that many
1878/// constant exenders.
1880 const MCAsmInfo &MAI,
1881 const TargetSubtargetInfo *STI) const {
1882 StringRef AStr(Str);
1883 // Count the number of instructions in the asm.
1884 bool atInsnStart = true;
1885 unsigned Length = 0;
1886 const unsigned MaxInstLength = MAI.getMaxInstLength(STI);
1887 for (; *Str; ++Str) {
1888 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1889 strlen(MAI.getSeparatorString())) == 0)
1890 atInsnStart = true;
1891 if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {
1892 Length += MaxInstLength;
1893 atInsnStart = false;
1894 }
1895 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1896 MAI.getCommentString().size()) == 0)
1897 atInsnStart = false;
1898 }
1899
1900 // Add to size number of constant extenders seen * 4.
1901 StringRef Occ("##");
1902 Length += AStr.count(Occ)*4;
1903 return Length;
1904}
1905
1913
1914/// For a comparison instruction, return the source registers in
1915/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1916/// compares against in CmpValue. Return true if the comparison instruction
1917/// can be analyzed.
1919 Register &SrcReg2, int64_t &Mask,
1920 int64_t &Value) const {
1921 unsigned Opc = MI.getOpcode();
1922
1923 // Set mask and the first source register.
1924 switch (Opc) {
1925 case Hexagon::C2_cmpeq:
1926 case Hexagon::C2_cmpeqp:
1927 case Hexagon::C2_cmpgt:
1928 case Hexagon::C2_cmpgtp:
1929 case Hexagon::C2_cmpgtu:
1930 case Hexagon::C2_cmpgtup:
1931 case Hexagon::C4_cmpneq:
1932 case Hexagon::C4_cmplte:
1933 case Hexagon::C4_cmplteu:
1934 case Hexagon::C2_cmpeqi:
1935 case Hexagon::C2_cmpgti:
1936 case Hexagon::C2_cmpgtui:
1937 case Hexagon::C4_cmpneqi:
1938 case Hexagon::C4_cmplteui:
1939 case Hexagon::C4_cmpltei:
1940 SrcReg = MI.getOperand(1).getReg();
1941 Mask = ~0;
1942 break;
1943 case Hexagon::A4_cmpbeq:
1944 case Hexagon::A4_cmpbgt:
1945 case Hexagon::A4_cmpbgtu:
1946 case Hexagon::A4_cmpbeqi:
1947 case Hexagon::A4_cmpbgti:
1948 case Hexagon::A4_cmpbgtui:
1949 SrcReg = MI.getOperand(1).getReg();
1950 Mask = 0xFF;
1951 break;
1952 case Hexagon::A4_cmpheq:
1953 case Hexagon::A4_cmphgt:
1954 case Hexagon::A4_cmphgtu:
1955 case Hexagon::A4_cmpheqi:
1956 case Hexagon::A4_cmphgti:
1957 case Hexagon::A4_cmphgtui:
1958 SrcReg = MI.getOperand(1).getReg();
1959 Mask = 0xFFFF;
1960 break;
1961 }
1962
1963 // Set the value/second source register.
1964 switch (Opc) {
1965 case Hexagon::C2_cmpeq:
1966 case Hexagon::C2_cmpeqp:
1967 case Hexagon::C2_cmpgt:
1968 case Hexagon::C2_cmpgtp:
1969 case Hexagon::C2_cmpgtu:
1970 case Hexagon::C2_cmpgtup:
1971 case Hexagon::A4_cmpbeq:
1972 case Hexagon::A4_cmpbgt:
1973 case Hexagon::A4_cmpbgtu:
1974 case Hexagon::A4_cmpheq:
1975 case Hexagon::A4_cmphgt:
1976 case Hexagon::A4_cmphgtu:
1977 case Hexagon::C4_cmpneq:
1978 case Hexagon::C4_cmplte:
1979 case Hexagon::C4_cmplteu:
1980 SrcReg2 = MI.getOperand(2).getReg();
1981 Value = 0;
1982 return true;
1983
1984 case Hexagon::C2_cmpeqi:
1985 case Hexagon::C2_cmpgtui:
1986 case Hexagon::C2_cmpgti:
1987 case Hexagon::C4_cmpneqi:
1988 case Hexagon::C4_cmplteui:
1989 case Hexagon::C4_cmpltei:
1990 case Hexagon::A4_cmpbeqi:
1991 case Hexagon::A4_cmpbgti:
1992 case Hexagon::A4_cmpbgtui:
1993 case Hexagon::A4_cmpheqi:
1994 case Hexagon::A4_cmphgti:
1995 case Hexagon::A4_cmphgtui: {
1996 SrcReg2 = 0;
1997 const MachineOperand &Op2 = MI.getOperand(2);
1998 if (!Op2.isImm())
1999 return false;
2000 Value = MI.getOperand(2).getImm();
2001 return true;
2002 }
2003 }
2004
2005 return false;
2006}
2007
2009 const MachineInstr &MI,
2010 unsigned *PredCost) const {
2011 return getInstrTimingClassLatency(ItinData, MI);
2012}
2013
2015 const TargetSubtargetInfo &STI) const {
2017 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
2018}
2019
2020// Inspired by this pair:
2021// %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
2022// S2_storeri_io %r29, 132, killed %r1; flags: mem:ST4[FixedStack1]
2023// Currently AA considers the addresses in these instructions to be aliasing.
2025 const MachineInstr &MIa, const MachineInstr &MIb) const {
2028 return false;
2029
2030 // Instructions that are pure loads, not loads and stores like memops are not
2031 // dependent.
2032 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
2033 return true;
2034
2035 // Get the base register in MIa.
2036 unsigned BasePosA, OffsetPosA;
2037 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
2038 return false;
2039 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
2040 Register BaseRegA = BaseA.getReg();
2041 unsigned BaseSubA = BaseA.getSubReg();
2042
2043 // Get the base register in MIb.
2044 unsigned BasePosB, OffsetPosB;
2045 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
2046 return false;
2047 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
2048 Register BaseRegB = BaseB.getReg();
2049 unsigned BaseSubB = BaseB.getSubReg();
2050
2051 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
2052 return false;
2053
2054 // Get the access sizes.
2055 unsigned SizeA = getMemAccessSize(MIa);
2056 unsigned SizeB = getMemAccessSize(MIb);
2057
2058 // Get the offsets. Handle immediates only for now.
2059 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
2060 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
2061 if (!MIa.getOperand(OffsetPosA).isImm() ||
2062 !MIb.getOperand(OffsetPosB).isImm())
2063 return false;
2064 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
2065 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
2066
2067 // This is a mem access with the same base register and known offsets from it.
2068 // Reason about it.
2069 if (OffsetA > OffsetB) {
2070 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
2071 return SizeB <= OffDiff;
2072 }
2073 if (OffsetA < OffsetB) {
2074 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
2075 return SizeA <= OffDiff;
2076 }
2077
2078 return false;
2079}
2080
2081/// If the instruction is an increment of a constant value, return the amount.
2083 int &Value) const {
2084 if (isPostIncrement(MI)) {
2085 unsigned BasePos = 0, OffsetPos = 0;
2086 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
2087 return false;
2088 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2089 if (OffsetOp.isImm()) {
2090 Value = OffsetOp.getImm();
2091 return true;
2092 }
2093 } else if (MI.getOpcode() == Hexagon::A2_addi) {
2094 const MachineOperand &AddOp = MI.getOperand(2);
2095 if (AddOp.isImm()) {
2096 Value = AddOp.getImm();
2097 return true;
2098 }
2099 }
2100
2101 return false;
2102}
2103
2104std::pair<unsigned, unsigned>
2106 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
2108}
2109
2112 using namespace HexagonII;
2113
2114 static const std::pair<unsigned, const char*> Flags[] = {
2115 {MO_PCREL, "hexagon-pcrel"},
2116 {MO_GOT, "hexagon-got"},
2117 {MO_LO16, "hexagon-lo16"},
2118 {MO_HI16, "hexagon-hi16"},
2119 {MO_GPREL, "hexagon-gprel"},
2120 {MO_GDGOT, "hexagon-gdgot"},
2121 {MO_GDPLT, "hexagon-gdplt"},
2122 {MO_IE, "hexagon-ie"},
2123 {MO_IEGOT, "hexagon-iegot"},
2124 {MO_TPREL, "hexagon-tprel"}
2125 };
2126 return ArrayRef(Flags);
2127}
2128
2131 using namespace HexagonII;
2132
2133 static const std::pair<unsigned, const char*> Flags[] = {
2134 {HMOTF_ConstExtended, "hexagon-ext"}
2135 };
2136 return ArrayRef(Flags);
2137}
2138
2141 const TargetRegisterClass *TRC;
2142 if (VT == MVT::i1) {
2143 TRC = &Hexagon::PredRegsRegClass;
2144 } else if (VT == MVT::i32 || VT == MVT::f32) {
2145 TRC = &Hexagon::IntRegsRegClass;
2146 } else if (VT == MVT::i64 || VT == MVT::f64) {
2147 TRC = &Hexagon::DoubleRegsRegClass;
2148 } else {
2149 llvm_unreachable("Cannot handle this register class");
2150 }
2151
2152 Register NewReg = MRI.createVirtualRegister(TRC);
2153 return NewReg;
2154}
2155
2159
2161 const uint64_t F = MI.getDesc().TSFlags;
2163}
2164
2168
2170 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&
2171 !MI.getDesc().mayStore() &&
2172 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&
2173 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&
2174 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();
2175}
2176
2177// Return true if the instruction is a compound branch instruction.
2179 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
2180}
2181
2182// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
2183// isFPImm and later getFPImm as well.
2185 const uint64_t F = MI.getDesc().TSFlags;
2187 if (isExtended) // Instruction must be extended.
2188 return true;
2189
2190 unsigned isExtendable =
2192 if (!isExtendable)
2193 return false;
2194
2195 if (MI.isCall())
2196 return false;
2197
2198 short ExtOpNum = getCExtOpNum(MI);
2199 const MachineOperand &MO = MI.getOperand(ExtOpNum);
2200 // Use MO operand flags to determine if MO
2201 // has the HMOTF_ConstExtended flag set.
2203 return true;
2204 // If this is a Machine BB address we are talking about, and it is
2205 // not marked as extended, say so.
2206 if (MO.isMBB())
2207 return false;
2208
2209 // We could be using an instruction with an extendable immediate and shoehorn
2210 // a global address into it. If it is a global address it will be constant
2211 // extended. We do this for COMBINE.
2212 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
2213 MO.isJTI() || MO.isCPI() || MO.isFPImm())
2214 return true;
2215
2216 // If the extendable operand is not 'Immediate' type, the instruction should
2217 // have 'isExtended' flag set.
2218 assert(MO.isImm() && "Extendable operand must be Immediate type");
2219
2220 int64_t Value = MO.getImm();
2222 int32_t SValue = Value;
2223 int32_t MinValue = getMinValue(MI);
2224 int32_t MaxValue = getMaxValue(MI);
2225 return SValue < MinValue || SValue > MaxValue;
2226 }
2227 uint32_t UValue = Value;
2228 uint32_t MinValue = getMinValue(MI);
2229 uint32_t MaxValue = getMaxValue(MI);
2230 return UValue < MinValue || UValue > MaxValue;
2231}
2232
2234 switch (MI.getOpcode()) {
2235 case Hexagon::L4_return:
2236 case Hexagon::L4_return_t:
2237 case Hexagon::L4_return_f:
2238 case Hexagon::L4_return_tnew_pnt:
2239 case Hexagon::L4_return_fnew_pnt:
2240 case Hexagon::L4_return_tnew_pt:
2241 case Hexagon::L4_return_fnew_pt:
2242 return true;
2243 }
2244 return false;
2245}
2246
2247// Return true when ConsMI uses a register defined by ProdMI.
2249 const MachineInstr &ConsMI) const {
2250 if (!ProdMI.getDesc().getNumDefs())
2251 return false;
2252 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
2253
2258
2259 parseOperands(ProdMI, DefsA, UsesA);
2260 parseOperands(ConsMI, DefsB, UsesB);
2261
2262 for (auto &RegA : DefsA)
2263 for (auto &RegB : UsesB) {
2264 // True data dependency.
2265 if (RegA == RegB)
2266 return true;
2267
2268 if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))
2269 return true;
2270
2271 if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))
2272 return true;
2273 }
2274
2275 return false;
2276}
2277
2278// Returns true if the instruction is already a .cur.
2280 switch (MI.getOpcode()) {
2281 case Hexagon::V6_vL32b_cur_pi:
2282 case Hexagon::V6_vL32b_cur_ai:
2283 return true;
2284 }
2285 return false;
2286}
2287
2288// Returns true, if any one of the operands is a dot new
2289// insn, whether it is predicated dot new or register dot new.
2292 return true;
2293
2294 return false;
2295}
2296
2297/// Symmetrical. See if these two instructions are fit for duplex pair.
2299 const MachineInstr &MIb) const {
2302 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
2303}
2304
2305bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
2306 return (Opcode == Hexagon::ENDLOOP0 ||
2307 Opcode == Hexagon::ENDLOOP1);
2308}
2309
2310bool HexagonInstrInfo::isExpr(unsigned OpType) const {
2311 switch(OpType) {
2318 return true;
2319 default:
2320 return false;
2321 }
2322}
2323
2325 const MCInstrDesc &MID = MI.getDesc();
2326 const uint64_t F = MID.TSFlags;
2328 return true;
2329
2330 // TODO: This is largely obsolete now. Will need to be removed
2331 // in consecutive patches.
2332 switch (MI.getOpcode()) {
2333 // PS_fi and PS_fia remain special cases.
2334 case Hexagon::PS_fi:
2335 case Hexagon::PS_fia:
2336 return true;
2337 default:
2338 return false;
2339 }
2340 return false;
2341}
2342
2343// This returns true in two cases:
2344// - The OP code itself indicates that this is an extended instruction.
2345// - One of MOs has been marked with HMOTF_ConstExtended flag.
2347 // First check if this is permanently extended op code.
2348 const uint64_t F = MI.getDesc().TSFlags;
2350 return true;
2351 // Use MO operand flags to determine if one of MI's operands
2352 // has HMOTF_ConstExtended flag set.
2353 for (const MachineOperand &MO : MI.operands())
2354 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
2355 return true;
2356 return false;
2357}
2358
2360 unsigned Opcode = MI.getOpcode();
2361 const uint64_t F = get(Opcode).TSFlags;
2362 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
2363}
2364
2365// No V60 HVX VMEM with A_INDIRECT.
2367 const MachineInstr &J) const {
2368 if (!isHVXVec(I))
2369 return false;
2370 if (!I.mayLoad() && !I.mayStore())
2371 return false;
2372 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2373}
2374
2376 switch (MI.getOpcode()) {
2377 case Hexagon::J2_callr:
2378 case Hexagon::J2_callrf:
2379 case Hexagon::J2_callrt:
2380 case Hexagon::PS_call_nr:
2381 return true;
2382 }
2383 return false;
2384}
2385
2387 switch (MI.getOpcode()) {
2388 case Hexagon::L4_return:
2389 case Hexagon::L4_return_t:
2390 case Hexagon::L4_return_f:
2391 case Hexagon::L4_return_fnew_pnt:
2392 case Hexagon::L4_return_fnew_pt:
2393 case Hexagon::L4_return_tnew_pnt:
2394 case Hexagon::L4_return_tnew_pt:
2395 return true;
2396 }
2397 return false;
2398}
2399
2401 switch (MI.getOpcode()) {
2402 case Hexagon::J2_jumpr:
2403 case Hexagon::J2_jumprt:
2404 case Hexagon::J2_jumprf:
2405 case Hexagon::J2_jumprtnewpt:
2406 case Hexagon::J2_jumprfnewpt:
2407 case Hexagon::J2_jumprtnew:
2408 case Hexagon::J2_jumprfnew:
2409 return true;
2410 }
2411 return false;
2412}
2413
2414// Return true if a given MI can accommodate given offset.
2415// Use abs estimate as oppose to the exact number.
2416// TODO: This will need to be changed to use MC level
2417// definition of instruction extendable field size.
2419 unsigned offset) const {
2420 // This selection of jump instructions matches to that what
2421 // analyzeBranch can parse, plus NVJ.
2422 if (isNewValueJump(MI)) // r9:2
2423 return isInt<11>(offset);
2424
2425 switch (MI.getOpcode()) {
2426 // Still missing Jump to address condition on register value.
2427 default:
2428 return false;
2429 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2430 case Hexagon::J2_call:
2431 case Hexagon::PS_call_nr:
2432 return isInt<24>(offset);
2433 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2434 case Hexagon::J2_jumpf:
2435 case Hexagon::J2_jumptnew:
2436 case Hexagon::J2_jumptnewpt:
2437 case Hexagon::J2_jumpfnew:
2438 case Hexagon::J2_jumpfnewpt:
2439 case Hexagon::J2_callt:
2440 case Hexagon::J2_callf:
2441 return isInt<17>(offset);
2442 case Hexagon::J2_loop0i:
2443 case Hexagon::J2_loop0iext:
2444 case Hexagon::J2_loop0r:
2445 case Hexagon::J2_loop0rext:
2446 case Hexagon::J2_loop1i:
2447 case Hexagon::J2_loop1iext:
2448 case Hexagon::J2_loop1r:
2449 case Hexagon::J2_loop1rext:
2450 return isInt<9>(offset);
2451 // TODO: Add all the compound branches here. Can we do this in Relation model?
2452 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2453 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2454 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
2455 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
2456 return isInt<11>(offset);
2457 }
2458}
2459
2461 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2462 // resource, but all operands can be received late like an ALU instruction.
2464}
2465
2467 unsigned Opcode = MI.getOpcode();
2468 return Opcode == Hexagon::J2_loop0i ||
2469 Opcode == Hexagon::J2_loop0r ||
2470 Opcode == Hexagon::J2_loop0iext ||
2471 Opcode == Hexagon::J2_loop0rext ||
2472 Opcode == Hexagon::J2_loop1i ||
2473 Opcode == Hexagon::J2_loop1r ||
2474 Opcode == Hexagon::J2_loop1iext ||
2475 Opcode == Hexagon::J2_loop1rext;
2476}
2477
2479 switch (MI.getOpcode()) {
2480 default: return false;
2481 case Hexagon::L4_iadd_memopw_io:
2482 case Hexagon::L4_isub_memopw_io:
2483 case Hexagon::L4_add_memopw_io:
2484 case Hexagon::L4_sub_memopw_io:
2485 case Hexagon::L4_and_memopw_io:
2486 case Hexagon::L4_or_memopw_io:
2487 case Hexagon::L4_iadd_memoph_io:
2488 case Hexagon::L4_isub_memoph_io:
2489 case Hexagon::L4_add_memoph_io:
2490 case Hexagon::L4_sub_memoph_io:
2491 case Hexagon::L4_and_memoph_io:
2492 case Hexagon::L4_or_memoph_io:
2493 case Hexagon::L4_iadd_memopb_io:
2494 case Hexagon::L4_isub_memopb_io:
2495 case Hexagon::L4_add_memopb_io:
2496 case Hexagon::L4_sub_memopb_io:
2497 case Hexagon::L4_and_memopb_io:
2498 case Hexagon::L4_or_memopb_io:
2499 case Hexagon::L4_ior_memopb_io:
2500 case Hexagon::L4_ior_memoph_io:
2501 case Hexagon::L4_ior_memopw_io:
2502 case Hexagon::L4_iand_memopb_io:
2503 case Hexagon::L4_iand_memoph_io:
2504 case Hexagon::L4_iand_memopw_io:
2505 return true;
2506 }
2507 return false;
2508}
2509
2511 const uint64_t F = MI.getDesc().TSFlags;
2513}
2514
2515bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2516 const uint64_t F = get(Opcode).TSFlags;
2518}
2519
2523
2525 return isNewValue(MI) && MI.isBranch();
2526}
2527
2528bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2529 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2530}
2531
2533 const uint64_t F = MI.getDesc().TSFlags;
2535}
2536
2537bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2538 const uint64_t F = get(Opcode).TSFlags;
2540}
2541
2542// Returns true if a particular operand is extendable for an instruction.
2544 unsigned OperandNum) const {
2545 const uint64_t F = MI.getDesc().TSFlags;
2547 == OperandNum;
2548}
2549
2551 const uint64_t F = MI.getDesc().TSFlags;
2554}
2555
2556bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2557 const uint64_t F = get(Opcode).TSFlags;
2558 assert(isPredicated(Opcode));
2560}
2561
2563 const uint64_t F = MI.getDesc().TSFlags;
2564 return !((F >> HexagonII::PredicatedFalsePos) &
2566}
2567
2568bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2569 const uint64_t F = get(Opcode).TSFlags;
2570 // Make sure that the instruction is predicated.
2572 return !((F >> HexagonII::PredicatedFalsePos) &
2574}
2575
2576bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2577 const uint64_t F = get(Opcode).TSFlags;
2579}
2580
2581bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2582 const uint64_t F = get(Opcode).TSFlags;
2584}
2585
2586bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2587 const uint64_t F = get(Opcode).TSFlags;
2588 assert(get(Opcode).isBranch() &&
2589 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2591}
2592
2594 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2595 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2596 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2597 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
2598}
2599
2601 switch (MI.getOpcode()) {
2602 // Byte
2603 case Hexagon::L2_loadrb_io:
2604 case Hexagon::L4_loadrb_ur:
2605 case Hexagon::L4_loadrb_ap:
2606 case Hexagon::L2_loadrb_pr:
2607 case Hexagon::L2_loadrb_pbr:
2608 case Hexagon::L2_loadrb_pi:
2609 case Hexagon::L2_loadrb_pci:
2610 case Hexagon::L2_loadrb_pcr:
2611 case Hexagon::L2_loadbsw2_io:
2612 case Hexagon::L4_loadbsw2_ur:
2613 case Hexagon::L4_loadbsw2_ap:
2614 case Hexagon::L2_loadbsw2_pr:
2615 case Hexagon::L2_loadbsw2_pbr:
2616 case Hexagon::L2_loadbsw2_pi:
2617 case Hexagon::L2_loadbsw2_pci:
2618 case Hexagon::L2_loadbsw2_pcr:
2619 case Hexagon::L2_loadbsw4_io:
2620 case Hexagon::L4_loadbsw4_ur:
2621 case Hexagon::L4_loadbsw4_ap:
2622 case Hexagon::L2_loadbsw4_pr:
2623 case Hexagon::L2_loadbsw4_pbr:
2624 case Hexagon::L2_loadbsw4_pi:
2625 case Hexagon::L2_loadbsw4_pci:
2626 case Hexagon::L2_loadbsw4_pcr:
2627 case Hexagon::L4_loadrb_rr:
2628 case Hexagon::L2_ploadrbt_io:
2629 case Hexagon::L2_ploadrbt_pi:
2630 case Hexagon::L2_ploadrbf_io:
2631 case Hexagon::L2_ploadrbf_pi:
2632 case Hexagon::L2_ploadrbtnew_io:
2633 case Hexagon::L2_ploadrbfnew_io:
2634 case Hexagon::L4_ploadrbt_rr:
2635 case Hexagon::L4_ploadrbf_rr:
2636 case Hexagon::L4_ploadrbtnew_rr:
2637 case Hexagon::L4_ploadrbfnew_rr:
2638 case Hexagon::L2_ploadrbtnew_pi:
2639 case Hexagon::L2_ploadrbfnew_pi:
2640 case Hexagon::L4_ploadrbt_abs:
2641 case Hexagon::L4_ploadrbf_abs:
2642 case Hexagon::L4_ploadrbtnew_abs:
2643 case Hexagon::L4_ploadrbfnew_abs:
2644 case Hexagon::L2_loadrbgp:
2645 // Half
2646 case Hexagon::L2_loadrh_io:
2647 case Hexagon::L4_loadrh_ur:
2648 case Hexagon::L4_loadrh_ap:
2649 case Hexagon::L2_loadrh_pr:
2650 case Hexagon::L2_loadrh_pbr:
2651 case Hexagon::L2_loadrh_pi:
2652 case Hexagon::L2_loadrh_pci:
2653 case Hexagon::L2_loadrh_pcr:
2654 case Hexagon::L4_loadrh_rr:
2655 case Hexagon::L2_ploadrht_io:
2656 case Hexagon::L2_ploadrht_pi:
2657 case Hexagon::L2_ploadrhf_io:
2658 case Hexagon::L2_ploadrhf_pi:
2659 case Hexagon::L2_ploadrhtnew_io:
2660 case Hexagon::L2_ploadrhfnew_io:
2661 case Hexagon::L4_ploadrht_rr:
2662 case Hexagon::L4_ploadrhf_rr:
2663 case Hexagon::L4_ploadrhtnew_rr:
2664 case Hexagon::L4_ploadrhfnew_rr:
2665 case Hexagon::L2_ploadrhtnew_pi:
2666 case Hexagon::L2_ploadrhfnew_pi:
2667 case Hexagon::L4_ploadrht_abs:
2668 case Hexagon::L4_ploadrhf_abs:
2669 case Hexagon::L4_ploadrhtnew_abs:
2670 case Hexagon::L4_ploadrhfnew_abs:
2671 case Hexagon::L2_loadrhgp:
2672 return true;
2673 default:
2674 return false;
2675 }
2676}
2677
2679 const uint64_t F = MI.getDesc().TSFlags;
2681}
2682
2684 switch (MI.getOpcode()) {
2685 case Hexagon::STriw_pred:
2686 case Hexagon::LDriw_pred:
2687 return true;
2688 default:
2689 return false;
2690 }
2691}
2692
2694 if (!MI.isBranch())
2695 return false;
2696
2697 for (auto &Op : MI.operands())
2698 if (Op.isGlobal() || Op.isSymbol())
2699 return true;
2700 return false;
2701}
2702
2703// Returns true when SU has a timing class TC1.
2705 unsigned SchedClass = MI.getDesc().getSchedClass();
2706 return is_TC1(SchedClass);
2707}
2708
2710 unsigned SchedClass = MI.getDesc().getSchedClass();
2711 return is_TC2(SchedClass);
2712}
2713
2715 unsigned SchedClass = MI.getDesc().getSchedClass();
2716 return is_TC2early(SchedClass);
2717}
2718
2720 unsigned SchedClass = MI.getDesc().getSchedClass();
2721 return is_TC4x(SchedClass);
2722}
2723
2724// Schedule this ASAP.
2726 const MachineInstr &MI2) const {
2727 if (mayBeCurLoad(MI1)) {
2728 // if (result of SU is used in Next) return true;
2729 Register DstReg = MI1.getOperand(0).getReg();
2730 int N = MI2.getNumOperands();
2731 for (int I = 0; I < N; I++)
2732 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
2733 return true;
2734 }
2735 if (mayBeNewStore(MI2))
2736 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2737 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2738 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
2739 return true;
2740 return false;
2741}
2742
2744 const uint64_t V = getType(MI);
2746}
2747
2748// Check if the Offset is a valid auto-inc imm by Load/Store Type.
2750 int Size = VT.getSizeInBits() / 8;
2751 if (Offset % Size != 0)
2752 return false;
2753 int Count = Offset / Size;
2754
2755 switch (VT.getSimpleVT().SimpleTy) {
2756 // For scalars the auto-inc is s4
2757 case MVT::i8:
2758 case MVT::i16:
2759 case MVT::i32:
2760 case MVT::i64:
2761 case MVT::f32:
2762 case MVT::f64:
2763 case MVT::v2i16:
2764 case MVT::v2i32:
2765 case MVT::v4i8:
2766 case MVT::v4i16:
2767 case MVT::v8i8:
2768 return isInt<4>(Count);
2769 // For HVX vectors the auto-inc is s3
2770 case MVT::v64i8:
2771 case MVT::v32i16:
2772 case MVT::v16i32:
2773 case MVT::v8i64:
2774 case MVT::v128i8:
2775 case MVT::v64i16:
2776 case MVT::v32i32:
2777 case MVT::v16i64:
2778 return isInt<3>(Count);
2779 default:
2780 break;
2781 }
2782
2783 llvm_unreachable("Not an valid type!");
2784}
2785
2786bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2787 bool Extend) const {
2788 // This function is to check whether the "Offset" is in the correct range of
2789 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
2790 // inserted to calculate the final address. Due to this reason, the function
2791 // assumes that the "Offset" has correct alignment.
2792 // We used to assert if the offset was not properly aligned, however,
2793 // there are cases where a misaligned pointer recast can cause this
2794 // problem, and we need to allow for it. The front end warns of such
2795 // misaligns with respect to load size.
2796 switch (Opcode) {
2797 case Hexagon::PS_vstorerq_ai:
2798 case Hexagon::PS_vstorerv_ai:
2799 case Hexagon::PS_vstorerw_ai:
2800 case Hexagon::PS_vstorerw_nt_ai:
2801 case Hexagon::PS_vloadrq_ai:
2802 case Hexagon::PS_vloadrv_ai:
2803 case Hexagon::PS_vloadrw_ai:
2804 case Hexagon::PS_vloadrw_nt_ai:
2805 case Hexagon::V6_vL32b_ai:
2806 case Hexagon::V6_vS32b_ai:
2807 case Hexagon::V6_vS32b_pred_ai:
2808 case Hexagon::V6_vS32b_npred_ai:
2809 case Hexagon::V6_vS32b_qpred_ai:
2810 case Hexagon::V6_vS32b_nqpred_ai:
2811 case Hexagon::V6_vS32b_new_ai:
2812 case Hexagon::V6_vS32b_new_pred_ai:
2813 case Hexagon::V6_vS32b_new_npred_ai:
2814 case Hexagon::V6_vS32b_nt_pred_ai:
2815 case Hexagon::V6_vS32b_nt_npred_ai:
2816 case Hexagon::V6_vS32b_nt_new_ai:
2817 case Hexagon::V6_vS32b_nt_new_pred_ai:
2818 case Hexagon::V6_vS32b_nt_new_npred_ai:
2819 case Hexagon::V6_vS32b_nt_qpred_ai:
2820 case Hexagon::V6_vS32b_nt_nqpred_ai:
2821 case Hexagon::V6_vL32b_nt_ai:
2822 case Hexagon::V6_vS32b_nt_ai:
2823 case Hexagon::V6_vL32Ub_ai:
2824 case Hexagon::V6_vS32Ub_ai:
2825 case Hexagon::V6_vL32b_cur_ai:
2826 case Hexagon::V6_vL32b_tmp_ai:
2827 case Hexagon::V6_vL32b_pred_ai:
2828 case Hexagon::V6_vL32b_npred_ai:
2829 case Hexagon::V6_vL32b_cur_pred_ai:
2830 case Hexagon::V6_vL32b_cur_npred_ai:
2831 case Hexagon::V6_vL32b_tmp_pred_ai:
2832 case Hexagon::V6_vL32b_tmp_npred_ai:
2833 case Hexagon::V6_vL32b_nt_cur_ai:
2834 case Hexagon::V6_vL32b_nt_tmp_ai:
2835 case Hexagon::V6_vL32b_nt_pred_ai:
2836 case Hexagon::V6_vL32b_nt_npred_ai:
2837 case Hexagon::V6_vL32b_nt_cur_pred_ai:
2838 case Hexagon::V6_vL32b_nt_cur_npred_ai:
2839 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
2840 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
2841 case Hexagon::V6_vS32Ub_pred_ai:
2842 case Hexagon::V6_vS32Ub_npred_ai:
2843 case Hexagon::V6_vgathermh_pseudo:
2844 case Hexagon::V6_vgather_vscatter_mh_pseudo:
2845 case Hexagon::V6_vgathermw_pseudo:
2846 case Hexagon::V6_vgathermhw_pseudo:
2847 case Hexagon::V6_vgathermhq_pseudo:
2848 case Hexagon::V6_vgathermwq_pseudo:
2849 case Hexagon::V6_vgathermhwq_pseudo: {
2850 unsigned VectorSize = RegInfo.getSpillSize(Hexagon::HvxVRRegClass);
2851 assert(isPowerOf2_32(VectorSize));
2852 if (Offset & (VectorSize-1))
2853 return false;
2854 return isInt<4>(Offset >> Log2_32(VectorSize));
2855 }
2856
2857 case Hexagon::J2_loop0i:
2858 case Hexagon::J2_loop1i:
2859 return isUInt<10>(Offset);
2860
2861 case Hexagon::S4_storeirb_io:
2862 case Hexagon::S4_storeirbt_io:
2863 case Hexagon::S4_storeirbf_io:
2864 return isUInt<6>(Offset);
2865
2866 case Hexagon::S4_storeirh_io:
2867 case Hexagon::S4_storeirht_io:
2868 case Hexagon::S4_storeirhf_io:
2869 return isShiftedUInt<6,1>(Offset);
2870
2871 case Hexagon::S4_storeiri_io:
2872 case Hexagon::S4_storeirit_io:
2873 case Hexagon::S4_storeirif_io:
2874 return isShiftedUInt<6,2>(Offset);
2875 // Handle these two compare instructions that are not extendable.
2876 case Hexagon::A4_cmpbeqi:
2877 return isUInt<8>(Offset);
2878 case Hexagon::A4_cmpbgti:
2879 return isInt<8>(Offset);
2880 }
2881
2882 if (Extend)
2883 return true;
2884
2885 switch (Opcode) {
2886 case Hexagon::L2_loadri_io:
2887 case Hexagon::S2_storeri_io:
2888 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2890
2891 case Hexagon::L2_loadrd_io:
2892 case Hexagon::S2_storerd_io:
2893 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2895
2896 case Hexagon::L2_loadrh_io:
2897 case Hexagon::L2_loadruh_io:
2898 case Hexagon::S2_storerh_io:
2899 case Hexagon::S2_storerf_io:
2900 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2902
2903 case Hexagon::L2_loadrb_io:
2904 case Hexagon::L2_loadrub_io:
2905 case Hexagon::S2_storerb_io:
2906 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2908
2909 case Hexagon::A2_addi:
2910 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2912
2913 case Hexagon::L4_iadd_memopw_io:
2914 case Hexagon::L4_isub_memopw_io:
2915 case Hexagon::L4_add_memopw_io:
2916 case Hexagon::L4_sub_memopw_io:
2917 case Hexagon::L4_iand_memopw_io:
2918 case Hexagon::L4_ior_memopw_io:
2919 case Hexagon::L4_and_memopw_io:
2920 case Hexagon::L4_or_memopw_io:
2921 return (0 <= Offset && Offset <= 255);
2922
2923 case Hexagon::L4_iadd_memoph_io:
2924 case Hexagon::L4_isub_memoph_io:
2925 case Hexagon::L4_add_memoph_io:
2926 case Hexagon::L4_sub_memoph_io:
2927 case Hexagon::L4_iand_memoph_io:
2928 case Hexagon::L4_ior_memoph_io:
2929 case Hexagon::L4_and_memoph_io:
2930 case Hexagon::L4_or_memoph_io:
2931 return (0 <= Offset && Offset <= 127);
2932
2933 case Hexagon::L4_iadd_memopb_io:
2934 case Hexagon::L4_isub_memopb_io:
2935 case Hexagon::L4_add_memopb_io:
2936 case Hexagon::L4_sub_memopb_io:
2937 case Hexagon::L4_iand_memopb_io:
2938 case Hexagon::L4_ior_memopb_io:
2939 case Hexagon::L4_and_memopb_io:
2940 case Hexagon::L4_or_memopb_io:
2941 return (0 <= Offset && Offset <= 63);
2942
2943 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
2944 // any size. Later pass knows how to handle it.
2945 case Hexagon::STriw_pred:
2946 case Hexagon::LDriw_pred:
2947 case Hexagon::STriw_ctr:
2948 case Hexagon::LDriw_ctr:
2949 return true;
2950
2951 case Hexagon::PS_fi:
2952 case Hexagon::PS_fia:
2953 case Hexagon::INLINEASM:
2954 return true;
2955
2956 case Hexagon::L2_ploadrbt_io:
2957 case Hexagon::L2_ploadrbf_io:
2958 case Hexagon::L2_ploadrubt_io:
2959 case Hexagon::L2_ploadrubf_io:
2960 case Hexagon::S2_pstorerbt_io:
2961 case Hexagon::S2_pstorerbf_io:
2962 return isUInt<6>(Offset);
2963
2964 case Hexagon::L2_ploadrht_io:
2965 case Hexagon::L2_ploadrhf_io:
2966 case Hexagon::L2_ploadruht_io:
2967 case Hexagon::L2_ploadruhf_io:
2968 case Hexagon::S2_pstorerht_io:
2969 case Hexagon::S2_pstorerhf_io:
2970 case Hexagon::S2_pstorerft_io:
2971 case Hexagon::S2_pstorerff_io:
2972 return isShiftedUInt<6,1>(Offset);
2973
2974 case Hexagon::L2_ploadrit_io:
2975 case Hexagon::L2_ploadrif_io:
2976 case Hexagon::S2_pstorerit_io:
2977 case Hexagon::S2_pstorerif_io:
2978 return isShiftedUInt<6,2>(Offset);
2979
2980 case Hexagon::L2_ploadrdt_io:
2981 case Hexagon::L2_ploadrdf_io:
2982 case Hexagon::S2_pstorerdt_io:
2983 case Hexagon::S2_pstorerdf_io:
2984 return isShiftedUInt<6,3>(Offset);
2985
2986 case Hexagon::L2_loadbsw2_io:
2987 case Hexagon::L2_loadbzw2_io:
2988 return isShiftedInt<11,1>(Offset);
2989
2990 case Hexagon::L2_loadbsw4_io:
2991 case Hexagon::L2_loadbzw4_io:
2992 return isShiftedInt<11,2>(Offset);
2993 } // switch
2994
2995 dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)
2996 << ")\n";
2997 llvm_unreachable("No offset range is defined for this opcode. "
2998 "Please define it in the above switch statement!");
2999}
3000
3002 return isHVXVec(MI) && isAccumulator(MI);
3003}
3004
3006 const uint64_t F = get(MI.getOpcode()).TSFlags;
3007 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
3008 return
3009 V == HexagonII::TypeCVI_VA ||
3011}
3012
3014 const MachineInstr &ConsMI) const {
3015 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
3016 return true;
3017
3018 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
3019 return true;
3020
3021 if (mayBeNewStore(ConsMI))
3022 return true;
3023
3024 return false;
3025}
3026
3028 switch (MI.getOpcode()) {
3029 // Byte
3030 case Hexagon::L2_loadrub_io:
3031 case Hexagon::L4_loadrub_ur:
3032 case Hexagon::L4_loadrub_ap:
3033 case Hexagon::L2_loadrub_pr:
3034 case Hexagon::L2_loadrub_pbr:
3035 case Hexagon::L2_loadrub_pi:
3036 case Hexagon::L2_loadrub_pci:
3037 case Hexagon::L2_loadrub_pcr:
3038 case Hexagon::L2_loadbzw2_io:
3039 case Hexagon::L4_loadbzw2_ur:
3040 case Hexagon::L4_loadbzw2_ap:
3041 case Hexagon::L2_loadbzw2_pr:
3042 case Hexagon::L2_loadbzw2_pbr:
3043 case Hexagon::L2_loadbzw2_pi:
3044 case Hexagon::L2_loadbzw2_pci:
3045 case Hexagon::L2_loadbzw2_pcr:
3046 case Hexagon::L2_loadbzw4_io:
3047 case Hexagon::L4_loadbzw4_ur:
3048 case Hexagon::L4_loadbzw4_ap:
3049 case Hexagon::L2_loadbzw4_pr:
3050 case Hexagon::L2_loadbzw4_pbr:
3051 case Hexagon::L2_loadbzw4_pi:
3052 case Hexagon::L2_loadbzw4_pci:
3053 case Hexagon::L2_loadbzw4_pcr:
3054 case Hexagon::L4_loadrub_rr:
3055 case Hexagon::L2_ploadrubt_io:
3056 case Hexagon::L2_ploadrubt_pi:
3057 case Hexagon::L2_ploadrubf_io:
3058 case Hexagon::L2_ploadrubf_pi:
3059 case Hexagon::L2_ploadrubtnew_io:
3060 case Hexagon::L2_ploadrubfnew_io:
3061 case Hexagon::L4_ploadrubt_rr:
3062 case Hexagon::L4_ploadrubf_rr:
3063 case Hexagon::L4_ploadrubtnew_rr:
3064 case Hexagon::L4_ploadrubfnew_rr:
3065 case Hexagon::L2_ploadrubtnew_pi:
3066 case Hexagon::L2_ploadrubfnew_pi:
3067 case Hexagon::L4_ploadrubt_abs:
3068 case Hexagon::L4_ploadrubf_abs:
3069 case Hexagon::L4_ploadrubtnew_abs:
3070 case Hexagon::L4_ploadrubfnew_abs:
3071 case Hexagon::L2_loadrubgp:
3072 // Half
3073 case Hexagon::L2_loadruh_io:
3074 case Hexagon::L4_loadruh_ur:
3075 case Hexagon::L4_loadruh_ap:
3076 case Hexagon::L2_loadruh_pr:
3077 case Hexagon::L2_loadruh_pbr:
3078 case Hexagon::L2_loadruh_pi:
3079 case Hexagon::L2_loadruh_pci:
3080 case Hexagon::L2_loadruh_pcr:
3081 case Hexagon::L4_loadruh_rr:
3082 case Hexagon::L2_ploadruht_io:
3083 case Hexagon::L2_ploadruht_pi:
3084 case Hexagon::L2_ploadruhf_io:
3085 case Hexagon::L2_ploadruhf_pi:
3086 case Hexagon::L2_ploadruhtnew_io:
3087 case Hexagon::L2_ploadruhfnew_io:
3088 case Hexagon::L4_ploadruht_rr:
3089 case Hexagon::L4_ploadruhf_rr:
3090 case Hexagon::L4_ploadruhtnew_rr:
3091 case Hexagon::L4_ploadruhfnew_rr:
3092 case Hexagon::L2_ploadruhtnew_pi:
3093 case Hexagon::L2_ploadruhfnew_pi:
3094 case Hexagon::L4_ploadruht_abs:
3095 case Hexagon::L4_ploadruhf_abs:
3096 case Hexagon::L4_ploadruhtnew_abs:
3097 case Hexagon::L4_ploadruhfnew_abs:
3098 case Hexagon::L2_loadruhgp:
3099 return true;
3100 default:
3101 return false;
3102 }
3103}
3104
3105// Add latency to instruction.
3107 const MachineInstr &MI2) const {
3108 if (isHVXVec(MI1) && isHVXVec(MI2))
3109 if (!isVecUsableNextPacket(MI1, MI2))
3110 return true;
3111 return false;
3112}
3113
3114/// Get the base register and byte offset of a load/store instr.
3117 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const {
3118 OffsetIsScalable = false;
3119 const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);
3120 if (!BaseOp || !BaseOp->isReg())
3121 return false;
3122 BaseOps.push_back(BaseOp);
3123 return true;
3124}
3125
3126/// Can these instructions execute at the same time in a bundle.
3128 const MachineInstr &Second) const {
3129 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
3130 const MachineOperand &Op = Second.getOperand(0);
3131 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
3132 return true;
3133 }
3135 return false;
3136 if (mayBeNewStore(Second)) {
3137 // Make sure the definition of the first instruction is the value being
3138 // stored.
3139 const MachineOperand &Stored =
3140 Second.getOperand(Second.getNumOperands() - 1);
3141 if (!Stored.isReg())
3142 return false;
3143 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
3144 const MachineOperand &Op = First.getOperand(i);
3145 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
3146 return true;
3147 }
3148 }
3149 return false;
3150}
3151
3153 unsigned Opc = CallMI.getOpcode();
3154 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
3155}
3156
3158 for (auto &I : *B)
3159 if (I.isEHLabel())
3160 return true;
3161 return false;
3162}
3163
3164// Returns true if an instruction can be converted into a non-extended
3165// equivalent instruction.
3167 short NonExtOpcode;
3168 // Check if the instruction has a register form that uses register in place
3169 // of the extended operand, if so return that as the non-extended form.
3170 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
3171 return true;
3172
3173 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
3174 // Check addressing mode and retrieve non-ext equivalent instruction.
3175
3176 switch (getAddrMode(MI)) {
3178 // Load/store with absolute addressing mode can be converted into
3179 // base+offset mode.
3180 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());
3181 break;
3183 // Load/store with base+offset addressing mode can be converted into
3184 // base+register offset addressing mode. However left shift operand should
3185 // be set to 0.
3186 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());
3187 break;
3189 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
3190 break;
3191 default:
3192 return false;
3193 }
3194 if (NonExtOpcode < 0)
3195 return false;
3196 return true;
3197 }
3198 return false;
3199}
3200
3202 const {
3203 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
3204 while (I != E) {
3205 if (I->isBarrier())
3206 return true;
3207 ++I;
3208 }
3209 return false;
3210}
3211
3212// Returns true, if a LD insn can be promoted to a cur load.
3214 const uint64_t F = MI.getDesc().TSFlags;
3216 Subtarget.hasV60Ops();
3217}
3218
3219// Returns true, if a ST insn can be promoted to a new-value store.
3221 if (MI.mayStore() && !Subtarget.useNewValueStores())
3222 return false;
3223
3224 const uint64_t F = MI.getDesc().TSFlags;
3226}
3227
3229 const MachineInstr &ConsMI) const {
3230 // There is no stall when ProdMI is not a V60 vector.
3231 if (!isHVXVec(ProdMI))
3232 return false;
3233
3234 // There is no stall when ProdMI and ConsMI are not dependent.
3235 if (!isDependent(ProdMI, ConsMI))
3236 return false;
3237
3238 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
3239 // are scheduled in consecutive packets.
3240 if (isVecUsableNextPacket(ProdMI, ConsMI))
3241 return false;
3242
3243 return true;
3244}
3245
3248 // There is no stall when I is not a V60 vector.
3249 if (!isHVXVec(MI))
3250 return false;
3251
3253 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
3254
3255 if (!MII->isBundle())
3256 return producesStall(*MII, MI);
3257
3258 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
3259 const MachineInstr &J = *MII;
3260 if (producesStall(J, MI))
3261 return true;
3262 }
3263 return false;
3264}
3265
3267 Register PredReg) const {
3268 for (const MachineOperand &MO : MI.operands()) {
3269 // Predicate register must be explicitly defined.
3270 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
3271 return false;
3272 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
3273 return false;
3274 }
3275
3276 // Instruction that produce late predicate cannot be used as sources of
3277 // dot-new.
3278 switch (MI.getOpcode()) {
3279 case Hexagon::A4_addp_c:
3280 case Hexagon::A4_subp_c:
3281 case Hexagon::A4_tlbmatch:
3282 case Hexagon::A5_ACS:
3283 case Hexagon::F2_sfinvsqrta:
3284 case Hexagon::F2_sfrecipa:
3285 case Hexagon::J2_endloop0:
3286 case Hexagon::J2_endloop01:
3287 case Hexagon::J2_ploop1si:
3288 case Hexagon::J2_ploop1sr:
3289 case Hexagon::J2_ploop2si:
3290 case Hexagon::J2_ploop2sr:
3291 case Hexagon::J2_ploop3si:
3292 case Hexagon::J2_ploop3sr:
3293 case Hexagon::S2_cabacdecbin:
3294 case Hexagon::S2_storew_locked:
3295 case Hexagon::S4_stored_locked:
3296 return false;
3297 }
3298 return true;
3299}
3300
3301bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
3302 return Opcode == Hexagon::J2_jumpt ||
3303 Opcode == Hexagon::J2_jumptpt ||
3304 Opcode == Hexagon::J2_jumpf ||
3305 Opcode == Hexagon::J2_jumpfpt ||
3306 Opcode == Hexagon::J2_jumptnew ||
3307 Opcode == Hexagon::J2_jumpfnew ||
3308 Opcode == Hexagon::J2_jumptnewpt ||
3309 Opcode == Hexagon::J2_jumpfnewpt;
3310}
3311
3313 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
3314 return false;
3315 return !isPredicatedTrue(Cond[0].getImm());
3316}
3317
3319 const uint64_t F = MI.getDesc().TSFlags;
3321}
3322
3323// Returns the base register in a memory access (load/store). The offset is
3324// returned in Offset and the access size is returned in AccessSize.
3325// If the base operand has a subregister or the offset field does not contain
3326// an immediate value, return nullptr.
3329 LocationSize &AccessSize) const {
3330 // Return if it is not a base+offset type instruction or a MemOp.
3334 return nullptr;
3335
3337
3338 unsigned BasePos = 0, OffsetPos = 0;
3339 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
3340 return nullptr;
3341
3342 // Post increment updates its EA after the mem access,
3343 // so we need to treat its offset as zero.
3344 if (isPostIncrement(MI)) {
3345 Offset = 0;
3346 } else {
3347 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
3348 if (!OffsetOp.isImm())
3349 return nullptr;
3350 Offset = OffsetOp.getImm();
3351 }
3352
3353 const MachineOperand &BaseOp = MI.getOperand(BasePos);
3354 if (BaseOp.getSubReg() != 0)
3355 return nullptr;
3356 return &const_cast<MachineOperand&>(BaseOp);
3357}
3358
3359/// Return the position of the base and offset operands for this instruction.
3361 unsigned &BasePos, unsigned &OffsetPos) const {
3363 return false;
3364
3365 // Deal with memops first.
3366 if (isMemOp(MI)) {
3367 BasePos = 0;
3368 OffsetPos = 1;
3369 } else if (MI.mayStore()) {
3370 BasePos = 0;
3371 OffsetPos = 1;
3372 } else if (MI.mayLoad()) {
3373 BasePos = 1;
3374 OffsetPos = 2;
3375 } else
3376 return false;
3377
3378 if (isPredicated(MI)) {
3379 BasePos++;
3380 OffsetPos++;
3381 }
3382 if (isPostIncrement(MI)) {
3383 BasePos++;
3384 OffsetPos++;
3385 }
3386
3387 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
3388 return false;
3389
3390 return true;
3391}
3392
3393// Inserts branching instructions in reverse order of their occurrence.
3394// e.g. jump_t t1 (i1)
3395// jump t2 (i2)
3396// Jumpers = {i2, i1}
3398 MachineBasicBlock& MBB) const {
3400 // If the block has no terminators, it just falls into the block after it.
3402 if (I == MBB.instr_begin())
3403 return Jumpers;
3404
3405 // A basic block may looks like this:
3406 //
3407 // [ insn
3408 // EH_LABEL
3409 // insn
3410 // insn
3411 // insn
3412 // EH_LABEL
3413 // insn ]
3414 //
3415 // It has two succs but does not have a terminator
3416 // Don't know how to handle it.
3417 do {
3418 --I;
3419 if (I->isEHLabel())
3420 return Jumpers;
3421 } while (I != MBB.instr_begin());
3422
3423 I = MBB.instr_end();
3424 --I;
3425
3426 while (I->isDebugInstr()) {
3427 if (I == MBB.instr_begin())
3428 return Jumpers;
3429 --I;
3430 }
3431 if (!isUnpredicatedTerminator(*I))
3432 return Jumpers;
3433
3434 // Get the last instruction in the block.
3435 MachineInstr *LastInst = &*I;
3436 Jumpers.push_back(LastInst);
3437 MachineInstr *SecondLastInst = nullptr;
3438 // Find one more terminator if present.
3439 do {
3440 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
3441 if (!SecondLastInst) {
3442 SecondLastInst = &*I;
3443 Jumpers.push_back(SecondLastInst);
3444 } else // This is a third branch.
3445 return Jumpers;
3446 }
3447 if (I == MBB.instr_begin())
3448 break;
3449 --I;
3450 } while (true);
3451 return Jumpers;
3452}
3453
3454// Returns Operand Index for the constant extended instruction.
3456 const uint64_t F = MI.getDesc().TSFlags;
3458}
3459
3460// See if instruction could potentially be a duplex candidate.
3461// If so, return its group. Zero otherwise.
3463 const MachineInstr &MI) const {
3464 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3465
3466 switch (MI.getOpcode()) {
3467 default:
3468 return HexagonII::HCG_None;
3469 //
3470 // Compound pairs.
3471 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3472 // "Rd16=#U6 ; jump #r9:2"
3473 // "Rd16=Rs16 ; jump #r9:2"
3474 //
3475 case Hexagon::C2_cmpeq:
3476 case Hexagon::C2_cmpgt:
3477 case Hexagon::C2_cmpgtu:
3478 DstReg = MI.getOperand(0).getReg();
3479 Src1Reg = MI.getOperand(1).getReg();
3480 Src2Reg = MI.getOperand(2).getReg();
3481 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3482 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3483 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3484 return HexagonII::HCG_A;
3485 break;
3486 case Hexagon::C2_cmpeqi:
3487 case Hexagon::C2_cmpgti:
3488 case Hexagon::C2_cmpgtui:
3489 // P0 = cmp.eq(Rs,#u2)
3490 DstReg = MI.getOperand(0).getReg();
3491 SrcReg = MI.getOperand(1).getReg();
3492 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3493 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3494 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3495 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3496 (MI.getOperand(2).getImm() == -1)))
3497 return HexagonII::HCG_A;
3498 break;
3499 case Hexagon::A2_tfr:
3500 // Rd = Rs
3501 DstReg = MI.getOperand(0).getReg();
3502 SrcReg = MI.getOperand(1).getReg();
3503 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3504 return HexagonII::HCG_A;
3505 break;
3506 case Hexagon::A2_tfrsi:
3507 // Rd = #u6
3508 // Do not test for #u6 size since the const is getting extended
3509 // regardless and compound could be formed.
3510 DstReg = MI.getOperand(0).getReg();
3511 if (isIntRegForSubInst(DstReg))
3512 return HexagonII::HCG_A;
3513 break;
3514 case Hexagon::S2_tstbit_i:
3515 DstReg = MI.getOperand(0).getReg();
3516 Src1Reg = MI.getOperand(1).getReg();
3517 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3518 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3519 MI.getOperand(2).isImm() &&
3520 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
3521 return HexagonII::HCG_A;
3522 break;
3523 // The fact that .new form is used pretty much guarantees
3524 // that predicate register will match. Nevertheless,
3525 // there could be some false positives without additional
3526 // checking.
3527 case Hexagon::J2_jumptnew:
3528 case Hexagon::J2_jumpfnew:
3529 case Hexagon::J2_jumptnewpt:
3530 case Hexagon::J2_jumpfnewpt:
3531 Src1Reg = MI.getOperand(0).getReg();
3532 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3533 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3534 return HexagonII::HCG_B;
3535 break;
3536 // Transfer and jump:
3537 // Rd=#U6 ; jump #r9:2
3538 // Rd=Rs ; jump #r9:2
3539 // Do not test for jump range here.
3540 case Hexagon::J2_jump:
3541 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3542 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
3543 return HexagonII::HCG_C;
3544 }
3545
3546 return HexagonII::HCG_None;
3547}
3548
3549// Returns -1 when there is no opcode found.
3551 const MachineInstr &GB) const {
3554 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3555 (GB.getOpcode() != Hexagon::J2_jumptnew))
3556 return -1u;
3557 Register DestReg = GA.getOperand(0).getReg();
3558 if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))
3559 return -1u;
3560 if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)
3561 return -1u;
3562 // The value compared against must be either u5 or -1.
3563 const MachineOperand &CmpOp = GA.getOperand(2);
3564 if (!CmpOp.isImm())
3565 return -1u;
3566 int V = CmpOp.getImm();
3567 if (V == -1)
3568 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt
3569 : Hexagon::J4_cmpeqn1_tp1_jump_nt;
3570 if (!isUInt<5>(V))
3571 return -1u;
3572 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt
3573 : Hexagon::J4_cmpeqi_tp1_jump_nt;
3574}
3575
3576// Returns -1 if there is no opcode found.
3578 bool ForBigCore) const {
3579 // Static table to switch the opcodes across Tiny Core and Big Core.
3580 // dup_ opcodes are Big core opcodes.
3581 // NOTE: There are special instructions that need to handled later.
3582 // L4_return* instructions, they will only occupy SLOT0 (on big core too).
3583 // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.
3584 // The compiler need to base the root instruction to L6_return_map_to_raw
3585 // which can go any slot.
3586 static const std::map<unsigned, unsigned> DupMap = {
3587 {Hexagon::A2_add, Hexagon::dup_A2_add},
3588 {Hexagon::A2_addi, Hexagon::dup_A2_addi},
3589 {Hexagon::A2_andir, Hexagon::dup_A2_andir},
3590 {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},
3591 {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},
3592 {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},
3593 {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},
3594 {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},
3595 {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},
3596 {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},
3597 {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},
3598 {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},
3599 {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},
3600 {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},
3601 {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},
3602 {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},
3603 {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},
3604 {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},
3605 {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},
3606 {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},
3607 {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},
3608 {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},
3609 {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},
3610 {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},
3611 {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},
3612 {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},
3613 {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},
3614 {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},
3615 {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},
3616 {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},
3617 {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},
3618 {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},
3619 };
3620 unsigned OpNum = MI.getOpcode();
3621 // Conversion to Big core.
3622 if (ForBigCore) {
3623 auto Iter = DupMap.find(OpNum);
3624 if (Iter != DupMap.end())
3625 return Iter->second;
3626 } else { // Conversion to Tiny core.
3627 for (const auto &Iter : DupMap)
3628 if (Iter.second == OpNum)
3629 return Iter.first;
3630 }
3631 return -1;
3632}
3633
3634int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3635 enum Hexagon::PredSense inPredSense;
3636 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3637 Hexagon::PredSense_true;
3638 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3639 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3640 return CondOpcode;
3641
3642 llvm_unreachable("Unexpected predicable instruction");
3643}
3644
3645// Return the cur value instruction for a given store.
3647 switch (MI.getOpcode()) {
3648 default: llvm_unreachable("Unknown .cur type");
3649 case Hexagon::V6_vL32b_pi:
3650 return Hexagon::V6_vL32b_cur_pi;
3651 case Hexagon::V6_vL32b_ai:
3652 return Hexagon::V6_vL32b_cur_ai;
3653 case Hexagon::V6_vL32b_nt_pi:
3654 return Hexagon::V6_vL32b_nt_cur_pi;
3655 case Hexagon::V6_vL32b_nt_ai:
3656 return Hexagon::V6_vL32b_nt_cur_ai;
3657 case Hexagon::V6_vL32b_ppu:
3658 return Hexagon::V6_vL32b_cur_ppu;
3659 case Hexagon::V6_vL32b_nt_ppu:
3660 return Hexagon::V6_vL32b_nt_cur_ppu;
3661 }
3662 return 0;
3663}
3664
3665// Return the regular version of the .cur instruction.
3667 switch (MI.getOpcode()) {
3668 default: llvm_unreachable("Unknown .cur type");
3669 case Hexagon::V6_vL32b_cur_pi:
3670 return Hexagon::V6_vL32b_pi;
3671 case Hexagon::V6_vL32b_cur_ai:
3672 return Hexagon::V6_vL32b_ai;
3673 case Hexagon::V6_vL32b_nt_cur_pi:
3674 return Hexagon::V6_vL32b_nt_pi;
3675 case Hexagon::V6_vL32b_nt_cur_ai:
3676 return Hexagon::V6_vL32b_nt_ai;
3677 case Hexagon::V6_vL32b_cur_ppu:
3678 return Hexagon::V6_vL32b_ppu;
3679 case Hexagon::V6_vL32b_nt_cur_ppu:
3680 return Hexagon::V6_vL32b_nt_ppu;
3681 }
3682 return 0;
3683}
3684
3685// The diagram below shows the steps involved in the conversion of a predicated
3686// store instruction to its .new predicated new-value form.
3687//
3688// Note: It doesn't include conditional new-value stores as they can't be
3689// converted to .new predicate.
3690//
3691// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3692// ^ ^
3693// / \ (not OK. it will cause new-value store to be
3694// / X conditional on p0.new while R2 producer is
3695// / \ on p0)
3696// / \.
3697// p.new store p.old NV store
3698// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3699// ^ ^
3700// \ /
3701// \ /
3702// \ /
3703// p.old store
3704// [if (p0)memw(R0+#0)=R2]
3705//
3706// The following set of instructions further explains the scenario where
3707// conditional new-value store becomes invalid when promoted to .new predicate
3708// form.
3709//
3710// { 1) if (p0) r0 = add(r1, r2)
3711// 2) p0 = cmp.eq(r3, #0) }
3712//
3713// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3714// the first two instructions because in instr 1, r0 is conditional on old value
3715// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3716// is not valid for new-value stores.
3717// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3718// from the "Conditional Store" list. Because a predicated new value store
3719// would NOT be promoted to a double dot new store. See diagram below:
3720// This function returns yes for those stores that are predicated but not
3721// yet promoted to predicate dot new instructions.
3722//
3723// +---------------------+
3724// /-----| if (p0) memw(..)=r0 |---------\~
3725// || +---------------------+ ||
3726// promote || /\ /\ || promote
3727// || /||\ /||\ ||
3728// \||/ demote || \||/
3729// \/ || || \/
3730// +-------------------------+ || +-------------------------+
3731// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3732// +-------------------------+ || +-------------------------+
3733// || || ||
3734// || demote \||/
3735// promote || \/ NOT possible
3736// || || /\~
3737// \||/ || /||\~
3738// \/ || ||
3739// +-----------------------------+
3740// | if (p0.new) memw(..)=r0.new |
3741// +-----------------------------+
3742// Double Dot New Store
3743//
3744// Returns the most basic instruction for the .new predicated instructions and
3745// new-value stores.
3746// For example, all of the following instructions will be converted back to the
3747// same instruction:
3748// 1) if (p0.new) memw(R0+#0) = R1.new --->
3749// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3750// 3) if (p0.new) memw(R0+#0) = R1 --->
3751//
3752// To understand the translation of instruction 1 to its original form, consider
3753// a packet with 3 instructions.
3754// { p0 = cmp.eq(R0,R1)
3755// if (p0.new) R2 = add(R3, R4)
3756// R5 = add (R3, R1)
3757// }
3758// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3759//
3760// This instruction can be part of the previous packet only if both p0 and R2
3761// are promoted to .new values. This promotion happens in steps, first
3762// predicate register is promoted to .new and in the next iteration R2 is
3763// promoted. Therefore, in case of dependence check failure (due to R5) during
3764// next iteration, it should be converted back to its most basic form.
3765
3766// Return the new value instruction for a given store.
3768 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
3769 if (NVOpcode >= 0) // Valid new-value store instruction.
3770 return NVOpcode;
3771
3772 switch (MI.getOpcode()) {
3773 default:
3774 report_fatal_error(Twine("Unknown .new type: ") +
3775 std::to_string(MI.getOpcode()));
3776 case Hexagon::S4_storerb_ur:
3777 return Hexagon::S4_storerbnew_ur;
3778
3779 case Hexagon::S2_storerb_pci:
3780 return Hexagon::S2_storerb_pci;
3781
3782 case Hexagon::S2_storeri_pci:
3783 return Hexagon::S2_storeri_pci;
3784
3785 case Hexagon::S2_storerh_pci:
3786 return Hexagon::S2_storerh_pci;
3787
3788 case Hexagon::S2_storerd_pci:
3789 return Hexagon::S2_storerd_pci;
3790
3791 case Hexagon::S2_storerf_pci:
3792 return Hexagon::S2_storerf_pci;
3793
3794 case Hexagon::V6_vS32b_ai:
3795 return Hexagon::V6_vS32b_new_ai;
3796
3797 case Hexagon::V6_vS32b_pi:
3798 return Hexagon::V6_vS32b_new_pi;
3799 }
3800 return 0;
3801}
3802
3803// Returns the opcode to use when converting MI, which is a conditional jump,
3804// into a conditional instruction which uses the .new value of the predicate.
3805// We also use branch probabilities to add a hint to the jump.
3806// If MBPI is null, all edges will be treated as equally likely for the
3807// purposes of establishing a predication hint.
3809 const MachineBranchProbabilityInfo *MBPI) const {
3810 // We assume that block can have at most two successors.
3811 const MachineBasicBlock *Src = MI.getParent();
3812 const MachineOperand &BrTarget = MI.getOperand(1);
3813 bool Taken = false;
3814 const BranchProbability OneHalf(1, 2);
3815
3816 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3817 const MachineBasicBlock *Dst) {
3818 if (MBPI)
3819 return MBPI->getEdgeProbability(Src, Dst);
3820 return BranchProbability(1, Src->succ_size());
3821 };
3822
3823 if (BrTarget.isMBB()) {
3824 const MachineBasicBlock *Dst = BrTarget.getMBB();
3825 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
3826 } else {
3827 // The branch target is not a basic block (most likely a function).
3828 // Since BPI only gives probabilities for targets that are basic blocks,
3829 // try to identify another target of this branch (potentially a fall-
3830 // -through) and check the probability of that target.
3831 //
3832 // The only handled branch combinations are:
3833 // - one conditional branch,
3834 // - one conditional branch followed by one unconditional branch.
3835 // Otherwise, assume not-taken.
3836 assert(MI.isConditionalBranch());
3837 const MachineBasicBlock &B = *MI.getParent();
3838 bool SawCond = false, Bad = false;
3839 for (const MachineInstr &I : B) {
3840 if (!I.isBranch())
3841 continue;
3842 if (I.isConditionalBranch()) {
3843 SawCond = true;
3844 if (&I != &MI) {
3845 Bad = true;
3846 break;
3847 }
3848 }
3849 if (I.isUnconditionalBranch() && !SawCond) {
3850 Bad = true;
3851 break;
3852 }
3853 }
3854 if (!Bad) {
3856 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3857 if (NextIt == B.instr_end()) {
3858 // If this branch is the last, look for the fall-through block.
3859 for (const MachineBasicBlock *SB : B.successors()) {
3860 if (!B.isLayoutSuccessor(SB))
3861 continue;
3862 Taken = getEdgeProbability(Src, SB) < OneHalf;
3863 break;
3864 }
3865 } else {
3866 assert(NextIt->isUnconditionalBranch());
3867 // Find the first MBB operand and assume it's the target.
3868 const MachineBasicBlock *BT = nullptr;
3869 for (const MachineOperand &Op : NextIt->operands()) {
3870 if (!Op.isMBB())
3871 continue;
3872 BT = Op.getMBB();
3873 break;
3874 }
3875 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
3876 }
3877 } // if (!Bad)
3878 }
3879
3880 // The Taken flag should be set to something reasonable by this point.
3881
3882 switch (MI.getOpcode()) {
3883 case Hexagon::J2_jumpt:
3884 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3885 case Hexagon::J2_jumpf:
3886 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3887
3888 default:
3889 llvm_unreachable("Unexpected jump instruction.");
3890 }
3891}
3892
3893// Return .new predicate version for an instruction.
3895 const MachineBranchProbabilityInfo *MBPI) const {
3896 switch (MI.getOpcode()) {
3897 // Conditional Jumps
3898 case Hexagon::J2_jumpt:
3899 case Hexagon::J2_jumpf:
3900 return getDotNewPredJumpOp(MI, MBPI);
3901 }
3902
3903 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3904 if (NewOpcode >= 0)
3905 return NewOpcode;
3906 return 0;
3907}
3908
3910 int NewOp = MI.getOpcode();
3911 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3912 NewOp = Hexagon::getPredOldOpcode(NewOp);
3913 // All Hexagon architectures have prediction bits on dot-new branches,
3914 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
3915 // to pick the right opcode when converting back to dot-old.
3916 if (!Subtarget.hasFeature(Hexagon::ArchV60)) {
3917 switch (NewOp) {
3918 case Hexagon::J2_jumptpt:
3919 NewOp = Hexagon::J2_jumpt;
3920 break;
3921 case Hexagon::J2_jumpfpt:
3922 NewOp = Hexagon::J2_jumpf;
3923 break;
3924 case Hexagon::J2_jumprtpt:
3925 NewOp = Hexagon::J2_jumprt;
3926 break;
3927 case Hexagon::J2_jumprfpt:
3928 NewOp = Hexagon::J2_jumprf;
3929 break;
3930 }
3931 }
3932 assert(NewOp >= 0 &&
3933 "Couldn't change predicate new instruction to its old form.");
3934 }
3935
3936 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3937 NewOp = Hexagon::getNonNVStore(NewOp);
3938 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3939 }
3940
3941 if (Subtarget.hasV60Ops())
3942 return NewOp;
3943
3944 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
3945 switch (NewOp) {
3946 case Hexagon::J2_jumpfpt:
3947 return Hexagon::J2_jumpf;
3948 case Hexagon::J2_jumptpt:
3949 return Hexagon::J2_jumpt;
3950 case Hexagon::J2_jumprfpt:
3951 return Hexagon::J2_jumprf;
3952 case Hexagon::J2_jumprtpt:
3953 return Hexagon::J2_jumprt;
3954 }
3955 return NewOp;
3956}
3957
3958// See if instruction could potentially be a duplex candidate.
3959// If so, return its group. Zero otherwise.
3961 const MachineInstr &MI) const {
3962 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3963 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
3964
3965 switch (MI.getOpcode()) {
3966 default:
3967 return HexagonII::HSIG_None;
3968 //
3969 // Group L1:
3970 //
3971 // Rd = memw(Rs+#u4:2)
3972 // Rd = memub(Rs+#u4:0)
3973 case Hexagon::L2_loadri_io:
3974 case Hexagon::dup_L2_loadri_io:
3975 DstReg = MI.getOperand(0).getReg();
3976 SrcReg = MI.getOperand(1).getReg();
3977 // Special case this one from Group L2.
3978 // Rd = memw(r29+#u5:2)
3979 if (isIntRegForSubInst(DstReg)) {
3980 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3981 HRI.getStackRegister() == SrcReg &&
3982 MI.getOperand(2).isImm() &&
3983 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
3984 return HexagonII::HSIG_L2;
3985 // Rd = memw(Rs+#u4:2)
3986 if (isIntRegForSubInst(SrcReg) &&
3987 (MI.getOperand(2).isImm() &&
3988 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
3989 return HexagonII::HSIG_L1;
3990 }
3991 break;
3992 case Hexagon::L2_loadrub_io:
3993 case Hexagon::dup_L2_loadrub_io:
3994 // Rd = memub(Rs+#u4:0)
3995 DstReg = MI.getOperand(0).getReg();
3996 SrcReg = MI.getOperand(1).getReg();
3997 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3998 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
3999 return HexagonII::HSIG_L1;
4000 break;
4001 //
4002 // Group L2:
4003 //
4004 // Rd = memh/memuh(Rs+#u3:1)
4005 // Rd = memb(Rs+#u3:0)
4006 // Rd = memw(r29+#u5:2) - Handled above.
4007 // Rdd = memd(r29+#u5:3)
4008 // deallocframe
4009 // [if ([!]p0[.new])] dealloc_return
4010 // [if ([!]p0[.new])] jumpr r31
4011 case Hexagon::L2_loadrh_io:
4012 case Hexagon::L2_loadruh_io:
4013 case Hexagon::dup_L2_loadrh_io:
4014 case Hexagon::dup_L2_loadruh_io:
4015 // Rd = memh/memuh(Rs+#u3:1)
4016 DstReg = MI.getOperand(0).getReg();
4017 SrcReg = MI.getOperand(1).getReg();
4018 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4019 MI.getOperand(2).isImm() &&
4020 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
4021 return HexagonII::HSIG_L2;
4022 break;
4023 case Hexagon::L2_loadrb_io:
4024 case Hexagon::dup_L2_loadrb_io:
4025 // Rd = memb(Rs+#u3:0)
4026 DstReg = MI.getOperand(0).getReg();
4027 SrcReg = MI.getOperand(1).getReg();
4028 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4029 MI.getOperand(2).isImm() &&
4030 isUInt<3>(MI.getOperand(2).getImm()))
4031 return HexagonII::HSIG_L2;
4032 break;
4033 case Hexagon::L2_loadrd_io:
4034 case Hexagon::dup_L2_loadrd_io:
4035 // Rdd = memd(r29+#u5:3)
4036 DstReg = MI.getOperand(0).getReg();
4037 SrcReg = MI.getOperand(1).getReg();
4038 if (isDblRegForSubInst(DstReg, HRI) &&
4039 Hexagon::IntRegsRegClass.contains(SrcReg) &&
4040 HRI.getStackRegister() == SrcReg &&
4041 MI.getOperand(2).isImm() &&
4042 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4043 return HexagonII::HSIG_L2;
4044 break;
4045 // dealloc_return is not documented in Hexagon Manual, but marked
4046 // with A_SUBINSN attribute in iset_v4classic.py.
4047 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
4048 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
4049 case Hexagon::L4_return:
4050 case Hexagon::L2_deallocframe:
4051 case Hexagon::dup_L2_deallocframe:
4052 return HexagonII::HSIG_L2;
4053 case Hexagon::EH_RETURN_JMPR:
4054 case Hexagon::PS_jmpret:
4055 case Hexagon::SL2_jumpr31:
4056 // jumpr r31
4057 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0
4058 DstReg = MI.getOperand(0).getReg();
4059 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
4060 return HexagonII::HSIG_L2;
4061 break;
4062 case Hexagon::PS_jmprett:
4063 case Hexagon::PS_jmpretf:
4064 case Hexagon::PS_jmprettnewpt:
4065 case Hexagon::PS_jmpretfnewpt:
4066 case Hexagon::PS_jmprettnew:
4067 case Hexagon::PS_jmpretfnew:
4068 case Hexagon::SL2_jumpr31_t:
4069 case Hexagon::SL2_jumpr31_f:
4070 case Hexagon::SL2_jumpr31_tnew:
4071 case Hexagon::SL2_jumpr31_fnew:
4072 DstReg = MI.getOperand(1).getReg();
4073 SrcReg = MI.getOperand(0).getReg();
4074 // [if ([!]p0[.new])] jumpr r31
4075 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
4076 (Hexagon::P0 == SrcReg)) &&
4077 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
4078 return HexagonII::HSIG_L2;
4079 break;
4080 case Hexagon::L4_return_t:
4081 case Hexagon::L4_return_f:
4082 case Hexagon::L4_return_tnew_pnt:
4083 case Hexagon::L4_return_fnew_pnt:
4084 case Hexagon::L4_return_tnew_pt:
4085 case Hexagon::L4_return_fnew_pt:
4086 // [if ([!]p0[.new])] dealloc_return
4087 SrcReg = MI.getOperand(0).getReg();
4088 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
4089 return HexagonII::HSIG_L2;
4090 break;
4091 //
4092 // Group S1:
4093 //
4094 // memw(Rs+#u4:2) = Rt
4095 // memb(Rs+#u4:0) = Rt
4096 case Hexagon::S2_storeri_io:
4097 case Hexagon::dup_S2_storeri_io:
4098 // Special case this one from Group S2.
4099 // memw(r29+#u5:2) = Rt
4100 Src1Reg = MI.getOperand(0).getReg();
4101 Src2Reg = MI.getOperand(2).getReg();
4102 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4103 isIntRegForSubInst(Src2Reg) &&
4104 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4105 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
4106 return HexagonII::HSIG_S2;
4107 // memw(Rs+#u4:2) = Rt
4108 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4109 MI.getOperand(1).isImm() &&
4110 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
4111 return HexagonII::HSIG_S1;
4112 break;
4113 case Hexagon::S2_storerb_io:
4114 case Hexagon::dup_S2_storerb_io:
4115 // memb(Rs+#u4:0) = Rt
4116 Src1Reg = MI.getOperand(0).getReg();
4117 Src2Reg = MI.getOperand(2).getReg();
4118 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4119 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
4120 return HexagonII::HSIG_S1;
4121 break;
4122 //
4123 // Group S2:
4124 //
4125 // memh(Rs+#u3:1) = Rt
4126 // memw(r29+#u5:2) = Rt
4127 // memd(r29+#s6:3) = Rtt
4128 // memw(Rs+#u4:2) = #U1
4129 // memb(Rs+#u4) = #U1
4130 // allocframe(#u5:3)
4131 case Hexagon::S2_storerh_io:
4132 case Hexagon::dup_S2_storerh_io:
4133 // memh(Rs+#u3:1) = Rt
4134 Src1Reg = MI.getOperand(0).getReg();
4135 Src2Reg = MI.getOperand(2).getReg();
4136 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4137 MI.getOperand(1).isImm() &&
4138 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
4139 return HexagonII::HSIG_S1;
4140 break;
4141 case Hexagon::S2_storerd_io:
4142 case Hexagon::dup_S2_storerd_io:
4143 // memd(r29+#s6:3) = Rtt
4144 Src1Reg = MI.getOperand(0).getReg();
4145 Src2Reg = MI.getOperand(2).getReg();
4146 if (isDblRegForSubInst(Src2Reg, HRI) &&
4147 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4148 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4149 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
4150 return HexagonII::HSIG_S2;
4151 break;
4152 case Hexagon::S4_storeiri_io:
4153 case Hexagon::dup_S4_storeiri_io:
4154 // memw(Rs+#u4:2) = #U1
4155 Src1Reg = MI.getOperand(0).getReg();
4156 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
4157 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
4158 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4159 return HexagonII::HSIG_S2;
4160 break;
4161 case Hexagon::S4_storeirb_io:
4162 case Hexagon::dup_S4_storeirb_io:
4163 // memb(Rs+#u4) = #U1
4164 Src1Reg = MI.getOperand(0).getReg();
4165 if (isIntRegForSubInst(Src1Reg) &&
4166 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
4167 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4168 return HexagonII::HSIG_S2;
4169 break;
4170 case Hexagon::S2_allocframe:
4171 case Hexagon::dup_S2_allocframe:
4172 if (MI.getOperand(2).isImm() &&
4173 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4174 return HexagonII::HSIG_S1;
4175 break;
4176 //
4177 // Group A:
4178 //
4179 // Rx = add(Rx,#s7)
4180 // Rd = Rs
4181 // Rd = #u6
4182 // Rd = #-1
4183 // if ([!]P0[.new]) Rd = #0
4184 // Rd = add(r29,#u6:2)
4185 // Rx = add(Rx,Rs)
4186 // P0 = cmp.eq(Rs,#u2)
4187 // Rdd = combine(#0,Rs)
4188 // Rdd = combine(Rs,#0)
4189 // Rdd = combine(#u2,#U2)
4190 // Rd = add(Rs,#1)
4191 // Rd = add(Rs,#-1)
4192 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4193 // Rd = and(Rs,#1)
4194 case Hexagon::A2_addi:
4195 case Hexagon::dup_A2_addi:
4196 DstReg = MI.getOperand(0).getReg();
4197 SrcReg = MI.getOperand(1).getReg();
4198 if (isIntRegForSubInst(DstReg)) {
4199 // Rd = add(r29,#u6:2)
4200 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
4201 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
4202 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
4203 return HexagonII::HSIG_A;
4204 // Rx = add(Rx,#s7)
4205 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
4206 isInt<7>(MI.getOperand(2).getImm()))
4207 return HexagonII::HSIG_A;
4208 // Rd = add(Rs,#1)
4209 // Rd = add(Rs,#-1)
4210 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
4211 ((MI.getOperand(2).getImm() == 1) ||
4212 (MI.getOperand(2).getImm() == -1)))
4213 return HexagonII::HSIG_A;
4214 }
4215 break;
4216 case Hexagon::A2_add:
4217 case Hexagon::dup_A2_add:
4218 // Rx = add(Rx,Rs)
4219 DstReg = MI.getOperand(0).getReg();
4220 Src1Reg = MI.getOperand(1).getReg();
4221 Src2Reg = MI.getOperand(2).getReg();
4222 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
4223 isIntRegForSubInst(Src2Reg))
4224 return HexagonII::HSIG_A;
4225 break;
4226 case Hexagon::A2_andir:
4227 case Hexagon::dup_A2_andir:
4228 // Same as zxtb.
4229 // Rd16=and(Rs16,#255)
4230 // Rd16=and(Rs16,#1)
4231 DstReg = MI.getOperand(0).getReg();
4232 SrcReg = MI.getOperand(1).getReg();
4233 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4234 MI.getOperand(2).isImm() &&
4235 ((MI.getOperand(2).getImm() == 1) ||
4236 (MI.getOperand(2).getImm() == 255)))
4237 return HexagonII::HSIG_A;
4238 break;
4239 case Hexagon::A2_tfr:
4240 case Hexagon::dup_A2_tfr:
4241 // Rd = Rs
4242 DstReg = MI.getOperand(0).getReg();
4243 SrcReg = MI.getOperand(1).getReg();
4244 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4245 return HexagonII::HSIG_A;
4246 break;
4247 case Hexagon::A2_tfrsi:
4248 case Hexagon::dup_A2_tfrsi:
4249 // Rd = #u6
4250 // Do not test for #u6 size since the const is getting extended
4251 // regardless and compound could be formed.
4252 // Rd = #-1
4253 DstReg = MI.getOperand(0).getReg();
4254 if (isIntRegForSubInst(DstReg))
4255 return HexagonII::HSIG_A;
4256 break;
4257 case Hexagon::C2_cmoveit:
4258 case Hexagon::C2_cmovenewit:
4259 case Hexagon::C2_cmoveif:
4260 case Hexagon::C2_cmovenewif:
4261 case Hexagon::dup_C2_cmoveit:
4262 case Hexagon::dup_C2_cmovenewit:
4263 case Hexagon::dup_C2_cmoveif:
4264 case Hexagon::dup_C2_cmovenewif:
4265 // if ([!]P0[.new]) Rd = #0
4266 // Actual form:
4267 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
4268 DstReg = MI.getOperand(0).getReg();
4269 SrcReg = MI.getOperand(1).getReg();
4270 if (isIntRegForSubInst(DstReg) &&
4271 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
4272 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
4273 return HexagonII::HSIG_A;
4274 break;
4275 case Hexagon::C2_cmpeqi:
4276 case Hexagon::dup_C2_cmpeqi:
4277 // P0 = cmp.eq(Rs,#u2)
4278 DstReg = MI.getOperand(0).getReg();
4279 SrcReg = MI.getOperand(1).getReg();
4280 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
4281 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
4282 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
4283 return HexagonII::HSIG_A;
4284 break;
4285 case Hexagon::A2_combineii:
4286 case Hexagon::A4_combineii:
4287 case Hexagon::dup_A2_combineii:
4288 case Hexagon::dup_A4_combineii:
4289 // Rdd = combine(#u2,#U2)
4290 DstReg = MI.getOperand(0).getReg();
4291 if (isDblRegForSubInst(DstReg, HRI) &&
4292 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
4293 (MI.getOperand(1).isGlobal() &&
4294 isUInt<2>(MI.getOperand(1).getOffset()))) &&
4295 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
4296 (MI.getOperand(2).isGlobal() &&
4297 isUInt<2>(MI.getOperand(2).getOffset()))))
4298 return HexagonII::HSIG_A;
4299 break;
4300 case Hexagon::A4_combineri:
4301 case Hexagon::dup_A4_combineri:
4302 // Rdd = combine(Rs,#0)
4303 // Rdd = combine(Rs,#0)
4304 DstReg = MI.getOperand(0).getReg();
4305 SrcReg = MI.getOperand(1).getReg();
4306 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4307 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
4308 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
4309 return HexagonII::HSIG_A;
4310 break;
4311 case Hexagon::A4_combineir:
4312 case Hexagon::dup_A4_combineir:
4313 // Rdd = combine(#0,Rs)
4314 DstReg = MI.getOperand(0).getReg();
4315 SrcReg = MI.getOperand(2).getReg();
4316 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4317 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
4318 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
4319 return HexagonII::HSIG_A;
4320 break;
4321 case Hexagon::A2_sxtb:
4322 case Hexagon::A2_sxth:
4323 case Hexagon::A2_zxtb:
4324 case Hexagon::A2_zxth:
4325 case Hexagon::dup_A2_sxtb:
4326 case Hexagon::dup_A2_sxth:
4327 case Hexagon::dup_A2_zxtb:
4328 case Hexagon::dup_A2_zxth:
4329 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4330 DstReg = MI.getOperand(0).getReg();
4331 SrcReg = MI.getOperand(1).getReg();
4332 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4333 return HexagonII::HSIG_A;
4334 break;
4335 }
4336
4337 return HexagonII::HSIG_None;
4338}
4339
4341 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
4342 // Default to one cycle for no itinerary. However, an "empty" itinerary may
4343 // still have a MinLatency property, which getStageLatency checks.
4344 if (!ItinData)
4345 return getInstrLatency(ItinData, MI);
4346
4347 if (MI.isTransient())
4348 return 0;
4349 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
4350}
4351
4352/// getOperandLatency - Compute and return the use operand latency of a given
4353/// pair of def and use.
4354/// In most cases, the static scheduling itinerary was enough to determine the
4355/// operand latency. But it may not be possible for instructions with variable
4356/// number of defs / uses.
4357///
4358/// This is a raw interface to the itinerary that may be directly overridden by
4359/// a target. Use computeOperandLatency to get the best estimate of latency.
4361 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4362 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
4363 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4364
4365 // Get DefIdx and UseIdx for super registers.
4366 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
4367
4368 if (DefMO.isReg() && DefMO.getReg().isPhysical()) {
4369 if (DefMO.isImplicit()) {
4370 for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {
4371 int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);
4372 if (Idx != -1) {
4373 DefIdx = Idx;
4374 break;
4375 }
4376 }
4377 }
4378
4379 const MachineOperand &UseMO = UseMI.getOperand(UseIdx);
4380 if (UseMO.isImplicit()) {
4381 for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {
4382 int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);
4383 if (Idx != -1) {
4384 UseIdx = Idx;
4385 break;
4386 }
4387 }
4388 }
4389 }
4390
4391 std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(
4392 ItinData, DefMI, DefIdx, UseMI, UseIdx);
4393 if (Latency == 0)
4394 // We should never have 0 cycle latency between two instructions unless
4395 // they can be packetized together. However, this decision can't be made
4396 // here.
4397 Latency = 1;
4398 return Latency;
4399}
4400
4401// inverts the predication logic.
4402// p -> NotP
4403// NotP -> P
4406 if (Cond.empty())
4407 return false;
4408 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
4409 Cond[0].setImm(Opc);
4410 return true;
4411}
4412
4414 int InvPredOpcode;
4415 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
4416 : Hexagon::getTruePredOpcode(Opc);
4417 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
4418 return InvPredOpcode;
4419
4420 llvm_unreachable("Unexpected predicated instruction");
4421}
4422
4423// Returns the max value that doesn't need to be extended.
4425 const uint64_t F = MI.getDesc().TSFlags;
4426 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4428 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4430
4431 if (isSigned) // if value is signed
4432 return ~(-1U << (bits - 1));
4433 else
4434 return ~(-1U << bits);
4435}
4436
4437
4439 switch (MI.getOpcode()) {
4440 case Hexagon::L2_loadrbgp:
4441 case Hexagon::L2_loadrdgp:
4442 case Hexagon::L2_loadrhgp:
4443 case Hexagon::L2_loadrigp:
4444 case Hexagon::L2_loadrubgp:
4445 case Hexagon::L2_loadruhgp:
4446 case Hexagon::S2_storerbgp:
4447 case Hexagon::S2_storerbnewgp:
4448 case Hexagon::S2_storerhgp:
4449 case Hexagon::S2_storerhnewgp:
4450 case Hexagon::S2_storerigp:
4451 case Hexagon::S2_storerinewgp:
4452 case Hexagon::S2_storerdgp:
4453 case Hexagon::S2_storerfgp:
4454 return true;
4455 }
4456 const uint64_t F = MI.getDesc().TSFlags;
4457 unsigned addrMode =
4459 // Disallow any base+offset instruction. The assembler does not yet reorder
4460 // based up any zero offset instruction.
4461 return (addrMode == HexagonII::BaseRegOffset ||
4462 addrMode == HexagonII::BaseImmOffset ||
4463 addrMode == HexagonII::BaseLongOffset);
4464}
4465
4467 // Workaround for the Global Scheduler. Sometimes, it creates
4468 // A4_ext as a Pseudo instruction and calls this function to see if
4469 // it can be added to an existing bundle. Since the instruction doesn't
4470 // belong to any BB yet, we can't use getUnits API.
4471 if (MI.getOpcode() == Hexagon::A4_ext)
4472 return false;
4473
4474 unsigned FuncUnits = getUnits(MI);
4475 return HexagonFUnits::isSlot0Only(FuncUnits);
4476}
4477
4479 const uint64_t F = MI.getDesc().TSFlags;
4482}
4483
4485 bool ToBigInstrs) const {
4486 int Opcode = -1;
4487 if (ToBigInstrs) { // To BigCore Instr.
4488 // Check if the instruction can form a Duplex.
4489 if (getDuplexCandidateGroup(*MII))
4490 // Get the opcode marked "dup_*" tag.
4491 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4492 } else // To TinyCore Instr.
4493 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4494
4495 // Change the opcode of the instruction.
4496 if (Opcode >= 0)
4497 MII->setDesc(get(Opcode));
4498}
4499
4500// This function is used to translate instructions to facilitate generating
4501// Duplexes on TinyCore.
4503 bool ToBigInstrs) const {
4504 for (auto &MB : MF)
4505 for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),
4506 End = MB.instr_end();
4507 Instr != End; ++Instr)
4508 changeDuplexOpcode(Instr, ToBigInstrs);
4509}
4510
4511// This is a specialized form of above function.
4513 MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {
4514 MachineBasicBlock *MBB = MII->getParent();
4515 while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {
4516 changeDuplexOpcode(MII, ToBigInstrs);
4517 ++MII;
4518 }
4519}
4520
4522 using namespace HexagonII;
4523
4524 const uint64_t F = MI.getDesc().TSFlags;
4525 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
4526 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
4527 if (Size != 0)
4528 return Size;
4529 // Y2_dcfetchbo is special
4530 if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)
4532
4533 // Handle vector access sizes.
4534 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4535 switch (S) {
4537 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
4538 default:
4539 llvm_unreachable("Unexpected instruction");
4540 }
4541}
4542
4543// Returns the min value that doesn't need to be extended.
4545 const uint64_t F = MI.getDesc().TSFlags;
4546 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4548 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4550
4551 if (isSigned) // if value is signed
4552 return -1U << (bits - 1);
4553 else
4554 return 0;
4555}
4556
4557// Returns opcode of the non-extended equivalent instruction.
4559 // Check if the instruction has a register form that uses register in place
4560 // of the extended operand, if so return that as the non-extended form.
4561 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
4562 if (NonExtOpcode >= 0)
4563 return NonExtOpcode;
4564
4565 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
4566 // Check addressing mode and retrieve non-ext equivalent instruction.
4567 switch (getAddrMode(MI)) {
4569 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());
4571 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());
4573 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
4574
4575 default:
4576 return -1;
4577 }
4578 }
4579 return -1;
4580}
4581
4583 Register &PredReg, unsigned &PredRegPos,
4584 RegState &PredRegFlags) const {
4585 if (Cond.empty())
4586 return false;
4587 assert(Cond.size() == 2);
4588 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
4589 LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
4590 return false;
4591 }
4592 PredReg = Cond[1].getReg();
4593 PredRegPos = 1;
4594 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
4595 PredRegFlags = {};
4596 if (Cond[1].isImplicit())
4597 PredRegFlags = RegState::Implicit;
4598 if (Cond[1].isUndef())
4599 PredRegFlags |= RegState::Undef;
4600 return true;
4601}
4602
4604 return Hexagon::getRegForm(MI.getOpcode());
4605}
4606
4607// Return the number of bytes required to encode the instruction.
4608// Hexagon instructions are fixed length, 4 bytes, unless they
4609// use a constant extender, which requires another 4 bytes.
4610// For debug instructions and prolog labels, return 0.
4612 if (MI.isDebugInstr() || MI.isPosition())
4613 return 0;
4614
4615 unsigned Size = MI.getDesc().getSize();
4616 if (!Size)
4617 // Assume the default insn size in case it cannot be determined
4618 // for whatever reason.
4620
4623
4624 // Try and compute number of instructions in asm.
4625 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
4626 const MachineBasicBlock &MBB = *MI.getParent();
4627 const MachineFunction *MF = MBB.getParent();
4628 const MCAsmInfo &MAI = MF->getTarget().getMCAsmInfo();
4629
4630 // Count the number of register definitions to find the asm string.
4631 unsigned NumDefs = 0;
4632 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
4633 ++NumDefs)
4634 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
4635
4636 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
4637 // Disassemble the AsmStr and approximate number of instructions.
4638 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
4639 Size = getInlineAsmLength(AsmStr, MAI);
4640 }
4641
4642 return Size;
4643}
4644
4646 const uint64_t F = MI.getDesc().TSFlags;
4648}
4649
4651 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();
4652 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
4653
4654 return IS.getUnits();
4655}
4656
4657// Calculate size of the basic block without debug instructions.
4659 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4660}
4661
4663 MachineBasicBlock::const_iterator BundleHead) const {
4664 assert(BundleHead->isBundle() && "Not a bundle header");
4665 auto MII = BundleHead.getInstrIterator();
4666 // Skip the bundle header.
4667 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
4668}
4669
4670/// immediateExtend - Changes the instruction in place to one using an immediate
4671/// extender.
4674 "Instruction must be extendable");
4675 // Find which operand is extendable.
4676 short ExtOpNum = getCExtOpNum(MI);
4677 MachineOperand &MO = MI.getOperand(ExtOpNum);
4678 // This needs to be something we understand.
4679 assert((MO.isMBB() || MO.isImm()) &&
4680 "Branch with unknown extendable field type");
4681 // Mark given operand as extended.
4683}
4684
4686 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
4687 LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "
4688 << printMBBReference(*NewTarget);
4689 MI.dump(););
4690 assert(MI.isBranch());
4691 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4692 int TargetPos = MI.getNumOperands() - 1;
4693 // In general branch target is the last operand,
4694 // but some implicit defs added at the end might change it.
4695 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
4696 --TargetPos;
4697 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4698 MI.getOperand(TargetPos).setMBB(NewTarget);
4700 NewOpcode = reversePrediction(NewOpcode);
4701 }
4702 MI.setDesc(get(NewOpcode));
4703 return true;
4704}
4705
4707 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4709 MachineBasicBlock &B = *A;
4711 DebugLoc DL = I->getDebugLoc();
4712 MachineInstr *NewMI;
4713
4714 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4715 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4716 NewMI = BuildMI(B, I, DL, get(insn));
4717 LLVM_DEBUG(dbgs() << "\n"
4718 << getName(NewMI->getOpcode())
4719 << " Class: " << NewMI->getDesc().getSchedClass());
4720 NewMI->eraseFromParent();
4721 }
4722 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4723}
4724
4725// inverts the predication logic.
4726// p -> NotP
4727// NotP -> P
4729 LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4730 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
4731 return true;
4732}
4733
4734// Reverse the branch prediction.
4735unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4736 int PredRevOpcode = -1;
4737 if (isPredictedTaken(Opcode))
4738 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4739 else
4740 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4741 assert(PredRevOpcode > 0);
4742 return PredRevOpcode;
4743}
4744
4745// TODO: Add more rigorous validation.
4747 const {
4748 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4749}
4750
4753 assert(MIB->isBundle());
4754 MachineOperand &Operand = MIB->getOperand(0);
4755 if (Operand.isImm())
4756 Operand.setImm(Operand.getImm() | memShufDisabledMask);
4757 else
4758 MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));
4759}
4760
4762 assert(MIB.isBundle());
4763 const MachineOperand &Operand = MIB.getOperand(0);
4764 return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);
4765}
4766
4768 return (MI->getOpcode() == Hexagon::V6_vmpy_qf16_hf ||
4769 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4770 MI->getOpcode() == Hexagon::V6_vmpy_qf32_hf ||
4771 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4772 MI->getOpcode() == Hexagon::V6_vmpy_qf32_sf ||
4773 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4774 MI->getOpcode() == Hexagon::V6_vmpy_qf16 ||
4775 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4776 MI->getOpcode() == Hexagon::V6_vmpy_qf32_qf16 ||
4777 MI->getOpcode() == Hexagon::V6_vmpy_qf32);
4778}
4779
4780namespace llvm::HexagonII {
4781
4784 RegType In3 = RegType::Unknown) {
4785 RegTypeInfo I;
4786 I.Output = Out;
4787 I.Input1 = In1;
4788 I.Input2 = In2;
4789 I.Input3 = In3;
4790 return I;
4791}
4792
4793RegTypeInfo getRegTypeInfo(unsigned Opcode) {
4794 switch (Opcode) {
4795 default:
4796 return {};
4797
4798 case Hexagon::V6_vabs_qf16_hf:
4799 return make(RegType::QF16);
4800 case Hexagon::V6_vabs_qf16_qf16:
4802 case Hexagon::V6_vabs_qf32_qf32:
4804 case Hexagon::V6_vabs_qf32_sf:
4805 return make(RegType::QF32);
4806 case Hexagon::V6_vadd_hf:
4807 return make(RegType::QF16);
4808 case Hexagon::V6_vadd_qf16:
4810 case Hexagon::V6_vadd_qf16_mix:
4812 case Hexagon::V6_vadd_qf32:
4814 case Hexagon::V6_vadd_qf32_mix:
4816 case Hexagon::V6_vadd_sf:
4817 return make(RegType::QF32);
4818 case Hexagon::V6_vconv_bf_qf32:
4820 case Hexagon::V6_vconv_f8_qf16:
4822 case Hexagon::V6_vconv_hf_qf16:
4824 case Hexagon::V6_vconv_hf_qf32:
4826 case Hexagon::V6_vconv_qf16_f8:
4827 return make(RegType::QF16);
4828 case Hexagon::V6_vconv_qf16_hf:
4829 return make(RegType::QF16);
4830 case Hexagon::V6_vconv_qf16_qf16:
4832 case Hexagon::V6_vconv_qf32_qf32:
4834 case Hexagon::V6_vconv_qf32_sf:
4835 return make(RegType::QF32);
4836 case Hexagon::V6_vconv_sf_qf32:
4838 case Hexagon::V6_vilog2_qf16:
4840 case Hexagon::V6_vilog2_qf32:
4842 case Hexagon::V6_vmpy_qf16:
4844 case Hexagon::V6_vmpy_qf16_hf:
4845 return make(RegType::QF16);
4846 case Hexagon::V6_vmpy_qf16_mix_hf:
4848 case Hexagon::V6_vmpy_qf32:
4850 case Hexagon::V6_vmpy_qf32_hf:
4851 return make(RegType::QF32);
4852 case Hexagon::V6_vmpy_qf32_mix_hf:
4854 case Hexagon::V6_vmpy_qf32_qf16:
4856 case Hexagon::V6_vmpy_qf32_sf:
4857 return make(RegType::QF32);
4858 case Hexagon::V6_vmpy_rt_hf:
4859 return make(RegType::QF16);
4860 case Hexagon::V6_vmpy_rt_qf16:
4862 case Hexagon::V6_vmpy_rt_sf:
4863 return make(RegType::QF32);
4864 case Hexagon::V6_vneg_qf16_hf:
4865 return make(RegType::QF16);
4866 case Hexagon::V6_vneg_qf16_qf16:
4868 case Hexagon::V6_vneg_qf32_qf32:
4870 case Hexagon::V6_vneg_qf32_sf:
4871 return make(RegType::QF32);
4872 case Hexagon::V6_vsub_hf:
4873 return make(RegType::QF16);
4874 case Hexagon::V6_vsub_qf16:
4876 case Hexagon::V6_vsub_qf16_mix:
4878 case Hexagon::V6_vsub_qf32:
4880 case Hexagon::V6_vsub_qf32_mix:
4882 case Hexagon::V6_vsub_sf:
4883 return make(RegType::QF32);
4884 case Hexagon::V6_vsub_sf_mix:
4886 case Hexagon::V6_vsub_hf_mix:
4888 }
4889}
4890
4891} // namespace llvm::HexagonII
4892
4894 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
4895 switch (Index) {
4896 case 1:
4897 return Info.Input1 == HexagonII::RegType::QF32;
4898 case 2:
4899 return Info.Input2 == HexagonII::RegType::QF32;
4900 case 3:
4901 return Info.Input3 == HexagonII::RegType::QF32;
4902 case 0:
4903 return Info.Input1 == HexagonII::RegType::QF32 ||
4904 Info.Input2 == HexagonII::RegType::QF32 ||
4905 Info.Input3 == HexagonII::RegType::QF32;
4906 default: // No instruction with more than 3 operands uses QF32.
4907 return false;
4908 }
4909 return false;
4910}
4911
4913 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
4914 switch (Index) {
4915 case 1:
4916 return Info.Input1 == HexagonII::RegType::QF16;
4917 case 2:
4918 return Info.Input2 == HexagonII::RegType::QF16;
4919 case 3:
4920 return Info.Input3 == HexagonII::RegType::QF16;
4921 case 0:
4922 return Info.Input1 == HexagonII::RegType::QF16 ||
4923 Info.Input2 == HexagonII::RegType::QF16 ||
4924 Info.Input3 == HexagonII::RegType::QF16;
4925 default: // No instruction with more than 3 operands uses QF16.
4926 return false;
4927 }
4928 return false;
4929}
4930
4932 return usesQF32Operand(MI, Index) || usesQF16Operand(MI, Index);
4933}
4934
4938
4942
4946
4947// Return true if the function contains any qf-generating instructions.
4949 for (const MachineBasicBlock &MBB : MF)
4950 for (const MachineInstr &MI : MBB)
4951 if (isQFPInstr(const_cast<MachineInstr *>(&MI)))
4952 return true;
4953 return false;
4954}
4955
4956// Returns true if A appears before B within the same basic block.
4958 const MachineInstr *B) const {
4959 if (!A || !B || A->getParent() != B->getParent())
4960 return false;
4961
4962 for (const MachineInstr &MI : *A->getParent()) {
4963 if (&MI == A)
4964 return true;
4965 if (&MI == B)
4966 return false;
4967 }
4968 return false;
4969}
4970
4971// Addressing mode relations.
4973 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
4974}
4975
4977 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
4978}
4979
4981 return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;
4982}
4983
4985 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
4986}
4987
4989 return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;
4990}
4991
4993 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
4994}
4995
4997 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;
4998}
4999
5001 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;
5002}
5003
5005 static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);
5006
5007 return MCInstBuilder(Hexagon::BUNDLE)
5008 .addImm(0)
5009 .addInst(&Nop);
5010}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool mayAlias(MachineInstr &MIa, SmallVectorImpl< MachineInstr * > &MemInsns, AliasAnalysis *AA)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
BitTracker BT
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Forward Handle Accesses
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
static void parseOperands(MachineInstr *MI, SmallVector< unsigned, 4 > &Defs, SmallVector< unsigned, 8 > &Uses)
Gather register def/uses from MI.
static cl::opt< bool > DisableNVSchedule("disable-hexagon-nv-schedule", cl::Hidden, cl::desc("Disable schedule adjustment for new value stores."))
const int Hexagon_MEMH_OFFSET_MAX
const int Hexagon_MEMB_OFFSET_MAX
const int Hexagon_MEMH_OFFSET_MIN
const int Hexagon_MEMD_OFFSET_MAX
static cl::opt< bool > EnableTimingClassLatency("enable-timing-class-latency", cl::Hidden, cl::init(false), cl::desc("Enable timing class latency"))
const int Hexagon_MEMD_OFFSET_MIN
const int Hexagon_ADDI_OFFSET_MAX
static cl::opt< bool > EnableACCForwarding("enable-acc-forwarding", cl::Hidden, cl::init(true), cl::desc("Enable vec acc forwarding"))
static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI)
const int Hexagon_MEMW_OFFSET_MAX
Constants for Hexagon instructions.
const int Hexagon_MEMW_OFFSET_MIN
cl::opt< bool > ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary."))
const int Hexagon_ADDI_OFFSET_MIN
static cl::opt< bool > BranchRelaxAsmLarge("branch-relax-asm-large", cl::init(true), cl::Hidden, cl::desc("branch relax asm"))
static cl::opt< bool > EnableALUForwarding("enable-alu-forwarding", cl::Hidden, cl::init(true), cl::desc("Enable vec alu forwarding"))
const int Hexagon_MEMB_OFFSET_MIN
static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB, MachineBasicBlock::const_instr_iterator MIE)
Calculate number of instructions excluding the debug instructions.
static cl::opt< bool > EnableBranchPrediction("hexagon-enable-branch-prediction", cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"))
static bool isDblRegForSubInst(Register Reg, const HexagonRegisterInfo &HRI)
static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI)
static cl::opt< bool > UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden, cl::desc("Use the DFA based hazard recognizer."))
static bool isIntRegForSubInst(Register Reg)
static bool isDuplexPairMatch(unsigned Ga, unsigned Gb)
#define HEXAGON_INSTR_SIZE
IRTranslator LLVM IR MI
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
static bool isUndef(const MachineInstr &MI)
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
uint64_t IntrinsicInst * II
PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC)
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
static bool isBranch(unsigned Opcode)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
Remove Loads Into Fake Uses
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:479
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A debug info location.
Definition DebugLoc.h:126
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
int getDuplexOpcode(const MachineInstr &MI, bool ForBigCore=true) const
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
short changeAddrMode_abs_io(short Opc) const
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
short getRegForm(const MachineInstr &MI) const
bool isVecALU(const MachineInstr &MI) const
bool isCompoundBranchInstr(const MachineInstr &MI) const
bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const
Symmetrical. See if these two instructions are fit for duplex pair.
bool isJumpR(const MachineInstr &MI) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
Decompose the machine operand's target flags into two values - the direct target flag value and any o...
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const override
Get the base register and byte offset of a load/store instr.
bool producesStall(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
bool invertAndChangeJumpTarget(MachineInstr &MI, MachineBasicBlock *NewTarget) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
bool isPredictedTaken(unsigned Opcode) const
bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const
bool hasQFPInstrs(const MachineFunction &MF) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const
int getDotNewPredOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const
bool isQFP32Instr(MachineInstr *MI) const
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
If the specified instruction defines any predicate or condition code register(s) used for predication...
unsigned getInvertedPredicatedOpcode(const int Opc) const
bool isPureSlot0(const MachineInstr &MI) const
bool doesNotReturn(const MachineInstr &CallMI) const
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool usesQF16Operand(MachineInstr *MI, unsigned Index=0) const
bool isPredicatedNew(const MachineInstr &MI) const
bool isSignExtendingLoad(const MachineInstr &MI) const
bool isVecAcc(const MachineInstr &MI) const
bool reversePredSense(MachineInstr &MI) const
bool isPostIncWithImmOffset(const MachineInstr &MI) const
bool isQFPMul(const MachineInstr *MF) const
unsigned getAddrMode(const MachineInstr &MI) const
MCInst getNop() const override
bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const
bool mayBeNewStore(const MachineInstr &MI) const
bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const
bool canExecuteInBundle(const MachineInstr &First, const MachineInstr &Second) const
Can these instructions execute at the same time in a bundle.
bool isQFP16Instr(MachineInstr *MI) const
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
getOperandLatency - Compute and return the use operand latency of a given pair of def and use.
bool isAddrModeWithOffset(const MachineInstr &MI) const
bool isBaseImmOffset(const MachineInstr &MI) const
bool isAbsoluteSet(const MachineInstr &MI) const
short changeAddrMode_io_pi(short Opc) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Emit instructions to copy a pair of physical registers.
short changeAddrMode_pi_io(short Opc) const
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
std::unique_ptr< PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
bool isLoopN(const MachineInstr &MI) const
bool isSpillPredRegOp(const MachineInstr &MI) const
bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has store to stack slots.
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
Return an array that contains the direct target flag values and their names.
bool isIndirectCall(const MachineInstr &MI) const
short changeAddrMode_ur_rr(short Opc) const
bool isValidAutoIncImm(const EVT VT, const int Offset) const
bool hasNonExtEquivalent(const MachineInstr &MI) const
bool isConstExtended(const MachineInstr &MI) const
bool getIncrementValue(const MachineInstr &MI, int &Value) const override
If the instruction is an increment of a constant value, return the amount.
int getCondOpcode(int Opc, bool sense) const
MachineInstr * findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp, MachineBasicBlock *TargetBB, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData, const MachineInstr &MI) const
bool usesQF32Operand(MachineInstr *MI, unsigned Index=0) const
bool isAccumulator(const MachineInstr &MI) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Compute the instruction latency of a given instruction.
bool PredOpcodeHasJMP_c(unsigned Opcode) const
bool isNewValue(const MachineInstr &MI) const
Register createVR(MachineFunction *MF, MVT VT) const
HexagonInstrInfo specifics.
bool isDotCurInst(const MachineInstr &MI) const
bool validateBranchCond(const ArrayRef< MachineOperand > &Cond) const
bool isExtended(const MachineInstr &MI) const
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Return true if it's profitable to predicate instructions with accumulated instruction latency of "Num...
bool isAsCheapAsAMove(const MachineInstr &MI) const override
int getMaxValue(const MachineInstr &MI) const
bool isPredicateLate(unsigned Opcode) const
short changeAddrMode_rr_ur(short Opc) const
bool isNewValueInst(const MachineInstr &MI) const
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI, const TargetSubtargetInfo *STI=nullptr) const override
Measure the specified inline asm to determine an approximation of its length.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
int getNonDotCurOp(const MachineInstr &MI) const
bool isIndirectL4Return(const MachineInstr &MI) const
unsigned reversePrediction(unsigned Opcode) const
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
Return an array that contains the bitmask target flag values and their names.
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
InstrStage::FuncUnits getUnits(const MachineInstr &MI) const
unsigned getMemAccessSize(const MachineInstr &MI) const
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
bool isComplex(const MachineInstr &MI) const
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const
MachineBasicBlock::instr_iterator expandVGatherPseudo(MachineInstr &MI) const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
int getDotNewOp(const MachineInstr &MI) const
void changeDuplexOpcode(MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const
bool isMemOp(const MachineInstr &MI) const
int getDotOldOp(const MachineInstr &MI) const
bool hasUncondBranch(const MachineBasicBlock *B) const
short getNonExtOpcode(const MachineInstr &MI) const
bool isTailCall(const MachineInstr &MI) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert a noop into the instruction stream at the specified point.
bool isDeallocRet(const MachineInstr &MI) const
HexagonInstrInfo(const HexagonSubtarget &ST)
unsigned getCExtOpNum(const MachineInstr &MI) const
bool isSolo(const MachineInstr &MI) const
DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override
Create machine specific model for scheduling.
bool isLateSourceInstr(const MachineInstr &MI) const
bool isDotNewInst(const MachineInstr &MI) const
void translateInstrsForDup(MachineFunction &MF, bool ToBigInstrs=true) const
bool isTC1(const MachineInstr &MI) const
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
Test if the given instruction should be considered a scheduling boundary.
bool predCanBeUsedAsDotNew(const MachineInstr &MI, Register PredReg) const
unsigned getSize(const MachineInstr &MI) const
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
Return true if it's profitable for if-converter to duplicate instructions of specified accumulated in...
short changeAddrMode_io_abs(short Opc) const
int getDotCurOp(const MachineInstr &MI) const
bool expandPostRAPseudo(MachineInstr &MI) const override
This function is called for all pseudo instructions that remain after register allocation.
bool isMIBefore(const MachineInstr *A, const MachineInstr *B) const
bool isExpr(unsigned OpType) const
void genAllInsnTimingClasses(MachineFunction &MF) const
bool isTC2Early(const MachineInstr &MI) const
bool hasEHLabel(const MachineBasicBlock *B) const
bool shouldSink(const MachineInstr &MI) const override
bool isZeroExtendingLoad(const MachineInstr &MI) const
short changeAddrMode_rr_io(short Opc) const
bool isHVXVec(const MachineInstr &MI) const
bool isDependent(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
short changeAddrMode_io_rr(short Opc) const
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
Returns true if the first specified predicate subsumes the second, e.g.
bool mayBeCurLoad(const MachineInstr &MI) const
bool getBundleNoShuf(const MachineInstr &MIB) const
bool isNewValueJump(const MachineInstr &MI) const
bool isTC4x(const MachineInstr &MI) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
bool getPredReg(ArrayRef< MachineOperand > Cond, Register &PredReg, unsigned &PredRegPos, RegState &PredRegFlags) const
bool isFloat(const MachineInstr &MI) const
bool isQFPInstr(MachineInstr *MI) const
bool isToBeScheduledASAP(const MachineInstr &MI1, const MachineInstr &MI2) const
MachineOperand * getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, LocationSize &AccessSize) const
bool getInvertedPredSense(SmallVectorImpl< MachineOperand > &Cond) const
unsigned nonDbgBBSize(const MachineBasicBlock *BB) const
getInstrTimingClassLatency - Compute the instruction latency of a given instruction using Timing Clas...
uint64_t getType(const MachineInstr &MI) const
bool isEndLoopN(unsigned Opcode) const
bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
For instructions with a base and offset, return the position of the base register and offset operands...
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
bool isExtendable(const MachineInstr &MI) const
void immediateExtend(MachineInstr &MI) const
immediateExtend - Changes the instruction in place to one using an immediate extender.
bool isValidOffset(unsigned Opcode, int Offset, bool Extend=true) const
HexagonII::CompoundGroup getCompoundCandidateGroup(const MachineInstr &MI) const
bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has load from stack slots.
SmallVector< MachineInstr *, 2 > getBranchingInstrs(MachineBasicBlock &MBB) const
bool isPredicatedTrue(const MachineInstr &MI) const
bool isNewValueStore(const MachineInstr &MI) const
int getMinValue(const MachineInstr &MI) const
bool isVecUsableNextPacket(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
unsigned getCompoundOpcode(const MachineInstr &GA, const MachineInstr &GB) const
bool addLatencyToSchedule(const MachineInstr &MI1, const MachineInstr &MI2) const
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
int getDotNewPredJumpOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const
bool usesQFOperand(MachineInstr *MI, unsigned Index=0) const
bool isTC2(const MachineInstr &MI) const
Register getFrameRegister(const MachineFunction &MF) const override
Itinerary data supplied by a subtarget to be used by a target.
unsigned getStageLatency(unsigned ItinClassIndx) const
Return the total stage latency of the given class.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
A set of physical registers with utility functions to track liveness when walking backward/forward th...
LLVM_ABI void stepForward(const MachineInstr &MI, SmallVectorImpl< std::pair< MCPhysReg, const MachineOperand * > > &Clobbers)
Simulates liveness when stepping forward over an instruction(bundle).
LLVM_ABI void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB.
LLVM_ABI bool available(const MachineRegisterInfo &MRI, MCRegister Reg) const
Returns true if register Reg and no aliasing register is in the set.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds all live-out registers of basic block MBB.
bool contains(MCRegister Reg) const
Returns true if register Reg is contained in the set.
static LocationSize precise(uint64_t Value)
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
virtual unsigned getMaxInstLength(const MCSubtargetInfo *STI=nullptr) const
Returns the maximum possible encoded instruction size in bytes.
Definition MCAsmInfo.h:548
StringRef getCommentString() const
Definition MCAsmInfo.h:559
const char * getSeparatorString() const
Definition MCAsmInfo.h:554
MCInstBuilder & addInst(const MCInst *Val)
Add a new MCInst operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Machine Value Type.
SimpleValueType SimpleTy
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
bool isBundle() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
void setImm(int64_t immVal)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
void addTargetFlag(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Register getReg() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition StringRef.h:471
Object returned by analyzeLoopForPipelining.
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a store to a stack slot, return true along with the FrameInd...
virtual std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const
virtual bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a load from a stack slot, return true along with the FrameIn...
Primary interface to the complete machine description for the target machine.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const InstrItineraryData * getInstrItineraryData() const
getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSlot0Only(unsigned units)
HexagonII - This namespace holds all of the target specific flags that instruction info tracks.
unsigned const TypeCVI_LAST
static constexpr RegTypeInfo make(RegType Out, RegType In1=RegType::Unknown, RegType In2=RegType::Unknown, RegType In3=RegType::Unknown)
unsigned const TypeCVI_FIRST
RegType getOpRegType(unsigned Opcode)
RegTypeInfo getRegTypeInfo(unsigned Opcode)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ InternalRead
Register reads a value that is defined inside the same instruction or bundle.
@ Undef
Value of the register doesn't matter.
@ NoFlags
No Specific Flags.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
bool is_TC1(unsigned SchedClass)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
bool is_TC2(unsigned SchedClass)
bool is_TC2early(unsigned SchedClass)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:183
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool isSpace(char C)
Checks whether character C is whitespace in the "C" locale.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
constexpr RegState getUndefRegState(bool B)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
bool is_TC4x(unsigned SchedClass)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:411
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:354
These values represent a non-pipelined step in the execution of an instruction.
uint64_t FuncUnits
Bitmask representing a set of functional units.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.