10 #define DEBUG_TYPE "hsdr"
57 cl::desc(
"Maximum number of split partitions"));
59 cl::desc(
"Do not split loads or stores"));
71 return "Hexagon Split Double Registers";
90 typedef std::set<unsigned> USet;
91 typedef std::map<unsigned,USet> UUSetMap;
92 typedef std::pair<unsigned,unsigned> UUPair;
93 typedef std::map<unsigned,UUPair> UUPairMap;
94 typedef std::map<const MachineLoop*,USet> LoopRegMap;
96 bool isInduction(
unsigned Reg, LoopRegMap &IRM)
const;
99 void partitionRegisters(UUSetMap &P2Rs);
101 bool isProfitable(
const USet &Part, LoopRegMap &IRM)
const;
103 void collectIndRegsForLoop(
const MachineLoop *
L, USet &Rs);
104 void collectIndRegs(LoopRegMap &IRM);
107 const UUPairMap &PairMap,
unsigned SubR);
115 void replaceSubregUses(
MachineInstr *
MI,
const UUPairMap &PairMap);
116 void collapseRegPairs(
MachineInstr *
MI,
const UUPairMap &PairMap);
117 bool splitPartition(
const USet &Part);
120 static void dump_partition(
raw_ostream&,
const USet&,
127 = &Hexagon::DoubleRegsRegClass;
132 "Hexagon Split Double Registers",
false,
false)
134 void HexagonSplitDoubleRegs::dump_partition(
raw_ostream &os,
142 bool HexagonSplitDoubleRegs::isInduction(
unsigned Reg, LoopRegMap &IRM)
const {
144 const USet &Rs =
I.second;
145 if (Rs.find(Reg) != Rs.end())
151 bool HexagonSplitDoubleRegs::isVolatileInstr(
const MachineInstr *
MI)
const {
158 bool HexagonSplitDoubleRegs::isFixedInstr(
const MachineInstr *MI)
const {
160 if (MemRefsFixed || isVolatileInstr(MI))
170 case TargetOpcode::PHI:
171 case TargetOpcode::COPY:
174 case Hexagon::L2_loadrd_io:
179 case Hexagon::S2_storerd_io:
184 case Hexagon::L2_loadrd_pi:
185 case Hexagon::S2_storerd_pi:
187 case Hexagon::A2_tfrpi:
188 case Hexagon::A2_combineii:
189 case Hexagon::A4_combineir:
190 case Hexagon::A4_combineii:
191 case Hexagon::A4_combineri:
192 case Hexagon::A2_combinew:
193 case Hexagon::CONST64:
195 case Hexagon::A2_sxtw:
197 case Hexagon::A2_andp:
198 case Hexagon::A2_orp:
199 case Hexagon::A2_xorp:
200 case Hexagon::S2_asl_i_p_or:
201 case Hexagon::S2_asl_i_p:
202 case Hexagon::S2_asr_i_p:
203 case Hexagon::S2_lsr_i_p:
210 unsigned R =
Op.getReg();
217 void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
218 typedef std::map<unsigned,unsigned> UUMap;
219 typedef std::vector<unsigned> UVect;
221 unsigned NumRegs =
MRI->getNumVirtRegs();
223 for (
unsigned i = 0;
i < NumRegs; ++
i) {
225 if (
MRI->getRegClass(R) == DoubleRC)
230 for (
int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
236 if (!DefI || isFixedInstr(DefI))
241 for (
int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
246 USet &Asc = AssocMap[R];
247 for (
auto U =
MRI->use_nodbg_begin(R), Z =
MRI->use_nodbg_end();
251 if (isFixedInstr(UseI))
263 if (
MRI->getRegClass(T) != DoubleRC)
271 AssocMap[
T].insert(R);
280 for (
int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
282 if (Visited.count(R))
285 unsigned ThisP = FixedRegs[x] ? 0 : NextP++;
288 for (
unsigned i = 0;
i < WorkQ.size(); ++
i) {
289 unsigned T = WorkQ[
i];
290 if (Visited.count(T))
295 USet &Asc = AssocMap[
T];
296 for (USet::iterator J = Asc.begin(),
F = Asc.end(); J !=
F; ++J)
302 P2Rs[
I.second].insert(
I.first);
307 bool LoZ1 =
false, HiZ1 =
false;
308 if (Lo == 0 || Lo == 0xFFFFFFFF)
309 P += 10, LoZ1 =
true;
310 if (Hi == 0 || Hi == 0xFFFFFFFF)
311 P += 10, HiZ1 =
true;
312 if (!LoZ1 && !HiZ1 && Lo == Hi)
317 int32_t HexagonSplitDoubleRegs::profit(
const MachineInstr *MI)
const {
321 case TargetOpcode::PHI:
322 for (
const auto &Op : MI->
operands())
326 case TargetOpcode::COPY:
331 case Hexagon::L2_loadrd_io:
332 case Hexagon::S2_storerd_io:
334 case Hexagon::L2_loadrd_pi:
335 case Hexagon::S2_storerd_pi:
338 case Hexagon::A2_tfrpi:
339 case Hexagon::CONST64: {
341 unsigned Lo = D & 0xFFFFFFFFULL;
342 unsigned Hi = D >> 32;
345 case Hexagon::A2_combineii:
346 case Hexagon::A4_combineii:
349 case Hexagon::A4_combineri:
351 case Hexagon::A4_combineir: {
354 if (V == 0 || V == -1)
359 case Hexagon::A2_combinew:
362 case Hexagon::A2_sxtw:
365 case Hexagon::A2_andp:
366 case Hexagon::A2_orp:
367 case Hexagon::A2_xorp:
370 case Hexagon::S2_asl_i_p_or: {
372 if (S == 0 || S == 32)
376 case Hexagon::S2_asl_i_p:
377 case Hexagon::S2_asr_i_p:
378 case Hexagon::S2_lsr_i_p:
380 if (S == 0 || S == 32)
392 bool HexagonSplitDoubleRegs::isProfitable(
const USet &Part, LoopRegMap &IRM)
394 unsigned FixedNum = 0, SplitNum = 0, LoopPhiNum = 0;
397 for (
unsigned DR : Part) {
399 int32_t
P = profit(DefI);
404 if (isInduction(DR, IRM))
407 for (
auto U =
MRI->use_nodbg_begin(DR), W =
MRI->use_nodbg_end();
410 if (isFixedInstr(UseI)) {
432 int32_t P = profit(UseI);
439 if (FixedNum > 0 && LoopPhiNum > 0)
440 TotalP -= 20*LoopPhiNum;
442 DEBUG(
dbgs() <<
"Partition profit: " << TotalP <<
'\n');
446 void HexagonSplitDoubleRegs::collectIndRegsForLoop(
const MachineLoop *L,
462 if (BadLB || Cond.
size() != 2)
468 if (TB != HB && FB != HB)
470 assert(Cond[1].
isReg() &&
"Unexpected Cond vector from analyzeBranch");
472 unsigned PR = Cond[1].getReg();
473 assert(
MRI->getRegClass(PR) == &Hexagon::PredRegsRegClass);
477 unsigned CmpR1 = 0, CmpR2 = 0;
479 while (CmpI->
getOpcode() == Hexagon::C2_not)
482 int Mask = 0, Val = 0;
487 if (CmpR1 &&
MRI->getRegClass(CmpR1) != DoubleRC)
489 if (CmpR2 &&
MRI->getRegClass(CmpR2) != DoubleRC)
491 if (!CmpR1 && !CmpR2)
501 typedef std::vector<unsigned> UVect;
503 for (
auto &MI : *HB) {
508 if (
MRI->getRegClass(R) == DoubleRC)
514 auto NoIndOp = [
this, CmpR1, CmpR2] (
unsigned R) ->
bool {
515 for (
auto I =
MRI->use_nodbg_begin(R),
E =
MRI->use_nodbg_end();
518 if (UseI->
getOpcode() != Hexagon::A2_addp)
524 if (T == CmpR1 || T == CmpR2)
530 Rs.insert(DP.begin(),
End);
535 dbgs() <<
"For loop at BB#" << HB->getNumber() <<
" ind regs: ";
536 dump_partition(
dbgs(), Rs, *TRI);
541 void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) {
542 typedef std::vector<MachineLoop*> LoopVector;
547 for (
unsigned i = 0;
i < WorkQ.size(); ++
i) {
548 for (
auto I : *WorkQ[
i])
553 for (
unsigned i = 0, n = WorkQ.size(); i < n; ++
i) {
556 collectIndRegsForLoop(L, Rs);
558 IRM.insert(std::make_pair(L, Rs));
562 void HexagonSplitDoubleRegs::createHalfInstr(
unsigned Opc,
MachineInstr *MI,
563 const UUPairMap &PairMap,
unsigned SubR) {
577 bool isKill = Op.
isKill();
578 if (isVirtReg &&
MRI->getRegClass(R) == DoubleRC) {
580 UUPairMap::const_iterator
F = PairMap.find(R);
581 if (F == PairMap.end()) {
584 const UUPair &P = F->second;
585 R = (SubR == Hexagon::isub_lo) ? P.first : P.second;
596 void HexagonSplitDoubleRegs::splitMemRef(
MachineInstr *MI,
597 const UUPairMap &PairMap) {
600 bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi ||
601 OrigOpc == Hexagon::S2_storerd_pi);
607 unsigned AdrX = PostInc ? (Load ? 2 : 1)
614 UUPairMap::const_iterator F = PairMap.find(ValOp.
getReg());
615 assert(F != PairMap.end());
618 const UUPair &P = F->second;
620 LowI =
BuildMI(B, MI, DL,
TII->get(Hexagon::L2_loadri_io), P.first)
623 HighI =
BuildMI(B, MI, DL,
TII->get(Hexagon::L2_loadri_io), P.second)
627 const UUPair &P = F->second;
629 LowI =
BuildMI(B, MI, DL,
TII->get(Hexagon::S2_storeri_io))
633 HighI =
BuildMI(B, MI, DL,
TII->get(Hexagon::S2_storeri_io))
645 unsigned NewR =
MRI->createVirtualRegister(RC);
647 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_addi), NewR)
648 .addReg(AdrOp.
getReg(), RSA)
650 MRI->replaceRegWith(UpdOp.
getReg(), NewR);
659 int A = MO->getAlignment();
668 void HexagonSplitDoubleRegs::splitImmediate(
MachineInstr *MI,
669 const UUPairMap &PairMap) {
673 uint64_t V = Op1.
getImm();
677 UUPairMap::const_iterator F = PairMap.find(Op0.
getReg());
678 assert(F != PairMap.end());
679 const UUPair &P = F->second;
689 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.first)
690 .addImm(int32_t(V & 0xFFFFFFFFULL));
691 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.second)
692 .addImm(int32_t(V >> 32));
695 void HexagonSplitDoubleRegs::splitCombine(
MachineInstr *MI,
696 const UUPairMap &PairMap) {
704 UUPairMap::const_iterator F = PairMap.find(Op0.
getReg());
705 assert(F != PairMap.end());
706 const UUPair &P = F->second;
709 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.second)
711 }
else if (Op1.
isReg()) {
712 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.second)
718 BuildMI(B, MI, DL,
TII->get(Hexagon::A2_tfrsi), P.first)
720 }
else if (Op2.
isReg()) {
721 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.first)
728 const UUPairMap &PairMap) {
735 UUPairMap::const_iterator F = PairMap.find(Op0.
getReg());
736 assert(F != PairMap.end());
737 const UUPair &P = F->second;
740 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), P.first)
742 BuildMI(B, MI, DL,
TII->get(Hexagon::S2_asr_i_r), P.second)
747 void HexagonSplitDoubleRegs::splitShift(
MachineInstr *MI,
748 const UUPairMap &PairMap) {
749 using namespace Hexagon;
755 int64_t Sh64 = Op2.
getImm();
756 assert(Sh64 >= 0 && Sh64 < 64);
759 UUPairMap::const_iterator F = PairMap.find(Op0.
getReg());
760 assert(F != PairMap.end());
761 const UUPair &P = F->second;
762 unsigned LoR = P.first;
763 unsigned HiR = P.second;
766 bool Right = (Opc == S2_lsr_i_p || Opc == S2_asr_i_p);
768 bool Signed = (Opc == S2_asr_i_p);
774 : (
Signed ? S2_asr_i_r : S2_lsr_i_r);
775 unsigned LoSR = isub_lo;
776 unsigned HiSR = isub_hi;
780 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
782 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), HiR)
783 .addReg(Op1.
getReg(), RS, HiSR);
786 unsigned TmpR =
MRI->createVirtualRegister(IntRC);
807 else if (S == 16 &&
Signed)
817 BuildMI(B, MI, DL,
TII->get(S2_extractu), TmpR)
822 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
838 }
else if (S == 32) {
839 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), (
Left ? HiR : LoR))
846 .addReg(Op1.
getReg(), RS, HiSR)
853 else if (S == 16 &&
Signed)
863 .addReg(Op1.
getReg(), RS, HiSR)
871 void HexagonSplitDoubleRegs::splitAslOr(
MachineInstr *MI,
872 const UUPairMap &PairMap) {
873 using namespace Hexagon;
880 int64_t Sh64 = Op3.getImm();
881 assert(Sh64 >= 0 && Sh64 < 64);
884 UUPairMap::const_iterator F = PairMap.find(Op0.
getReg());
885 assert(F != PairMap.end());
886 const UUPair &P = F->second;
887 unsigned LoR = P.first;
888 unsigned HiR = P.second;
896 unsigned LoSR = isub_lo;
897 unsigned HiSR = isub_hi;
919 .addReg(Op1.
getReg(), RS1, HiSR)
920 .addReg(Op2.
getReg(), RS2, HiSR);
922 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), LoR)
926 unsigned TmpR1 =
MRI->createVirtualRegister(IntRC);
927 BuildMI(B, MI, DL,
TII->get(S2_extractu), TmpR1)
931 unsigned TmpR2 =
MRI->createVirtualRegister(IntRC);
933 .addReg(Op1.
getReg(), RS1, HiSR)
935 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
939 }
else if (S == 32) {
944 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
947 .addReg(Op1.
getReg(), RS1, HiSR)
948 .addReg(Op2.
getReg(), RS2, LoSR);
955 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), LoR)
957 BuildMI(B, MI, DL,
TII->get(S2_asl_i_r_or), HiR)
958 .addReg(Op1.
getReg(), RS1, HiSR)
959 .addReg(Op2.
getReg(), RS2, LoSR)
964 bool HexagonSplitDoubleRegs::splitInstr(
MachineInstr *MI,
965 const UUPairMap &PairMap) {
966 using namespace Hexagon;
973 case TargetOpcode::PHI:
974 case TargetOpcode::COPY: {
976 if (
MRI->getRegClass(DstR) == DoubleRC) {
977 createHalfInstr(Opc, MI, PairMap, isub_lo);
978 createHalfInstr(Opc, MI, PairMap, isub_hi);
984 createHalfInstr(A2_and, MI, PairMap, isub_lo);
985 createHalfInstr(A2_and, MI, PairMap, isub_hi);
989 createHalfInstr(A2_or, MI, PairMap, isub_lo);
990 createHalfInstr(A2_or, MI, PairMap, isub_hi);
994 createHalfInstr(A2_xor, MI, PairMap, isub_lo);
995 createHalfInstr(A2_xor, MI, PairMap, isub_hi);
1003 splitMemRef(MI, PairMap);
1009 splitImmediate(MI, PairMap);
1018 splitCombine(MI, PairMap);
1023 splitExt(MI, PairMap);
1030 splitShift(MI, PairMap);
1035 splitAslOr(MI, PairMap);
1047 void HexagonSplitDoubleRegs::replaceSubregUses(
MachineInstr *MI,
1048 const UUPairMap &PairMap) {
1052 unsigned R = Op.
getReg();
1053 UUPairMap::const_iterator F = PairMap.find(R);
1054 if (F == PairMap.end())
1056 const UUPair &P = F->second;
1058 case Hexagon::isub_lo:
1061 case Hexagon::isub_hi:
1069 void HexagonSplitDoubleRegs::collapseRegPairs(
MachineInstr *MI,
1070 const UUPairMap &PairMap) {
1077 unsigned R = Op.
getReg();
1082 UUPairMap::const_iterator F = PairMap.find(R);
1083 if (F == PairMap.end())
1085 const UUPair &Pr = F->second;
1086 unsigned NewDR =
MRI->createVirtualRegister(DoubleRC);
1087 BuildMI(B, MI, DL,
TII->get(TargetOpcode::REG_SEQUENCE), NewDR)
1089 .
addImm(Hexagon::isub_lo)
1091 .
addImm(Hexagon::isub_hi);
1096 bool HexagonSplitDoubleRegs::splitPartition(
const USet &Part) {
1098 typedef std::set<MachineInstr*> MISet;
1099 bool Changed =
false;
1101 DEBUG(
dbgs() <<
"Splitting partition: "; dump_partition(
dbgs(), Part, *TRI);
1107 for (
unsigned DR : Part) {
1109 SplitIns.insert(DefI);
1113 for (
auto U =
MRI->use_nodbg_begin(DR), W =
MRI->use_nodbg_end();
1115 SplitIns.insert(U->getParent());
1117 unsigned LoR =
MRI->createVirtualRegister(IntRC);
1118 unsigned HiR =
MRI->createVirtualRegister(IntRC);
1121 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR)));
1125 for (
auto MI : SplitIns) {
1126 if (isFixedInstr(MI)) {
1127 collapseRegPairs(MI, PairMap);
1129 bool Done = splitInstr(MI, PairMap);
1136 for (
unsigned DR : Part) {
1141 for (
auto U =
MRI->use_nodbg_begin(DR), W =
MRI->use_nodbg_end();
1143 Uses.insert(U->getParent());
1145 replaceSubregUses(M, PairMap);
1148 for (
auto MI : Erase) {
1156 bool HexagonSplitDoubleRegs::runOnMachineFunction(
MachineFunction &MF) {
1157 DEBUG(
dbgs() <<
"Splitting double registers in function: "
1164 TRI =
ST.getRegisterInfo();
1165 TII =
ST.getInstrInfo();
1167 MLI = &getAnalysis<MachineLoopInfo>();
1172 collectIndRegs(IRM);
1173 partitionRegisters(P2Rs);
1176 dbgs() <<
"Register partitioning: (partition #0 is fixed)\n";
1177 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1178 dbgs() <<
'#' <<
I->first <<
" -> ";
1179 dump_partition(
dbgs(),
I->second, *TRI);
1184 bool Changed =
false;
1185 int Limit = MaxHSDR;
1187 for (UUSetMap::iterator
I = P2Rs.begin(),
E = P2Rs.end();
I !=
E; ++
I) {
1190 if (Limit >= 0 &&
Counter >= Limit)
1192 USet &Part =
I->second;
1193 DEBUG(
dbgs() <<
"Calculating profit for partition #" <<
I->first <<
'\n');
1194 if (!isProfitable(Part, IRM))
1197 Changed |= splitPartition(Part);
1204 return new HexagonSplitDoubleRegs();
static bool isReg(const MCInst &MI, unsigned OpNo)
INITIALIZE_PASS(HexagonSplitDoubleRegs,"hexagon-split-double","Hexagon Split Double Registers", false, false) void HexagonSplitDoubleRegs
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool PredOpcodeHasJMP_c(unsigned Opcode) const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mmo_iterator > memoperands()
iterator_range< mop_iterator > operands()
BlockT * getHeader() const
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
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()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
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 isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bool isEarlyClobber() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
unsigned const MachineRegisterInfo * MRI
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...
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createHexagonSplitDoubleRegs()
static int32_t profitImm(unsigned Lo, unsigned Hi)
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Flags
Flags values. These may be or'd together.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
void setSubReg(unsigned subReg)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void initializeHexagonSplitDoubleRegsPass(PassRegistry &)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
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...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static void Split(std::vector< std::string > &V, StringRef S)
Split - Splits a string of comma separated items in to a vector of strings.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
bool isInternalRead() const