10 #define DEBUG_TYPE "hsdr" 29 #include "llvm/Config/llvm-config.h" 56 cl::desc(
"Maximum number of split partitions"));
58 cl::desc(
"Do not split loads or stores"));
71 return "Hexagon Split Double Registers";
90 using USet = std::set<unsigned>;
91 using UUSetMap = std::map<unsigned, USet>;
92 using UUPair = std::pair<unsigned, unsigned>;
93 using UUPairMap = std::map<unsigned, UUPair>;
94 using LoopRegMap = std::map<const MachineLoop *, USet>;
96 bool isInduction(
unsigned Reg, LoopRegMap &IRM)
const;
99 void partitionRegisters(UUSetMap &P2Rs);
101 int32_t profit(
unsigned Reg)
const;
102 bool isProfitable(
const USet &Part, LoopRegMap &IRM)
const;
104 void collectIndRegsForLoop(
const MachineLoop *L, USet &Rs);
105 void collectIndRegs(LoopRegMap &IRM);
108 const UUPairMap &PairMap,
unsigned SubR);
109 void splitMemRef(
MachineInstr *MI,
const UUPairMap &PairMap);
110 void splitImmediate(
MachineInstr *MI,
const UUPairMap &PairMap);
111 void splitCombine(
MachineInstr *MI,
const UUPairMap &PairMap);
112 void splitExt(
MachineInstr *MI,
const UUPairMap &PairMap);
113 void splitShift(
MachineInstr *MI,
const UUPairMap &PairMap);
114 void splitAslOr(
MachineInstr *MI,
const UUPairMap &PairMap);
115 bool splitInstr(
MachineInstr *MI,
const UUPairMap &PairMap);
116 void replaceSubregUses(
MachineInstr *MI,
const UUPairMap &PairMap);
117 void collapseRegPairs(
MachineInstr *MI,
const UUPairMap &PairMap);
118 bool splitPartition(
const USet &Part);
122 static void dump_partition(
raw_ostream&,
const USet&,
129 int HexagonSplitDoubleRegs::Counter = 0;
131 &Hexagon::DoubleRegsRegClass;
134 "Hexagon Split Double Registers",
false,
false)
136 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 146 bool HexagonSplitDoubleRegs::isInduction(
unsigned Reg, LoopRegMap &IRM)
const {
148 const USet &Rs =
I.second;
149 if (Rs.find(Reg) != Rs.end())
155 bool HexagonSplitDoubleRegs::isVolatileInstr(
const MachineInstr *
MI)
const {
162 bool HexagonSplitDoubleRegs::isFixedInstr(
const MachineInstr *MI)
const {
164 if (MemRefsFixed || isVolatileInstr(MI))
174 case TargetOpcode::PHI:
175 case TargetOpcode::COPY:
178 case Hexagon::L2_loadrd_io:
183 case Hexagon::S2_storerd_io:
188 case Hexagon::L2_loadrd_pi:
189 case Hexagon::S2_storerd_pi:
191 case Hexagon::A2_tfrpi:
192 case Hexagon::A2_combineii:
193 case Hexagon::A4_combineir:
194 case Hexagon::A4_combineii:
195 case Hexagon::A4_combineri:
196 case Hexagon::A2_combinew:
197 case Hexagon::CONST64:
199 case Hexagon::A2_sxtw:
201 case Hexagon::A2_andp:
202 case Hexagon::A2_orp:
203 case Hexagon::A2_xorp:
204 case Hexagon::S2_asl_i_p_or:
205 case Hexagon::S2_asl_i_p:
206 case Hexagon::S2_asr_i_p:
207 case Hexagon::S2_lsr_i_p:
214 unsigned R =
Op.getReg();
221 void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
222 using UUMap = std::map<unsigned, unsigned>;
223 using UVect = std::vector<unsigned>;
225 unsigned NumRegs =
MRI->getNumVirtRegs();
227 for (
unsigned i = 0; i < NumRegs; ++i) {
229 if (
MRI->getRegClass(R) == DoubleRC)
240 if (!DefI || isFixedInstr(DefI))
250 USet &Asc = AssocMap[R];
251 for (
auto U =
MRI->use_nodbg_begin(R),
Z =
MRI->use_nodbg_end();
255 if (isFixedInstr(UseI))
267 if (
MRI->getRegClass(T) != DoubleRC)
275 AssocMap[
T].insert(R);
286 if (Visited.count(R))
289 unsigned ThisP = FixedRegs[x] ? 0 : NextP++;
292 for (
unsigned i = 0; i < WorkQ.size(); ++i) {
293 unsigned T = WorkQ[i];
294 if (Visited.count(T))
299 USet &Asc = AssocMap[
T];
300 for (USet::iterator J = Asc.begin(),
F = Asc.end(); J !=
F; ++J)
306 P2Rs[
I.second].insert(
I.first);
311 if (Imm == 0 || Imm == 0xFFFFFFFF)
316 int32_t HexagonSplitDoubleRegs::profit(
const MachineInstr *MI)
const {
320 case TargetOpcode::PHI:
325 case TargetOpcode::COPY:
330 case Hexagon::L2_loadrd_io:
331 case Hexagon::S2_storerd_io:
333 case Hexagon::L2_loadrd_pi:
334 case Hexagon::S2_storerd_pi:
337 case Hexagon::A2_tfrpi:
338 case Hexagon::CONST64: {
340 unsigned Lo = D & 0xFFFFFFFFULL;
341 unsigned Hi = D >> 32;
344 case Hexagon::A2_combineii:
345 case Hexagon::A4_combineii: {
350 return Prof1 + Prof2;
352 case Hexagon::A4_combineri:
356 case Hexagon::A4_combineir: {
361 if (V == 0 || V == -1)
367 case Hexagon::A2_combinew:
370 case Hexagon::A2_sxtw:
373 case Hexagon::A2_andp:
374 case Hexagon::A2_orp:
375 case Hexagon::A2_xorp: {
378 return profit(Rs) + profit(Rt);
381 case Hexagon::S2_asl_i_p_or: {
383 if (S == 0 || S == 32)
387 case Hexagon::S2_asl_i_p:
388 case Hexagon::S2_asr_i_p:
389 case Hexagon::S2_lsr_i_p:
391 if (S == 0 || S == 32)
403 int32_t HexagonSplitDoubleRegs::profit(
unsigned Reg)
const {
408 case Hexagon::A2_tfrpi:
409 case Hexagon::CONST64:
410 case Hexagon::A2_combineii:
411 case Hexagon::A4_combineii:
412 case Hexagon::A4_combineri:
413 case Hexagon::A4_combineir:
414 case Hexagon::A2_combinew:
422 bool HexagonSplitDoubleRegs::isProfitable(
const USet &Part, LoopRegMap &IRM)
424 unsigned FixedNum = 0, LoopPhiNum = 0;
427 for (
unsigned DR : Part) {
429 int32_t
P = profit(DefI);
430 if (P == std::numeric_limits<int>::min())
434 if (isInduction(DR, IRM))
437 for (
auto U =
MRI->use_nodbg_begin(DR),
W =
MRI->use_nodbg_end();
440 if (isFixedInstr(UseI)) {
444 if (
Op.isReg() && Part.count(
Op.getReg()))
461 int32_t P = profit(UseI);
462 if (P == std::numeric_limits<int>::min())
468 if (FixedNum > 0 && LoopPhiNum > 0)
469 TotalP -= 20*LoopPhiNum;
477 void HexagonSplitDoubleRegs::collectIndRegsForLoop(
const MachineLoop *L,
493 if (BadLB || Cond.
size() != 2)
499 if (TB != HB && FB != HB)
501 assert(Cond[1].
isReg() &&
"Unexpected Cond vector from analyzeBranch");
503 unsigned PR = Cond[1].getReg();
504 assert(
MRI->getRegClass(PR) == &Hexagon::PredRegsRegClass);
508 unsigned CmpR1 = 0, CmpR2 = 0;
510 while (CmpI->
getOpcode() == Hexagon::C2_not)
513 int Mask = 0, Val = 0;
518 if (CmpR1 &&
MRI->getRegClass(CmpR1) != DoubleRC)
520 if (CmpR2 &&
MRI->getRegClass(CmpR2) != DoubleRC)
522 if (!CmpR1 && !CmpR2)
532 using UVect = std::vector<unsigned>;
535 for (
auto &MI : *HB) {
540 if (
MRI->getRegClass(R) == DoubleRC)
546 auto NoIndOp = [
this, CmpR1, CmpR2] (
unsigned R) ->
bool {
547 for (
auto I =
MRI->use_nodbg_begin(R),
E =
MRI->use_nodbg_end();
550 if (UseI->
getOpcode() != Hexagon::A2_addp)
556 if (T == CmpR1 || T == CmpR2)
562 Rs.insert(DP.begin(), End);
568 dump_partition(
dbgs(), Rs, *
TRI);
573 void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) {
574 using LoopVector = std::vector<MachineLoop *>;
580 for (
unsigned i = 0; i < WorkQ.size(); ++i) {
581 for (
auto I : *WorkQ[i])
586 for (
unsigned i = 0, n = WorkQ.size(); i < n; ++i) {
589 collectIndRegsForLoop(L, Rs);
591 IRM.insert(std::make_pair(L, Rs));
595 void HexagonSplitDoubleRegs::createHalfInstr(
unsigned Opc,
MachineInstr *MI,
596 const UUPairMap &PairMap,
unsigned SubR) {
607 unsigned R =
Op.getReg();
608 unsigned SR =
Op.getSubReg();
610 bool isKill =
Op.isKill();
611 if (isVirtReg &&
MRI->getRegClass(R) == DoubleRC) {
613 UUPairMap::const_iterator
F = PairMap.find(R);
614 if (F == PairMap.end()) {
617 const UUPair &
P = F->second;
618 R = (SubR == Hexagon::isub_lo) ? P.first : P.second;
623 Op.isDead(),
Op.isUndef(),
Op.isEarlyClobber(), SR,
Op.isDebug(),
624 Op.isInternalRead());
629 void HexagonSplitDoubleRegs::splitMemRef(
MachineInstr *MI,
630 const UUPairMap &PairMap) {
633 bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi ||
634 OrigOpc == Hexagon::S2_storerd_pi);
640 unsigned AdrX = PostInc ? (Load ? 2 : 1)
647 UUPairMap::const_iterator
F = PairMap.find(ValOp.
getReg());
648 assert(F != PairMap.end());
651 const UUPair &
P = F->second;
653 LowI =
BuildMI(B, MI, DL,
TII->get(Hexagon::L2_loadri_io), P.first)
656 HighI =
BuildMI(B, MI, DL,
TII->get(Hexagon::L2_loadri_io), P.second)
660 const UUPair &
P = F->second;
662 LowI =
BuildMI(B, MI, DL,
TII->get(Hexagon::S2_storeri_io))
666 HighI =
BuildMI(B, MI, DL,
TII->get(Hexagon::S2_storeri_io))
678 unsigned NewR =
MRI->createVirtualRegister(RC);
680 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_addi), NewR)
681 .addReg(AdrOp.
getReg(), RSA)
683 MRI->replaceRegWith(UpdOp.
getReg(), NewR);
692 int A = MO->getAlignment();
701 void HexagonSplitDoubleRegs::splitImmediate(
MachineInstr *MI,
702 const UUPairMap &PairMap) {
706 uint64_t V = Op1.
getImm();
710 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
711 assert(F != PairMap.end());
712 const UUPair &
P = F->second;
722 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.first)
723 .addImm(int32_t(V & 0xFFFFFFFFULL));
724 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.second)
725 .addImm(int32_t(V >> 32));
728 void HexagonSplitDoubleRegs::splitCombine(
MachineInstr *MI,
729 const UUPairMap &PairMap) {
737 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
738 assert(F != PairMap.end());
739 const UUPair &
P = F->second;
742 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.second)
745 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.second)
750 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.first)
753 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.first)
759 const UUPairMap &PairMap) {
766 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
767 assert(F != PairMap.end());
768 const UUPair &
P = F->second;
771 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.first)
773 BuildMI(B, MI, DL,
TII->get(Hexagon::S2_asr_i_r), P.second)
778 void HexagonSplitDoubleRegs::splitShift(
MachineInstr *MI,
779 const UUPairMap &PairMap) {
780 using namespace Hexagon;
786 int64_t Sh64 = Op2.
getImm();
787 assert(Sh64 >= 0 && Sh64 < 64);
790 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
791 assert(F != PairMap.end());
792 const UUPair &
P = F->second;
793 unsigned LoR = P.first;
794 unsigned HiR = P.second;
797 bool Right = (Opc == S2_lsr_i_p || Opc == S2_asr_i_p);
799 bool Signed = (Opc == S2_asr_i_p);
804 unsigned ShiftOpc = Left ? S2_asl_i_r
805 : (Signed ? S2_asr_i_r : S2_lsr_i_r);
806 unsigned LoSR = isub_lo;
807 unsigned HiSR = isub_hi;
811 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
813 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), HiR)
814 .addReg(Op1.
getReg(), RS, HiSR);
817 unsigned TmpR =
MRI->createVirtualRegister(IntRC);
838 else if (S == 16 && Signed)
842 BuildMI(B, MI, DL,
TII->get(ShiftOpc), (Left ? LoR : TmpR))
848 BuildMI(B, MI, DL,
TII->get(S2_extractu), TmpR)
853 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
869 }
else if (S == 32) {
870 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), (Left ? HiR : LoR))
873 BuildMI(B, MI, DL,
TII->get(A2_tfrsi), (Left ? LoR : HiR))
877 .addReg(Op1.
getReg(), RS, HiSR)
884 else if (S == 16 && Signed)
888 BuildMI(B, MI, DL,
TII->get(ShiftOpc), (Left ? HiR : LoR))
894 .addReg(Op1.
getReg(), RS, HiSR)
897 BuildMI(B, MI, DL,
TII->get(A2_tfrsi), (Left ? LoR : HiR))
902 void HexagonSplitDoubleRegs::splitAslOr(
MachineInstr *MI,
903 const UUPairMap &PairMap) {
904 using namespace Hexagon;
911 int64_t Sh64 = Op3.
getImm();
912 assert(Sh64 >= 0 && Sh64 < 64);
915 UUPairMap::const_iterator
F = PairMap.find(Op0.
getReg());
916 assert(F != PairMap.end());
917 const UUPair &
P = F->second;
918 unsigned LoR = P.first;
919 unsigned HiR = P.second;
927 unsigned LoSR = isub_lo;
928 unsigned HiSR = isub_hi;
950 .addReg(Op1.
getReg(), RS1, HiSR)
951 .addReg(Op2.
getReg(), RS2, HiSR);
953 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), LoR)
957 unsigned TmpR1 =
MRI->createVirtualRegister(IntRC);
958 BuildMI(B, MI, DL,
TII->get(S2_extractu), TmpR1)
962 unsigned TmpR2 =
MRI->createVirtualRegister(IntRC);
964 .addReg(Op1.
getReg(), RS1, HiSR)
966 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
970 }
else if (S == 32) {
975 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
978 .addReg(Op1.
getReg(), RS1, HiSR)
979 .addReg(Op2.
getReg(), RS2, LoSR);
986 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
988 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
989 .addReg(Op1.
getReg(), RS1, HiSR)
990 .addReg(Op2.
getReg(), RS2, LoSR)
995 bool HexagonSplitDoubleRegs::splitInstr(
MachineInstr *MI,
996 const UUPairMap &PairMap) {
997 using namespace Hexagon;
1004 case TargetOpcode::PHI:
1005 case TargetOpcode::COPY: {
1007 if (
MRI->getRegClass(DstR) == DoubleRC) {
1008 createHalfInstr(Opc, MI, PairMap, isub_lo);
1009 createHalfInstr(Opc, MI, PairMap, isub_hi);
1015 createHalfInstr(A2_and, MI, PairMap, isub_lo);
1016 createHalfInstr(A2_and, MI, PairMap, isub_hi);
1020 createHalfInstr(A2_or, MI, PairMap, isub_lo);
1021 createHalfInstr(A2_or, MI, PairMap, isub_hi);
1025 createHalfInstr(A2_xor, MI, PairMap, isub_lo);
1026 createHalfInstr(A2_xor, MI, PairMap, isub_hi);
1034 splitMemRef(MI, PairMap);
1040 splitImmediate(MI, PairMap);
1049 splitCombine(MI, PairMap);
1054 splitExt(MI, PairMap);
1061 splitShift(MI, PairMap);
1066 splitAslOr(MI, PairMap);
1078 void HexagonSplitDoubleRegs::replaceSubregUses(
MachineInstr *MI,
1079 const UUPairMap &PairMap) {
1081 if (!
Op.isReg() || !
Op.isUse() || !
Op.getSubReg())
1083 unsigned R =
Op.getReg();
1084 UUPairMap::const_iterator
F = PairMap.find(R);
1085 if (F == PairMap.end())
1087 const UUPair &
P = F->second;
1088 switch (
Op.getSubReg()) {
1089 case Hexagon::isub_lo:
1092 case Hexagon::isub_hi:
1093 Op.setReg(P.second);
1100 void HexagonSplitDoubleRegs::collapseRegPairs(
MachineInstr *MI,
1101 const UUPairMap &PairMap) {
1106 if (!
Op.isReg() || !
Op.isUse())
1108 unsigned R =
Op.getReg();
1111 if (
MRI->getRegClass(R) != DoubleRC ||
Op.getSubReg())
1113 UUPairMap::const_iterator
F = PairMap.find(R);
1114 if (F == PairMap.end())
1116 const UUPair &Pr = F->second;
1117 unsigned NewDR =
MRI->createVirtualRegister(DoubleRC);
1118 BuildMI(B, MI, DL,
TII->get(TargetOpcode::REG_SEQUENCE), NewDR)
1120 .
addImm(Hexagon::isub_lo)
1122 .
addImm(Hexagon::isub_hi);
1127 bool HexagonSplitDoubleRegs::splitPartition(
const USet &Part) {
1128 using MISet = std::set<MachineInstr *>;
1131 bool Changed =
false;
1134 dump_partition(
dbgs(), Part, *
TRI);
dbgs() <<
'\n');
1139 for (
unsigned DR : Part) {
1141 SplitIns.insert(DefI);
1145 for (
auto U =
MRI->use_nodbg_begin(DR),
W =
MRI->use_nodbg_end();
1147 SplitIns.insert(U->getParent());
1149 unsigned LoR =
MRI->createVirtualRegister(IntRC);
1150 unsigned HiR =
MRI->createVirtualRegister(IntRC);
1154 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR)));
1158 for (
auto MI : SplitIns) {
1159 if (isFixedInstr(MI)) {
1160 collapseRegPairs(MI, PairMap);
1162 bool Done = splitInstr(MI, PairMap);
1169 for (
unsigned DR : Part) {
1174 for (
auto U =
MRI->use_nodbg_begin(DR),
W =
MRI->use_nodbg_end();
1176 Uses.insert(U->getParent());
1178 replaceSubregUses(M, PairMap);
1181 for (
auto MI : Erase) {
1189 bool HexagonSplitDoubleRegs::runOnMachineFunction(
MachineFunction &MF) {
1197 TRI = ST.getRegisterInfo();
1198 TII = ST.getInstrInfo();
1200 MLI = &getAnalysis<MachineLoopInfo>();
1205 collectIndRegs(IRM);
1206 partitionRegisters(P2Rs);
1209 dbgs() <<
"Register partitioning: (partition #0 is fixed)\n";
1210 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1211 dbgs() <<
'#' <<
I->first <<
" -> ";
1212 dump_partition(
dbgs(),
I->second, *TRI);
1217 bool Changed =
false;
1220 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1223 if (Limit >= 0 && Counter >= Limit)
1225 USet &Part =
I->second;
1228 if (!isProfitable(Part, IRM))
1231 Changed |= splitPartition(Part);
1238 return new HexagonSplitDoubleRegs();
static bool isReg(const MCInst &MI, unsigned OpNo)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
This class represents lattice values for constants.
INITIALIZE_PASS(HexagonSplitDoubleRegs, "hexagon-split-double", "Hexagon Split Double Registers", false, false) LLVM_DUMP_METHOD void HexagonSplitDoubleRegs
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
static int32_t profitImm(unsigned Imm)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getSubReg() const
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static cl::opt< int > MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1), cl::desc("Maximum number of split partitions"))
static MachineOperand CreateReg(unsigned 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)
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...
AnalysisUsage & addRequired()
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
zlib-gnu style compression
BlockT * getHeader() const
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createHexagonSplitDoubleRegs()
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isDebugInstr() const
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Flags
Flags values. These may be or'd together.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void initializeHexagonSplitDoubleRegsPass(PassRegistry &)
bool PredOpcodeHasJMP_c(unsigned Opcode) const
static cl::opt< bool > SplitAll("hsdr-split-all", cl::Hidden, cl::init(false), cl::desc("Split all partitions"))
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static cl::opt< bool > MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true), cl::desc("Do not split loads or stores"))
static void Split(std::vector< std::string > &V, StringRef S)
Splits a string of comma separated items in to a vector of strings.
const MachineOperand & getOperand(unsigned i) const
static const MCPhysReg DoubleRegs[32]