LLVM: lib/Target/PowerPC/PPCInstrInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
44
45using namespace llvm;
46
47#define DEBUG_TYPE "ppc-instr-info"
48
49#define GET_INSTRMAP_INFO
50#define GET_INSTRINFO_CTOR_DTOR
51#include "PPCGenInstrInfo.inc"
52
54 "Number of spillvsrrc spilled to stack as vec");
56 "Number of spillvsrrc spilled to stack as gpr");
57STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
59 "Number of ISELs that depend on comparison of constants converted");
60STATISTIC(MissedConvertibleImmediateInstrs,
61 "Number of compare-immediate instructions fed by constants");
63 "Number of record-form rotates converted to record-form andi");
64
67 cl::desc("Disable analysis for CTR loops"));
68
71
73cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),
75
78 cl::desc("Use the old (incorrect) instruction latency calculation"));
79
82 cl::desc("register pressure factor for the transformations."));
83
86 cl::desc("enable register pressure reduce in machine combiner pass."));
87
88
89void PPCInstrInfo::anchor() {}
90
93 -1,
94 STI.isPPC64() ? PPC::BLR8 : PPC::BLR),
95 Subtarget(STI), RI(STI.getTargetMachine()) {}
96
97
98
103 static_cast<const PPCSubtarget *>(STI)->getCPUDirective();
107 static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData();
109 }
110
112}
113
114
115
121
122
125
126
129 assert(DAG->TII && "No InstrInfo?");
130
132 }
133
135}
136
139 unsigned *PredCost) const {
141 return PPCGenInstrInfo::getInstrLatency(ItinData, MI, PredCost);
142
143
144
145
146
147
148
149
151 unsigned DefClass = MI.getDesc().getSchedClass();
152 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
155 continue;
156
159 continue;
160
162 }
163
165}
166
169 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
170 std::optional Latency = PPCGenInstrInfo::getOperandLatency(
171 ItinData, DefMI, DefIdx, UseMI, UseIdx);
172
173 if (.getParent())
175
178
179 bool IsRegCR;
180 if (Reg.isVirtual()) {
182 &DefMI.getParent()->getParent()->getRegInfo();
183 IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
184 MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
185 } else {
186 IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
187 PPC::CRBITRCRegClass.contains(Reg);
188 }
189
190 if (UseMI.isBranch() && IsRegCR) {
193
194
195
196 unsigned Directive = Subtarget.getCPUDirective();
198 default: break;
210
212 break;
213 }
214 }
215
217}
218
221 MI.setFlags(Flags);
225}
226
227
228
229
230
231
233 bool Invert) const {
234 if (Invert)
235 return false;
237
238
239 case PPC::FADD:
240 case PPC::FADDS:
241
242 case PPC::FMUL:
243 case PPC::FMULS:
244
245 case PPC::VADDFP:
246
247 case PPC::XSADDDP:
248 case PPC::XVADDDP:
249 case PPC::XVADDSP:
250 case PPC::XSADDSP:
251
252 case PPC::XSMULDP:
253 case PPC::XVMULDP:
254 case PPC::XVMULSP:
255 case PPC::XSMULSP:
258
259
260 case PPC::MULHD:
261 case PPC::MULLD:
262 case PPC::MULHW:
263 case PPC::MULLW:
264 return true;
265 default:
266 return false;
267 }
268}
269
270#define InfoArrayIdxFMAInst 0
271#define InfoArrayIdxFAddInst 1
272#define InfoArrayIdxFMULInst 2
273#define InfoArrayIdxAddOpIdx 3
274#define InfoArrayIdxMULOpIdx 4
275#define InfoArrayIdxFSubInst 5
276
277
278
279
280
281
282
283
285
286 {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
287 {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
288 {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
289 {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
290 {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
291 {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
292
293
294
295int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {
298 return I;
299 return -1;
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
352 bool DoRegPressureReduce) const {
356
357 auto IsAllOpsVirtualReg = [](const MachineInstr &Instr) {
358 for (const auto &MO : Instr.explicit_operands())
359 if (!(MO.isReg() && MO.getReg().isVirtual()))
360 return false;
361 return true;
362 };
363
364 auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,
365 unsigned OpType) {
366 if (Instr.getOpcode() !=
368 return false;
369
370
371
374 return false;
375
376
377 if (!IsAllOpsVirtualReg(Instr))
378 return false;
379
380
381
383 ->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
384 return false;
385
386 return true;
387 };
388
389 auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,
390 int16_t &MulOpIdx, bool IsLeaf) {
391 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
392 if (Idx < 0)
393 return false;
394
395
396
399 return false;
400
401
402 if (!IsAllOpsVirtualReg(Instr))
403 return false;
404
406 if (IsLeaf)
407 return true;
408
410
411 const MachineOperand &OpAdd = Instr.getOperand(AddOpIdx);
413
415 return false;
416
417
418
419 return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());
420 };
421
422 int16_t AddOpIdx = -1;
423 int16_t MulOpIdx = -1;
424
425 bool IsUsedOnceL = false;
426 bool IsUsedOnceR = false;
429
430 auto IsRPReductionCandidate = [&]() {
431
432
433 unsigned Opcode = Root.getOpcode();
434 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
435 return false;
436
437
438
439 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {
440 assert((MulOpIdx >= 0) && "mul operand index not right!");
441 Register MULRegL = TRI->lookThruSingleUseCopyChain(
443 Register MULRegR = TRI->lookThruSingleUseCopyChain(
445 if (!MULRegL && !MULRegR)
446 return false;
447
448 if (MULRegL && !MULRegR) {
449 MULRegR =
451 IsUsedOnceL = true;
452 } else if (!MULRegL && MULRegR) {
453 MULRegL =
455 IsUsedOnceR = true;
456 } else {
457 IsUsedOnceL = true;
458 IsUsedOnceR = true;
459 }
460
462 return false;
463
464 MULInstrL = MRI->getVRegDef(MULRegL);
465 MULInstrR = MRI->getVRegDef(MULRegR);
466 return true;
467 }
468 return false;
469 };
470
471
472 if (DoRegPressureReduce && IsRPReductionCandidate()) {
473 assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");
474
477 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");
479 return true;
480 }
481
482
485 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");
487 return true;
488 }
489 }
490
491
492
493 AddOpIdx = -1;
494 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))
495 return false;
496
497 assert((AddOpIdx >= 0) && "add operand index not right!");
498
501
502
503 AddOpIdx = -1;
504 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))
505 return false;
506
507 assert((AddOpIdx >= 0) && "add operand index not right!");
508
511 AddOpIdx = -1;
512 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {
514 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");
515 return true;
516 }
519 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");
520 return true;
521 }
522 return false;
523}
524
528 assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");
529
534
535 int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());
536 if (Idx < 0)
537 return;
538
540
541
542
546 ConstReg =
548 break;
550 ConstReg =
552 break;
553 default:
554
555 return;
556 }
557
559
562
563
568
569
571
573
574 for (auto *Inst : InsInstrs) {
575 for (MachineOperand &Operand : Inst->explicit_operands()) {
576 assert(Operand.isReg() && "Invalid instruction in InsInstrs!");
577 if (Operand.getReg() == PPC::ZERO8) {
578 Placeholder = &Operand;
579 break;
580 }
581 }
582 }
583
584 assert(Placeholder && "Placeholder does not exist!");
585
586
587
589 generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);
590
591
592 Placeholder->setReg(LoadNewConst);
593}
594
597
599 return false;
600
601
602
603
604
605
606
607
608
609
610
611
612
613 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
614 Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))
615 return false;
616
620
621 auto GetMBBPressure =
625
626
627 RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),
628 false, true);
629
631 if (MI.isDebugValue() || MI.isDebugLabel())
632 continue;
636 assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
637 RPTracker.recede(RegOpers);
638 }
639
640
642
644 };
645
646
647 unsigned VSSRCLimit =
649
650
651 return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >
653}
654
656
657 if (->hasOneMemOperand())
658 return false;
659
661 return Op->isLoad() && Op->getPseudoValue() &&
663}
664
665Register PPCInstrInfo::generateLoadForNewConst(
668
669
670
671 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
673 "Target not supported!\n");
674
677
678
679 Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
681 BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)
684
685 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
686 "Only float and double are supported!");
687
688 unsigned LoadOpcode;
689
690 if (Ty->isFloatTy())
691 LoadOpcode = PPC::DFLOADf32;
692 else
693 LoadOpcode = PPC::DFLOADf64;
694
696 Register VReg2 = MRI->createVirtualRegister(RC);
700
701
703 BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)
707
709
710
711 InsInstrs.insert(InsInstrs.begin(), Load);
712 InsInstrs.insert(InsInstrs.begin(), TOCOffset);
713 return VReg2;
714}
715
716
717
723 assert(I->mayLoad() && "Should be a load instruction.\n");
724 for (auto MO : I->uses()) {
725 if (!MO.isReg())
726 continue;
728 if (Reg == 0 || !Reg.isVirtual())
729 continue;
730
732 for (auto MO2 : DefMI->uses())
733 if (MO2.isCPI())
734 return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;
735 }
736 return nullptr;
737}
738
751
754 bool DoRegPressureReduce) const {
755
756
758 return false;
759
760 if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))
761 return true;
762
764 DoRegPressureReduce);
765}
766
777 reassociateFMA(Root, Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
778 break;
779 default:
780
782 DelInstrs, InstrIdxForVirtReg);
783 break;
784 }
785}
786
787void PPCInstrInfo::reassociateFMA(
798 MRI.constrainRegClass(RegC, RC);
799
800 unsigned FmaOp = Root.getOpcode();
801 int16_t Idx = getFMAOpIdxInfo(FmaOp);
802 assert(Idx >= 0 && "Root must be a FMA instruction");
803
804 bool IsILPReassociate =
807
810
814 default:
820 break;
824 Leaf = MRI.getVRegDef(MULReg);
825 break;
826 }
830 Leaf = MRI.getVRegDef(MULReg);
831 break;
832 }
833 }
834
835 uint32_t IntersectedFlags = 0;
836 if (IsILPReassociate)
838 else
840
841 auto GetOperandInfo = [&](const MachineOperand &Operand, Register &Reg,
842 bool &KillFlag) {
844 MRI.constrainRegClass(Reg, RC);
845 KillFlag = Operand.isKill();
846 };
847
848 auto GetFMAInstrInfo = [&](const MachineInstr &Instr, Register &MulOp1,
850 bool &MulOp1KillFlag, bool &MulOp2KillFlag,
851 bool &AddOpKillFlag) {
852 GetOperandInfo(Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
853 GetOperandInfo(Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
854 GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
855 };
856
857 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
858 RegA21, RegB;
859 bool KillX = false, KillY = false, KillM11 = false, KillM12 = false,
860 KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,
861 KillA11 = false, KillA21 = false, KillB = false;
862
863 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
864
865 if (IsILPReassociate)
866 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
867
869 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
870 GetOperandInfo(Leaf->getOperand(AddOpIdx), RegX, KillX);
872 GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
873 GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
874 } else {
875
876 GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
877 GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
878 }
879
880
881
882
883
884
885
886 Register NewVRA = MRI.createVirtualRegister(RC);
887 InstrIdxForVirtReg.insert(std::make_pair(NewVRA, 0));
888
890 if (IsILPReassociate) {
891 NewVRB = MRI.createVirtualRegister(RC);
892 InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));
893 }
894
897 NewVRD = MRI.createVirtualRegister(RC);
898 InstrIdxForVirtReg.insert(std::make_pair(NewVRD, 2));
899 }
900
901 auto AdjustOperandOrder = [&](MachineInstr *MI, Register RegAdd, bool KillAdd,
902 Register RegMul1, bool KillRegMul1,
903 Register RegMul2, bool KillRegMul2) {
904 MI->getOperand(AddOpIdx).setReg(RegAdd);
905 MI->getOperand(AddOpIdx).setIsKill(KillAdd);
906 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
907 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
908 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
909 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
910 };
911
912 MachineInstrBuilder NewARegPressure, NewCRegPressure;
913 switch (Pattern) {
914 default:
917
918 MachineInstrBuilder MINewB =
923 MachineInstrBuilder MINewA =
928
929 if (AddOpIdx != 1) {
930 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
931 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
932 }
933
934 MachineInstrBuilder MINewC =
939
940
944
945
949 break;
950 }
952 assert(NewVRD && "new FMA register not created!");
953
954 MachineInstrBuilder MINewA =
959 MachineInstrBuilder MINewB =
964 MachineInstrBuilder MINewD =
969
970 if (AddOpIdx != 1) {
971 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
972 AdjustOperandOrder(MINewD, NewVRA, true, RegM31, KillM31, RegM32,
973 KillM32);
974 }
975
976 MachineInstrBuilder MINewC =
981
982
987
988
993 break;
994 }
998 bool KillVarReg = false;
1000 VarReg = RegM31;
1001 KillVarReg = KillM31;
1002 } else {
1003 VarReg = RegM32;
1004 KillVarReg = KillM32;
1005 }
1006
1007
1008
1009
1010
1011
1015 .addReg(PPC::ZERO8);
1020
1021
1022
1023
1024 break;
1025 }
1026 }
1027
1028 if (!IsILPReassociate) {
1031
1032 InsInstrs.push_back(NewARegPressure);
1033 InsInstrs.push_back(NewCRegPressure);
1034 }
1035
1037 "Insertion instructions set should not be empty!");
1038
1039
1041 if (IsILPReassociate)
1044}
1045
1046
1049 unsigned &SubIdx) const {
1050 switch (MI.getOpcode()) {
1051 default: return false;
1052 case PPC::EXTSW:
1053 case PPC::EXTSW_32:
1054 case PPC::EXTSW_32_64:
1055 SrcReg = MI.getOperand(1).getReg();
1056 DstReg = MI.getOperand(0).getReg();
1057 SubIdx = PPC::sub_32;
1058 return true;
1059 }
1060}
1061
1063 int &FrameIndex) const {
1065
1066
1067 if (MI.getOperand(1).isImm() && .getOperand(1).getImm() &&
1068 MI.getOperand(2).isFI()) {
1069 FrameIndex = MI.getOperand(2).getIndex();
1070 return MI.getOperand(0).getReg();
1071 }
1072 }
1073 return 0;
1074}
1075
1076
1077
1080 switch (MI.getOpcode()) {
1081 default:
1082
1083 break;
1084 case PPC::LI:
1085 case PPC::LI8:
1086 case PPC::PLI:
1087 case PPC::PLI8:
1088 case PPC::LIS:
1089 case PPC::LIS8:
1090 case PPC::ADDIStocHA:
1091 case PPC::ADDIStocHA8:
1092 case PPC::ADDItocL:
1093 case PPC::ADDItocL8:
1094 case PPC::LOAD_STACK_GUARD:
1095 case PPC::PPCLdFixedAddr:
1096 case PPC::XXLXORz:
1097 case PPC::XXLXORspz:
1098 case PPC::XXLXORdpz:
1099 case PPC::XXLEQVOnes:
1100 case PPC::XXSPLTI32DX:
1101 case PPC::XXSPLTIW:
1102 case PPC::XXSPLTIDP:
1103 case PPC::V_SET0B:
1104 case PPC::V_SET0H:
1105 case PPC::V_SET0:
1106 case PPC::V_SETALLONESB:
1107 case PPC::V_SETALLONESH:
1108 case PPC::V_SETALLONES:
1109 case PPC::CRSET:
1110 case PPC::CRUNSET:
1111 case PPC::XXSETACCZ:
1112 case PPC::DMXXSETACCZ:
1113 return true;
1114 }
1116}
1117
1119 int &FrameIndex) const {
1121 if (MI.getOperand(1).isImm() && .getOperand(1).getImm() &&
1122 MI.getOperand(2).isFI()) {
1123 FrameIndex = MI.getOperand(2).getIndex();
1124 return MI.getOperand(0).getReg();
1125 }
1126 }
1127 return 0;
1128}
1129
1131 unsigned OpIdx1,
1132 unsigned OpIdx2) const {
1134
1135
1136 if (MI.getOpcode() != PPC::RLWIMI && MI.getOpcode() != PPC::RLWIMI_rec)
1138
1139
1140
1141
1142
1143
1144 if (MI.getOperand(3).getImm() != 0)
1145 return nullptr;
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1156 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1157 Register Reg0 = MI.getOperand(0).getReg();
1158 Register Reg1 = MI.getOperand(1).getReg();
1159 Register Reg2 = MI.getOperand(2).getReg();
1160 unsigned SubReg1 = MI.getOperand(1).getSubReg();
1161 unsigned SubReg2 = MI.getOperand(2).getSubReg();
1162 bool Reg1IsKill = MI.getOperand(1).isKill();
1163 bool Reg2IsKill = MI.getOperand(2).isKill();
1164 bool ChangeReg0 = false;
1165
1166
1167 if (Reg0 == Reg1) {
1168
1170 "Expecting a two-address instruction!");
1171 assert(MI.getOperand(0).getSubReg() == SubReg1 && "Tied subreg mismatch");
1172 Reg2IsKill = false;
1173 ChangeReg0 = true;
1174 }
1175
1176
1177 unsigned MB = MI.getOperand(4).getImm();
1178 unsigned ME = MI.getOperand(5).getImm();
1179
1180
1181
1182 if (MB == 0 && ME == 31)
1183 return nullptr;
1184
1185 if (NewMI) {
1186
1187 Register Reg0 = ChangeReg0 ? Reg2 : MI.getOperand(0).getReg();
1188 bool Reg0IsDead = MI.getOperand(0).isDead();
1189 return BuildMI(MF, MI.getDebugLoc(), MI.getDesc())
1193 .addImm((ME + 1) & 31)
1194 .addImm((MB - 1) & 31);
1195 }
1196
1197 if (ChangeReg0) {
1198 MI.getOperand(0).setReg(Reg2);
1199 MI.getOperand(0).setSubReg(SubReg2);
1200 }
1201 MI.getOperand(2).setReg(Reg1);
1202 MI.getOperand(1).setReg(Reg2);
1203 MI.getOperand(2).setSubReg(SubReg1);
1204 MI.getOperand(1).setSubReg(SubReg2);
1205 MI.getOperand(2).setIsKill(Reg1IsKill);
1206 MI.getOperand(1).setIsKill(Reg2IsKill);
1207
1208
1209 MI.getOperand(4).setImm((ME + 1) & 31);
1210 MI.getOperand(5).setImm((MB - 1) & 31);
1211 return &MI;
1212}
1213
1215 unsigned &SrcOpIdx1,
1216 unsigned &SrcOpIdx2) const {
1217
1218
1219
1220
1222 if (AltOpc == -1)
1224
1225
1226
1227 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1228}
1229
1232
1233
1234 unsigned Directive = Subtarget.getCPUDirective();
1235 unsigned Opcode;
1237 default: Opcode = PPC::NOP; break;
1238 case PPC::DIR_PWR6: Opcode = PPC::NOP_GT_PWR6; break;
1239 case PPC::DIR_PWR7: Opcode = PPC::NOP_GT_PWR7; break;
1240 case PPC::DIR_PWR8: Opcode = PPC::NOP_GT_PWR7; break;
1241
1242 case PPC::DIR_PWR9: Opcode = PPC::NOP_GT_PWR7; break;
1243 }
1244
1247}
1248
1249
1255
1256
1257
1258
1263 bool AllowModify) const {
1264 bool isPPC64 = Subtarget.isPPC64();
1265
1266
1269 return false;
1270
1271 if (!isUnpredicatedTerminator(*I))
1272 return false;
1273
1274 if (AllowModify) {
1275
1276
1277 if (I->getOpcode() == PPC::B &&
1278 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
1279 I->eraseFromParent();
1280
1281
1282 I = MBB.getLastNonDebugInstr();
1283 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
1284 return false;
1285 }
1286 }
1287
1288
1290
1291
1292 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
1293 if (LastInst.getOpcode() == PPC::B) {
1295 return true;
1297 return false;
1298 } else if (LastInst.getOpcode() == PPC::BCC) {
1300 return true;
1301
1305 return false;
1306 } else if (LastInst.getOpcode() == PPC::BC) {
1308 return true;
1309
1313 return false;
1314 } else if (LastInst.getOpcode() == PPC::BCn) {
1316 return true;
1317
1321 return false;
1322 } else if (LastInst.getOpcode() == PPC::BDNZ8 ||
1323 LastInst.getOpcode() == PPC::BDNZ) {
1325 return true;
1327 return true;
1331 true));
1332 return false;
1333 } else if (LastInst.getOpcode() == PPC::BDZ8 ||
1334 LastInst.getOpcode() == PPC::BDZ) {
1336 return true;
1338 return true;
1342 true));
1343 return false;
1344 }
1345
1346
1347 return true;
1348 }
1349
1350
1352
1353
1354 if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
1355 return true;
1356
1357
1358 if (SecondLastInst.getOpcode() == PPC::BCC &&
1359 LastInst.getOpcode() == PPC::B) {
1362 return true;
1367 return false;
1368 } else if (SecondLastInst.getOpcode() == PPC::BC &&
1369 LastInst.getOpcode() == PPC::B) {
1372 return true;
1377 return false;
1378 } else if (SecondLastInst.getOpcode() == PPC::BCn &&
1379 LastInst.getOpcode() == PPC::B) {
1382 return true;
1387 return false;
1388 } else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||
1389 SecondLastInst.getOpcode() == PPC::BDNZ) &&
1390 LastInst.getOpcode() == PPC::B) {
1393 return true;
1395 return true;
1399 true));
1401 return false;
1402 } else if ((SecondLastInst.getOpcode() == PPC::BDZ8 ||
1403 SecondLastInst.getOpcode() == PPC::BDZ) &&
1404 LastInst.getOpcode() == PPC::B) {
1407 return true;
1409 return true;
1413 true));
1415 return false;
1416 }
1417
1418
1419
1420 if (SecondLastInst.getOpcode() == PPC::B && LastInst.getOpcode() == PPC::B) {
1422 return true;
1424 I = LastInst;
1425 if (AllowModify)
1426 I->eraseFromParent();
1427 return false;
1428 }
1429
1430
1431 return true;
1432}
1433
1435 int *BytesRemoved) const {
1436 assert(!BytesRemoved && "code size not handled");
1437
1440 return 0;
1441
1442 if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&
1443 I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
1444 I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
1445 I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ)
1446 return 0;
1447
1448
1449 I->eraseFromParent();
1450
1452
1453 if (I == MBB.begin()) return 1;
1454 --I;
1455 if (I->getOpcode() != PPC::BCC &&
1456 I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
1457 I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
1458 I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ)
1459 return 1;
1460
1461
1462 I->eraseFromParent();
1463 return 2;
1464}
1465
1471 int *BytesAdded) const {
1472
1473 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1475 "PPC branch conditions have two components!");
1476 assert(!BytesAdded && "code size not handled");
1477
1478 bool isPPC64 = Subtarget.isPPC64();
1479
1480
1481 if (!FBB) {
1482 if (Cond.empty())
1486 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1487 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB);
1492 else
1497 return 1;
1498 }
1499
1500
1503 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1504 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB);
1509 else
1515 return 2;
1516}
1517
1518
1522 Register FalseReg, int &CondCycles,
1523 int &TrueCycles, int &FalseCycles) const {
1524 if (!Subtarget.hasISEL())
1525 return false;
1526
1527 if (Cond.size() != 2)
1528 return false;
1529
1530
1531
1533 return false;
1534
1535
1536
1538 return false;
1539
1540
1543 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
1544 if (!RC)
1545 return false;
1546
1547
1548 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1549 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1550 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1551 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1552 return false;
1553
1554
1555
1556
1557
1558 CondCycles = 1;
1559 TrueCycles = 1;
1560 FalseCycles = 1;
1561
1562 return true;
1563}
1564
1571 "PPC branch conditions have two components!");
1572
1573
1576 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
1577 assert(RC && "TrueReg and FalseReg must have overlapping register classes");
1578
1579 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1580 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1582 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1583 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1584 "isel is for regular integer GPRs only");
1585
1586 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1588
1589 unsigned SubIdx = 0;
1590 bool SwapOps = false;
1591 switch (SelectPred) {
1595 SubIdx = PPC::sub_eq; SwapOps = false; break;
1599 SubIdx = PPC::sub_eq; SwapOps = true; break;
1603 SubIdx = PPC::sub_lt; SwapOps = false; break;
1607 SubIdx = PPC::sub_lt; SwapOps = true; break;
1611 SubIdx = PPC::sub_gt; SwapOps = false; break;
1615 SubIdx = PPC::sub_gt; SwapOps = true; break;
1619 SubIdx = PPC::sub_un; SwapOps = false; break;
1623 SubIdx = PPC::sub_un; SwapOps = true; break;
1626 }
1627
1628 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1629 SecondReg = SwapOps ? TrueReg : FalseReg;
1630
1631
1632
1633
1634 if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
1635 MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
1637 MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
1638 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1639 Register OldFirstReg = FirstReg;
1640 FirstReg = MRI.createVirtualRegister(FirstRC);
1642 .addReg(OldFirstReg);
1643 }
1644
1648}
1649
1651 unsigned Ret = 4;
1652 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1653 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1654 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1655 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1656 Ret = 3;
1657 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1658 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1659 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1660 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1661 Ret = 2;
1662 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1663 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1664 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1665 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1666 Ret = 1;
1667 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1668 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1669 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1670 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1671 Ret = 0;
1672
1673 assert(Ret != 4 && "Invalid CR bit register");
1674 return Ret;
1675}
1676
1680 Register SrcReg, bool KillSrc,
1681 bool RenamableDest, bool RenamableSrc) const {
1682
1683
1685 if (PPC::F8RCRegClass.contains(DestReg) &&
1686 PPC::VSRCRegClass.contains(SrcReg)) {
1688 TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1689
1692
1693 DestReg = SuperReg;
1694 } else if (PPC::F8RCRegClass.contains(SrcReg) &&
1695 PPC::VSRCRegClass.contains(DestReg)) {
1697 TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1698
1701
1702 SrcReg = SuperReg;
1703 }
1704
1705
1706 if (PPC::CRBITRCRegClass.contains(SrcReg) &&
1707 PPC::GPRCRegClass.contains(DestReg)) {
1711
1712
1718 return;
1719 } else if (PPC::CRRCRegClass.contains(SrcReg) &&
1720 (PPC::G8RCRegClass.contains(DestReg) ||
1721 PPC::GPRCRegClass.contains(DestReg))) {
1722 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1723 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1724 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1725 unsigned CRNum = TRI->getEncodingValue(SrcReg);
1728 if (CRNum == 7)
1729 return;
1730
1733 .addImm(CRNum * 4 + 4)
1736 return;
1737 } else if (PPC::G8RCRegClass.contains(SrcReg) &&
1738 PPC::VSFRCRegClass.contains(DestReg)) {
1739 assert(Subtarget.hasDirectMove() &&
1740 "Subtarget doesn't support directmove, don't know how to copy.");
1742 NumGPRtoVSRSpill++;
1744 return;
1745 } else if (PPC::VSFRCRegClass.contains(SrcReg) &&
1746 PPC::G8RCRegClass.contains(DestReg)) {
1747 assert(Subtarget.hasDirectMove() &&
1748 "Subtarget doesn't support directmove, don't know how to copy.");
1751 return;
1752 } else if (PPC::SPERCRegClass.contains(SrcReg) &&
1753 PPC::GPRCRegClass.contains(DestReg)) {
1756 return;
1757 } else if (PPC::GPRCRegClass.contains(SrcReg) &&
1758 PPC::SPERCRegClass.contains(DestReg)) {
1761 return;
1762 } else if ((PPC::G8RCRegClass.contains(DestReg) ||
1763 PPC::GPRCRegClass.contains(DestReg)) &&
1764 SrcReg == PPC::CARRY) {
1765 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1766 BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MFSPR8 : PPC::MFSPR), DestReg)
1769 return;
1770 } else if ((PPC::G8RCRegClass.contains(SrcReg) ||
1771 PPC::GPRCRegClass.contains(SrcReg)) &&
1772 DestReg == PPC::CARRY) {
1773 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1774 BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MTSPR8 : PPC::MTSPR))
1778 return;
1779 }
1780
1781 unsigned Opc;
1782 if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
1783 Opc = PPC::OR;
1784 else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))
1785 Opc = PPC::OR8;
1786 else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))
1787 Opc = PPC::FMR;
1788 else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))
1789 Opc = PPC::MCRF;
1790 else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))
1791 Opc = PPC::VOR;
1792 else if (PPC::VSRCRegClass.contains(DestReg, SrcReg))
1793
1794
1795
1796
1797
1798
1799
1800
1801 Opc = PPC::XXLOR;
1802 else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||
1803 PPC::VSSRCRegClass.contains(DestReg, SrcReg))
1804 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1805 else if (Subtarget.pairedVectorMemops() &&
1806 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1807 if (SrcReg > PPC::VSRp15)
1808 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1809 else
1810 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1811 if (DestReg > PPC::VSRp15)
1812 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1813 else
1814 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1819 return;
1820 }
1821 else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
1822 Opc = PPC::CROR;
1823 else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
1824 Opc = PPC::EVOR;
1825 else if ((PPC::ACCRCRegClass.contains(DestReg) ||
1826 PPC::UACCRCRegClass.contains(DestReg)) &&
1827 (PPC::ACCRCRegClass.contains(SrcReg) ||
1828 PPC::UACCRCRegClass.contains(SrcReg))) {
1829
1830
1831
1832
1834 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1835 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1837 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1839 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1840 if (SrcPrimed)
1842 for (unsigned Idx = 0; Idx < 4; Idx++)
1844 .addReg(VSLSrcReg + Idx)
1846 if (DestPrimed)
1848 if (SrcPrimed && !KillSrc)
1850 return;
1851 } else if (PPC::G8pRCRegClass.contains(DestReg) &&
1852 PPC::G8pRCRegClass.contains(SrcReg)) {
1853
1854 unsigned DestRegIdx = DestReg - PPC::G8p0;
1855 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1856 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1857 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1858 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1859 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1866 return;
1867 } else if ((PPC::WACCRCRegClass.contains(DestReg) ||
1868 PPC::WACC_HIRCRegClass.contains(DestReg)) &&
1869 (PPC::WACCRCRegClass.contains(SrcReg) ||
1870 PPC::WACC_HIRCRegClass.contains(SrcReg))) {
1871
1872 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1873 : PPC::DMXXEXTFDMR512_HI;
1874
1876 RS.enterBasicBlockEnd(MBB);
1877 RS.backward(std::next(I));
1878
1879 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass, I,
1880 false, 0,
1881 false);
1882
1883 RS.setRegUsed(TmpReg1);
1884 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass, I,
1885 false, 0,
1886 false);
1887
1892
1893 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1894 : PPC::DMXXINSTDMR512_HI;
1895
1899
1900 return;
1901 } else if (PPC::DMRRCRegClass.contains(DestReg) &&
1902 PPC::DMRRCRegClass.contains(SrcReg)) {
1903
1906
1907 return;
1908
1909 } else
1911
1913 if (MCID.getNumOperands() == 3)
1916 else
1918}
1919
1920unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
1922
1923 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1924 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1926 } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1927 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1929 } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1931 } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1933 } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1935 } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1937 } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1939 } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1941 } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1943 } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1945 } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1947 } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1949 } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1950 assert(Subtarget.pairedVectorMemops() &&
1951 "Register unexpected when paired memops are disabled.");
1953 } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1954 assert(Subtarget.pairedVectorMemops() &&
1955 "Register unexpected when paired memops are disabled.");
1957 } else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1958 assert(Subtarget.pairedVectorMemops() &&
1959 "Register unexpected when paired memops are disabled.");
1961 } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1962 assert(Subtarget.pairedVectorMemops() &&
1963 "Register unexpected when paired memops are disabled.");
1965 } else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1967 } else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1969 } else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1970 llvm_unreachable("TODO: Implement spill DMRROWp regclass!");
1971 } else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1973 } else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1975 } else {
1977 }
1979}
1980
1981unsigned
1983 ArrayRef OpcodesForSpill = getStoreOpcodesForSpillArray();
1984 return OpcodesForSpill[getSpillIndex(RC)];
1985}
1986
1987unsigned
1990 return OpcodesForSpill[getSpillIndex(RC)];
1991}
1992
1993void PPCInstrInfo::StoreRegToStackSlot(
1994 MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,
1999
2002
2005 FrameIdx));
2006
2007 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
2008 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2010
2013}
2014
2020
2021 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2022
2025
2031 NewMIs.back()->addMemOperand(MF, MMO);
2032}
2033
2038
2039
2040
2041
2042
2043
2044
2047}
2048
2050 unsigned DestReg, int FrameIdx,
2053 const {
2056 FrameIdx));
2057}
2058
2065 if (MI != MBB.end()) DL = MI->getDebugLoc();
2066
2067 LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);
2068
2071
2077 NewMIs.back()->addMemOperand(MF, MMO);
2078}
2079
2082 Register DestReg, int FrameIdx,
2086
2087
2088
2089
2090
2091
2092
2094
2096}
2097
2100 assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
2103 else
2104
2106 return false;
2107}
2108
2109
2110
2111
2114
2115 unsigned DefOpc = DefMI.getOpcode();
2116 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2117 return false;
2118 if (.getOperand(1).isImm())
2119 return false;
2120 if (DefMI.getOperand(1).getImm() != 0)
2121 return false;
2122
2123
2124
2125
2126
2128
2129
2131 return false;
2132
2133
2134
2135 unsigned UseIdx;
2136 for (UseIdx = 0; UseIdx < UseMI.getNumOperands(); ++UseIdx)
2137 if (UseMI.getOperand(UseIdx).isReg() &&
2138 UseMI.getOperand(UseIdx).getReg() == Reg)
2139 break;
2140
2141 assert(UseIdx < UseMI.getNumOperands() && "Cannot find Reg in UseMI");
2142 assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");
2143
2144
2145
2146
2148 int16_t RegClass = getOpRegClassID(UseInfo);
2149 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2150 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2151 return false;
2152
2153
2154
2155
2156 if (UseInfo.Constraints != 0)
2157 return false;
2158
2160 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2161
2162 LLVM_DEBUG(dbgs() << "Folded immediate zero for: ");
2164 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2167 return true;
2168}
2169
2170
2171
2172
2176 if (MRI->use_nodbg_empty(Reg))
2177 DefMI.eraseFromParent();
2179}
2180
2183 if (MI.definesRegister(PPC::CTR, nullptr) ||
2184 MI.definesRegister(PPC::CTR8, nullptr))
2185 return true;
2186 return false;
2187}
2188
2189
2190
2191
2192
2193
2194
2196 unsigned NumT, unsigned ExtraT,
2198 unsigned NumF, unsigned ExtraF,
2201}
2202
2203
2205
2206
2207
2208
2209
2210
2211
2212 return false;
2213}
2214
2218 switch (MI.getOpcode()) {
2219 default:
2220 break;
2221
2222
2223
2224 case PPC::MFFS:
2225 case PPC::MTFSF:
2226 case PPC::FENCE:
2227 return true;
2228 }
2230}
2231
2234 unsigned OpC = MI.getOpcode();
2235 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2236 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
2237 bool isPPC64 = Subtarget.isPPC64();
2238 MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2239 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2240
2245 MI.setDesc(get(PPC::BCLR));
2248 MI.setDesc(get(PPC::BCLRn));
2250 } else {
2251 MI.setDesc(get(PPC::BCCLR));
2254 .add(Pred[1]);
2255 }
2256
2257 return true;
2258 } else if (OpC == PPC::B) {
2259 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
2260 bool isPPC64 = Subtarget.isPPC64();
2261 MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2262 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2263
2269 MI.removeOperand(0);
2270
2271 MI.setDesc(get(PPC::BC));
2273 .add(Pred[1])
2277 MI.removeOperand(0);
2278
2279 MI.setDesc(get(PPC::BCn));
2281 .add(Pred[1])
2283 } else {
2285 MI.removeOperand(0);
2286
2287 MI.setDesc(get(PPC::BCC));
2290 .add(Pred[1])
2292 }
2293
2294 return true;
2295 } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2296 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2297 OpC == PPC::BCTRL8_RM) {
2298 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)
2299 llvm_unreachable("Cannot predicate bctr[l] on the ctr register");
2300
2301 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2302 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2303 bool isPPC64 = Subtarget.isPPC64();
2304
2306 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2307 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2310 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2311 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2313 } else {
2314 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2315 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2318 .add(Pred[1]);
2319 }
2320
2321
2322 if (setLR)
2326 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2329
2330 return true;
2331 }
2332
2333 return false;
2334}
2335
2338 assert(Pred1.size() == 2 && "Invalid PPC first predicate");
2339 assert(Pred2.size() == 2 && "Invalid PPC second predicate");
2340
2341 if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)
2342 return false;
2343 if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)
2344 return false;
2345
2346
2348 return false;
2349
2352
2353 if (P1 == P2)
2354 return true;
2355
2356
2359 return true;
2362 return true;
2363
2364 return false;
2365}
2366
2368 std::vector &Pred,
2369 bool SkipDead) const {
2370
2371
2372
2373
2374
2375
2377 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2378 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2379
2380 bool Found = false;
2382 for (unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2384 if (MO.isReg()) {
2385 if (MO.isDef() && RC->contains(MO.getReg())) {
2386 Pred.push_back(MO);
2387 Found = true;
2388 }
2389 } else if (MO.isRegMask()) {
2391 if (MO.clobbersPhysReg(R)) {
2392 Pred.push_back(MO);
2393 Found = true;
2394 }
2395 }
2396 }
2397 }
2398
2399 return Found;
2400}
2401
2403 Register &SrcReg2, int64_t &Mask,
2404 int64_t &Value) const {
2405 unsigned Opc = MI.getOpcode();
2406
2407 switch (Opc) {
2408 default: return false;
2409 case PPC::CMPWI:
2410 case PPC::CMPLWI:
2411 case PPC::CMPDI:
2412 case PPC::CMPLDI:
2413 SrcReg = MI.getOperand(1).getReg();
2414 SrcReg2 = 0;
2415 Value = MI.getOperand(2).getImm();
2416 Mask = 0xFFFF;
2417 return true;
2418 case PPC::CMPW:
2419 case PPC::CMPLW:
2420 case PPC::CMPD:
2421 case PPC::CMPLD:
2422 case PPC::FCMPUS:
2423 case PPC::FCMPUD:
2424 SrcReg = MI.getOperand(1).getReg();
2425 SrcReg2 = MI.getOperand(2).getReg();
2427 Mask = 0;
2428 return true;
2429 }
2430}
2431
2433 Register SrcReg2, int64_t Mask,
2437 return false;
2438
2441
2442
2443
2444 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2445 return false;
2446
2448
2449
2450
2451
2452
2453
2454
2455
2456 bool isPPC64 = Subtarget.isPPC64();
2457 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2458 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2459 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2460
2461
2462 Register ActualSrc = TRI->lookThruCopyLike(SrcReg, MRI);
2464 SrcReg = ActualSrc;
2465
2466
2468 if () return false;
2469
2470 bool equalityOnly = false;
2471 bool noSub = false;
2472 if (isPPC64) {
2473 if (is32BitSignedCompare) {
2474
2476 noSub = true;
2477 else
2478 return false;
2479 } else if (is32BitUnsignedCompare) {
2480
2481
2483 noSub = true;
2484 equalityOnly = true;
2485 } else
2486 return false;
2487 } else
2488 equalityOnly = is64BitUnsignedCompare;
2489 } else
2490 equalityOnly = is32BitUnsignedCompare;
2491
2492 if (equalityOnly) {
2493
2494
2496 I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
2499 if (UseMI->getOpcode() == PPC::BCC) {
2502
2504 return false;
2505 } else if (UseMI->getOpcode() == PPC::ISEL ||
2506 UseMI->getOpcode() == PPC::ISEL8) {
2507 unsigned SubIdx = UseMI->getOperand(3).getSubReg();
2508 if (SubIdx != PPC::sub_eq)
2509 return false;
2510 } else
2511 return false;
2512 }
2513 }
2514
2516
2517
2519 ++I) {
2520 bool FoundUse = false;
2522 J = MRI->use_instr_begin(CRReg), JE = MRI->use_instr_end();
2523 J != JE; ++J)
2524 if (&*J == &*I) {
2525 FoundUse = true;
2526 break;
2527 }
2528
2529 if (FoundUse)
2530 break;
2531 }
2532
2535
2536
2537
2538
2540 if (SrcReg2 != 0)
2541
2542 MI = nullptr;
2543
2544
2545
2546
2547 else if (MI->getParent() != CmpInstr.getParent())
2548 return false;
2549 else if (Value != 0) {
2550
2551
2552
2553
2554
2555
2556
2557
2558 if (equalityOnly || ->hasOneUse(CRReg))
2559 return false;
2560
2562 if (UseMI->getOpcode() != PPC::BCC)
2563 return false;
2564
2568 int16_t Immed = (int16_t)Value;
2569
2570
2571
2572 if (Immed == -1 && PredCond == PPC::PRED_GT)
2573
2574
2576 else if (Immed == -1 && PredCond == PPC::PRED_LE)
2577
2579 else if (Immed == 1 && PredCond == PPC::PRED_LT)
2580
2582 else if (Immed == 1 && PredCond == PPC::PRED_GE)
2583
2585 else
2586 return false;
2587
2588
2589
2590
2591
2592 UseMI->getOperand(0).setImm(Pred);
2594 }
2595
2596
2597 --I;
2598
2599
2601
2602 for (; I != E && !noSub; --I) {
2604 unsigned IOpC = Instr.getOpcode();
2605
2606 if (&*I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, TRI) ||
2607 Instr.readsRegister(PPC::CR0, TRI)))
2608
2609
2610
2611
2612
2613 return false;
2614
2615
2616 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2617 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2618 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2619 ((Instr.getOperand(1).getReg() == SrcReg &&
2620 Instr.getOperand(2).getReg() == SrcReg2) ||
2621 (Instr.getOperand(1).getReg() == SrcReg2 &&
2622 Instr.getOperand(2).getReg() == SrcReg))) {
2624 break;
2625 }
2626
2628
2629 return false;
2630 }
2631
2632
2633 if ( &&
)
2634 return false;
2635
2636
2638
2639 int NewOpC = -1;
2640 int MIOpC = MI->getOpcode();
2641 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2642 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2643 NewOpC = MIOpC;
2644 else {
2645 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2647 NewOpC = MIOpC;
2648 }
2649
2650
2651
2652
2653
2654
2655
2656 if (NewOpC == -1)
2657 return false;
2658
2659
2660
2661
2662
2663 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2665 return false;
2666
2667
2668
2669
2670
2671
2672
2673 bool ShouldSwap = false;
2675 ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
2676 Sub->getOperand(2).getReg() == SrcReg;
2677
2678
2679
2680 ShouldSwap = !ShouldSwap;
2681 }
2682
2683 if (ShouldSwap)
2685 I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
2688 if (UseMI->getOpcode() == PPC::BCC) {
2691 assert((!equalityOnly ||
2693 "Invalid predicate for equality-only optimization");
2694 (void)PredCond;
2695 PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
2697 } else if (UseMI->getOpcode() == PPC::ISEL ||
2698 UseMI->getOpcode() == PPC::ISEL8) {
2699 unsigned NewSubReg = UseMI->getOperand(3).getSubReg();
2700 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2701 "Invalid CR bit for equality-only optimization");
2702
2703 if (NewSubReg == PPC::sub_lt)
2704 NewSubReg = PPC::sub_gt;
2705 else if (NewSubReg == PPC::sub_gt)
2706 NewSubReg = PPC::sub_lt;
2707
2708 SubRegsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(3)),
2709 NewSubReg));
2710 } else
2711 return false;
2712 }
2714 "Non-zero immediate support and ShouldSwap"
2715 "may conflict in updating predicate");
2716
2717
2718
2719
2721
2723 BuildMI(*MI->getParent(), std::next(MII), MI->getDebugLoc(),
2724 get(TargetOpcode::COPY), CRReg)
2726
2727
2728
2729 MI->clearRegisterDeads(PPC::CR0);
2730
2731 if (MIOpC != NewOpC) {
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2742 Register GPRRes = MI->getOperand(0).getReg();
2743 int64_t SH = MI->getOperand(2).getImm();
2744 int64_t MB = MI->getOperand(3).getImm();
2745 int64_t ME = MI->getOperand(4).getImm();
2746
2747
2748 bool MBInLoHWord = MB >= 16;
2749 bool MEInLoHWord = ME >= 16;
2751
2752 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2753 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2754
2755 Mask >>= MBInLoHWord ? 0 : 16;
2756 NewOpC = MIOpC == PPC::RLWINM
2757 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2758 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2759 } else if (MRI->use_empty(GPRRes) && (ME == 31) &&
2760 (ME - MB + 1 == SH) && (MB >= 16)) {
2761
2762
2763
2764 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2765 Mask >>= 16;
2766 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2767 }
2768
2769 if (Mask != ~0LLU) {
2770 MI->removeOperand(4);
2771 MI->removeOperand(3);
2772 MI->getOperand(2).setImm(Mask);
2773 NumRcRotatesConvertedToRcAnd++;
2774 }
2775 } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {
2776 int64_t MB = MI->getOperand(3).getImm();
2777 if (MB >= 48) {
2778 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2779 NewOpC = PPC::ANDI8_rec;
2780 MI->removeOperand(3);
2781 MI->getOperand(2).setImm(Mask);
2782 NumRcRotatesConvertedToRcAnd++;
2783 }
2784 }
2785
2787 MI->setDesc(NewDesc);
2788
2790 if (->definesRegister(ImpDef, nullptr)) {
2791 MI->addOperand(*MI->getParent()->getParent(),
2793 }
2794 }
2796 if (->readsRegister(ImpUse, nullptr)) {
2797 MI->addOperand(*MI->getParent()->getParent(),
2799 }
2800 }
2801 }
2802 assert(MI->definesRegister(PPC::CR0, nullptr) &&
2803 "Record-form instruction does not define cr0?");
2804
2805
2806
2807
2808 for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)
2809 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2810
2811 for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)
2812 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2813
2814 return true;
2815}
2816
2819 if (MRI->isSSA())
2820 return false;
2821
2823 int64_t CmpMask, CmpValue;
2824 if ((CmpMI, SrcReg, SrcReg2, CmpMask, CmpValue))
2825 return false;
2826
2827
2828 if (CmpValue || !CmpMask || SrcReg2)
2829 return false;
2830
2831
2832
2833
2834
2836 if (Opc == PPC::CMPLWI || Opc == PPC::CMPLDI)
2837 return false;
2838
2839
2840
2841
2842
2843 if (Subtarget.isPPC64() && Opc == PPC::CMPWI)
2844 return false;
2845
2846
2848 return false;
2849
2850 bool SrcRegHasOtherUse = false;
2852 if (!SrcMI || !SrcMI->definesRegister(SrcReg, nullptr))
2853 return false;
2854
2857 if (CRReg != PPC::CR0)
2858 return false;
2859
2860
2861 bool SeenUseOfCRReg = false;
2862 bool IsCRRegKilled = false;
2863 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI, false, IsCRRegKilled,
2864 SeenUseOfCRReg) ||
2865 SrcMI->definesRegister(CRReg, nullptr) || SeenUseOfCRReg)
2866 return false;
2867
2868 int SrcMIOpc = SrcMI->getOpcode();
2869 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2870 if (NewOpC == -1)
2871 return false;
2872
2875
2877 SrcMI->setDesc(NewDesc);
2881
2883 "Record-form instruction does not define cr0?");
2884
2889 return true;
2890}
2891
2897 OffsetIsScalable = false;
2899 return false;
2901 return true;
2902}
2903
2906
2908 return false;
2909
2911 return true;
2912
2914
2915
2917 return false;
2918
2919 return true;
2920}
2921
2922
2923
2926 switch (FirstOpc) {
2927 default:
2928 return false;
2929 case PPC::STD:
2930 case PPC::STFD:
2931 case PPC::STXSD:
2932 case PPC::DFSTOREf64:
2933 return FirstOpc == SecondOpc;
2934
2935
2936
2937 case PPC::STW:
2938 case PPC::STW8:
2939 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2940 }
2941}
2942
2946 int64_t OpOffset2, bool OffsetIsScalable2, unsigned ClusterSize,
2947 unsigned NumBytes) const {
2948
2949 assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);
2953 "Only base registers and frame indices are supported.");
2954
2955
2956
2957
2958 if (ClusterSize > 2)
2959 return false;
2960
2961
2962
2963 if ((BaseOp1.isReg() != BaseOp2.isReg()) ||
2966 return false;
2967
2968
2969
2972 unsigned FirstOpc = FirstLdSt.getOpcode();
2973 unsigned SecondOpc = SecondLdSt.getOpcode();
2975
2976
2978 return false;
2979
2980
2983 return false;
2984
2985 int64_t Offset1 = 0, Offset2 = 0;
2988 const MachineOperand *Base1 = nullptr, *Base2 = nullptr;
2991 Width1 != Width2)
2992 return false;
2993
2994 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2995 "getMemOperandWithOffsetWidth return incorrect base op");
2996
2997 assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");
2998 return Offset1 + (int64_t)Width1.getValue() == Offset2;
2999}
3000
3001
3002
3003
3005 unsigned Opcode = MI.getOpcode();
3006
3007 if (Opcode == PPC::INLINEASM || Opcode == PPC::INLINEASM_BR) {
3009 const char *AsmStr = MI.getOperand(0).getSymbolName();
3011 } else if (Opcode == TargetOpcode::STACKMAP) {
3014 } else if (Opcode == TargetOpcode::PATCHPOINT) {
3017 } else {
3018 return get(Opcode).getSize();
3019 }
3020}
3021
3022std::pair<unsigned, unsigned>
3024
3025 return std::make_pair(TF, 0u);
3026}
3027
3030 using namespace PPCII;
3031 static const std::pair<unsigned, const char *> TargetFlags[] = {
3032 {MO_PLT, "ppc-plt"},
3033 {MO_PIC_FLAG, "ppc-pic"},
3034 {MO_PCREL_FLAG, "ppc-pcrel"},
3035 {MO_GOT_FLAG, "ppc-got"},
3036 {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
3037 {MO_TLSGD_FLAG, "ppc-tlsgd"},
3038 {MO_TPREL_FLAG, "ppc-tprel"},
3039 {MO_TLSLDM_FLAG, "ppc-tlsldm"},
3040 {MO_TLSLD_FLAG, "ppc-tlsld"},
3041 {MO_TLSGDM_FLAG, "ppc-tlsgdm"},
3042 {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
3043 {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
3044 {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"},
3045 {MO_LO, "ppc-lo"},
3046 {MO_HA, "ppc-ha"},
3047 {MO_TPREL_LO, "ppc-tprel-lo"},
3048 {MO_TPREL_HA, "ppc-tprel-ha"},
3049 {MO_DTPREL_LO, "ppc-dtprel-lo"},
3050 {MO_TLSLD_LO, "ppc-tlsld-lo"},
3051 {MO_TOC_LO, "ppc-toc-lo"},
3052 {MO_TLS, "ppc-tls"},
3053 {MO_PIC_HA_FLAG, "ppc-ha-pic"},
3054 {MO_PIC_LO_FLAG, "ppc-lo-pic"},
3055 {MO_TPREL_PCREL_FLAG, "ppc-tprel-pcrel"},
3056 {MO_TLS_PCREL_FLAG, "ppc-tls-pcrel"},
3057 {MO_GOT_PCREL_FLAG, "ppc-got-pcrel"},
3058 };
3059 return ArrayRef(TargetFlags);
3060}
3061
3062
3063
3064
3065
3066
3067
3069 unsigned UpperOpcode, LowerOpcode;
3070 switch (MI.getOpcode()) {
3071 case PPC::DFLOADf32:
3072 UpperOpcode = PPC::LXSSP;
3073 LowerOpcode = PPC::LFS;
3074 break;
3075 case PPC::DFLOADf64:
3076 UpperOpcode = PPC::LXSD;
3077 LowerOpcode = PPC::LFD;
3078 break;
3079 case PPC::DFSTOREf32:
3080 UpperOpcode = PPC::STXSSP;
3081 LowerOpcode = PPC::STFS;
3082 break;
3083 case PPC::DFSTOREf64:
3084 UpperOpcode = PPC::STXSD;
3085 LowerOpcode = PPC::STFD;
3086 break;
3087 case PPC::XFLOADf32:
3088 UpperOpcode = PPC::LXSSPX;
3089 LowerOpcode = PPC::LFSX;
3090 break;
3091 case PPC::XFLOADf64:
3092 UpperOpcode = PPC::LXSDX;
3093 LowerOpcode = PPC::LFDX;
3094 break;
3095 case PPC::XFSTOREf32:
3096 UpperOpcode = PPC::STXSSPX;
3097 LowerOpcode = PPC::STFSX;
3098 break;
3099 case PPC::XFSTOREf64:
3100 UpperOpcode = PPC::STXSDX;
3101 LowerOpcode = PPC::STFDX;
3102 break;
3103 case PPC::LIWAX:
3104 UpperOpcode = PPC::LXSIWAX;
3105 LowerOpcode = PPC::LFIWAX;
3106 break;
3107 case PPC::LIWZX:
3108 UpperOpcode = PPC::LXSIWZX;
3109 LowerOpcode = PPC::LFIWZX;
3110 break;
3111 case PPC::STIWX:
3112 UpperOpcode = PPC::STXSIWX;
3113 LowerOpcode = PPC::STFIWX;
3114 break;
3115 default:
3117 }
3118
3119 Register TargetReg = MI.getOperand(0).getReg();
3120 unsigned Opcode;
3121 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3122 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3123 Opcode = LowerOpcode;
3124 else
3125 Opcode = UpperOpcode;
3127 return true;
3128}
3129
3133
3135 auto &MBB = *MI.getParent();
3136 auto DL = MI.getDebugLoc();
3137
3138 switch (MI.getOpcode()) {
3139 case PPC::BUILD_UACC: {
3141 MCRegister UACC = MI.getOperand(1).getReg();
3142 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3143 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3144 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3145
3146
3147
3148 for (int VecNo = 0; VecNo < 4; VecNo++)
3150 .addReg(SrcVSR + VecNo)
3151 .addReg(SrcVSR + VecNo);
3152 }
3153
3154
3155
3156 [[fallthrough]];
3157 }
3158 case PPC::KILL_PAIR: {
3159 MI.setDesc(get(PPC::UNENCODED_NOP));
3160 MI.removeOperand(1);
3161 MI.removeOperand(0);
3162 return true;
3163 }
3164 case TargetOpcode::LOAD_STACK_GUARD: {
3165 auto M = MBB.getParent()->getFunction().getParent();
3167 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() == "tls") &&
3168 "Only Linux target or tls mode are expected to contain "
3169 "LOAD_STACK_GUARD");
3171 if (M->getStackProtectorGuard() == "tls")
3172 Offset = M->getStackProtectorGuardOffset();
3173 else
3174 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3175 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3176 MI.setDesc(get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3180 return true;
3181 }
3182 case PPC::PPCLdFixedAddr: {
3183 assert((Subtarget.getTargetTriple().isOSGlibc() ||
3184 Subtarget.getTargetTriple().isMusl()) &&
3185 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3187 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3188 MI.setDesc(get(PPC::LWZ));
3189 uint64_t FAType = MI.getOperand(1).getImm();
3190#undef PPC_LNX_FEATURE
3191#undef PPC_CPU
3192#define PPC_LNX_DEFINE_OFFSETS
3193#include "llvm/TargetParser/PPCTargetParser.def"
3194 bool IsLE = Subtarget.isLittleEndian();
3195 bool Is64 = Subtarget.isPPC64();
3196 if (FAType == PPC_FAWORD_HWCAP) {
3197 if (IsLE)
3198 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3199 else
3200 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3201 } else if (FAType == PPC_FAWORD_HWCAP2) {
3202 if (IsLE)
3203 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3204 else
3205 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3206 } else if (FAType == PPC_FAWORD_CPUID) {
3207 if (IsLE)
3208 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3209 else
3210 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3211 }
3212 assert(Offset && "Do not know the offset for this fixed addr load");
3213 MI.removeOperand(1);
3214 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3218 return true;
3219#define PPC_TGT_PARSER_UNDEF_MACROS
3220#include "llvm/TargetParser/PPCTargetParser.def"
3221#undef PPC_TGT_PARSER_UNDEF_MACROS
3222 }
3223 case PPC::DFLOADf32:
3224 case PPC::DFLOADf64:
3225 case PPC::DFSTOREf32:
3226 case PPC::DFSTOREf64: {
3227 assert(Subtarget.hasP9Vector() &&
3228 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3229 assert(MI.getOperand(2).isReg() &&
3231 "D-form op must have register and immediate operands");
3233 }
3234 case PPC::XFLOADf32:
3235 case PPC::XFSTOREf32:
3236 case PPC::LIWAX:
3237 case PPC::LIWZX:
3238 case PPC::STIWX: {
3239 assert(Subtarget.hasP8Vector() &&
3240 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3241 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
3242 "X-form op must have register and register operands");
3244 }
3245 case PPC::XFLOADf64:
3246 case PPC::XFSTOREf64: {
3247 assert(Subtarget.hasVSX() &&
3248 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3249 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
3250 "X-form op must have register and register operands");
3252 }
3253 case PPC::SPILLTOVSR_LD: {
3254 Register TargetReg = MI.getOperand(0).getReg();
3255 if (PPC::VSFRCRegClass.contains(TargetReg)) {
3256 MI.setDesc(get(PPC::DFLOADf64));
3258 }
3259 else
3260 MI.setDesc(get(PPC::LD));
3261 return true;
3262 }
3263 case PPC::SPILLTOVSR_ST: {
3264 Register SrcReg = MI.getOperand(0).getReg();
3265 if (PPC::VSFRCRegClass.contains(SrcReg)) {
3266 NumStoreSPILLVSRRCAsVec++;
3267 MI.setDesc(get(PPC::DFSTOREf64));
3269 } else {
3270 NumStoreSPILLVSRRCAsGpr++;
3271 MI.setDesc(get(PPC::STD));
3272 }
3273 return true;
3274 }
3275 case PPC::SPILLTOVSR_LDX: {
3276 Register TargetReg = MI.getOperand(0).getReg();
3277 if (PPC::VSFRCRegClass.contains(TargetReg))
3278 MI.setDesc(get(PPC::LXSDX));
3279 else
3280 MI.setDesc(get(PPC::LDX));
3281 return true;
3282 }
3283 case PPC::SPILLTOVSR_STX: {
3284 Register SrcReg = MI.getOperand(0).getReg();
3285 if (PPC::VSFRCRegClass.contains(SrcReg)) {
3286 NumStoreSPILLVSRRCAsVec++;
3287 MI.setDesc(get(PPC::STXSDX));
3288 } else {
3289 NumStoreSPILLVSRRCAsGpr++;
3290 MI.setDesc(get(PPC::STDX));
3291 }
3292 return true;
3293 }
3294
3295
3296 case PPC::CFENCE:
3297 case PPC::CFENCE8: {
3298 auto Val = MI.getOperand(0).getReg();
3299 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3305 MI.setDesc(get(PPC::ISYNC));
3306 MI.removeOperand(0);
3307 return true;
3308 }
3309 }
3310 return false;
3311}
3312
3313
3314
3315
3316
3317static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
3318 unsigned TrueReg, unsigned FalseReg,
3319 unsigned CRSubReg) {
3320
3321 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3322 switch (CRSubReg) {
3323 default: llvm_unreachable("Unknown integer comparison type.");
3324 case PPC::sub_lt:
3325 return Imm1 < Imm2 ? TrueReg : FalseReg;
3326 case PPC::sub_gt:
3327 return Imm1 > Imm2 ? TrueReg : FalseReg;
3328 case PPC::sub_eq:
3329 return Imm1 == Imm2 ? TrueReg : FalseReg;
3330 }
3331 }
3332
3333 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3334 switch (CRSubReg) {
3335 default: llvm_unreachable("Unknown integer comparison type.");
3336 case PPC::sub_lt:
3337 return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
3338 case PPC::sub_gt:
3339 return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
3340 case PPC::sub_eq:
3341 return Imm1 == Imm2 ? TrueReg : FalseReg;
3342 }
3343 }
3344 return PPC::NoRegister;
3345}
3346
3348 unsigned OpNo,
3349 int64_t Imm) const {
3350 assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");
3351
3352 Register InUseReg = MI.getOperand(OpNo).getReg();
3353 MI.getOperand(OpNo).ChangeToImmediate(Imm);
3354
3355
3356
3357
3358
3359
3361 int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, TRI, false);
3362 if (UseOpIdx >= 0) {
3365
3366
3367
3368
3369
3370
3371
3372 MI.removeOperand(UseOpIdx);
3373 }
3374}
3375
3376
3377
3380
3381 int OperandToKeep = LII.SetCR ? 1 : 0;
3382 for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
3383 MI.removeOperand(i);
3384
3385
3386 if (LII.SetCR) {
3387 MI.setDesc(get(LII.Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3388
3391 return;
3392 }
3393 else
3394 MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));
3395
3396
3399}
3400
3402 bool &SeenIntermediateUse) const {
3403 assert(.getParent()->getParent()->getRegInfo().isSSA() &&
3404 "Should be called after register allocation.");
3407 It++;
3408 SeenIntermediateUse = false;
3409 for (; It != E; ++It) {
3410 if (It->modifiesRegister(Reg, TRI))
3411 return &*It;
3412 if (It->readsRegister(Reg, TRI))
3413 SeenIntermediateUse = true;
3414 }
3415 return nullptr;
3416}
3417
3421 int64_t Imm) const {
3422 assert(.getParent()->getRegInfo().isSSA() &&
3423 "Register should be in non-SSA form after RA");
3424 bool isPPC64 = Subtarget.isPPC64();
3425
3426
3427
3433 if (Imm & 0xFFFF)
3436 .addImm(Imm & 0xFFFF);
3437 } else {
3438 assert(isPPC64 && "Materializing 64-bit immediate to single register is "
3439 "only supported in PPC64");
3441 if ((Imm >> 32) & 0xFFFF)
3444 .addImm((Imm >> 32) & 0xFFFF);
3451 .addImm((Imm >> 16) & 0xFFFF);
3452 if (Imm & 0xFFFF)
3455 .addImm(Imm & 0xFFFF);
3456 }
3457}
3458
3459MachineInstr *PPCInstrInfo::getForwardingDefMI(
3461 unsigned &OpNoForForwarding,
3462 bool &SeenIntermediateUse) const {
3463 OpNoForForwarding = ~0U;
3467
3468
3469
3470 if (MRI->isSSA()) {
3471 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
3472 if (.getOperand(i).isReg())
3473 continue;
3474 Register Reg = MI.getOperand(i).getReg();
3475 if (!Reg.isVirtual())
3476 continue;
3479 MachineInstr *DefMIForTrueReg = MRI->getVRegDef(TrueReg);
3480 if (DefMIForTrueReg->getOpcode() == PPC::LI ||
3481 DefMIForTrueReg->getOpcode() == PPC::LI8 ||
3482 DefMIForTrueReg->getOpcode() == PPC::ADDI ||
3483 DefMIForTrueReg->getOpcode() == PPC::ADDI8) {
3484 OpNoForForwarding = i;
3485 DefMI = DefMIForTrueReg;
3486
3487
3488
3489
3490 if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)
3491 break;
3492 }
3493 }
3494 }
3495 } else {
3496
3497
3498
3499 ImmInstrInfo III;
3500 unsigned Opc = MI.getOpcode();
3501 bool ConvertibleImmForm =
3502 Opc == PPC::CMPWI || Opc == PPC::CMPLWI || Opc == PPC::CMPDI ||
3503 Opc == PPC::CMPLDI || Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
3504 Opc == PPC::ORI || Opc == PPC::ORI8 || Opc == PPC::XORI ||
3505 Opc == PPC::XORI8 || Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec ||
3506 Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
3507 Opc == PPC::RLWINM || Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8 ||
3508 Opc == PPC::RLWINM8_rec;
3509 bool IsVFReg = (MI.getNumOperands() && MI.getOperand(0).isReg())
3512 if (!ConvertibleImmForm && (Opc, IsVFReg, III, true))
3513 return nullptr;
3514
3515
3516 if ((Opc == PPC::OR || Opc == PPC::OR8) &&
3517 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
3518 return nullptr;
3519 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
3520 MachineOperand &MO = MI.getOperand(i);
3521 SeenIntermediateUse = false;
3524
3525
3528
3529
3531 default:
3532 break;
3533 case PPC::LI:
3534 case PPC::LI8:
3535 case PPC::ADDItocL8:
3536 case PPC::ADDI:
3537 case PPC::ADDI8:
3538 OpNoForForwarding = i;
3540 }
3541 }
3542 }
3543 }
3544 }
3545 return OpNoForForwarding == ~0U ? nullptr : DefMI;
3546}
3547
3548unsigned PPCInstrInfo::getSpillTarget() const {
3549
3550
3551 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3552
3553 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3554 2 : Subtarget.hasP9Vector() ?
3555 1 : 0;
3556}
3557
3558ArrayRef PPCInstrInfo::getStoreOpcodesForSpillArray() const {
3560}
3561
3562ArrayRef PPCInstrInfo::getLoadOpcodesForSpillArray() const {
3564}
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3593 bool PostRA = ->isSSA();
3594
3595
3596
3597 if (!PostRA)
3598 return false;
3599 unsigned ToBeDeletedReg = 0;
3600 int64_t OffsetImm = 0;
3601 unsigned XFormOpcode = 0;
3603
3604
3606 III))
3607 return false;
3608
3609 bool OtherIntermediateUse = false;
3611
3612
3613 if (OtherIntermediateUse || !ADDMI)
3614 return false;
3615
3616
3618 return false;
3619
3620 unsigned ScaleRegIdx = 0;
3621 int64_t OffsetAddi = 0;
3623
3624
3625
3626
3627
3629 ScaleRegIdx = 2;
3631 ScaleRegIdx = 1;
3632 else
3633 return false;
3634
3635 assert(ADDIMI && "There should be ADDIMI for valid ToBeChangedReg.");
3640 for (auto It = ++Start; It != End; It++)
3642 return true;
3643 return false;
3644 };
3645
3646
3647
3649 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3650 return false;
3651
3652
3653
3654 if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI))
3655 return false;
3656
3657
3659 << "\n");
3664 << "\n");
3665
3666
3668
3669
3670 MI.setDesc(get(XFormOpcode));
3672 .ChangeToRegister(ScaleReg, false, false,
3674
3676 .ChangeToRegister(ToBeChangedReg, false, false, true);
3677
3678
3680
3683
3684 return true;
3685}
3686
3688 int64_t &Imm) const {
3690
3691
3692 if (Opc != PPC::ADDI && Opc != PPC::ADDI8)
3693 return false;
3694
3695
3697 return false;
3698
3700
3701 return true;
3702}
3703
3706
3707
3708 return Opc == PPC::ADD4 || Opc == PPC::ADD8;
3709}
3710
3712 unsigned &ToBeDeletedReg,
3713 unsigned &XFormOpcode,
3714 int64_t &OffsetImm,
3716
3717 if (.mayLoadOrStore())
3718 return false;
3719
3720 unsigned Opc = MI.getOpcode();
3721
3722 XFormOpcode = RI.getMappedIdxOpcForImmOpc(Opc);
3723
3724
3725 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3726 return false;
3727
3728
3731 return false;
3732
3734 return false;
3735
3738
3739 if (!ImmOperand.isImm())
3740 return false;
3741
3742 assert(RegOperand.isReg() && "Instruction format is not right");
3743
3744
3745 if (!RegOperand.isKill())
3746 return false;
3747
3748 ToBeDeletedReg = RegOperand.getReg();
3749 OffsetImm = ImmOperand.getImm();
3750
3751 return true;
3752}
3753
3756 int64_t &OffsetAddi,
3757 int64_t OffsetImm) const {
3758 assert((Index == 1 || Index == 2) && "Invalid operand index for add.");
3760
3762 return false;
3763
3764 bool OtherIntermediateUse = false;
3765
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785 if (OtherIntermediateUse || !ADDIMI)
3786 return false;
3787
3789 return false;
3790
3791 if (isInt<16>(OffsetAddi + OffsetImm))
3792 return true;
3793 return false;
3794}
3795
3796
3797
3798
3804 bool PostRA = ->isSSA();
3805 bool SeenIntermediateUse = true;
3806 unsigned ForwardingOperand = ~0U;
3808 SeenIntermediateUse);
3810 return false;
3811 assert(ForwardingOperand < MI.getNumOperands() &&
3812 "The forwarding operand needs to be valid at this point");
3813 bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
3814 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3815 if (KilledDef && KillFwdDefMI)
3816 *KilledDef = DefMI;
3817
3818
3819
3826
3827
3828
3829 if (RI.getMappedIdxOpcForImmOpc(MI.getOpcode()) !=
3830 PPC::INSTRUCTION_LIST_END &&
3831 transformToNewImmFormFedByAdd(MI, *DefMI, ForwardingOperand))
3832 return true;
3833
3835 bool IsVFReg = MI.getOperand(0).isReg()
3837 : false;
3838 bool HasImmForm = instrHasImmForm(MI.getOpcode(), IsVFReg, III, PostRA);
3839
3840
3841
3842 if (HasImmForm &&
3843 transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,
3844 KillFwdDefMI))
3845 return true;
3846
3847
3848
3849 if (HasImmForm &&
3850 transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))
3851 return true;
3852
3853
3854
3855 if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))
3856 return true;
3857
3858 return false;
3859}
3860
3864 Register FoldingReg = MI.getOperand(1).getReg();
3866 return false;
3868 if (SrcMI->getOpcode() != PPC::RLWINM &&
3869 SrcMI->getOpcode() != PPC::RLWINM_rec &&
3870 SrcMI->getOpcode() != PPC::RLWINM8 &&
3871 SrcMI->getOpcode() != PPC::RLWINM8_rec)
3872 return false;
3873 assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
3876 "Invalid PPC::RLWINM Instruction!");
3878 uint64_t SHMI = MI.getOperand(2).getImm();
3880 uint64_t MBMI = MI.getOperand(3).getImm();
3882 uint64_t MEMI = MI.getOperand(4).getImm();
3883
3884 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3885 "Invalid PPC::RLWINM Instruction!");
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3908
3909
3910 if ((MBMI > MEMI) && !SrcMaskFull)
3911 return false;
3912
3913
3915
3916
3917
3919
3920 APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
3921 APInt FinalMask = RotatedSrcMask & MaskMI;
3923 bool Simplified = false;
3924
3925
3926 if (FinalMask.isZero()) {
3927 bool Is64Bit =
3928 (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
3929 Simplified = true;
3932
3933 if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
3934
3935 MI.removeOperand(4);
3936 MI.removeOperand(3);
3937 MI.removeOperand(2);
3938 MI.getOperand(1).ChangeToImmediate(0);
3939 MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
3940 } else {
3941
3942 MI.removeOperand(4);
3943 MI.removeOperand(3);
3944 MI.getOperand(2).setImm(0);
3945 MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3948 MI.getOperand(1).setIsKill(true);
3950 } else
3951
3952 MI.getOperand(1).setIsKill(false);
3953 }
3954
3957
3959 NewMB <= NewME) ||
3960 SrcMaskFull) {
3961
3962
3963
3964 Simplified = true;
3967
3968 uint16_t NewSH = (SHSrc + SHMI) % 32;
3969 MI.getOperand(2).setImm(NewSH);
3970
3971 if (!SrcMaskFull) {
3972 MI.getOperand(3).setImm(NewMB);
3973 MI.getOperand(4).setImm(NewME);
3974 }
3977 MI.getOperand(1).setIsKill(true);
3979 } else
3980
3981 MI.getOperand(1).setIsKill(false);
3982
3985 }
3986 if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
3988
3989
3990
3991 *ToErase = SrcMI;
3994 }
3995 return Simplified;
3996}
3997
4000
4001
4002
4003
4010 switch (Opc) {
4011 default: return false;
4012 case PPC::ADD4:
4013 case PPC::ADD8:
4019 III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4020 break;
4021 case PPC::ADDC:
4022 case PPC::ADDC8:
4028 III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4029 break;
4030 case PPC::ADDC_rec:
4037 break;
4038 case PPC::SUBFC:
4039 case PPC::SUBFC8:
4044 III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4045 break;
4046 case PPC::CMPW:
4047 case PPC::CMPD:
4052 III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4053 break;
4054 case PPC::CMPLW:
4055 case PPC::CMPLD:
4060 III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4061 break;
4062 case PPC::AND_rec:
4063 case PPC::AND8_rec:
4064 case PPC::OR:
4065 case PPC::OR8:
4066 case PPC::XOR:
4067 case PPC::XOR8:
4072 switch(Opc) {
4074 case PPC::AND_rec:
4076 break;
4077 case PPC::AND8_rec:
4079 break;
4080 case PPC::OR: III.ImmOpcode = PPC::ORI; break;
4081 case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
4082 case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
4083 case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
4084 }
4085 break;
4086 case PPC::RLWNM:
4087 case PPC::RLWNM8:
4088 case PPC::RLWNM_rec:
4089 case PPC::RLWNM8_rec:
4090 case PPC::SLW:
4091 case PPC::SLW8:
4092 case PPC::SLW_rec:
4093 case PPC::SLW8_rec:
4094 case PPC::SRW:
4095 case PPC::SRW8:
4096 case PPC::SRW_rec:
4097 case PPC::SRW8_rec:
4098 case PPC::SRAW:
4099 case PPC::SRAW_rec:
4104
4105
4106
4107
4109 if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 || Opc == PPC::RLWNM_rec ||
4110 Opc == PPC::RLWNM8_rec)
4112 else
4114 switch(Opc) {
4116 case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
4117 case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
4118 case PPC::RLWNM_rec:
4119 III.ImmOpcode = PPC::RLWINM_rec;
4120 break;
4121 case PPC::RLWNM8_rec:
4122 III.ImmOpcode = PPC::RLWINM8_rec;
4123 break;
4124 case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
4125 case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
4126 case PPC::SLW_rec:
4127 III.ImmOpcode = PPC::RLWINM_rec;
4128 break;
4129 case PPC::SLW8_rec:
4130 III.ImmOpcode = PPC::RLWINM8_rec;
4131 break;
4132 case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
4133 case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
4134 case PPC::SRW_rec:
4135 III.ImmOpcode = PPC::RLWINM_rec;
4136 break;
4137 case PPC::SRW8_rec:
4138 III.ImmOpcode = PPC::RLWINM8_rec;
4139 break;
4140 case PPC::SRAW:
4144 break;
4145 case PPC::SRAW_rec:
4149 break;
4150 }
4151 break;
4152 case PPC::RLDCL:
4153 case PPC::RLDCL_rec:
4154 case PPC::RLDCR:
4155 case PPC::RLDCR_rec:
4156 case PPC::SLD:
4157 case PPC::SLD_rec:
4158 case PPC::SRD:
4159 case PPC::SRD_rec:
4160 case PPC::SRAD:
4161 case PPC::SRAD_rec:
4166
4167
4168
4169
4171 if (Opc == PPC::RLDCL || Opc == PPC::RLDCL_rec || Opc == PPC::RLDCR ||
4172 Opc == PPC::RLDCR_rec)
4174 else
4176 switch(Opc) {
4178 case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
4179 case PPC::RLDCL_rec:
4180 III.ImmOpcode = PPC::RLDICL_rec;
4181 break;
4182 case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
4183 case PPC::RLDCR_rec:
4184 III.ImmOpcode = PPC::RLDICR_rec;
4185 break;
4186 case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
4187 case PPC::SLD_rec:
4188 III.ImmOpcode = PPC::RLDICR_rec;
4189 break;
4190 case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
4191 case PPC::SRD_rec:
4192 III.ImmOpcode = PPC::RLDICL_rec;
4193 break;
4194 case PPC::SRAD:
4198 break;
4199 case PPC::SRAD_rec:
4203 break;
4204 }
4205 break;
4206
4207 case PPC::LBZX:
4208 case PPC::LBZX8:
4209 case PPC::LHZX:
4210 case PPC::LHZX8:
4211 case PPC::LHAX:
4212 case PPC::LHAX8:
4213 case PPC::LWZX:
4214 case PPC::LWZX8:
4215 case PPC::LWAX:
4216 case PPC::LDX:
4217 case PPC::LFSX:
4218 case PPC::LFDX:
4219 case PPC::STBX:
4220 case PPC::STBX8:
4221 case PPC::STHX:
4222 case PPC::STHX8:
4223 case PPC::STWX:
4224 case PPC::STWX8:
4225 case PPC::STDX:
4226 case PPC::STFSX:
4227 case PPC::STFDX:
4235 switch(Opc) {
4237 case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
4238 case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
4239 case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
4240 case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
4241 case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
4242 case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
4243 case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
4244 case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
4245 case PPC::LWAX:
4248 break;
4250 case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
4251 case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
4252 case PPC::STBX: III.ImmOpcode = PPC::STB; break;
4253 case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
4254 case PPC::STHX: III.ImmOpcode = PPC::STH; break;
4255 case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
4256 case PPC::STWX: III.ImmOpcode = PPC::STW; break;
4257 case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
4258 case PPC::STDX:
4261 break;
4262 case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
4263 case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
4264 }
4265 break;
4266 case PPC::LBZUX:
4267 case PPC::LBZUX8:
4268 case PPC::LHZUX:
4269 case PPC::LHZUX8:
4270 case PPC::LHAUX:
4271 case PPC::LHAUX8:
4272 case PPC::LWZUX:
4273 case PPC::LWZUX8:
4274 case PPC::LDUX:
4275 case PPC::LFSUX:
4276 case PPC::LFDUX:
4277 case PPC::STBUX:
4278 case PPC::STBUX8:
4279 case PPC::STHUX:
4280 case PPC::STHUX8:
4281 case PPC::STWUX:
4282 case PPC::STWUX8:
4283 case PPC::STDUX:
4284 case PPC::STFSUX:
4285 case PPC::STFDUX:
4293 switch(Opc) {
4295 case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
4296 case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
4297 case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
4298 case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
4299 case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
4300 case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
4301 case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
4302 case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
4303 case PPC::LDUX:
4306 break;
4307 case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
4308 case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
4309 case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
4310 case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
4311 case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
4312 case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
4313 case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
4314 case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
4315 case PPC::STDUX:
4318 break;
4319 case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
4320 case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
4321 }
4322 break;
4323
4324
4325
4326
4327 case PPC::LXVX:
4328 case PPC::LXSSPX:
4329 case PPC::LXSDX:
4330 case PPC::STXVX:
4331 case PPC::STXSSPX:
4332 case PPC::STXSDX:
4333 case PPC::XFLOADf32:
4334 case PPC::XFLOADf64:
4335 case PPC::XFSTOREf32:
4336 case PPC::XFSTOREf64:
4337 if (!Subtarget.hasP9Vector())
4338 return false;
4347 switch(Opc) {
4349 case PPC::LXVX:
4352 break;
4353 case PPC::LXSSPX:
4354 if (PostRA) {
4355 if (IsVFReg)
4357 else {
4360 }
4361 break;
4362 }
4363 [[fallthrough]];
4364 case PPC::XFLOADf32:
4366 break;
4367 case PPC::LXSDX:
4368 if (PostRA) {
4369 if (IsVFReg)
4371 else {
4374 }
4375 break;
4376 }
4377 [[fallthrough]];
4378 case PPC::XFLOADf64:
4380 break;
4381 case PPC::STXVX:
4384 break;
4385 case PPC::STXSSPX:
4386 if (PostRA) {
4387 if (IsVFReg)
4389 else {
4392 }
4393 break;
4394 }
4395 [[fallthrough]];
4396 case PPC::XFSTOREf32:
4397 III.ImmOpcode = PPC::DFSTOREf32;
4398 break;
4399 case PPC::STXSDX:
4400 if (PostRA) {
4401 if (IsVFReg)
4403 else {
4406 }
4407 break;
4408 }
4409 [[fallthrough]];
4410 case PPC::XFSTOREf64:
4411 III.ImmOpcode = PPC::DFSTOREf64;
4412 break;
4413 }
4414 break;
4415 }
4416 return true;
4417}
4418
4419
4421 assert(Op1 != Op2 && "Cannot swap operand with itself.");
4422
4423 unsigned MaxOp = std::max(Op1, Op2);
4424 unsigned MinOp = std::min(Op1, Op2);
4427 MI.removeOperand(std::max(Op1, Op2));
4428 MI.removeOperand(std::min(Op1, Op2));
4429
4430
4431
4432 if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
4433 MI.addOperand(MOp2);
4434 MI.addOperand(MOp1);
4435 } else {
4436
4437
4439 unsigned TotalOps = MI.getNumOperands() + 2;
4440 for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
4442 MI.removeOperand(i);
4443 }
4444
4445 MI.addOperand(MOp2);
4446
4447 for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
4448 if (i == MaxOp)
4449 MI.addOperand(MOp1);
4450 else {
4451 MI.addOperand(MOps.back());
4453 }
4454 }
4455 }
4456}
4457
4458
4459
4460bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
4462 unsigned OpNoForForwarding
4463 ) const {
4464
4465
4466 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4467 if (MRI.isSSA())
4468 return false;
4469
4470
4472 return false;
4473
4474
4476 return false;
4477
4478
4479
4481 return false;
4482
4483
4484
4487 return false;
4488
4489
4490
4491
4492
4493 return true;
4494}
4495
4496
4497
4498bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
4502 unsigned Opc = DefMI.getOpcode();
4503 if (Opc != PPC::ADDItocL8 && Opc != PPC::ADDI && Opc != PPC::ADDI8)
4504 return false;
4505
4506
4507
4508
4509 if (Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4510 return false;
4511
4513 "Add inst must have at least three operands");
4514 RegMO = &DefMI.getOperand(1);
4515 ImmMO = &DefMI.getOperand(2);
4516
4517
4518 if (!RegMO->isReg())
4519 return false;
4520
4521
4522
4523
4525}
4526
4527bool PPCInstrInfo::isRegElgibleForForwarding(
4530 bool &IsFwdFeederRegKilled, bool &SeenIntermediateUse) const {
4531
4532
4533
4534
4535
4536
4537 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4538 if (MRI.isSSA())
4539 return false;
4540
4542
4543
4546 It++;
4547 for (; It != E; ++It) {
4549 return false;
4551 IsFwdFeederRegKilled = true;
4553 SeenIntermediateUse = true;
4554
4555 if ((&*It) == &DefMI)
4556 break;
4557 }
4558 assert((&*It) == &DefMI && "DefMI is missing");
4559
4560
4561
4563 return KillDefMI;
4564
4565 return true;
4566}
4567
4568bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
4571 int64_t &Imm,
4572 int64_t BaseImm) const {
4574 if (DefMI.getOpcode() == PPC::ADDItocL8) {
4575
4576
4577
4580 return false;
4581
4582
4583
4584
4585
4589 return false;
4590 }
4591
4592 return true;
4593 }
4594
4595 if (ImmMO.isImm()) {
4596
4597
4598
4599
4600 APInt ActualValue(64, ImmMO.getImm() + BaseImm, true);
4602 return false;
4604 return false;
4606
4608 return false;
4611 }
4612 else
4613 return false;
4614
4615
4616
4617 return true;
4618}
4619
4621 unsigned OpNoForForwarding,
4623 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
4624 .getOperand(1).isImm())
4625 return false;
4626
4627 MachineFunction *MF = MI.getParent()->getParent();
4630
4631 int64_t Immediate = DefMI.getOperand(1).getImm();
4632
4634
4635 bool ReplaceWithLI = false;
4636 bool Is64BitLI = false;
4637 int64_t NewImm = 0;
4638 bool SetCR = false;
4639 unsigned Opc = MI.getOpcode();
4640 switch (Opc) {
4641 default:
4642 return false;
4643
4644
4645
4646
4647
4648 case PPC::CMPWI:
4649 case PPC::CMPLWI:
4650 case PPC::CMPDI:
4651 case PPC::CMPLDI: {
4652
4653
4654
4655
4656 if (PostRA)
4657 return false;
4658
4659
4661 Register DefReg = MI.getOperand(0).getReg();
4662 int64_t Comparand = MI.getOperand(2).getImm();
4663 int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
4664 ? (Comparand | 0xFFFFFFFFFFFF0000)
4665 : Comparand;
4666
4667 for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
4668 unsigned UseOpc = CompareUseMI.getOpcode();
4669 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4670 continue;
4671 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4672 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4673 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4674 unsigned RegToCopy =
4675 selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);
4676 if (RegToCopy == PPC::NoRegister)
4677 continue;
4678
4679 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4680 CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4682 CompareUseMI.removeOperand(3);
4683 CompareUseMI.removeOperand(2);
4684 continue;
4685 }
4687 dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4690
4691 CompareUseMI.setDesc(get(PPC::COPY));
4692 CompareUseMI.removeOperand(3);
4693 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4694 CmpIselsConverted++;
4697 }
4699 return true;
4700
4701
4702
4703 MissedConvertibleImmediateInstrs++;
4704 return false;
4705 }
4706
4707
4708 case PPC::ADDI:
4709 case PPC::ADDI8: {
4710
4711 int64_t Addend = MI.getOperand(2).getImm();
4712 if (isInt<16>(Addend + SExtImm)) {
4713 ReplaceWithLI = true;
4714 Is64BitLI = Opc == PPC::ADDI8;
4715 NewImm = Addend + SExtImm;
4716 break;
4717 }
4718 return false;
4719 }
4720 case PPC::SUBFIC:
4721 case PPC::SUBFIC8: {
4722
4723 if (MI.getNumOperands() > 3 && .getOperand(3).isDead())
4724 return false;
4725 int64_t Minuend = MI.getOperand(2).getImm();
4726 if (isInt<16>(Minuend - SExtImm)) {
4727 ReplaceWithLI = true;
4728 Is64BitLI = Opc == PPC::SUBFIC8;
4729 NewImm = Minuend - SExtImm;
4730 break;
4731 }
4732 return false;
4733 }
4734 case PPC::RLDICL:
4735 case PPC::RLDICL_rec:
4736 case PPC::RLDICL_32:
4737 case PPC::RLDICL_32_64: {
4738
4739 int64_t SH = MI.getOperand(2).getImm();
4740 int64_t MB = MI.getOperand(3).getImm();
4741 APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
4742 SExtImm, true);
4743 InVal = InVal.rotl(SH);
4744 uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
4745 InVal &= Mask;
4746
4747
4748
4749 if (isUInt<15>(InVal.getSExtValue()) ||
4750 (Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
4751 ReplaceWithLI = true;
4752 Is64BitLI = Opc != PPC::RLDICL_32;
4753 NewImm = InVal.getSExtValue();
4754 SetCR = Opc == PPC::RLDICL_rec;
4755 break;
4756 }
4757 return false;
4758 }
4759 case PPC::RLWINM:
4760 case PPC::RLWINM8:
4761 case PPC::RLWINM_rec:
4762 case PPC::RLWINM8_rec: {
4763 int64_t SH = MI.getOperand(2).getImm();
4764 int64_t MB = MI.getOperand(3).getImm();
4765 int64_t ME = MI.getOperand(4).getImm();
4766 APInt InVal(32, SExtImm, true);
4767 InVal = InVal.rotl(SH);
4769 InVal &= Mask;
4770
4771
4772
4773 bool ValueFits = isUInt<15>(InVal.getSExtValue());
4774 ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
4776 if (ValueFits) {
4777 ReplaceWithLI = true;
4778 Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
4779 NewImm = InVal.getSExtValue();
4780 SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
4781 break;
4782 }
4783 return false;
4784 }
4785 case PPC::ORI:
4786 case PPC::ORI8:
4787 case PPC::XORI:
4788 case PPC::XORI8: {
4789 int64_t LogicalImm = MI.getOperand(2).getImm();
4791 if (Opc == PPC::ORI || Opc == PPC::ORI8)
4792 Result = LogicalImm | SExtImm;
4793 else
4794 Result = LogicalImm ^ SExtImm;
4796 ReplaceWithLI = true;
4797 Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
4799 break;
4800 }
4801 return false;
4802 }
4803 }
4804
4805 if (ReplaceWithLI) {
4806
4807 if (SetCR) {
4808
4809
4810 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4811 if (PostRA && ImmChanged)
4812 return false;
4813
4814 if (!PostRA) {
4815
4816
4818 DefMI.getOperand(1).setImm(NewImm);
4819
4820
4821
4822 else if (MRI->use_empty(MI.getOperand(0).getReg())) {
4823 if (NewImm) {
4824 assert(Immediate && "Transformation converted zero to non-zero?");
4825 NewImm = Immediate;
4826 }
4827 } else if (ImmChanged)
4828 return false;
4829 }
4830 }
4831
4832 LLVM_DEBUG(dbgs() << "Replacing constant instruction:\n");
4836 LoadImmediateInfo LII;
4837 LII.Imm = NewImm;
4838 LII.Is64Bit = Is64BitLI;
4839 LII.SetCR = SetCR;
4840
4841
4842 if (KilledDef && SetCR)
4843 *KilledDef = nullptr;
4845
4846 if (PostRA)
4848
4851 return true;
4852 }
4853 return false;
4854}
4855
4856bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4858 MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
4860
4861
4862 if (PostRA)
4863 return false;
4864
4865
4866 if (.mayLoadOrStore())
4867 return false;
4868
4869 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(MI.getOpcode());
4870
4871 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4872 "MI must have x-form opcode");
4873
4874
4875 ImmInstrInfo III;
4876 bool IsVFReg = MI.getOperand(0).isReg()
4879
4880 if ((XFormOpcode, IsVFReg, III, PostRA))
4881 return false;
4882
4884 return false;
4885
4887 return false;
4888
4889 MachineOperand ImmOperandMI = MI.getOperand(III.ImmOpNo);
4890 if (!ImmOperandMI.isImm())
4891 return false;
4892
4893
4894 MachineOperand *ImmMO = nullptr;
4895 MachineOperand *RegMO = nullptr;
4896 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
4897 return false;
4898 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
4899
4900
4901
4902
4903 int64_t ImmBase = ImmOperandMI.getImm();
4904 int64_t Imm = 0;
4905 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm, ImmBase))
4906 return false;
4907
4908
4909 LLVM_DEBUG(dbgs() << "Replacing existing reg+imm instruction:\n");
4913
4915 MI.getOperand(III.ImmOpNo).setImm(Imm);
4916
4919 return true;
4920}
4921
4922
4923
4924
4925
4926bool PPCInstrInfo::transformToImmFormFedByAdd(
4929
4930
4931
4932
4933
4934
4935
4936 if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))
4937 return false;
4938
4939
4940
4941 MachineOperand *ImmMO = nullptr;
4942 MachineOperand *RegMO = nullptr;
4943 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
4944 return false;
4945 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
4946
4947
4948
4949 int64_t Imm = 0;
4950 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
4951 return false;
4952
4953 bool IsFwdFeederRegKilled = false;
4954 bool SeenIntermediateUse = false;
4955
4956 if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,
4957 IsFwdFeederRegKilled, SeenIntermediateUse))
4958 return false;
4959
4960 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4962
4963
4964
4965
4966 LLVM_DEBUG(dbgs() << "Replacing indexed instruction:\n");
4970
4971
4973 false, false,
4975
4976
4977 if (ImmMO->isImm()) {
4978
4979
4981 }
4982 else {
4983
4984
4985
4986
4987
4988 if (DefMI.getOpcode() == PPC::ADDItocL8)
4990
4991
4992
4993
4994
4996 for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {
4998 MI.removeOperand(i);
4999 }
5000
5001
5003
5004 MI.addOperand(*ImmMO);
5005
5006 for (auto &MO : MOps)
5007 MI.addOperand(MO);
5008 }
5009
5010
5012
5013 if (PostRA)
5017
5018 return true;
5019}
5020
5021bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
5023 unsigned ConstantOpNo,
5025
5026 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
5027 .getOperand(1).isImm())
5028 return false;
5029
5030
5032
5033 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
5035
5037 return false;
5039 return false;
5043 APInt ActualValue(64, Imm, true);
5044 if (!ActualValue.isSignedIntN(III.ImmWidth))
5045 return false;
5046 } else {
5047 uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
5048 if ((uint64_t)Imm > UnsignedMax)
5049 return false;
5050 }
5051
5052
5053
5054
5058 Register OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
5060
5061
5062 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5064 return false;
5065 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5066 ConstantOpNo != PosForOrigZero)
5067 return false;
5068 }
5069
5070 unsigned Opc = MI.getOpcode();
5071 bool SpecialShift32 = Opc == PPC::SLW || Opc == PPC::SLW_rec ||
5072 Opc == PPC::SRW || Opc == PPC::SRW_rec ||
5073 Opc == PPC::SLW8 || Opc == PPC::SLW8_rec ||
5074 Opc == PPC::SRW8 || Opc == PPC::SRW8_rec;
5075 bool SpecialShift64 = Opc == PPC::SLD || Opc == PPC::SLD_rec ||
5076 Opc == PPC::SRD || Opc == PPC::SRD_rec;
5077 bool SetCR = Opc == PPC::SLW_rec || Opc == PPC::SRW_rec ||
5078 Opc == PPC::SLD_rec || Opc == PPC::SRD_rec;
5079 bool RightShift = Opc == PPC::SRW || Opc == PPC::SRW_rec || Opc == PPC::SRD ||
5080 Opc == PPC::SRD_rec;
5081
5082 LLVM_DEBUG(dbgs() << "Replacing reg+reg instruction: ");
5088
5089
5090
5091
5092
5093
5094 if (SpecialShift32 || SpecialShift64) {
5095 LoadImmediateInfo LII;
5096 LII.Imm = 0;
5097 LII.SetCR = SetCR;
5098 LII.Is64Bit = SpecialShift64;
5099 uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
5100 if (Imm & (SpecialShift32 ? 0x20 : 0x40))
5102
5103
5104
5105 else if (!SetCR && ShAmt == 0 && !PostRA) {
5106 MI.removeOperand(2);
5107 MI.setDesc(get(PPC::COPY));
5108 } else {
5109
5110 if (SpecialShift32) {
5111
5112
5113
5114 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 32 - ShAmt : ShAmt;
5115 uint64_t MB = RightShift ? ShAmt : 0;
5116 uint64_t ME = RightShift ? 31 : 31 - ShAmt;
5118 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
5119 .addImm(ME);
5120 } else {
5121
5122
5123
5124 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 64 - ShAmt : ShAmt;
5125 uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
5127 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
5128 }
5129 }
5130 } else
5132 }
5133
5134
5138 } else
5140
5141
5142
5145
5146
5147
5148
5151
5152
5155 const TargetRegisterClass *NewRC =
5156 MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
5157 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5158 MRI.setRegClass(RegToModify, NewRC);
5159 }
5160 }
5161 }
5162
5163 if (PostRA)
5165
5169 return true;
5170}
5171
5174 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5175 return &PPC::VSRCRegClass;
5176 return RC;
5177}
5178
5180 return PPC::getRecordFormOpcode(Opcode);
5181}
5182
5184 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5185 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5186 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5187 Opcode == PPC::LHZUX8);
5188}
5189
5190
5194 return false;
5195
5197 if ()
5198 return false;
5199
5200 int Opcode = MI->getOpcode();
5202 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5203 if (TII->isSExt32To64(Opcode))
5204 return true;
5205
5206
5208 return true;
5209
5210
5211
5212 if (Opcode == PPC::RLDICL && MI->getOperand(3).getImm() >= 33)
5213 return true;
5214
5215
5216
5217
5218 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5219 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5220 MI->getOperand(3).getImm() > 0 &&
5221 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
5222 return true;
5223
5224
5225
5226 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5227 uint16_t Imm = MI->getOperand(2).getImm();
5228 if ((Imm & 0x8000) == 0)
5229 return true;
5230 }
5231
5232 return false;
5233}
5234
5235
5236
5237
5241 return false;
5242
5244 if ()
5245 return false;
5246
5247 int Opcode = MI->getOpcode();
5249 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5250 if (TII->isZExt32To64(Opcode))
5251 return true;
5252
5253
5255 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5256 MI->getOperand(0).getReg() == Reg)
5257 return true;
5258
5259
5260
5261 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5262 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5263 int64_t Imm = MI->getOperand(1).getImm();
5264 if (((uint64_t)Imm & ~0x7FFFuLL) == 0)
5265 return true;
5266 }
5267
5268
5269
5270 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5271 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5272 Opcode == PPC::RLDICL_32_64) &&
5273 MI->getOperand(3).getImm() >= 32)
5274 return true;
5275
5276 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5277 MI->getOperand(3).getImm() >= 32 &&
5278 MI->getOperand(3).getImm() <= 63 - MI->getOperand(2).getImm())
5279 return true;
5280
5281 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5282 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5283 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5284 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
5285 return true;
5286
5287 return false;
5288}
5289
5290
5291
5293 if (.getOperand(1).isImm() ||
.getOperand(2).isReg())
5294 return false;
5295 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5296 unsigned StackOffset = MI.getOperand(1).getImm();
5297 Register StackReg = MI.getOperand(2).getReg();
5298 Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
5300 return true;
5301
5302 return false;
5303}
5304
5305
5306
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5320 unsigned BinOpDepth,
5322 if (!Reg.isVirtual())
5323 return;
5324
5326 if ()
5327 return;
5328
5329 unsigned Opcode = MI->getOpcode();
5330
5331 switch (Opcode) {
5332 case PPC::OR:
5333 case PPC::ISEL:
5334 case PPC::OR8:
5335 case PPC::PHI: {
5337 break;
5338 unsigned OperandEnd = 3, OperandStride = 1;
5339 if (Opcode == PPC::PHI) {
5340 OperandEnd = MI->getNumOperands();
5341 OperandStride = 2;
5342 }
5343
5344 for (unsigned I = 1; I < OperandEnd; I += OperandStride) {
5345 assert(MI->getOperand(I).isReg() && "Operand must be register");
5347 BinOpDepth + 1, LV);
5348 }
5349
5350 break;
5351 }
5352 case PPC::COPY: {
5353
5354
5355
5356 Register SrcReg = MI->getOperand(1).getReg();
5357
5358
5361
5362
5364 return;
5365 }
5366
5367
5368
5369
5370 if (SrcReg != PPC::X3)
5371
5372
5374 return;
5375 }
5376 case PPC::ORI:
5377 case PPC::XORI:
5378 case PPC::ORIS:
5379 case PPC::XORIS:
5380 case PPC::ORI8:
5381 case PPC::XORI8:
5382 case PPC::ORIS8:
5383 case PPC::XORIS8:
5385 LV);
5386 break;
5387 case PPC::AND:
5388 case PPC::AND8:
5390 break;
5391
5393 BinOpDepth + 1, LV);
5395 BinOpDepth + 1, LV);
5396 break;
5397 }
5398
5400 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5401 return;
5402
5404 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5405
5406
5407
5408
5409 std::unordered_map<unsigned, unsigned> OpcodeMap = {
5410 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5411 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5412 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5413 {PPC::AND, PPC::AND8}};
5414
5415 int NewOpcode = -1;
5416 auto It = OpcodeMap.find(Opcode);
5417 if (It != OpcodeMap.end()) {
5418
5419 NewOpcode = It->second;
5420 } else {
5421 if (->isSExt32To64(Opcode))
5422 return;
5423
5424
5425
5426
5427 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5428 }
5429
5430 assert(NewOpcode != -1 &&
5431 "Must have a 64-bit opcode to map the 32-bit opcode!");
5432
5436 TRI->getRegClass(MCID.operands()[0].RegClass);
5437
5438 Register SrcReg = MI->getOperand(0).getReg();
5440
5441
5442
5443
5444 if (NewRC == SrcRC)
5445 return;
5446
5448 auto MBB = MI->getParent();
5449
5450
5451
5452
5453
5454
5456 for (unsigned i = 1; i < MI->getNumOperands(); i++) {
5458 if (!Operand.isReg())
5459 continue;
5460
5463 continue;
5464
5466 TRI->getRegClass(MCID.operands()[i].RegClass);
5468 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5469 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5470
5471 Register TmpReg = MRI->createVirtualRegister(NewUsedRegRC);
5472 Register DstTmpReg = MRI->createVirtualRegister(NewUsedRegRC);
5477 .addImm(PPC::sub_32);
5478 PromoteRegs[i] = DstTmpReg;
5479 }
5480 }
5481
5482 Register NewDefinedReg = MRI->createVirtualRegister(NewRC);
5483
5486 --Iter;
5488 for (unsigned i = 1; i < MI->getNumOperands(); i++) {
5489 if (auto It = PromoteRegs.find(i); It != PromoteRegs.end())
5491 else
5493 }
5494
5495 for (unsigned i = 1; i < Iter->getNumOperands(); i++) {
5497 if (!Operand.isReg())
5498 continue;
5501 continue;
5503 }
5504
5505 MI->eraseFromParent();
5506
5507
5508
5509
5510
5514}
5515
5516
5517
5518
5519
5520
5521std::pair<bool, bool>
5523 const unsigned BinOpDepth,
5526 return std::pair<bool, bool>(false, false);
5527
5529 if ()
5530 return std::pair<bool, bool>(false, false);
5531
5534
5535
5536
5537 if (IsSExt && IsZExt)
5538 return std::pair<bool, bool>(IsSExt, IsZExt);
5539
5540 switch (MI->getOpcode()) {
5541 case PPC::COPY: {
5542 Register SrcReg = MI->getOperand(1).getReg();
5543
5544
5545
5547
5549
5551 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5552 SrcExt.second || IsZExt);
5553 }
5554
5555
5557
5558 if (MI->getParent()->getBasicBlock() ==
5560 Register VReg = MI->getOperand(0).getReg();
5564 return std::pair<bool, bool>(IsSExt, IsZExt);
5565 }
5566 }
5567
5568 if (SrcReg != PPC::X3) {
5569
5571 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5572 SrcExt.second || IsZExt);
5573 }
5574
5575
5576
5577
5578
5579
5580
5582 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5585 if (II == MBB->instr_begin() || (--II)->getOpcode() != PPC::ADJCALLSTACKUP)
5586 return IsExtendPair;
5587
5590 return IsExtendPair;
5591
5594 if (!CalleeFn)
5595 return IsExtendPair;
5597 if (IntTy && IntTy->getBitWidth() <= 32) {
5599 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5600 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5601 return std::pair<bool, bool>(IsSExt, IsZExt);
5602 }
5603
5604 return IsExtendPair;
5605 }
5606
5607
5608
5609 case PPC::ORI:
5610 case PPC::XORI:
5611 case PPC::ORI8:
5612 case PPC::XORI8: {
5613 Register SrcReg = MI->getOperand(1).getReg();
5615 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5616 SrcExt.second || IsZExt);
5617 }
5618
5619
5620
5621
5622
5623 case PPC::ORIS:
5624 case PPC::XORIS:
5625 case PPC::ORIS8:
5626 case PPC::XORIS8: {
5627 Register SrcReg = MI->getOperand(1).getReg();
5629 uint16_t Imm = MI->getOperand(2).getImm();
5630 if (Imm & 0x8000)
5631 return std::pair<bool, bool>(false, SrcExt.second || IsZExt);
5632 else
5633 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5634 SrcExt.second || IsZExt);
5635 }
5636
5637
5638
5639 case PPC::OR:
5640 case PPC::OR8:
5641 case PPC::ISEL:
5642 case PPC::PHI: {
5644 return std::pair<bool, bool>(false, false);
5645
5646
5647
5648 unsigned OperandEnd = 3, OperandStride = 1;
5649 if (MI->getOpcode() == PPC::PHI) {
5650 OperandEnd = MI->getNumOperands();
5651 OperandStride = 2;
5652 }
5653
5654 IsSExt = true;
5655 IsZExt = true;
5656 for (unsigned I = 1; I != OperandEnd; I += OperandStride) {
5657 if (->getOperand(I).isReg())
5658 return std::pair<bool, bool>(false, false);
5659
5660 Register SrcReg = MI->getOperand(I).getReg();
5662 IsSExt &= SrcExt.first;
5663 IsZExt &= SrcExt.second;
5664 }
5665 return std::pair<bool, bool>(IsSExt, IsZExt);
5666 }
5667
5668
5669
5670
5671 case PPC::AND:
5672 case PPC::AND8: {
5674 return std::pair<bool, bool>(false, false);
5675
5676 Register SrcReg1 = MI->getOperand(1).getReg();
5677 Register SrcReg2 = MI->getOperand(2).getReg();
5680 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5681 Src1Ext.second || Src2Ext.second);
5682 }
5683
5684 default:
5685 break;
5686 }
5687 return std::pair<bool, bool>(IsSExt, IsZExt);
5688}
5689
5691 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5692}
5693
5694namespace {
5699 int64_t TripCount;
5700
5701public:
5704 : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5706 TII(MF->getSubtarget().getInstrInfo()) {
5707
5708
5709 if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI)
5711 else
5712 TripCount = -1;
5713 }
5714
5715 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
5716
5717 return MI == EndLoop;
5718 }
5719
5720 std::optional createTripCountGreaterCondition(
5721 int TC, MachineBasicBlock &MBB,
5722 SmallVectorImpl &Cond) override {
5723 if (TripCount == -1) {
5724
5725
5728 MF->getSubtarget().isPPC64() ? PPC::CTR8 : PPC::CTR,
5729 true));
5730 return {};
5731 }
5732
5733 return TripCount > TC;
5734 }
5735
5736 void setPreheader(MachineBasicBlock *NewPreheader) override {
5737
5738
5739 }
5740
5741 void adjustTripCount(int TripCountAdjust) override {
5742
5743
5744 if (LoopCount->getOpcode() == PPC::LI8 ||
5745 LoopCount->getOpcode() == PPC::LI) {
5746 int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;
5748 return;
5749 }
5750
5751
5752
5753 }
5754
5755 void disposed(LiveIntervals *LIS) override {
5756 if (LIS) {
5759 }
5761
5763 }
5764};
5765}
5766
5767std::unique_ptrTargetInstrInfo::PipelinerLoopInfo
5769
5772 if (Preheader == LoopBB)
5773 Preheader = *std::next(LoopBB->pred_begin());
5775
5776 if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {
5779 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5781 MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
5782 return std::make_unique(LoopInst, &*I, LoopCount);
5783 }
5784 }
5785 return nullptr;
5786}
5787
5791
5792 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5793
5794
5795 for (auto &I : PreHeader.instrs())
5796 if (I.getOpcode() == LOOPi)
5797 return &I;
5798 return nullptr;
5799}
5800
5801
5802
5807 return false;
5808
5809
5812 return false;
5815 return false;
5816
5818 return false;
5819
5823 return true;
5824}
5825
5830
5833 return false;
5834
5835
5836
5837
5838
5839
5841 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
5842 int64_t OffsetA = 0, OffsetB = 0;
5848 int LowOffset = std::min(OffsetA, OffsetB);
5849 int HighOffset = std::max(OffsetA, OffsetB);
5850 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5852 LowOffset + (int)LowWidth.getValue() <= HighOffset)
5853 return true;
5854 }
5855 }
5856 return false;
5857}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static const Function * getParent(const Value *V)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
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)
uint64_t IntrinsicInst * II
static bool isOpZeroOfSubwordPreincLoad(int Opcode)
Definition PPCInstrInfo.cpp:5183
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
Definition PPCInstrInfo.cpp:2181
static bool definedByZeroExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)
Definition PPCInstrInfo.cpp:5238
static cl::opt< float > FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5), cl::desc("register pressure factor for the transformations."))
#define InfoArrayIdxMULOpIdx
Definition PPCInstrInfo.cpp:274
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, unsigned TrueReg, unsigned FalseReg, unsigned CRSubReg)
Definition PPCInstrInfo.cpp:3317
static unsigned getCRBitValue(unsigned CRBit)
Definition PPCInstrInfo.cpp:1650
static bool isAnImmediateOperand(const MachineOperand &MO)
Definition PPCInstrInfo.cpp:3130
static const uint16_t FMAOpIdxInfo[][6]
Definition PPCInstrInfo.cpp:284
static cl::opt< bool > DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops"))
#define InfoArrayIdxAddOpIdx
Definition PPCInstrInfo.cpp:273
static cl::opt< bool > UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation"))
#define InfoArrayIdxFMAInst
Definition PPCInstrInfo.cpp:270
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc, const PPCSubtarget &Subtarget)
Definition PPCInstrInfo.cpp:2924
static cl::opt< bool > EnableFMARegPressureReduction("ppc-fma-rp-reduction", cl::Hidden, cl::init(true), cl::desc("enable register pressure reduce in machine combiner pass."))
static bool isLdStSafeToCluster(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
Definition PPCInstrInfo.cpp:2904
const unsigned MAX_BINOP_DEPTH
Definition PPCInstrInfo.cpp:5307
static cl::opt< bool > DisableCmpOpt("disable-ppc-cmp-opt", cl::desc("Disable compare instruction optimization"), cl::Hidden)
#define InfoArrayIdxFSubInst
Definition PPCInstrInfo.cpp:275
#define InfoArrayIdxFAddInst
Definition PPCInstrInfo.cpp:271
#define InfoArrayIdxFMULInst
Definition PPCInstrInfo.cpp:272
static bool definedBySignExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)
Definition PPCInstrInfo.cpp:5191
static cl::opt< bool > VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2)
Definition PPCInstrInfo.cpp:4420
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool isPhysical(const MachineOperand &MO)
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
LLVM_ABI APInt rotl(unsigned rotateAmt) const
Rotate left by rotateAmt.
static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit, unsigned hiBit)
Wrap version of getBitsSet.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
This class holds the attributes for a particular argument, parameter, function, or return value.
This is an important base class in LLVM.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const BasicBlock & getEntryBlock() const
AttributeList getAttributes() const
Return the attribute list for this Function.
Type * getReturnType() const
Returns the type of the ret val.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Itinerary data supplied by a subtarget to be used by a target.
std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
Class to represent integer types.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
Represents a single loop in the control flow graph.
Instances of this class represent a single low-level machine instruction.
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
ArrayRef< MCPhysReg > implicit_uses() const
Return a list of registers that are potentially read by any instance of this machine instruction.
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
This holds information about one operand of a machine instruction, indicating the register class for ...
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align 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.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasImplicitDef() const
Returns true if the instruction has implicit definition.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
LLVM_ABI void clearRegisterDeads(Register Reg)
Clear all dead flags on operands defining register Reg.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
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)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
LLVM_ABI bool isLiveIn(Register Reg) const
PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based hazard recognizer for P...
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isLiveInSExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and sign-extended.
bool isLiveInZExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and zero-extended.
PPCHazardRecognizer970 - This class defines a finite state automata that models the dispatch logic on...
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Definition PPCInstrInfo.cpp:1062
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Definition PPCInstrInfo.cpp:1118
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
Definition PPCInstrInfo.cpp:2215
bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for a fma chain ending in Root.
Definition PPCInstrInfo.cpp:350
bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase=nullptr) const
Definition PPCInstrInfo.cpp:3861
bool isReMaterializableImpl(const MachineInstr &MI) const override
Definition PPCInstrInfo.cpp:1078
PPCInstrInfo(const PPCSubtarget &STI)
Definition PPCInstrInfo.cpp:91
const TargetRegisterClass * updatedRC(const TargetRegisterClass *RC) const
Definition PPCInstrInfo.cpp:5173
bool isPredicated(const MachineInstr &MI) const override
Definition PPCInstrInfo.cpp:2204
bool expandVSXMemPseudo(MachineInstr &MI) const
Definition PPCInstrInfo.cpp:3068
bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg) const
Definition PPCInstrInfo.cpp:2112
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Definition PPCInstrInfo.cpp:1677
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
Fixup the placeholders we put in genAlternativeCodeSequence() for MachineCombiner.
Definition PPCInstrInfo.cpp:525
MCInst getNop() const override
Return the noop instruction to use for a noop.
Definition PPCInstrInfo.cpp:1250
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Definition PPCInstrInfo.cpp:2034
static int getRecordFormOpcode(unsigned Opcode)
Definition PPCInstrInfo.cpp:5179
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
Definition PPCInstrInfo.cpp:1130
bool isXFormMemOp(unsigned Opcode) const
const PPCRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
CombinerObjective getCombinerObjective(unsigned Pattern) const override
Definition PPCInstrInfo.cpp:739
unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const
Definition PPCInstrInfo.cpp:1982
unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const
Definition PPCInstrInfo.cpp:1988
void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth, LiveVariables *LV) const
Definition PPCInstrInfo.cpp:5318
bool isTOCSaveMI(const MachineInstr &MI) const
Definition PPCInstrInfo.cpp:5292
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer to use for this target when ...
Definition PPCInstrInfo.cpp:117
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
Definition PPCInstrInfo.cpp:2173
bool isBDNZ(unsigned Opcode) const
Check Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).
Definition PPCInstrInfo.cpp:5690
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Definition PPCInstrInfo.cpp:2099
bool isZeroExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
Definition PPCInstrInfo.cpp:3023
std::pair< bool, bool > isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, const MachineRegisterInfo *MRI) const
Definition PPCInstrInfo.cpp:5522
bool expandPostRAPseudo(MachineInstr &MI) const override
Definition PPCInstrInfo.cpp:3134
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Definition PPCInstrInfo.cpp:1230
bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index, MachineInstr *&ADDIMI, int64_t &OffsetAddi, int64_t OffsetImm) const
Definition PPCInstrInfo.cpp:3754
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const override
Definition PPCInstrInfo.cpp:2432
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
Definition PPCInstrInfo.cpp:3029
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
Definition PPCInstrInfo.cpp:167
void materializeImmPostRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register Reg, int64_t Imm) const
Definition PPCInstrInfo.cpp:3418
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const
Definition PPCInstrInfo.cpp:3704
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
Return true if two MIs access different memory addresses and false otherwise.
Definition PPCInstrInfo.cpp:5826
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
Definition PPCInstrInfo.cpp:2336
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
CreateTargetHazardRecognizer - Return the hazard recognizer to use for this target when scheduling th...
Definition PPCInstrInfo.cpp:100
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
Definition PPCInstrInfo.cpp:1519
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
Get the base operand and byte offset of an instruction that reads/writes memory.
Definition PPCInstrInfo.cpp:2892
void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const
Definition PPCInstrInfo.cpp:219
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const
Definition PPCInstrInfo.cpp:3687
void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const
Definition PPCInstrInfo.cpp:2059
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Definition PPCInstrInfo.cpp:2080
bool foldFrameOffset(MachineInstr &MI) const
Definition PPCInstrInfo.cpp:3590
bool isLoadFromConstantPool(MachineInstr *I) const
Definition PPCInstrInfo.cpp:655
MachineInstr * findLoopInstr(MachineBasicBlock &PreHeader, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
Definition PPCInstrInfo.cpp:5788
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Definition PPCInstrInfo.cpp:1434
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Definition PPCInstrInfo.cpp:137
void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const
Definition PPCInstrInfo.cpp:2015
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
Definition PPCInstrInfo.cpp:1047
bool convertToImmediateForm(MachineInstr &MI, SmallSet< Register, 4 > &RegsToUpdate, MachineInstr **KilledDef=nullptr) const
Definition PPCInstrInfo.cpp:3799
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
Definition PPCInstrInfo.cpp:232
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
Definition PPCInstrInfo.cpp:2402
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
Return true if get the base operand, byte offset of an instruction and the memory width.
Definition PPCInstrInfo.cpp:5803
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Definition PPCInstrInfo.cpp:1466
bool shouldReduceRegisterPressure(const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const override
On PowerPC, we leverage machine combiner pass to reduce register pressure when the register pressure ...
Definition PPCInstrInfo.cpp:595
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
Definition PPCInstrInfo.cpp:767
bool isSignExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, int64_t Imm) const
Definition PPCInstrInfo.cpp:3347
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
Definition PPCInstrInfo.cpp:3004
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
Definition PPCInstrInfo.cpp:5768
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
Returns true if the two given memory operations should be scheduled adjacent.
Definition PPCInstrInfo.cpp:2943
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const
Definition PPCInstrInfo.cpp:3378
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const
Definition PPCInstrInfo.cpp:3711
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
Definition PPCInstrInfo.cpp:2232
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...
Definition PPCInstrInfo.cpp:752
bool optimizeCmpPostRA(MachineInstr &MI) const
Definition PPCInstrInfo.cpp:2817
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Definition PPCInstrInfo.cpp:1259
const Constant * getConstantFromConstantPool(MachineInstr *I) const
Definition PPCInstrInfo.cpp:719
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
Definition PPCInstrInfo.cpp:2367
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
Definition PPCInstrInfo.cpp:1565
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
Definition PPCInstrInfo.cpp:1214
bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, bool PostRA) const
Definition PPCInstrInfo.cpp:3998
MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const
Definition PPCInstrInfo.cpp:3401
static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg)
const PPCTargetMachine & getTargetMachine() const
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void closeRegion()
Finalize the region boundaries and recored live ins and live outs.
LLVM_ABI void recede(SmallVectorImpl< VRegMaskOrUnit > *LiveUses=nullptr)
Recede across the previous instruction.
RegisterPressure & getPressure()
Get the resulting register pressure over the traversed region.
LLVM_ABI void recedeSkipDebugValues()
Recede until we find an instruction which is not a DebugValue.
LLVM_ABI void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)
Setup the RegPressureTracker.
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
List of registers defined and used by a machine instruction.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const TargetInstrInfo * TII
Target instruction information.
MachineFunction & MF
Machine function.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
StackOffset holds a fixed and a scalable offset in bytes.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
CodeModel::Model getCodeModel() const
Returns the code model.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ C
The default llvm calling convention, compatible with C.
PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.
Define some predicates that are used for node matching.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
int getAltVSXFMAOpcode(uint16_t Opcode)
int getNonRecordFormOpcode(uint16_t)
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
static bool isVFRegister(MCRegister Reg)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
template class LLVM_TEMPLATE_ABI opt< bool >
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...
unsigned getDeadRegState(bool B)
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static unsigned getCRFromCRBit(unsigned SrcReg)
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
@ MustReduceRegisterPressure
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
@ Sub
Subtraction of integers.
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t IsSummingOperands
uint64_t OpNoForForwarding
uint64_t ImmMustBeMultipleOf
uint64_t ZeroIsSpecialNew
uint64_t ZeroIsSpecialOrig
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.