27#include "llvm/Config/llvm-config.h"
44#define DEBUG_TYPE "hsdr"
49 cl::desc(
"Maximum number of split partitions"));
51 cl::desc(
"Do not split loads or stores"));
63 StringRef getPassName()
const override {
64 return "Hexagon Split Double Registers";
67 void getAnalysisUsage(AnalysisUsage &AU)
const override {
78 const HexagonRegisterInfo *TRI =
nullptr;
79 const HexagonInstrInfo *TII =
nullptr;
80 const MachineLoopInfo *MLI;
81 MachineRegisterInfo *MRI;
83 using USet = std::set<unsigned>;
84 using UUSetMap = std::map<unsigned, USet>;
85 using UUPair = std::pair<unsigned, unsigned>;
86 using UUPairMap = std::map<unsigned, UUPair>;
87 using LoopRegMap = std::map<const MachineLoop *, USet>;
89 bool isInduction(
unsigned Reg, LoopRegMap &IRM)
const;
90 bool isVolatileInstr(
const MachineInstr *
MI)
const;
91 bool isFixedInstr(
const MachineInstr *
MI)
const;
92 void partitionRegisters(UUSetMap &P2Rs);
93 int32_t profit(
const MachineInstr *
MI)
const;
95 bool isProfitable(
const USet &Part, LoopRegMap &IRM)
const;
97 void collectIndRegsForLoop(
const MachineLoop *L, USet &Rs);
98 void collectIndRegs(LoopRegMap &IRM);
100 void createHalfInstr(
unsigned Opc, MachineInstr *
MI,
101 const UUPairMap &PairMap,
unsigned SubR);
102 void splitMemRef(MachineInstr *
MI,
const UUPairMap &PairMap);
103 void splitImmediate(MachineInstr *
MI,
const UUPairMap &PairMap);
104 void splitCombine(MachineInstr *
MI,
const UUPairMap &PairMap);
105 void splitExt(MachineInstr *
MI,
const UUPairMap &PairMap);
106 void splitShift(MachineInstr *
MI,
const UUPairMap &PairMap);
107 void splitAslOr(MachineInstr *
MI,
const UUPairMap &PairMap);
108 bool splitInstr(MachineInstr *
MI,
const UUPairMap &PairMap);
109 void replaceSubregUses(MachineInstr *
MI,
const UUPairMap &PairMap);
110 void collapseRegPairs(MachineInstr *
MI,
const UUPairMap &PairMap);
111 bool splitPartition(
const USet &Part);
115 static void dump_partition(raw_ostream&,
const USet&,
116 const TargetRegisterInfo&);
121char HexagonSplitDoubleRegs::ID;
122int HexagonSplitDoubleRegs::Counter = 0;
124 &Hexagon::DoubleRegsRegClass;
127 "Hexagon Split Double Registers",
false,
false)
129#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
139bool HexagonSplitDoubleRegs::isInduction(
unsigned Reg, LoopRegMap &IRM)
const {
141 const USet &Rs =
I.second;
142 if (Rs.find(
Reg) != Rs.end())
148bool HexagonSplitDoubleRegs::isVolatileInstr(
const MachineInstr *
MI)
const {
149 for (
auto &MO :
MI->memoperands())
150 if (MO->isVolatile() || MO->isAtomic())
155bool HexagonSplitDoubleRegs::isFixedInstr(
const MachineInstr *
MI)
const {
156 if (
MI->mayLoadOrStore())
159 if (
MI->isDebugInstr())
162 unsigned Opc =
MI->getOpcode();
167 case TargetOpcode::PHI:
168 case TargetOpcode::COPY:
171 case Hexagon::L2_loadrd_io:
173 if (
MI->getOperand(1).isReg())
176 case Hexagon::S2_storerd_io:
178 if (
MI->getOperand(0).isReg())
181 case Hexagon::L2_loadrd_pi:
182 case Hexagon::S2_storerd_pi:
184 case Hexagon::A2_tfrpi:
185 case Hexagon::A2_combineii:
186 case Hexagon::A4_combineir:
187 case Hexagon::A4_combineii:
188 case Hexagon::A4_combineri:
189 case Hexagon::A2_combinew:
190 case Hexagon::CONST64:
192 case Hexagon::A2_sxtw:
194 case Hexagon::A2_andp:
195 case Hexagon::A2_orp:
196 case Hexagon::A2_xorp:
197 case Hexagon::S2_asl_i_p_or:
198 case Hexagon::S2_asl_i_p:
199 case Hexagon::S2_asr_i_p:
200 case Hexagon::S2_lsr_i_p:
204 for (
auto &
Op :
MI->operands()) {
214void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
215 using UUMap = std::map<unsigned, unsigned>;
216 using UVect = std::vector<unsigned>;
220 for (
unsigned i = 0; i < NumRegs; ++i) {
226 BitVector FixedRegs(NumRegs);
233 if (!DefI || isFixedInstr(DefI))
243 USet &Asc = AssocMap[
R];
246 MachineOperand &
Op = *
U;
247 MachineInstr *UseI =
Op.getParent();
248 if (isFixedInstr(UseI))
250 for (MachineOperand &MO : UseI->
operands()) {
252 if (&MO == &
Op || !MO.isReg() || MO.getSubReg())
255 if (!
T.isVirtual()) {
261 unsigned u =
T.virtRegIndex();
267 AssocMap[
T].insert(R);
278 if (Visited.count(R))
281 unsigned ThisP = FixedRegs[
x] ? 0 : NextP++;
284 for (
unsigned i = 0; i < WorkQ.size(); ++i) {
285 unsigned T = WorkQ[i];
286 if (Visited.count(
T))
291 USet &Asc = AssocMap[
T];
297 P2Rs[
I.second].insert(
I.first);
302 if (
Imm == 0 ||
Imm == 0xFFFFFFFF)
307int32_t HexagonSplitDoubleRegs::profit(
const MachineInstr *
MI)
const {
309 unsigned Opc =
MI->getOpcode();
311 case TargetOpcode::PHI:
312 for (
const auto &
Op :
MI->operands())
316 case TargetOpcode::COPY:
317 if (
MI->getOperand(1).getSubReg() != 0)
321 case Hexagon::L2_loadrd_io:
322 case Hexagon::S2_storerd_io:
324 case Hexagon::L2_loadrd_pi:
325 case Hexagon::S2_storerd_pi:
328 case Hexagon::A2_tfrpi:
329 case Hexagon::CONST64: {
331 unsigned Lo =
D & 0xFFFFFFFFULL;
332 unsigned Hi =
D >> 32;
335 case Hexagon::A2_combineii:
336 case Hexagon::A4_combineii: {
337 const MachineOperand &Op1 =
MI->getOperand(1);
338 const MachineOperand &Op2 =
MI->getOperand(2);
341 return Prof1 + Prof2;
343 case Hexagon::A4_combineri:
347 case Hexagon::A4_combineir: {
349 const MachineOperand &OpX =
MI->getOperand(ImmX);
352 if (V == 0 || V == -1)
358 case Hexagon::A2_combinew:
361 case Hexagon::A2_sxtw:
364 case Hexagon::A2_andp:
365 case Hexagon::A2_orp:
366 case Hexagon::A2_xorp: {
369 return profit(Rs) + profit(Rt);
372 case Hexagon::S2_asl_i_p_or: {
373 unsigned S =
MI->getOperand(3).getImm();
374 if (S == 0 || S == 32)
378 case Hexagon::S2_asl_i_p:
379 case Hexagon::S2_asr_i_p:
380 case Hexagon::S2_lsr_i_p:
381 unsigned S =
MI->getOperand(2).getImm();
382 if (S == 0 || S == 32)
394int32_t HexagonSplitDoubleRegs::profit(
Register Reg)
const {
399 case Hexagon::A2_tfrpi:
400 case Hexagon::CONST64:
401 case Hexagon::A2_combineii:
402 case Hexagon::A4_combineii:
403 case Hexagon::A4_combineri:
404 case Hexagon::A4_combineir:
405 case Hexagon::A2_combinew:
413bool HexagonSplitDoubleRegs::isProfitable(
const USet &Part, LoopRegMap &IRM)
415 unsigned FixedNum = 0, LoopPhiNum = 0;
418 for (
unsigned DR : Part) {
420 int32_t
P = profit(DefI);
421 if (
P == std::numeric_limits<int>::min())
425 if (isInduction(DR, IRM))
430 MachineInstr *UseI =
U->getParent();
431 if (isFixedInstr(UseI)) {
435 if (
Op.isReg() && Part.count(
Op.getReg()))
448 if (L &&
L->getHeader() ==
PB)
452 int32_t
P = profit(UseI);
453 if (
P == std::numeric_limits<int>::min())
459 if (FixedNum > 0 && LoopPhiNum > 0)
460 TotalP -= 20*LoopPhiNum;
468void HexagonSplitDoubleRegs::collectIndRegsForLoop(
const MachineLoop *L,
470 const MachineBasicBlock *HB =
L->getHeader();
471 const MachineBasicBlock *LB =
L->getLoopLatch();
477 const MachineBasicBlock *
TB =
nullptr, *FB =
nullptr;
489 if (TB != HB && FB != HB)
491 assert(
Cond[1].
isReg() &&
"Unexpected Cond vector from analyzeBranch");
499 const MachineInstr *CmpI = MRI->
getVRegDef(PR);
500 while (CmpI->
getOpcode() == Hexagon::C2_not)
503 int64_t
Mask = 0, Val = 0;
512 if (!CmpR1 && !CmpR2)
522 using UVect = std::vector<unsigned>;
525 for (
auto &
MI : *HB) {
528 const MachineOperand &MD =
MI.getOperand(0);
536 auto NoIndOp = [
this, CmpR1, CmpR2] (
unsigned R) ->
bool {
540 if (UseI->
getOpcode() != Hexagon::A2_addp)
546 if (
T == CmpR1 ||
T == CmpR2)
552 Rs.insert(DP.begin(), End);
558 dump_partition(
dbgs(), Rs, *
TRI);
563void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) {
564 using LoopVector = std::vector<MachineLoop *>;
569 for (
unsigned i = 0; i < WorkQ.
size(); ++i)
573 for (MachineLoop *L : WorkQ) {
575 collectIndRegsForLoop(L, Rs);
577 IRM.insert(std::make_pair(L, Rs));
581void HexagonSplitDoubleRegs::createHalfInstr(
unsigned Opc, MachineInstr *
MI,
582 const UUPairMap &PairMap,
unsigned SubR) {
583 MachineBasicBlock &
B = *
MI->getParent();
587 for (
auto &
Op :
MI->operands()) {
594 unsigned SR =
Op.getSubReg();
595 bool isVirtReg =
R.isVirtual();
596 bool isKill =
Op.isKill();
597 if (isVirtReg && MRI->
getRegClass(R) == DoubleRC) {
599 UUPairMap::const_iterator
F = PairMap.find(R);
600 if (
F == PairMap.end()) {
603 const UUPair &
P =
F->second;
604 R = (SubR == Hexagon::isub_lo) ?
P.first :
P.second;
609 Op.isDead(),
Op.isUndef(),
Op.isEarlyClobber(), SR,
Op.isDebug(),
610 Op.isInternalRead());
615void HexagonSplitDoubleRegs::splitMemRef(MachineInstr *
MI,
616 const UUPairMap &PairMap) {
617 bool Load =
MI->mayLoad();
618 unsigned OrigOpc =
MI->getOpcode();
619 bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi ||
620 OrigOpc == Hexagon::S2_storerd_pi);
621 MachineInstr *LowI, *HighI;
622 MachineBasicBlock &
B = *
MI->getParent();
628 MachineOperand &AdrOp =
MI->getOperand(AdrX);
630 MachineOperand &ValOp =
Load ?
MI->getOperand(0)
632 :
MI->getOperand(2));
633 UUPairMap::const_iterator
F = PairMap.find(ValOp.
getReg());
637 const UUPair &
P =
F->second;
646 const UUPair &
P =
F->second;
660 int64_t Inc =
Load ?
MI->getOperand(3).getImm()
661 :
MI->getOperand(2).getImm();
662 MachineOperand &UpdOp =
Load ?
MI->getOperand(1) :
MI->getOperand(0);
675 for (
auto &MO :
MI->memoperands()) {
676 const MachinePointerInfo &Ptr = MO->getPointerInfo();
688void HexagonSplitDoubleRegs::splitImmediate(MachineInstr *
MI,
689 const UUPairMap &PairMap) {
690 MachineOperand &Op0 =
MI->getOperand(0);
691 MachineOperand &Op1 =
MI->getOperand(1);
695 MachineBasicBlock &
B = *
MI->getParent();
697 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
699 const UUPair &
P =
F->second;
710 .
addImm(int32_t(V & 0xFFFFFFFFULL));
712 .
addImm(int32_t(V >> 32));
715void HexagonSplitDoubleRegs::splitCombine(MachineInstr *
MI,
716 const UUPairMap &PairMap) {
717 MachineOperand &Op0 =
MI->getOperand(0);
718 MachineOperand &Op1 =
MI->getOperand(1);
719 MachineOperand &Op2 =
MI->getOperand(2);
722 MachineBasicBlock &
B = *
MI->getParent();
724 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
726 const UUPair &
P =
F->second;
745void HexagonSplitDoubleRegs::splitExt(MachineInstr *
MI,
746 const UUPairMap &PairMap) {
747 MachineOperand &Op0 =
MI->getOperand(0);
748 MachineOperand &Op1 =
MI->getOperand(1);
751 MachineBasicBlock &
B = *
MI->getParent();
753 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
755 const UUPair &
P =
F->second;
765void HexagonSplitDoubleRegs::splitShift(MachineInstr *
MI,
766 const UUPairMap &PairMap) {
767 using namespace Hexagon;
769 MachineOperand &Op0 =
MI->getOperand(0);
770 MachineOperand &Op1 =
MI->getOperand(1);
771 MachineOperand &Op2 =
MI->getOperand(2);
773 int64_t Sh64 = Op2.
getImm();
774 assert(Sh64 >= 0 && Sh64 < 64);
777 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
779 const UUPair &
P =
F->second;
783 unsigned Opc =
MI->getOpcode();
784 bool Right = (
Opc == S2_lsr_i_p ||
Opc == S2_asr_i_p);
788 MachineBasicBlock &
B = *
MI->getParent();
792 : (
Signed ? S2_asr_i_r : S2_lsr_i_r);
793 unsigned LoSR = isub_lo;
794 unsigned HiSR = isub_hi;
825 else if (S == 16 &&
Signed)
856 }
else if (S == 32) {
871 else if (S == 16 &&
Signed)
889void HexagonSplitDoubleRegs::splitAslOr(MachineInstr *
MI,
890 const UUPairMap &PairMap) {
891 using namespace Hexagon;
893 MachineOperand &Op0 =
MI->getOperand(0);
894 MachineOperand &Op1 =
MI->getOperand(1);
895 MachineOperand &Op2 =
MI->getOperand(2);
896 MachineOperand &Op3 =
MI->getOperand(3);
898 int64_t Sh64 = Op3.
getImm();
899 assert(Sh64 >= 0 && Sh64 < 64);
902 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
904 const UUPair &
P =
F->second;
905 unsigned LoR =
P.first;
906 unsigned HiR =
P.second;
908 MachineBasicBlock &
B = *
MI->getParent();
914 unsigned LoSR = isub_lo;
915 unsigned HiSR = isub_hi;
957 }
else if (S == 32) {
982bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *
MI,
983 const UUPairMap &PairMap) {
984 using namespace Hexagon;
988 unsigned Opc =
MI->getOpcode();
991 case TargetOpcode::PHI:
992 case TargetOpcode::COPY: {
995 createHalfInstr(
Opc,
MI, PairMap, isub_lo);
996 createHalfInstr(
Opc,
MI, PairMap, isub_hi);
1002 createHalfInstr(A2_and,
MI, PairMap, isub_lo);
1003 createHalfInstr(A2_and,
MI, PairMap, isub_hi);
1007 createHalfInstr(A2_or,
MI, PairMap, isub_lo);
1008 createHalfInstr(A2_or,
MI, PairMap, isub_hi);
1012 createHalfInstr(A2_xor,
MI, PairMap, isub_lo);
1013 createHalfInstr(A2_xor,
MI, PairMap, isub_hi);
1021 splitMemRef(
MI, PairMap);
1027 splitImmediate(
MI, PairMap);
1036 splitCombine(
MI, PairMap);
1041 splitExt(
MI, PairMap);
1048 splitShift(
MI, PairMap);
1053 splitAslOr(
MI, PairMap);
1065void HexagonSplitDoubleRegs::replaceSubregUses(MachineInstr *
MI,
1066 const UUPairMap &PairMap) {
1067 for (
auto &
Op :
MI->operands()) {
1068 if (!
Op.isReg() || !
Op.isUse() || !
Op.getSubReg())
1071 UUPairMap::const_iterator
F = PairMap.find(R);
1072 if (
F == PairMap.end())
1074 const UUPair &
P =
F->second;
1075 switch (
Op.getSubReg()) {
1076 case Hexagon::isub_lo:
1079 case Hexagon::isub_hi:
1080 Op.setReg(
P.second);
1087void HexagonSplitDoubleRegs::collapseRegPairs(MachineInstr *
MI,
1088 const UUPairMap &PairMap) {
1089 MachineBasicBlock &
B = *
MI->getParent();
1092 for (
auto &
Op :
MI->operands()) {
1093 if (!
Op.isReg() || !
Op.isUse())
1100 UUPairMap::const_iterator
F = PairMap.find(R);
1101 if (
F == PairMap.end())
1103 const UUPair &Pr =
F->second;
1107 .
addImm(Hexagon::isub_lo)
1109 .
addImm(Hexagon::isub_hi);
1114bool HexagonSplitDoubleRegs::splitPartition(
const USet &Part) {
1115 using MISet = std::set<MachineInstr *>;
1121 dump_partition(
dbgs(), Part, *
TRI);
dbgs() <<
'\n');
1126 for (
unsigned DR : Part) {
1134 SplitIns.insert(
U->getParent());
1141 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR)));
1145 for (
auto *
MI : SplitIns) {
1146 if (isFixedInstr(
MI)) {
1147 collapseRegPairs(
MI, PairMap);
1149 bool Done = splitInstr(
MI, PairMap);
1156 for (
unsigned DR : Part) {
1163 Uses.insert(
U->getParent());
1164 for (
auto *M :
Uses)
1165 replaceSubregUses(M, PairMap);
1168 for (
auto *
MI : Erase) {
1169 MachineBasicBlock *
B =
MI->getParent();
1176bool HexagonSplitDoubleRegs::runOnMachineFunction(
MachineFunction &MF) {
1184 TRI =
ST.getRegisterInfo();
1185 TII =
ST.getInstrInfo();
1187 MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1192 collectIndRegs(IRM);
1193 partitionRegisters(P2Rs);
1196 dbgs() <<
"Register partitioning: (partition #0 is fixed)\n";
1197 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1198 dbgs() <<
'#' <<
I->first <<
" -> ";
1199 dump_partition(
dbgs(),
I->second, *
TRI);
1207 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1210 if (Limit >= 0 && Counter >= Limit)
1212 USet &Part =
I->second;
1218 Changed |= splitPartition(Part);
1225 return new HexagonSplitDoubleRegs();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
const HexagonInstrInfo * TII
static cl::opt< bool > MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true), cl::desc("Do not split loads or stores"))
static cl::opt< bool > SplitAll("hsdr-split-all", cl::Hidden, cl::init(false), cl::desc("Split all partitions"))
static cl::opt< int > MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1), cl::desc("Maximum number of split partitions"))
static int32_t profitImm(unsigned Imm)
SmallVector< Loop *, 4 > LoopVector
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isReg(const MCInst &MI, unsigned OpNo)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
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 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 PredOpcodeHasJMP_c(unsigned Opcode) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
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 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
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
Flags
Flags values. These may be or'd together.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static use_nodbg_iterator use_nodbg_end()
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Load
The value being inserted comes from a load (InsertElement only).
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
DWARFExpression::Operation Op
FunctionPass * createHexagonSplitDoubleRegs()
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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass