43#define AARCH64_EXPAND_PSEUDO_NAME "AArch64 pseudo instruction expansion pass"
67 unsigned ContiguousOpc,
unsigned StridedOpc);
78 unsigned LdarOp,
unsigned StlrOp,
unsigned CmpOp,
79 unsigned ExtendImm,
unsigned ZeroReg,
95 struct ConditionalBlocks {
113char AArch64ExpandPseudo::ID = 0;
125 assert(MO.isReg() && MO.getReg());
142 uint64_t
Imm =
MI.getOperand(1).getImm();
144 if (DstReg == AArch64::XZR || DstReg == AArch64::WZR) {
147 MI.eraseFromParent();
155 SmallVector<MachineInstrBuilder, 4> MIBS;
157 bool LastItem = std::next(
I) ==
E;
162 case AArch64::ORRWri:
163 case AArch64::ORRXri:
166 .
add(
MI.getOperand(0))
167 .
addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
171 bool DstIsDead =
MI.getOperand(0).isDead();
174 .
addReg(DstReg, RegState::Define |
181 case AArch64::EONXrs:
182 case AArch64::EORXrs:
183 case AArch64::ORRWrs:
184 case AArch64::ORRXrs: {
186 bool DstIsDead =
MI.getOperand(0).isDead();
189 .
addReg(DstReg, RegState::Define |
196 case AArch64::ANDXri:
197 case AArch64::EORXri:
200 .
add(
MI.getOperand(0))
201 .
addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
205 bool DstIsDead =
MI.getOperand(0).isDead();
208 .
addReg(DstReg, RegState::Define |
215 case AArch64::MOVNWi:
216 case AArch64::MOVNXi:
217 case AArch64::MOVZWi:
218 case AArch64::MOVZXi: {
219 bool DstIsDead =
MI.getOperand(0).isDead();
221 .
addReg(DstReg, RegState::Define |
227 case AArch64::MOVKWi:
228 case AArch64::MOVKXi: {
230 bool DstIsDead =
MI.getOperand(0).isDead();
243 MI.eraseFromParent();
247bool AArch64ExpandPseudo::expandCMP_SWAP(
249 unsigned StlrOp,
unsigned CmpOp,
unsigned ExtendImm,
unsigned ZeroReg,
253 const MachineOperand &Dest =
MI.getOperand(0);
254 Register StatusReg =
MI.getOperand(1).getReg();
255 bool StatusDead =
MI.getOperand(1).isDead();
258 assert(!
MI.getOperand(2).isUndef() &&
"cannot handle undef");
260 Register DesiredReg =
MI.getOperand(3).getReg();
269 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
270 MF->
insert(++StoreBB->getIterator(), DoneBB);
278 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::MOVZWi), StatusReg)
282 BuildMI(LoadCmpBB, MIMD,
TII->get(CmpOp), ZeroReg)
286 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::Bcc))
289 .
addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
290 LoadCmpBB->addSuccessor(DoneBB);
291 LoadCmpBB->addSuccessor(StoreBB);
296 BuildMI(StoreBB, MIMD,
TII->get(StlrOp), StatusReg)
299 BuildMI(StoreBB, MIMD,
TII->get(AArch64::CBNZW))
302 StoreBB->addSuccessor(LoadCmpBB);
303 StoreBB->addSuccessor(DoneBB);
305 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
306 DoneBB->transferSuccessors(&
MBB);
311 MI.eraseFromParent();
314 LivePhysRegs LiveRegs;
319 StoreBB->clearLiveIns();
321 LoadCmpBB->clearLiveIns();
327bool AArch64ExpandPseudo::expandCMP_SWAP_128(
332 MachineOperand &DestLo =
MI.getOperand(0);
333 MachineOperand &DestHi =
MI.getOperand(1);
334 Register StatusReg =
MI.getOperand(2).getReg();
335 bool StatusDead =
MI.getOperand(2).isDead();
338 assert(!
MI.getOperand(3).isUndef() &&
"cannot handle undef");
340 Register DesiredLoReg =
MI.getOperand(4).getReg();
341 Register DesiredHiReg =
MI.getOperand(5).getReg();
342 Register NewLoReg =
MI.getOperand(6).getReg();
343 Register NewHiReg =
MI.getOperand(7).getReg();
345 unsigned LdxpOp, StxpOp;
347 switch (
MI.getOpcode()) {
348 case AArch64::CMP_SWAP_128_MONOTONIC:
349 LdxpOp = AArch64::LDXPX;
350 StxpOp = AArch64::STXPX;
352 case AArch64::CMP_SWAP_128_RELEASE:
353 LdxpOp = AArch64::LDXPX;
354 StxpOp = AArch64::STLXPX;
356 case AArch64::CMP_SWAP_128_ACQUIRE:
357 LdxpOp = AArch64::LDAXPX;
358 StxpOp = AArch64::STXPX;
360 case AArch64::CMP_SWAP_128:
361 LdxpOp = AArch64::LDAXPX;
362 StxpOp = AArch64::STLXPX;
375 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
376 MF->
insert(++StoreBB->getIterator(), FailBB);
377 MF->
insert(++FailBB->getIterator(), DoneBB);
388 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::SUBSXrs), AArch64::XZR)
392 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CSINCWr), StatusReg)
396 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::SUBSXrs), AArch64::XZR)
400 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CSINCWr), StatusReg)
401 .
addUse(StatusReg, RegState::Kill)
402 .
addUse(StatusReg, RegState::Kill)
404 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CBNZW))
407 LoadCmpBB->addSuccessor(FailBB);
408 LoadCmpBB->addSuccessor(StoreBB);
413 BuildMI(StoreBB, MIMD,
TII->get(StxpOp), StatusReg)
417 BuildMI(StoreBB, MIMD,
TII->get(AArch64::CBNZW))
421 StoreBB->addSuccessor(LoadCmpBB);
422 StoreBB->addSuccessor(DoneBB);
427 BuildMI(FailBB, MIMD,
TII->get(StxpOp), StatusReg)
431 BuildMI(FailBB, MIMD,
TII->get(AArch64::CBNZW))
434 FailBB->addSuccessor(LoadCmpBB);
435 FailBB->addSuccessor(DoneBB);
437 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
438 DoneBB->transferSuccessors(&
MBB);
443 MI.eraseFromParent();
446 LivePhysRegs LiveRegs;
453 FailBB->clearLiveIns();
455 StoreBB->clearLiveIns();
457 LoadCmpBB->clearLiveIns();
501bool AArch64ExpandPseudo::expand_DestructiveOp(
503 MachineBasicBlock &
MBB,
510 bool DstIsDead =
MI.getOperand(0).isDead();
512 unsigned PredIdx, DOPIdx, SrcIdx, Src2Idx;
517 if (DstReg ==
MI.getOperand(3).getReg()) {
519 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(1, 3, 2);
526 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(1, 2, 3);
529 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(2, 3, 3);
532 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 2, 3, 4);
533 if (DstReg ==
MI.getOperand(3).getReg()) {
535 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 3, 4, 2);
537 }
else if (DstReg ==
MI.getOperand(4).getReg()) {
539 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 4, 3, 2);
546 std::tie(DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 1, 2);
555 bool DOPRegIsUnique =
false;
558 DOPRegIsUnique = DstReg !=
MI.getOperand(SrcIdx).getReg();
563 DstReg !=
MI.getOperand(DOPIdx).getReg() ||
564 MI.getOperand(DOPIdx).getReg() !=
MI.getOperand(SrcIdx).getReg();
569 DOPRegIsUnique =
true;
573 DstReg !=
MI.getOperand(DOPIdx).getReg() ||
574 (
MI.getOperand(DOPIdx).
getReg() !=
MI.getOperand(SrcIdx).getReg() &&
575 MI.getOperand(DOPIdx).getReg() !=
MI.getOperand(Src2Idx).getReg());
591 uint64_t ElementSize =
TII->getElementSizeForOpcode(Opcode);
592 unsigned MovPrfx, LSLZero, MovPrfxZero;
593 switch (ElementSize) {
596 MovPrfx = AArch64::MOVPRFX_ZZ;
597 LSLZero = AArch64::LSL_ZPmI_B;
598 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_B;
601 MovPrfx = AArch64::MOVPRFX_ZZ;
602 LSLZero = AArch64::LSL_ZPmI_H;
603 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_H;
606 MovPrfx = AArch64::MOVPRFX_ZZ;
607 LSLZero = AArch64::LSL_ZPmI_S;
608 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_S;
611 MovPrfx = AArch64::MOVPRFX_ZZ;
612 LSLZero = AArch64::LSL_ZPmI_D;
613 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_D;
625 MachineInstrBuilder PRFX, DOP;
632 "The destructive operand should be unique");
634 "This instruction is unpredicated");
638 .
addReg(DstReg, RegState::Define)
639 .
addReg(
MI.getOperand(PredIdx).getReg())
640 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState);
654 .
addReg(DstReg, RegState::Define)
655 .
add(
MI.getOperand(PredIdx))
659 }
else if (DstReg !=
MI.getOperand(DOPIdx).getReg()) {
660 assert(DOPRegIsUnique &&
"The destructive operand should be unique");
662 .
addReg(DstReg, RegState::Define)
663 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState);
673 DOPRegState = DOPRegState | RegState::Kill;
677 DOP.
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
678 .
add(
MI.getOperand(PredIdx))
679 .
add(
MI.getOperand(SrcIdx));
685 DOP.
add(
MI.getOperand(PredIdx))
686 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
687 .
add(
MI.getOperand(SrcIdx));
690 DOP.
add(
MI.getOperand(PredIdx))
691 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
692 .
add(
MI.getOperand(SrcIdx))
693 .
add(
MI.getOperand(Src2Idx));
696 DOP.
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
697 .
add(
MI.getOperand(SrcIdx))
698 .
add(
MI.getOperand(Src2Idx));
703 transferImpOps(
MI, PRFX, DOP);
706 transferImpOps(
MI, DOP, DOP);
708 MI.eraseFromParent();
712bool AArch64ExpandPseudo::expandSetTagLoop(
718 Register AddressReg =
MI.getOperand(1).getReg();
722 bool ZeroData =
MI.getOpcode() == AArch64::STZGloop_wback;
723 const unsigned OpCode1 =
724 ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex;
725 const unsigned OpCode2 =
726 ZeroData ? AArch64::STZ2GPostIndex : AArch64::ST2GPostIndex;
728 unsigned Size =
MI.getOperand(2).getImm();
730 if (
Size % (16 * 2) != 0) {
746 MF->
insert(++LoopBB->getIterator(), DoneBB);
763 .
addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
765 LoopBB->addSuccessor(LoopBB);
766 LoopBB->addSuccessor(DoneBB);
768 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
769 DoneBB->transferSuccessors(&
MBB);
774 MI.eraseFromParent();
776 LivePhysRegs LiveRegs;
781 LoopBB->clearLiveIns();
783 DoneBB->clearLiveIns();
789bool AArch64ExpandPseudo::expandSVESpillFill(MachineBasicBlock &
MBB,
791 unsigned Opc,
unsigned N) {
792 assert((
Opc == AArch64::LDR_ZXI ||
Opc == AArch64::STR_ZXI ||
793 Opc == AArch64::LDR_PXI ||
Opc == AArch64::STR_PXI) &&
794 "Unexpected opcode");
797 unsigned sub0 = (
Opc == AArch64::LDR_ZXI ||
Opc == AArch64::STR_ZXI)
800 const TargetRegisterInfo *
TRI =
804 int ImmOffset =
MI.getOperand(2).getImm() +
Offset;
805 bool Kill = (
Offset + 1 ==
N) ?
MI.getOperand(1).isKill() :
false;
806 assert(ImmOffset >= -256 && ImmOffset < 256 &&
807 "Immediate spill offset out of range");
814 MI.eraseFromParent();
825 unsigned RegMaskStartIdx) {
834 while (!
MBBI->getOperand(RegMaskStartIdx).isRegMask()) {
836 assert(MOP.
isReg() &&
"can only add register operands");
838 MOP.
getReg(),
false,
true,
false,
844 Call->addOperand(MO);
855 unsigned RegMaskStartIdx) {
856 unsigned Opc = CallTarget.
isGlobal() ? AArch64::BL : AArch64::BLR;
859 "invalid operand for regular call");
863bool AArch64ExpandPseudo::expandCALL_RVMARKER(
871 MachineOperand &RVTarget =
MI.getOperand(0);
872 bool DoEmitMarker =
MI.getOperand(1).getImm();
873 assert(RVTarget.
isGlobal() &&
"invalid operand for attached call");
875 MachineInstr *OriginalCall =
nullptr;
877 if (
MI.getOpcode() == AArch64::BLRA_RVMARKER) {
879 const MachineOperand &CallTarget =
MI.getOperand(2);
880 const MachineOperand &
Key =
MI.getOperand(3);
881 const MachineOperand &IntDisc =
MI.getOperand(4);
882 const MachineOperand &AddrDisc =
MI.getOperand(5);
886 "Invalid auth call key");
888 MachineOperand
Ops[] = {CallTarget,
Key, IntDisc, AddrDisc};
893 assert(
MI.getOpcode() == AArch64::BLR_RVMARKER &&
"unknown rvmarker MI");
901 .
addReg(AArch64::FP, RegState::Define)
910 if (
MI.shouldUpdateAdditionalCallInfo())
913 MI.eraseFromParent();
915 std::next(RVCall->getIterator()));
919bool AArch64ExpandPseudo::expandCALL_BTI(MachineBasicBlock &
MBB,
939 if (
MI.shouldUpdateAdditionalCallInfo())
942 MI.eraseFromParent();
947bool AArch64ExpandPseudo::expandStoreSwiftAsyncContext(
955 if (STI.getTargetTriple().getArchName() !=
"arm64e") {
972 unsigned Opc =
Offset >= 0 ? AArch64::ADDXri : AArch64::SUBXri;
1004AArch64ExpandPseudo::ConditionalBlocks
1005AArch64ExpandPseudo::expandConditionalPseudo(MachineBasicBlock &
MBB,
1008 MachineInstrBuilder &Branch) {
1011 "Unexpected unreachable in block");
1017 MachineInstr &PrevMI = *std::prev(
MBBI);
1018 MachineBasicBlock *CondBB =
MBB.
splitAt(PrevMI,
true);
1019 MachineBasicBlock *EndBB =
1020 std::next(
MBBI) == CondBB->
end()
1033 return {*CondBB, *EndBB};
1037AArch64ExpandPseudo::expandRestoreZASave(MachineBasicBlock &
MBB,
1039 MachineInstr &
MI = *
MBBI;
1043 MachineInstrBuilder
Branch =
1046 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Branch);
1048 MachineInstrBuilder MIB =
1051 for (
unsigned I = 2;
I <
MI.getNumOperands(); ++
I)
1052 MIB.
add(
MI.getOperand(
I));
1054 MIB.
addReg(
MI.getOperand(1).getReg(), RegState::Implicit);
1056 MI.eraseFromParent();
1067 [[maybe_unused]]
auto *RI =
MBB.getParent()->getSubtarget().getRegisterInfo();
1073 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Branch);
1078 for (
unsigned I = 3;
I <
MI.getNumOperands(); ++
I)
1079 MIB.
add(
MI.getOperand(
I));
1082 .
addImm(AArch64SysReg::TPIDR2_EL0)
1084 bool ZeroZA =
MI.getOperand(1).getImm() != 0;
1085 bool ZeroZT0 =
MI.getOperand(2).getImm() != 0;
1087 assert(
MI.definesRegister(AArch64::ZAB0, RI) &&
"should define ZA!");
1093 assert(
MI.definesRegister(AArch64::ZT0, RI) &&
"should define ZT0!");
1098 MI.eraseFromParent();
1103AArch64ExpandPseudo::expandCondSMToggle(MachineBasicBlock &
MBB,
1105 MachineInstr &
MI = *
MBBI;
1112 MI.getParent()->successors().begin() ==
1113 MI.getParent()->successors().end()) {
1114 MI.eraseFromParent();
1157 switch (
MI.getOperand(2).getImm()) {
1161 Opc = AArch64::TBNZW;
1164 Opc = AArch64::TBZW;
1167 auto PStateSM =
MI.getOperand(3).getReg();
1169 unsigned SMReg32 =
TRI->getSubReg(PStateSM, AArch64::sub_32);
1170 MachineInstrBuilder Tbx =
1173 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Tbx);
1175 MachineInstrBuilder MIB =
BuildMI(CondBB, CondBB.
back(),
MI.getDebugLoc(),
1176 TII->get(AArch64::MSRpstatesvcrImm1));
1180 MIB.
add(
MI.getOperand(0));
1181 MIB.
add(
MI.getOperand(1));
1182 for (
unsigned i = 4; i <
MI.getNumOperands(); ++i)
1183 MIB.
add(
MI.getOperand(i));
1185 MI.eraseFromParent();
1189bool AArch64ExpandPseudo::expandMultiVecPseudo(
1191 TargetRegisterClass ContiguousClass, TargetRegisterClass StridedClass,
1192 unsigned ContiguousOp,
unsigned StridedOpc) {
1193 MachineInstr &
MI = *
MBBI;
1207 .
add(
MI.getOperand(0))
1208 .
add(
MI.getOperand(1))
1209 .
add(
MI.getOperand(2))
1210 .
add(
MI.getOperand(3));
1211 transferImpOps(
MI, MIB, MIB);
1212 MI.eraseFromParent();
1216bool AArch64ExpandPseudo::expandFormTuplePseudo(
1220 MachineInstr &
MI = *
MBBI;
1221 Register ReturnTuple =
MI.getOperand(0).getReg();
1223 const TargetRegisterInfo *
TRI =
1225 for (
unsigned I = 0;
I <
Size; ++
I) {
1226 Register FormTupleOpReg =
MI.getOperand(
I + 1).getReg();
1228 TRI->getSubReg(ReturnTuple, AArch64::zsub0 +
I);
1231 if (FormTupleOpReg != ReturnTupleSubReg)
1233 .
addReg(ReturnTupleSubReg, RegState::Define)
1238 MI.eraseFromParent();
1244bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &
MBB,
1247 MachineInstr &
MI = *
MBBI;
1248 unsigned Opcode =
MI.getOpcode();
1252 if (OrigInstr != -1) {
1253 auto &Orig =
TII->get(OrigInstr);
1256 return expand_DestructiveOp(
MI,
MBB,
MBBI);
1264 case AArch64::BSPv8i8:
1265 case AArch64::BSPv16i8: {
1267 if (DstReg ==
MI.getOperand(3).getReg()) {
1270 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BITv8i8
1271 : AArch64::BITv16i8))
1272 .
add(
MI.getOperand(0))
1273 .
add(
MI.getOperand(3))
1274 .
add(
MI.getOperand(2))
1275 .
add(
MI.getOperand(1));
1276 transferImpOps(
MI,
I,
I);
1277 }
else if (DstReg ==
MI.getOperand(2).getReg()) {
1280 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BIFv8i8
1281 : AArch64::BIFv16i8))
1282 .
add(
MI.getOperand(0))
1283 .
add(
MI.getOperand(2))
1284 .
add(
MI.getOperand(3))
1285 .
add(
MI.getOperand(1));
1286 transferImpOps(
MI,
I,
I);
1289 if (DstReg ==
MI.getOperand(1).getReg()) {
1292 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BSLv8i8
1293 : AArch64::BSLv16i8))
1294 .
add(
MI.getOperand(0))
1295 .
add(
MI.getOperand(1))
1296 .
add(
MI.getOperand(2))
1297 .
add(
MI.getOperand(3));
1298 transferImpOps(
MI,
I,
I);
1303 MI.getOperand(1).isKill() &&
1304 MI.getOperand(1).getReg() !=
MI.getOperand(2).getReg() &&
1305 MI.getOperand(1).getReg() !=
MI.getOperand(3).getReg());
1307 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::ORRv8i8
1308 : AArch64::ORRv16i8))
1316 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BSLv8i8
1317 : AArch64::BSLv16i8))
1318 .
add(
MI.getOperand(0))
1321 MI.getOperand(0).isRenamable()))
1322 .
add(
MI.getOperand(2))
1323 .
add(
MI.getOperand(3));
1324 transferImpOps(
MI, I2, I2);
1327 MI.eraseFromParent();
1331 case AArch64::ADDWrr:
1332 case AArch64::SUBWrr:
1333 case AArch64::ADDXrr:
1334 case AArch64::SUBXrr:
1335 case AArch64::ADDSWrr:
1336 case AArch64::SUBSWrr:
1337 case AArch64::ADDSXrr:
1338 case AArch64::SUBSXrr:
1339 case AArch64::ANDWrr:
1340 case AArch64::ANDXrr:
1341 case AArch64::BICWrr:
1342 case AArch64::BICXrr:
1343 case AArch64::ANDSWrr:
1344 case AArch64::ANDSXrr:
1345 case AArch64::BICSWrr:
1346 case AArch64::BICSXrr:
1347 case AArch64::EONWrr:
1348 case AArch64::EONXrr:
1349 case AArch64::EORWrr:
1350 case AArch64::EORXrr:
1351 case AArch64::ORNWrr:
1352 case AArch64::ORNXrr:
1353 case AArch64::ORRWrr:
1354 case AArch64::ORRXrr: {
1356 switch (
MI.getOpcode()) {
1359 case AArch64::ADDWrr: Opcode = AArch64::ADDWrs;
break;
1360 case AArch64::SUBWrr: Opcode = AArch64::SUBWrs;
break;
1361 case AArch64::ADDXrr: Opcode = AArch64::ADDXrs;
break;
1362 case AArch64::SUBXrr: Opcode = AArch64::SUBXrs;
break;
1363 case AArch64::ADDSWrr: Opcode = AArch64::ADDSWrs;
break;
1364 case AArch64::SUBSWrr: Opcode = AArch64::SUBSWrs;
break;
1365 case AArch64::ADDSXrr: Opcode = AArch64::ADDSXrs;
break;
1366 case AArch64::SUBSXrr: Opcode = AArch64::SUBSXrs;
break;
1367 case AArch64::ANDWrr: Opcode = AArch64::ANDWrs;
break;
1368 case AArch64::ANDXrr: Opcode = AArch64::ANDXrs;
break;
1369 case AArch64::BICWrr: Opcode = AArch64::BICWrs;
break;
1370 case AArch64::BICXrr: Opcode = AArch64::BICXrs;
break;
1371 case AArch64::ANDSWrr: Opcode = AArch64::ANDSWrs;
break;
1372 case AArch64::ANDSXrr: Opcode = AArch64::ANDSXrs;
break;
1373 case AArch64::BICSWrr: Opcode = AArch64::BICSWrs;
break;
1374 case AArch64::BICSXrr: Opcode = AArch64::BICSXrs;
break;
1375 case AArch64::EONWrr: Opcode = AArch64::EONWrs;
break;
1376 case AArch64::EONXrr: Opcode = AArch64::EONXrs;
break;
1377 case AArch64::EORWrr: Opcode = AArch64::EORWrs;
break;
1378 case AArch64::EORXrr: Opcode = AArch64::EORXrs;
break;
1379 case AArch64::ORNWrr: Opcode = AArch64::ORNWrs;
break;
1380 case AArch64::ORNXrr: Opcode = AArch64::ORNXrs;
break;
1381 case AArch64::ORRWrr: Opcode = AArch64::ORRWrs;
break;
1382 case AArch64::ORRXrr: Opcode = AArch64::ORRXrs;
break;
1386 MachineInstr *NewMI = MF.CreateMachineInstr(
1387 TII->get(Opcode),
MI.getDebugLoc(),
true);
1389 MachineInstrBuilder MIB1(MF, NewMI);
1390 MIB1->setPCSections(MF,
MI.getPCSections());
1391 MIB1.addReg(
MI.getOperand(0).getReg(), RegState::Define)
1392 .add(
MI.getOperand(1))
1393 .add(
MI.getOperand(2))
1395 transferImpOps(
MI, MIB1, MIB1);
1396 if (
auto DebugNumber =
MI.peekDebugInstrNum())
1398 MI.eraseFromParent();
1402 case AArch64::LOADgot: {
1405 const MachineOperand &MO1 =
MI.getOperand(1);
1411 TII->get(AArch64::LDRXl), DstReg);
1419 "Only expect globals, externalsymbols, or constant pools");
1424 MachineFunction &MF = *
MI.getParent()->getParent();
1426 MachineInstrBuilder MIB1 =
1429 MachineInstrBuilder MIB2;
1430 if (MF.
getSubtarget<AArch64Subtarget>().isTargetILP32()) {
1432 unsigned Reg32 =
TRI->getSubReg(DstReg, AArch64::sub_32);
1435 .
addReg(DstReg, RegState::Kill)
1436 .
addReg(DstReg, RegState::Implicit);
1440 .
add(
MI.getOperand(0))
1441 .
addUse(DstReg, RegState::Kill);
1455 "Only expect globals, externalsymbols, or constant pools");
1466 if (
MI.peekDebugInstrNum() != 0)
1468 transferImpOps(
MI, MIB1, MIB2);
1470 MI.eraseFromParent();
1473 case AArch64::MOVaddrBA: {
1474 MachineFunction &MF = *
MI.getParent()->getParent();
1475 if (MF.
getSubtarget<AArch64Subtarget>().isTargetMachO()) {
1480 assert(
MI.getOperand(1).getOffset() == 0 &&
"unexpected offset");
1490 TII->get(AArch64::LDRXui), DstReg)
1494 transferImpOps(
MI, MIB1, MIB2);
1495 MI.eraseFromParent();
1500 case AArch64::MOVaddr:
1501 case AArch64::MOVaddrJT:
1502 case AArch64::MOVaddrCP:
1503 case AArch64::MOVaddrTLS:
1504 case AArch64::MOVaddrEXT: {
1507 assert(DstReg != AArch64::XZR);
1508 MachineInstrBuilder MIB1 =
1510 .
add(
MI.getOperand(1));
1520 auto Tag =
MI.getOperand(1);
1522 Tag.setOffset(0x100000000);
1529 MachineInstrBuilder MIB2 =
1531 .
add(
MI.getOperand(0))
1533 .
add(
MI.getOperand(2))
1536 transferImpOps(
MI, MIB1, MIB2);
1537 MI.eraseFromParent();
1540 case AArch64::ADDlowTLS:
1543 .
add(
MI.getOperand(0))
1544 .
add(
MI.getOperand(1))
1545 .
add(
MI.getOperand(2))
1547 MI.eraseFromParent();
1550 case AArch64::MOVbaseTLS: {
1552 auto SysReg = AArch64SysReg::TPIDR_EL0;
1554 if (MF->
getSubtarget<AArch64Subtarget>().useEL3ForTP())
1555 SysReg = AArch64SysReg::TPIDR_EL3;
1556 else if (MF->
getSubtarget<AArch64Subtarget>().useEL2ForTP())
1557 SysReg = AArch64SysReg::TPIDR_EL2;
1558 else if (MF->
getSubtarget<AArch64Subtarget>().useEL1ForTP())
1559 SysReg = AArch64SysReg::TPIDR_EL1;
1560 else if (MF->
getSubtarget<AArch64Subtarget>().useROEL0ForTP())
1561 SysReg = AArch64SysReg::TPIDRRO_EL0;
1564 MI.eraseFromParent();
1568 case AArch64::MOVi32imm:
1570 case AArch64::MOVi64imm:
1572 case AArch64::RET_ReallyLR: {
1578 MachineInstrBuilder MIB =
1580 .
addReg(AArch64::LR, RegState::Undef);
1581 transferImpOps(
MI, MIB, MIB);
1582 MI.eraseFromParent();
1585 case AArch64::CMP_SWAP_8:
1586 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRB, AArch64::STLXRB,
1589 AArch64::WZR, NextMBBI);
1590 case AArch64::CMP_SWAP_16:
1591 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRH, AArch64::STLXRH,
1594 AArch64::WZR, NextMBBI);
1595 case AArch64::CMP_SWAP_32:
1596 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRW, AArch64::STLXRW,
1599 AArch64::WZR, NextMBBI);
1600 case AArch64::CMP_SWAP_64:
1601 return expandCMP_SWAP(
MBB,
MBBI,
1602 AArch64::LDAXRX, AArch64::STLXRX, AArch64::SUBSXrs,
1604 AArch64::XZR, NextMBBI);
1605 case AArch64::CMP_SWAP_128:
1606 case AArch64::CMP_SWAP_128_RELEASE:
1607 case AArch64::CMP_SWAP_128_ACQUIRE:
1608 case AArch64::CMP_SWAP_128_MONOTONIC:
1609 return expandCMP_SWAP_128(
MBB,
MBBI, NextMBBI);
1611 case AArch64::AESMCrrTied:
1612 case AArch64::AESIMCrrTied: {
1613 MachineInstrBuilder MIB =
1615 TII->get(Opcode == AArch64::AESMCrrTied ? AArch64::AESMCrr :
1617 .
add(
MI.getOperand(0))
1618 .
add(
MI.getOperand(1));
1619 transferImpOps(
MI, MIB, MIB);
1620 MI.eraseFromParent();
1623 case AArch64::IRGstack: {
1625 const AArch64FunctionInfo *AFI = MF.
getInfo<AArch64FunctionInfo>();
1626 const AArch64FrameLowering *TFI =
1627 MF.
getSubtarget<AArch64Subtarget>().getFrameLowering();
1634 StackOffset FrameRegOffset = TFI->resolveFrameOffsetReference(
1640 if (FrameRegOffset) {
1642 SrcReg =
MI.getOperand(0).getReg();
1644 FrameRegOffset,
TII);
1647 .
add(
MI.getOperand(0))
1649 .
add(
MI.getOperand(2));
1650 MI.eraseFromParent();
1653 case AArch64::TAGPstack: {
1654 int64_t
Offset =
MI.getOperand(2).getImm();
1656 TII->get(
Offset >= 0 ? AArch64::ADDG : AArch64::SUBG))
1657 .
add(
MI.getOperand(0))
1658 .
add(
MI.getOperand(1))
1660 .
add(
MI.getOperand(4));
1661 MI.eraseFromParent();
1664 case AArch64::STGloop_wback:
1665 case AArch64::STZGloop_wback:
1666 return expandSetTagLoop(
MBB,
MBBI, NextMBBI);
1667 case AArch64::STGloop:
1668 case AArch64::STZGloop:
1670 "Non-writeback variants of STGloop / STZGloop should not "
1671 "survive past PrologEpilogInserter.");
1672 case AArch64::STR_ZZZZXI:
1673 case AArch64::STR_ZZZZXI_STRIDED_CONTIGUOUS:
1674 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 4);
1675 case AArch64::STR_ZZZXI:
1676 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 3);
1677 case AArch64::STR_ZZXI:
1678 case AArch64::STR_ZZXI_STRIDED_CONTIGUOUS:
1679 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 2);
1680 case AArch64::STR_PPXI:
1681 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_PXI, 2);
1682 case AArch64::LDR_ZZZZXI:
1683 case AArch64::LDR_ZZZZXI_STRIDED_CONTIGUOUS:
1684 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 4);
1685 case AArch64::LDR_ZZZXI:
1686 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 3);
1687 case AArch64::LDR_ZZXI:
1688 case AArch64::LDR_ZZXI_STRIDED_CONTIGUOUS:
1689 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 2);
1690 case AArch64::LDR_PPXI:
1691 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_PXI, 2);
1692 case AArch64::BLR_RVMARKER:
1693 case AArch64::BLRA_RVMARKER:
1694 return expandCALL_RVMARKER(
MBB,
MBBI);
1695 case AArch64::BLR_BTI:
1696 return expandCALL_BTI(
MBB,
MBBI);
1697 case AArch64::StoreSwiftAsyncContext:
1698 return expandStoreSwiftAsyncContext(
MBB,
MBBI);
1699 case AArch64::RestoreZAPseudo:
1700 case AArch64::CommitZASavePseudo:
1701 case AArch64::MSRpstatePseudo: {
1702 auto *NewMBB = [&] {
1704 case AArch64::RestoreZAPseudo:
1705 return expandRestoreZASave(
MBB,
MBBI);
1706 case AArch64::CommitZASavePseudo:
1707 return expandCommitZASave(
MBB,
MBBI);
1708 case AArch64::MSRpstatePseudo:
1709 return expandCondSMToggle(
MBB,
MBBI);
1718 case AArch64::InOutZAUsePseudo:
1719 case AArch64::RequiresZASavePseudo:
1720 case AArch64::RequiresZT0SavePseudo:
1721 case AArch64::SMEStateAllocPseudo:
1722 case AArch64::COALESCER_BARRIER_FPR16:
1723 case AArch64::COALESCER_BARRIER_FPR32:
1724 case AArch64::COALESCER_BARRIER_FPR64:
1725 case AArch64::COALESCER_BARRIER_FPR128:
1726 MI.eraseFromParent();
1728 case AArch64::LD1B_2Z_IMM_PSEUDO:
1729 return expandMultiVecPseudo(
1730 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1731 AArch64::LD1B_2Z_IMM, AArch64::LD1B_2Z_STRIDED_IMM);
1732 case AArch64::LD1H_2Z_IMM_PSEUDO:
1733 return expandMultiVecPseudo(
1734 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1735 AArch64::LD1H_2Z_IMM, AArch64::LD1H_2Z_STRIDED_IMM);
1736 case AArch64::LD1W_2Z_IMM_PSEUDO:
1737 return expandMultiVecPseudo(
1738 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1739 AArch64::LD1W_2Z_IMM, AArch64::LD1W_2Z_STRIDED_IMM);
1740 case AArch64::LD1D_2Z_IMM_PSEUDO:
1741 return expandMultiVecPseudo(
1742 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1743 AArch64::LD1D_2Z_IMM, AArch64::LD1D_2Z_STRIDED_IMM);
1744 case AArch64::LDNT1B_2Z_IMM_PSEUDO:
1745 return expandMultiVecPseudo(
1746 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1747 AArch64::LDNT1B_2Z_IMM, AArch64::LDNT1B_2Z_STRIDED_IMM);
1748 case AArch64::LDNT1H_2Z_IMM_PSEUDO:
1749 return expandMultiVecPseudo(
1750 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1751 AArch64::LDNT1H_2Z_IMM, AArch64::LDNT1H_2Z_STRIDED_IMM);
1752 case AArch64::LDNT1W_2Z_IMM_PSEUDO:
1753 return expandMultiVecPseudo(
1754 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1755 AArch64::LDNT1W_2Z_IMM, AArch64::LDNT1W_2Z_STRIDED_IMM);
1756 case AArch64::LDNT1D_2Z_IMM_PSEUDO:
1757 return expandMultiVecPseudo(
1758 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1759 AArch64::LDNT1D_2Z_IMM, AArch64::LDNT1D_2Z_STRIDED_IMM);
1760 case AArch64::LD1B_2Z_PSEUDO:
1761 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1762 AArch64::ZPR2StridedRegClass, AArch64::LD1B_2Z,
1763 AArch64::LD1B_2Z_STRIDED);
1764 case AArch64::LD1H_2Z_PSEUDO:
1765 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1766 AArch64::ZPR2StridedRegClass, AArch64::LD1H_2Z,
1767 AArch64::LD1H_2Z_STRIDED);
1768 case AArch64::LD1W_2Z_PSEUDO:
1769 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1770 AArch64::ZPR2StridedRegClass, AArch64::LD1W_2Z,
1771 AArch64::LD1W_2Z_STRIDED);
1772 case AArch64::LD1D_2Z_PSEUDO:
1773 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1774 AArch64::ZPR2StridedRegClass, AArch64::LD1D_2Z,
1775 AArch64::LD1D_2Z_STRIDED);
1776 case AArch64::LDNT1B_2Z_PSEUDO:
1777 return expandMultiVecPseudo(
1778 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1779 AArch64::LDNT1B_2Z, AArch64::LDNT1B_2Z_STRIDED);
1780 case AArch64::LDNT1H_2Z_PSEUDO:
1781 return expandMultiVecPseudo(
1782 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1783 AArch64::LDNT1H_2Z, AArch64::LDNT1H_2Z_STRIDED);
1784 case AArch64::LDNT1W_2Z_PSEUDO:
1785 return expandMultiVecPseudo(
1786 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1787 AArch64::LDNT1W_2Z, AArch64::LDNT1W_2Z_STRIDED);
1788 case AArch64::LDNT1D_2Z_PSEUDO:
1789 return expandMultiVecPseudo(
1790 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1791 AArch64::LDNT1D_2Z, AArch64::LDNT1D_2Z_STRIDED);
1792 case AArch64::LD1B_4Z_IMM_PSEUDO:
1793 return expandMultiVecPseudo(
1794 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1795 AArch64::LD1B_4Z_IMM, AArch64::LD1B_4Z_STRIDED_IMM);
1796 case AArch64::LD1H_4Z_IMM_PSEUDO:
1797 return expandMultiVecPseudo(
1798 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1799 AArch64::LD1H_4Z_IMM, AArch64::LD1H_4Z_STRIDED_IMM);
1800 case AArch64::LD1W_4Z_IMM_PSEUDO:
1801 return expandMultiVecPseudo(
1802 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1803 AArch64::LD1W_4Z_IMM, AArch64::LD1W_4Z_STRIDED_IMM);
1804 case AArch64::LD1D_4Z_IMM_PSEUDO:
1805 return expandMultiVecPseudo(
1806 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1807 AArch64::LD1D_4Z_IMM, AArch64::LD1D_4Z_STRIDED_IMM);
1808 case AArch64::LDNT1B_4Z_IMM_PSEUDO:
1809 return expandMultiVecPseudo(
1810 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1811 AArch64::LDNT1B_4Z_IMM, AArch64::LDNT1B_4Z_STRIDED_IMM);
1812 case AArch64::LDNT1H_4Z_IMM_PSEUDO:
1813 return expandMultiVecPseudo(
1814 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1815 AArch64::LDNT1H_4Z_IMM, AArch64::LDNT1H_4Z_STRIDED_IMM);
1816 case AArch64::LDNT1W_4Z_IMM_PSEUDO:
1817 return expandMultiVecPseudo(
1818 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1819 AArch64::LDNT1W_4Z_IMM, AArch64::LDNT1W_4Z_STRIDED_IMM);
1820 case AArch64::LDNT1D_4Z_IMM_PSEUDO:
1821 return expandMultiVecPseudo(
1822 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1823 AArch64::LDNT1D_4Z_IMM, AArch64::LDNT1D_4Z_STRIDED_IMM);
1824 case AArch64::LD1B_4Z_PSEUDO:
1825 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1826 AArch64::ZPR4StridedRegClass, AArch64::LD1B_4Z,
1827 AArch64::LD1B_4Z_STRIDED);
1828 case AArch64::LD1H_4Z_PSEUDO:
1829 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1830 AArch64::ZPR4StridedRegClass, AArch64::LD1H_4Z,
1831 AArch64::LD1H_4Z_STRIDED);
1832 case AArch64::LD1W_4Z_PSEUDO:
1833 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1834 AArch64::ZPR4StridedRegClass, AArch64::LD1W_4Z,
1835 AArch64::LD1W_4Z_STRIDED);
1836 case AArch64::LD1D_4Z_PSEUDO:
1837 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1838 AArch64::ZPR4StridedRegClass, AArch64::LD1D_4Z,
1839 AArch64::LD1D_4Z_STRIDED);
1840 case AArch64::LDNT1B_4Z_PSEUDO:
1841 return expandMultiVecPseudo(
1842 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1843 AArch64::LDNT1B_4Z, AArch64::LDNT1B_4Z_STRIDED);
1844 case AArch64::LDNT1H_4Z_PSEUDO:
1845 return expandMultiVecPseudo(
1846 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1847 AArch64::LDNT1H_4Z, AArch64::LDNT1H_4Z_STRIDED);
1848 case AArch64::LDNT1W_4Z_PSEUDO:
1849 return expandMultiVecPseudo(
1850 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1851 AArch64::LDNT1W_4Z, AArch64::LDNT1W_4Z_STRIDED);
1852 case AArch64::LDNT1D_4Z_PSEUDO:
1853 return expandMultiVecPseudo(
1854 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1855 AArch64::LDNT1D_4Z, AArch64::LDNT1D_4Z_STRIDED);
1856 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO:
1857 return expandFormTuplePseudo(
MBB,
MBBI, NextMBBI, 2);
1858 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO:
1859 return expandFormTuplePseudo(
MBB,
MBBI, NextMBBI, 4);
1866bool AArch64ExpandPseudo::expandMBB(MachineBasicBlock &
MBB) {
1879bool AArch64ExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
1883 for (
auto &
MBB : MF)
1890 return new AArch64ExpandPseudo();
#define AARCH64_EXPAND_PSEUDO_NAME
MachineInstrBuilder & UseMI
static MachineInstr * createCallWithOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const AArch64InstrInfo *TII, unsigned Opcode, ArrayRef< MachineOperand > ExplicitOps, unsigned RegMaskStartIdx)
static constexpr unsigned ZERO_ALL_ZA_MASK
static MachineInstr * createCall(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const AArch64InstrInfo *TII, MachineOperand &CallTarget, unsigned RegMaskStartIdx)
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
unsigned getTaggedBasePointerOffset() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void moveAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
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 & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) 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 & setMIFlags(unsigned Flags) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
void setDebugInstrNum(unsigned Num)
Set instruction number of this MachineInstr.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const char * getSymbolName() const
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)
int64_t getOffset() const
Return the offset from the symbol in this operand.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
CodeModel::Model getCodeModel() const
Returns the code model.
ArrayRef< MCPhysReg > getRegisters() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_PREL
MO_PREL - Indicates that the bits of the symbol operand represented by MO_G0 etc are PC relative.
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
@ MO_G3
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address,...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
void expandMOVImm(uint64_t Imm, unsigned BitSize, SmallVectorImpl< ImmInsnModel > &Insn)
Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more real move-immediate instructions to...
int getSVERevInstr(uint16_t Opcode)
@ Destructive2xRegImmUnpred
@ DestructiveInstTypeMask
@ DestructiveUnaryPassthru
@ DestructiveTernaryCommWithRev
@ DestructiveBinaryCommWithRev
int getSVEPseudoMap(uint16_t Opcode)
int getSVENonRevInstr(uint16_t Opcode)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
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.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
constexpr RegState getDeadRegState(bool B)
constexpr RegState getRenamableRegState(bool B)
FunctionPass * createAArch64ExpandPseudoPass()
Returns an instance of the pseudo instruction expansion pass.
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr RegState getDefRegState(bool B)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
constexpr RegState getUndefRegState(bool B)