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 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3186 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3187 MI.setDesc(get(PPC::LWZ));
3188 uint64_t FAType = MI.getOperand(1).getImm();
3189#undef PPC_LNX_FEATURE
3190#undef PPC_CPU
3191#define PPC_LNX_DEFINE_OFFSETS
3192#include "llvm/TargetParser/PPCTargetParser.def"
3193 bool IsLE = Subtarget.isLittleEndian();
3194 bool Is64 = Subtarget.isPPC64();
3195 if (FAType == PPC_FAWORD_HWCAP) {
3196 if (IsLE)
3197 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3198 else
3199 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3200 } else if (FAType == PPC_FAWORD_HWCAP2) {
3201 if (IsLE)
3202 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3203 else
3204 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3205 } else if (FAType == PPC_FAWORD_CPUID) {
3206 if (IsLE)
3207 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3208 else
3209 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3210 }
3211 assert(Offset && "Do not know the offset for this fixed addr load");
3212 MI.removeOperand(1);
3213 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3217 return true;
3218#define PPC_TGT_PARSER_UNDEF_MACROS
3219#include "llvm/TargetParser/PPCTargetParser.def"
3220#undef PPC_TGT_PARSER_UNDEF_MACROS
3221 }
3222 case PPC::DFLOADf32:
3223 case PPC::DFLOADf64:
3224 case PPC::DFSTOREf32:
3225 case PPC::DFSTOREf64: {
3226 assert(Subtarget.hasP9Vector() &&
3227 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3228 assert(MI.getOperand(2).isReg() &&
3230 "D-form op must have register and immediate operands");
3232 }
3233 case PPC::XFLOADf32:
3234 case PPC::XFSTOREf32:
3235 case PPC::LIWAX:
3236 case PPC::LIWZX:
3237 case PPC::STIWX: {
3238 assert(Subtarget.hasP8Vector() &&
3239 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3240 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
3241 "X-form op must have register and register operands");
3243 }
3244 case PPC::XFLOADf64:
3245 case PPC::XFSTOREf64: {
3246 assert(Subtarget.hasVSX() &&
3247 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3248 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
3249 "X-form op must have register and register operands");
3251 }
3252 case PPC::SPILLTOVSR_LD: {
3253 Register TargetReg = MI.getOperand(0).getReg();
3254 if (PPC::VSFRCRegClass.contains(TargetReg)) {
3255 MI.setDesc(get(PPC::DFLOADf64));
3257 }
3258 else
3259 MI.setDesc(get(PPC::LD));
3260 return true;
3261 }
3262 case PPC::SPILLTOVSR_ST: {
3263 Register SrcReg = MI.getOperand(0).getReg();
3264 if (PPC::VSFRCRegClass.contains(SrcReg)) {
3265 NumStoreSPILLVSRRCAsVec++;
3266 MI.setDesc(get(PPC::DFSTOREf64));
3268 } else {
3269 NumStoreSPILLVSRRCAsGpr++;
3270 MI.setDesc(get(PPC::STD));
3271 }
3272 return true;
3273 }
3274 case PPC::SPILLTOVSR_LDX: {
3275 Register TargetReg = MI.getOperand(0).getReg();
3276 if (PPC::VSFRCRegClass.contains(TargetReg))
3277 MI.setDesc(get(PPC::LXSDX));
3278 else
3279 MI.setDesc(get(PPC::LDX));
3280 return true;
3281 }
3282 case PPC::SPILLTOVSR_STX: {
3283 Register SrcReg = MI.getOperand(0).getReg();
3284 if (PPC::VSFRCRegClass.contains(SrcReg)) {
3285 NumStoreSPILLVSRRCAsVec++;
3286 MI.setDesc(get(PPC::STXSDX));
3287 } else {
3288 NumStoreSPILLVSRRCAsGpr++;
3289 MI.setDesc(get(PPC::STDX));
3290 }
3291 return true;
3292 }
3293
3294
3295 case PPC::CFENCE:
3296 case PPC::CFENCE8: {
3297 auto Val = MI.getOperand(0).getReg();
3298 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3304 MI.setDesc(get(PPC::ISYNC));
3305 MI.removeOperand(0);
3306 return true;
3307 }
3308 }
3309 return false;
3310}
3311
3312
3313
3314
3315
3316static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
3317 unsigned TrueReg, unsigned FalseReg,
3318 unsigned CRSubReg) {
3319
3320 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3321 switch (CRSubReg) {
3322 default: llvm_unreachable("Unknown integer comparison type.");
3323 case PPC::sub_lt:
3324 return Imm1 < Imm2 ? TrueReg : FalseReg;
3325 case PPC::sub_gt:
3326 return Imm1 > Imm2 ? TrueReg : FalseReg;
3327 case PPC::sub_eq:
3328 return Imm1 == Imm2 ? TrueReg : FalseReg;
3329 }
3330 }
3331
3332 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3333 switch (CRSubReg) {
3334 default: llvm_unreachable("Unknown integer comparison type.");
3335 case PPC::sub_lt:
3336 return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
3337 case PPC::sub_gt:
3338 return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
3339 case PPC::sub_eq:
3340 return Imm1 == Imm2 ? TrueReg : FalseReg;
3341 }
3342 }
3343 return PPC::NoRegister;
3344}
3345
3347 unsigned OpNo,
3348 int64_t Imm) const {
3349 assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");
3350
3351 Register InUseReg = MI.getOperand(OpNo).getReg();
3352 MI.getOperand(OpNo).ChangeToImmediate(Imm);
3353
3354
3355
3356
3357
3358
3360 int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, TRI, false);
3361 if (UseOpIdx >= 0) {
3364
3365
3366
3367
3368
3369
3370
3371 MI.removeOperand(UseOpIdx);
3372 }
3373}
3374
3375
3376
3379
3380 int OperandToKeep = LII.SetCR ? 1 : 0;
3381 for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
3382 MI.removeOperand(i);
3383
3384
3385 if (LII.SetCR) {
3386 MI.setDesc(get(LII.Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3387
3390 return;
3391 }
3392 else
3393 MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));
3394
3395
3398}
3399
3401 bool &SeenIntermediateUse) const {
3402 assert(.getParent()->getParent()->getRegInfo().isSSA() &&
3403 "Should be called after register allocation.");
3406 It++;
3407 SeenIntermediateUse = false;
3408 for (; It != E; ++It) {
3409 if (It->modifiesRegister(Reg, TRI))
3410 return &*It;
3411 if (It->readsRegister(Reg, TRI))
3412 SeenIntermediateUse = true;
3413 }
3414 return nullptr;
3415}
3416
3420 int64_t Imm) const {
3421 assert(.getParent()->getRegInfo().isSSA() &&
3422 "Register should be in non-SSA form after RA");
3423 bool isPPC64 = Subtarget.isPPC64();
3424
3425
3426
3432 if (Imm & 0xFFFF)
3435 .addImm(Imm & 0xFFFF);
3436 } else {
3437 assert(isPPC64 && "Materializing 64-bit immediate to single register is "
3438 "only supported in PPC64");
3440 if ((Imm >> 32) & 0xFFFF)
3443 .addImm((Imm >> 32) & 0xFFFF);
3450 .addImm((Imm >> 16) & 0xFFFF);
3451 if (Imm & 0xFFFF)
3454 .addImm(Imm & 0xFFFF);
3455 }
3456}
3457
3458MachineInstr *PPCInstrInfo::getForwardingDefMI(
3460 unsigned &OpNoForForwarding,
3461 bool &SeenIntermediateUse) const {
3462 OpNoForForwarding = ~0U;
3466
3467
3468
3469 if (MRI->isSSA()) {
3470 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
3471 if (.getOperand(i).isReg())
3472 continue;
3473 Register Reg = MI.getOperand(i).getReg();
3474 if (!Reg.isVirtual())
3475 continue;
3478 MachineInstr *DefMIForTrueReg = MRI->getVRegDef(TrueReg);
3479 if (DefMIForTrueReg->getOpcode() == PPC::LI ||
3480 DefMIForTrueReg->getOpcode() == PPC::LI8 ||
3481 DefMIForTrueReg->getOpcode() == PPC::ADDI ||
3482 DefMIForTrueReg->getOpcode() == PPC::ADDI8) {
3483 OpNoForForwarding = i;
3484 DefMI = DefMIForTrueReg;
3485
3486
3487
3488
3489 if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)
3490 break;
3491 }
3492 }
3493 }
3494 } else {
3495
3496
3497
3498 ImmInstrInfo III;
3499 unsigned Opc = MI.getOpcode();
3500 bool ConvertibleImmForm =
3501 Opc == PPC::CMPWI || Opc == PPC::CMPLWI || Opc == PPC::CMPDI ||
3502 Opc == PPC::CMPLDI || Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
3503 Opc == PPC::ORI || Opc == PPC::ORI8 || Opc == PPC::XORI ||
3504 Opc == PPC::XORI8 || Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec ||
3505 Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
3506 Opc == PPC::RLWINM || Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8 ||
3507 Opc == PPC::RLWINM8_rec;
3508 bool IsVFReg = (MI.getNumOperands() && MI.getOperand(0).isReg())
3511 if (!ConvertibleImmForm && (Opc, IsVFReg, III, true))
3512 return nullptr;
3513
3514
3515 if ((Opc == PPC::OR || Opc == PPC::OR8) &&
3516 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
3517 return nullptr;
3518 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
3519 MachineOperand &MO = MI.getOperand(i);
3520 SeenIntermediateUse = false;
3523
3524
3527
3528
3530 default:
3531 break;
3532 case PPC::LI:
3533 case PPC::LI8:
3534 case PPC::ADDItocL8:
3535 case PPC::ADDI:
3536 case PPC::ADDI8:
3537 OpNoForForwarding = i;
3539 }
3540 }
3541 }
3542 }
3543 }
3544 return OpNoForForwarding == ~0U ? nullptr : DefMI;
3545}
3546
3547unsigned PPCInstrInfo::getSpillTarget() const {
3548
3549
3550 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3551
3552 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3553 2 : Subtarget.hasP9Vector() ?
3554 1 : 0;
3555}
3556
3557ArrayRef PPCInstrInfo::getStoreOpcodesForSpillArray() const {
3559}
3560
3561ArrayRef PPCInstrInfo::getLoadOpcodesForSpillArray() const {
3563}
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
3592 bool PostRA = ->isSSA();
3593
3594
3595
3596 if (!PostRA)
3597 return false;
3598 unsigned ToBeDeletedReg = 0;
3599 int64_t OffsetImm = 0;
3600 unsigned XFormOpcode = 0;
3602
3603
3605 III))
3606 return false;
3607
3608 bool OtherIntermediateUse = false;
3610
3611
3612 if (OtherIntermediateUse || !ADDMI)
3613 return false;
3614
3615
3617 return false;
3618
3619 unsigned ScaleRegIdx = 0;
3620 int64_t OffsetAddi = 0;
3622
3623
3624
3625
3626
3628 ScaleRegIdx = 2;
3630 ScaleRegIdx = 1;
3631 else
3632 return false;
3633
3634 assert(ADDIMI && "There should be ADDIMI for valid ToBeChangedReg.");
3639 for (auto It = ++Start; It != End; It++)
3641 return true;
3642 return false;
3643 };
3644
3645
3646
3648 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3649 return false;
3650
3651
3652
3653 if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI))
3654 return false;
3655
3656
3658 << "\n");
3663 << "\n");
3664
3665
3667
3668
3669 MI.setDesc(get(XFormOpcode));
3671 .ChangeToRegister(ScaleReg, false, false,
3673
3675 .ChangeToRegister(ToBeChangedReg, false, false, true);
3676
3677
3679
3682
3683 return true;
3684}
3685
3687 int64_t &Imm) const {
3689
3690
3691 if (Opc != PPC::ADDI && Opc != PPC::ADDI8)
3692 return false;
3693
3694
3696 return false;
3697
3699
3700 return true;
3701}
3702
3705
3706
3707 return Opc == PPC::ADD4 || Opc == PPC::ADD8;
3708}
3709
3711 unsigned &ToBeDeletedReg,
3712 unsigned &XFormOpcode,
3713 int64_t &OffsetImm,
3715
3716 if (.mayLoadOrStore())
3717 return false;
3718
3719 unsigned Opc = MI.getOpcode();
3720
3721 XFormOpcode = RI.getMappedIdxOpcForImmOpc(Opc);
3722
3723
3724 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3725 return false;
3726
3727
3730 return false;
3731
3733 return false;
3734
3737
3738 if (!ImmOperand.isImm())
3739 return false;
3740
3741 assert(RegOperand.isReg() && "Instruction format is not right");
3742
3743
3744 if (!RegOperand.isKill())
3745 return false;
3746
3747 ToBeDeletedReg = RegOperand.getReg();
3748 OffsetImm = ImmOperand.getImm();
3749
3750 return true;
3751}
3752
3755 int64_t &OffsetAddi,
3756 int64_t OffsetImm) const {
3757 assert((Index == 1 || Index == 2) && "Invalid operand index for add.");
3759
3761 return false;
3762
3763 bool OtherIntermediateUse = false;
3764
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784 if (OtherIntermediateUse || !ADDIMI)
3785 return false;
3786
3788 return false;
3789
3790 if (isInt<16>(OffsetAddi + OffsetImm))
3791 return true;
3792 return false;
3793}
3794
3795
3796
3797
3803 bool PostRA = ->isSSA();
3804 bool SeenIntermediateUse = true;
3805 unsigned ForwardingOperand = ~0U;
3807 SeenIntermediateUse);
3809 return false;
3810 assert(ForwardingOperand < MI.getNumOperands() &&
3811 "The forwarding operand needs to be valid at this point");
3812 bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
3813 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3814 if (KilledDef && KillFwdDefMI)
3815 *KilledDef = DefMI;
3816
3817
3818
3825
3826
3827
3828 if (RI.getMappedIdxOpcForImmOpc(MI.getOpcode()) !=
3829 PPC::INSTRUCTION_LIST_END &&
3830 transformToNewImmFormFedByAdd(MI, *DefMI, ForwardingOperand))
3831 return true;
3832
3834 bool IsVFReg = MI.getOperand(0).isReg()
3836 : false;
3837 bool HasImmForm = instrHasImmForm(MI.getOpcode(), IsVFReg, III, PostRA);
3838
3839
3840
3841 if (HasImmForm &&
3842 transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,
3843 KillFwdDefMI))
3844 return true;
3845
3846
3847
3848 if (HasImmForm &&
3849 transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))
3850 return true;
3851
3852
3853
3854 if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))
3855 return true;
3856
3857 return false;
3858}
3859
3863 Register FoldingReg = MI.getOperand(1).getReg();
3865 return false;
3867 if (SrcMI->getOpcode() != PPC::RLWINM &&
3868 SrcMI->getOpcode() != PPC::RLWINM_rec &&
3869 SrcMI->getOpcode() != PPC::RLWINM8 &&
3870 SrcMI->getOpcode() != PPC::RLWINM8_rec)
3871 return false;
3872 assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
3875 "Invalid PPC::RLWINM Instruction!");
3877 uint64_t SHMI = MI.getOperand(2).getImm();
3879 uint64_t MBMI = MI.getOperand(3).getImm();
3881 uint64_t MEMI = MI.getOperand(4).getImm();
3882
3883 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3884 "Invalid PPC::RLWINM Instruction!");
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3907
3908
3909 if ((MBMI > MEMI) && !SrcMaskFull)
3910 return false;
3911
3912
3914
3915
3916
3918
3919 APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
3920 APInt FinalMask = RotatedSrcMask & MaskMI;
3922 bool Simplified = false;
3923
3924
3925 if (FinalMask.isZero()) {
3926 bool Is64Bit =
3927 (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
3928 Simplified = true;
3931
3932 if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
3933
3934 MI.removeOperand(4);
3935 MI.removeOperand(3);
3936 MI.removeOperand(2);
3937 MI.getOperand(1).ChangeToImmediate(0);
3938 MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
3939 } else {
3940
3941 MI.removeOperand(4);
3942 MI.removeOperand(3);
3943 MI.getOperand(2).setImm(0);
3944 MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3947 MI.getOperand(1).setIsKill(true);
3949 } else
3950
3951 MI.getOperand(1).setIsKill(false);
3952 }
3953
3956
3958 NewMB <= NewME) ||
3959 SrcMaskFull) {
3960
3961
3962
3963 Simplified = true;
3966
3967 uint16_t NewSH = (SHSrc + SHMI) % 32;
3968 MI.getOperand(2).setImm(NewSH);
3969
3970 if (!SrcMaskFull) {
3971 MI.getOperand(3).setImm(NewMB);
3972 MI.getOperand(4).setImm(NewME);
3973 }
3976 MI.getOperand(1).setIsKill(true);
3978 } else
3979
3980 MI.getOperand(1).setIsKill(false);
3981
3984 }
3985 if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
3987
3988
3989
3990 *ToErase = SrcMI;
3993 }
3994 return Simplified;
3995}
3996
3999
4000
4001
4002
4009 switch (Opc) {
4010 default: return false;
4011 case PPC::ADD4:
4012 case PPC::ADD8:
4018 III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4019 break;
4020 case PPC::ADDC:
4021 case PPC::ADDC8:
4027 III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4028 break;
4029 case PPC::ADDC_rec:
4036 break;
4037 case PPC::SUBFC:
4038 case PPC::SUBFC8:
4043 III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4044 break;
4045 case PPC::CMPW:
4046 case PPC::CMPD:
4051 III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4052 break;
4053 case PPC::CMPLW:
4054 case PPC::CMPLD:
4059 III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4060 break;
4061 case PPC::AND_rec:
4062 case PPC::AND8_rec:
4063 case PPC::OR:
4064 case PPC::OR8:
4065 case PPC::XOR:
4066 case PPC::XOR8:
4071 switch(Opc) {
4073 case PPC::AND_rec:
4075 break;
4076 case PPC::AND8_rec:
4078 break;
4079 case PPC::OR: III.ImmOpcode = PPC::ORI; break;
4080 case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
4081 case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
4082 case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
4083 }
4084 break;
4085 case PPC::RLWNM:
4086 case PPC::RLWNM8:
4087 case PPC::RLWNM_rec:
4088 case PPC::RLWNM8_rec:
4089 case PPC::SLW:
4090 case PPC::SLW8:
4091 case PPC::SLW_rec:
4092 case PPC::SLW8_rec:
4093 case PPC::SRW:
4094 case PPC::SRW8:
4095 case PPC::SRW_rec:
4096 case PPC::SRW8_rec:
4097 case PPC::SRAW:
4098 case PPC::SRAW_rec:
4103
4104
4105
4106
4108 if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 || Opc == PPC::RLWNM_rec ||
4109 Opc == PPC::RLWNM8_rec)
4111 else
4113 switch(Opc) {
4115 case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
4116 case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
4117 case PPC::RLWNM_rec:
4118 III.ImmOpcode = PPC::RLWINM_rec;
4119 break;
4120 case PPC::RLWNM8_rec:
4121 III.ImmOpcode = PPC::RLWINM8_rec;
4122 break;
4123 case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
4124 case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
4125 case PPC::SLW_rec:
4126 III.ImmOpcode = PPC::RLWINM_rec;
4127 break;
4128 case PPC::SLW8_rec:
4129 III.ImmOpcode = PPC::RLWINM8_rec;
4130 break;
4131 case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
4132 case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
4133 case PPC::SRW_rec:
4134 III.ImmOpcode = PPC::RLWINM_rec;
4135 break;
4136 case PPC::SRW8_rec:
4137 III.ImmOpcode = PPC::RLWINM8_rec;
4138 break;
4139 case PPC::SRAW:
4143 break;
4144 case PPC::SRAW_rec:
4148 break;
4149 }
4150 break;
4151 case PPC::RLDCL:
4152 case PPC::RLDCL_rec:
4153 case PPC::RLDCR:
4154 case PPC::RLDCR_rec:
4155 case PPC::SLD:
4156 case PPC::SLD_rec:
4157 case PPC::SRD:
4158 case PPC::SRD_rec:
4159 case PPC::SRAD:
4160 case PPC::SRAD_rec:
4165
4166
4167
4168
4170 if (Opc == PPC::RLDCL || Opc == PPC::RLDCL_rec || Opc == PPC::RLDCR ||
4171 Opc == PPC::RLDCR_rec)
4173 else
4175 switch(Opc) {
4177 case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
4178 case PPC::RLDCL_rec:
4179 III.ImmOpcode = PPC::RLDICL_rec;
4180 break;
4181 case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
4182 case PPC::RLDCR_rec:
4183 III.ImmOpcode = PPC::RLDICR_rec;
4184 break;
4185 case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
4186 case PPC::SLD_rec:
4187 III.ImmOpcode = PPC::RLDICR_rec;
4188 break;
4189 case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
4190 case PPC::SRD_rec:
4191 III.ImmOpcode = PPC::RLDICL_rec;
4192 break;
4193 case PPC::SRAD:
4197 break;
4198 case PPC::SRAD_rec:
4202 break;
4203 }
4204 break;
4205
4206 case PPC::LBZX:
4207 case PPC::LBZX8:
4208 case PPC::LHZX:
4209 case PPC::LHZX8:
4210 case PPC::LHAX:
4211 case PPC::LHAX8:
4212 case PPC::LWZX:
4213 case PPC::LWZX8:
4214 case PPC::LWAX:
4215 case PPC::LDX:
4216 case PPC::LFSX:
4217 case PPC::LFDX:
4218 case PPC::STBX:
4219 case PPC::STBX8:
4220 case PPC::STHX:
4221 case PPC::STHX8:
4222 case PPC::STWX:
4223 case PPC::STWX8:
4224 case PPC::STDX:
4225 case PPC::STFSX:
4226 case PPC::STFDX:
4234 switch(Opc) {
4236 case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
4237 case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
4238 case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
4239 case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
4240 case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
4241 case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
4242 case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
4243 case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
4244 case PPC::LWAX:
4247 break;
4249 case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
4250 case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
4251 case PPC::STBX: III.ImmOpcode = PPC::STB; break;
4252 case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
4253 case PPC::STHX: III.ImmOpcode = PPC::STH; break;
4254 case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
4255 case PPC::STWX: III.ImmOpcode = PPC::STW; break;
4256 case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
4257 case PPC::STDX:
4260 break;
4261 case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
4262 case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
4263 }
4264 break;
4265 case PPC::LBZUX:
4266 case PPC::LBZUX8:
4267 case PPC::LHZUX:
4268 case PPC::LHZUX8:
4269 case PPC::LHAUX:
4270 case PPC::LHAUX8:
4271 case PPC::LWZUX:
4272 case PPC::LWZUX8:
4273 case PPC::LDUX:
4274 case PPC::LFSUX:
4275 case PPC::LFDUX:
4276 case PPC::STBUX:
4277 case PPC::STBUX8:
4278 case PPC::STHUX:
4279 case PPC::STHUX8:
4280 case PPC::STWUX:
4281 case PPC::STWUX8:
4282 case PPC::STDUX:
4283 case PPC::STFSUX:
4284 case PPC::STFDUX:
4292 switch(Opc) {
4294 case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
4295 case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
4296 case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
4297 case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
4298 case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
4299 case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
4300 case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
4301 case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
4302 case PPC::LDUX:
4305 break;
4306 case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
4307 case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
4308 case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
4309 case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
4310 case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
4311 case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
4312 case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
4313 case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
4314 case PPC::STDUX:
4317 break;
4318 case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
4319 case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
4320 }
4321 break;
4322
4323
4324
4325
4326 case PPC::LXVX:
4327 case PPC::LXSSPX:
4328 case PPC::LXSDX:
4329 case PPC::STXVX:
4330 case PPC::STXSSPX:
4331 case PPC::STXSDX:
4332 case PPC::XFLOADf32:
4333 case PPC::XFLOADf64:
4334 case PPC::XFSTOREf32:
4335 case PPC::XFSTOREf64:
4336 if (!Subtarget.hasP9Vector())
4337 return false;
4346 switch(Opc) {
4348 case PPC::LXVX:
4351 break;
4352 case PPC::LXSSPX:
4353 if (PostRA) {
4354 if (IsVFReg)
4356 else {
4359 }
4360 break;
4361 }
4362 [[fallthrough]];
4363 case PPC::XFLOADf32:
4365 break;
4366 case PPC::LXSDX:
4367 if (PostRA) {
4368 if (IsVFReg)
4370 else {
4373 }
4374 break;
4375 }
4376 [[fallthrough]];
4377 case PPC::XFLOADf64:
4379 break;
4380 case PPC::STXVX:
4383 break;
4384 case PPC::STXSSPX:
4385 if (PostRA) {
4386 if (IsVFReg)
4388 else {
4391 }
4392 break;
4393 }
4394 [[fallthrough]];
4395 case PPC::XFSTOREf32:
4396 III.ImmOpcode = PPC::DFSTOREf32;
4397 break;
4398 case PPC::STXSDX:
4399 if (PostRA) {
4400 if (IsVFReg)
4402 else {
4405 }
4406 break;
4407 }
4408 [[fallthrough]];
4409 case PPC::XFSTOREf64:
4410 III.ImmOpcode = PPC::DFSTOREf64;
4411 break;
4412 }
4413 break;
4414 }
4415 return true;
4416}
4417
4418
4420 assert(Op1 != Op2 && "Cannot swap operand with itself.");
4421
4422 unsigned MaxOp = std::max(Op1, Op2);
4423 unsigned MinOp = std::min(Op1, Op2);
4426 MI.removeOperand(std::max(Op1, Op2));
4427 MI.removeOperand(std::min(Op1, Op2));
4428
4429
4430
4431 if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
4432 MI.addOperand(MOp2);
4433 MI.addOperand(MOp1);
4434 } else {
4435
4436
4438 unsigned TotalOps = MI.getNumOperands() + 2;
4439 for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
4441 MI.removeOperand(i);
4442 }
4443
4444 MI.addOperand(MOp2);
4445
4446 for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
4447 if (i == MaxOp)
4448 MI.addOperand(MOp1);
4449 else {
4450 MI.addOperand(MOps.back());
4452 }
4453 }
4454 }
4455}
4456
4457
4458
4459bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
4461 unsigned OpNoForForwarding
4462 ) const {
4463
4464
4465 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4466 if (MRI.isSSA())
4467 return false;
4468
4469
4471 return false;
4472
4473
4475 return false;
4476
4477
4478
4480 return false;
4481
4482
4483
4486 return false;
4487
4488
4489
4490
4491
4492 return true;
4493}
4494
4495
4496
4497bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
4501 unsigned Opc = DefMI.getOpcode();
4502 if (Opc != PPC::ADDItocL8 && Opc != PPC::ADDI && Opc != PPC::ADDI8)
4503 return false;
4504
4505
4506
4507
4508 if (Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4509 return false;
4510
4512 "Add inst must have at least three operands");
4513 RegMO = &DefMI.getOperand(1);
4514 ImmMO = &DefMI.getOperand(2);
4515
4516
4517 if (!RegMO->isReg())
4518 return false;
4519
4520
4521
4522
4524}
4525
4526bool PPCInstrInfo::isRegElgibleForForwarding(
4529 bool &IsFwdFeederRegKilled, bool &SeenIntermediateUse) const {
4530
4531
4532
4533
4534
4535
4536 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4537 if (MRI.isSSA())
4538 return false;
4539
4541
4542
4545 It++;
4546 for (; It != E; ++It) {
4548 return false;
4550 IsFwdFeederRegKilled = true;
4552 SeenIntermediateUse = true;
4553
4554 if ((&*It) == &DefMI)
4555 break;
4556 }
4557 assert((&*It) == &DefMI && "DefMI is missing");
4558
4559
4560
4562 return KillDefMI;
4563
4564 return true;
4565}
4566
4567bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
4570 int64_t &Imm,
4571 int64_t BaseImm) const {
4573 if (DefMI.getOpcode() == PPC::ADDItocL8) {
4574
4575
4576
4579 return false;
4580
4581
4582
4583
4584
4588 return false;
4589 }
4590
4591 return true;
4592 }
4593
4594 if (ImmMO.isImm()) {
4595
4596
4597
4598
4599 APInt ActualValue(64, ImmMO.getImm() + BaseImm, true);
4601 return false;
4603 return false;
4605
4607 return false;
4610 }
4611 else
4612 return false;
4613
4614
4615
4616 return true;
4617}
4618
4620 unsigned OpNoForForwarding,
4622 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
4623 .getOperand(1).isImm())
4624 return false;
4625
4626 MachineFunction *MF = MI.getParent()->getParent();
4629
4630 int64_t Immediate = DefMI.getOperand(1).getImm();
4631
4633
4634 bool ReplaceWithLI = false;
4635 bool Is64BitLI = false;
4636 int64_t NewImm = 0;
4637 bool SetCR = false;
4638 unsigned Opc = MI.getOpcode();
4639 switch (Opc) {
4640 default:
4641 return false;
4642
4643
4644
4645
4646
4647 case PPC::CMPWI:
4648 case PPC::CMPLWI:
4649 case PPC::CMPDI:
4650 case PPC::CMPLDI: {
4651
4652
4653
4654
4655 if (PostRA)
4656 return false;
4657
4658
4660 Register DefReg = MI.getOperand(0).getReg();
4661 int64_t Comparand = MI.getOperand(2).getImm();
4662 int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
4663 ? (Comparand | 0xFFFFFFFFFFFF0000)
4664 : Comparand;
4665
4666 for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
4667 unsigned UseOpc = CompareUseMI.getOpcode();
4668 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4669 continue;
4670 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4671 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4672 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4673 unsigned RegToCopy =
4674 selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);
4675 if (RegToCopy == PPC::NoRegister)
4676 continue;
4677
4678 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4679 CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4681 CompareUseMI.removeOperand(3);
4682 CompareUseMI.removeOperand(2);
4683 continue;
4684 }
4686 dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4689
4690 CompareUseMI.setDesc(get(PPC::COPY));
4691 CompareUseMI.removeOperand(3);
4692 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4693 CmpIselsConverted++;
4696 }
4698 return true;
4699
4700
4701
4702 MissedConvertibleImmediateInstrs++;
4703 return false;
4704 }
4705
4706
4707 case PPC::ADDI:
4708 case PPC::ADDI8: {
4709
4710 int64_t Addend = MI.getOperand(2).getImm();
4711 if (isInt<16>(Addend + SExtImm)) {
4712 ReplaceWithLI = true;
4713 Is64BitLI = Opc == PPC::ADDI8;
4714 NewImm = Addend + SExtImm;
4715 break;
4716 }
4717 return false;
4718 }
4719 case PPC::SUBFIC:
4720 case PPC::SUBFIC8: {
4721
4722 if (MI.getNumOperands() > 3 && .getOperand(3).isDead())
4723 return false;
4724 int64_t Minuend = MI.getOperand(2).getImm();
4725 if (isInt<16>(Minuend - SExtImm)) {
4726 ReplaceWithLI = true;
4727 Is64BitLI = Opc == PPC::SUBFIC8;
4728 NewImm = Minuend - SExtImm;
4729 break;
4730 }
4731 return false;
4732 }
4733 case PPC::RLDICL:
4734 case PPC::RLDICL_rec:
4735 case PPC::RLDICL_32:
4736 case PPC::RLDICL_32_64: {
4737
4738 int64_t SH = MI.getOperand(2).getImm();
4739 int64_t MB = MI.getOperand(3).getImm();
4740 APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
4741 SExtImm, true);
4742 InVal = InVal.rotl(SH);
4743 uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
4744 InVal &= Mask;
4745
4746
4747
4748 if (isUInt<15>(InVal.getSExtValue()) ||
4749 (Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
4750 ReplaceWithLI = true;
4751 Is64BitLI = Opc != PPC::RLDICL_32;
4752 NewImm = InVal.getSExtValue();
4753 SetCR = Opc == PPC::RLDICL_rec;
4754 break;
4755 }
4756 return false;
4757 }
4758 case PPC::RLWINM:
4759 case PPC::RLWINM8:
4760 case PPC::RLWINM_rec:
4761 case PPC::RLWINM8_rec: {
4762 int64_t SH = MI.getOperand(2).getImm();
4763 int64_t MB = MI.getOperand(3).getImm();
4764 int64_t ME = MI.getOperand(4).getImm();
4765 APInt InVal(32, SExtImm, true);
4766 InVal = InVal.rotl(SH);
4768 InVal &= Mask;
4769
4770
4771
4772 bool ValueFits = isUInt<15>(InVal.getSExtValue());
4773 ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
4775 if (ValueFits) {
4776 ReplaceWithLI = true;
4777 Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
4778 NewImm = InVal.getSExtValue();
4779 SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
4780 break;
4781 }
4782 return false;
4783 }
4784 case PPC::ORI:
4785 case PPC::ORI8:
4786 case PPC::XORI:
4787 case PPC::XORI8: {
4788 int64_t LogicalImm = MI.getOperand(2).getImm();
4790 if (Opc == PPC::ORI || Opc == PPC::ORI8)
4791 Result = LogicalImm | SExtImm;
4792 else
4793 Result = LogicalImm ^ SExtImm;
4795 ReplaceWithLI = true;
4796 Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
4798 break;
4799 }
4800 return false;
4801 }
4802 }
4803
4804 if (ReplaceWithLI) {
4805
4806 if (SetCR) {
4807
4808
4809 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4810 if (PostRA && ImmChanged)
4811 return false;
4812
4813 if (!PostRA) {
4814
4815
4817 DefMI.getOperand(1).setImm(NewImm);
4818
4819
4820
4821 else if (MRI->use_empty(MI.getOperand(0).getReg())) {
4822 if (NewImm) {
4823 assert(Immediate && "Transformation converted zero to non-zero?");
4824 NewImm = Immediate;
4825 }
4826 } else if (ImmChanged)
4827 return false;
4828 }
4829 }
4830
4831 LLVM_DEBUG(dbgs() << "Replacing constant instruction:\n");
4835 LoadImmediateInfo LII;
4836 LII.Imm = NewImm;
4837 LII.Is64Bit = Is64BitLI;
4838 LII.SetCR = SetCR;
4839
4840
4841 if (KilledDef && SetCR)
4842 *KilledDef = nullptr;
4844
4845 if (PostRA)
4847
4850 return true;
4851 }
4852 return false;
4853}
4854
4855bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4857 MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
4859
4860
4861 if (PostRA)
4862 return false;
4863
4864
4865 if (.mayLoadOrStore())
4866 return false;
4867
4868 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(MI.getOpcode());
4869
4870 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4871 "MI must have x-form opcode");
4872
4873
4874 ImmInstrInfo III;
4875 bool IsVFReg = MI.getOperand(0).isReg()
4878
4879 if ((XFormOpcode, IsVFReg, III, PostRA))
4880 return false;
4881
4883 return false;
4884
4886 return false;
4887
4888 MachineOperand ImmOperandMI = MI.getOperand(III.ImmOpNo);
4889 if (!ImmOperandMI.isImm())
4890 return false;
4891
4892
4893 MachineOperand *ImmMO = nullptr;
4894 MachineOperand *RegMO = nullptr;
4895 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
4896 return false;
4897 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
4898
4899
4900
4901
4902 int64_t ImmBase = ImmOperandMI.getImm();
4903 int64_t Imm = 0;
4904 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm, ImmBase))
4905 return false;
4906
4907
4908 LLVM_DEBUG(dbgs() << "Replacing existing reg+imm instruction:\n");
4912
4914 MI.getOperand(III.ImmOpNo).setImm(Imm);
4915
4918 return true;
4919}
4920
4921
4922
4923
4924
4925bool PPCInstrInfo::transformToImmFormFedByAdd(
4928
4929
4930
4931
4932
4933
4934
4935 if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))
4936 return false;
4937
4938
4939
4940 MachineOperand *ImmMO = nullptr;
4941 MachineOperand *RegMO = nullptr;
4942 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
4943 return false;
4944 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
4945
4946
4947
4948 int64_t Imm = 0;
4949 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
4950 return false;
4951
4952 bool IsFwdFeederRegKilled = false;
4953 bool SeenIntermediateUse = false;
4954
4955 if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,
4956 IsFwdFeederRegKilled, SeenIntermediateUse))
4957 return false;
4958
4959 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
4961
4962
4963
4964
4965 LLVM_DEBUG(dbgs() << "Replacing indexed instruction:\n");
4969
4970
4972 false, false,
4974
4975
4976 if (ImmMO->isImm()) {
4977
4978
4980 }
4981 else {
4982
4983
4984
4985
4986
4987 if (DefMI.getOpcode() == PPC::ADDItocL8)
4989
4990
4991
4992
4993
4995 for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {
4997 MI.removeOperand(i);
4998 }
4999
5000
5002
5003 MI.addOperand(*ImmMO);
5004
5005 for (auto &MO : MOps)
5006 MI.addOperand(MO);
5007 }
5008
5009
5011
5012 if (PostRA)
5016
5017 return true;
5018}
5019
5020bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
5022 unsigned ConstantOpNo,
5024
5025 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
5026 .getOperand(1).isImm())
5027 return false;
5028
5029
5031
5032 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
5034
5036 return false;
5038 return false;
5042 APInt ActualValue(64, Imm, true);
5043 if (!ActualValue.isSignedIntN(III.ImmWidth))
5044 return false;
5045 } else {
5046 uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
5047 if ((uint64_t)Imm > UnsignedMax)
5048 return false;
5049 }
5050
5051
5052
5053
5057 Register OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
5059
5060
5061 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5063 return false;
5064 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5065 ConstantOpNo != PosForOrigZero)
5066 return false;
5067 }
5068
5069 unsigned Opc = MI.getOpcode();
5070 bool SpecialShift32 = Opc == PPC::SLW || Opc == PPC::SLW_rec ||
5071 Opc == PPC::SRW || Opc == PPC::SRW_rec ||
5072 Opc == PPC::SLW8 || Opc == PPC::SLW8_rec ||
5073 Opc == PPC::SRW8 || Opc == PPC::SRW8_rec;
5074 bool SpecialShift64 = Opc == PPC::SLD || Opc == PPC::SLD_rec ||
5075 Opc == PPC::SRD || Opc == PPC::SRD_rec;
5076 bool SetCR = Opc == PPC::SLW_rec || Opc == PPC::SRW_rec ||
5077 Opc == PPC::SLD_rec || Opc == PPC::SRD_rec;
5078 bool RightShift = Opc == PPC::SRW || Opc == PPC::SRW_rec || Opc == PPC::SRD ||
5079 Opc == PPC::SRD_rec;
5080
5081 LLVM_DEBUG(dbgs() << "Replacing reg+reg instruction: ");
5087
5088
5089
5090
5091
5092
5093 if (SpecialShift32 || SpecialShift64) {
5094 LoadImmediateInfo LII;
5095 LII.Imm = 0;
5096 LII.SetCR = SetCR;
5097 LII.Is64Bit = SpecialShift64;
5098 uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
5099 if (Imm & (SpecialShift32 ? 0x20 : 0x40))
5101
5102
5103
5104 else if (!SetCR && ShAmt == 0 && !PostRA) {
5105 MI.removeOperand(2);
5106 MI.setDesc(get(PPC::COPY));
5107 } else {
5108
5109 if (SpecialShift32) {
5110
5111
5112
5113 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 32 - ShAmt : ShAmt;
5114 uint64_t MB = RightShift ? ShAmt : 0;
5115 uint64_t ME = RightShift ? 31 : 31 - ShAmt;
5117 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
5118 .addImm(ME);
5119 } else {
5120
5121
5122
5123 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 64 - ShAmt : ShAmt;
5124 uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
5126 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
5127 }
5128 }
5129 } else
5131 }
5132
5133
5137 } else
5139
5140
5141
5144
5145
5146
5147
5150
5151
5154 const TargetRegisterClass *NewRC =
5155 MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
5156 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5157 MRI.setRegClass(RegToModify, NewRC);
5158 }
5159 }
5160 }
5161
5162 if (PostRA)
5164
5168 return true;
5169}
5170
5173 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5174 return &PPC::VSRCRegClass;
5175 return RC;
5176}
5177
5179 return PPC::getRecordFormOpcode(Opcode);
5180}
5181
5183 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5184 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5185 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5186 Opcode == PPC::LHZUX8);
5187}
5188
5189
5193 return false;
5194
5196 if ()
5197 return false;
5198
5199 int Opcode = MI->getOpcode();
5201 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5202 if (TII->isSExt32To64(Opcode))
5203 return true;
5204
5205
5207 return true;
5208
5209
5210
5211 if (Opcode == PPC::RLDICL && MI->getOperand(3).getImm() >= 33)
5212 return true;
5213
5214
5215
5216
5217 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5218 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5219 MI->getOperand(3).getImm() > 0 &&
5220 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
5221 return true;
5222
5223
5224
5225 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5226 uint16_t Imm = MI->getOperand(2).getImm();
5227 if ((Imm & 0x8000) == 0)
5228 return true;
5229 }
5230
5231 return false;
5232}
5233
5234
5235
5236
5240 return false;
5241
5243 if ()
5244 return false;
5245
5246 int Opcode = MI->getOpcode();
5248 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5249 if (TII->isZExt32To64(Opcode))
5250 return true;
5251
5252
5254 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5255 MI->getOperand(0).getReg() == Reg)
5256 return true;
5257
5258
5259
5260 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5261 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5262 int64_t Imm = MI->getOperand(1).getImm();
5263 if (((uint64_t)Imm & ~0x7FFFuLL) == 0)
5264 return true;
5265 }
5266
5267
5268
5269 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5270 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5271 Opcode == PPC::RLDICL_32_64) &&
5272 MI->getOperand(3).getImm() >= 32)
5273 return true;
5274
5275 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5276 MI->getOperand(3).getImm() >= 32 &&
5277 MI->getOperand(3).getImm() <= 63 - MI->getOperand(2).getImm())
5278 return true;
5279
5280 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5281 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5282 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5283 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
5284 return true;
5285
5286 return false;
5287}
5288
5289
5290
5292 if (.getOperand(1).isImm() ||
.getOperand(2).isReg())
5293 return false;
5294 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5295 unsigned StackOffset = MI.getOperand(1).getImm();
5296 Register StackReg = MI.getOperand(2).getReg();
5297 Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
5299 return true;
5300
5301 return false;
5302}
5303
5304
5305
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5319 unsigned BinOpDepth,
5321 if (!Reg.isVirtual())
5322 return;
5323
5325 if ()
5326 return;
5327
5328 unsigned Opcode = MI->getOpcode();
5329
5330 switch (Opcode) {
5331 case PPC::OR:
5332 case PPC::ISEL:
5333 case PPC::OR8:
5334 case PPC::PHI: {
5336 break;
5337 unsigned OperandEnd = 3, OperandStride = 1;
5338 if (Opcode == PPC::PHI) {
5339 OperandEnd = MI->getNumOperands();
5340 OperandStride = 2;
5341 }
5342
5343 for (unsigned I = 1; I < OperandEnd; I += OperandStride) {
5344 assert(MI->getOperand(I).isReg() && "Operand must be register");
5346 BinOpDepth + 1, LV);
5347 }
5348
5349 break;
5350 }
5351 case PPC::COPY: {
5352
5353
5354
5355 Register SrcReg = MI->getOperand(1).getReg();
5356
5357
5360
5361
5363 return;
5364 }
5365
5366
5367
5368
5369 if (SrcReg != PPC::X3)
5370
5371
5373 return;
5374 }
5375 case PPC::ORI:
5376 case PPC::XORI:
5377 case PPC::ORIS:
5378 case PPC::XORIS:
5379 case PPC::ORI8:
5380 case PPC::XORI8:
5381 case PPC::ORIS8:
5382 case PPC::XORIS8:
5384 LV);
5385 break;
5386 case PPC::AND:
5387 case PPC::AND8:
5389 break;
5390
5392 BinOpDepth + 1, LV);
5394 BinOpDepth + 1, LV);
5395 break;
5396 }
5397
5399 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5400 return;
5401
5403 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5404
5405
5406
5407
5408 std::unordered_map<unsigned, unsigned> OpcodeMap = {
5409 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5410 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5411 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5412 {PPC::AND, PPC::AND8}};
5413
5414 int NewOpcode = -1;
5415 auto It = OpcodeMap.find(Opcode);
5416 if (It != OpcodeMap.end()) {
5417
5418 NewOpcode = It->second;
5419 } else {
5420 if (->isSExt32To64(Opcode))
5421 return;
5422
5423
5424
5425
5426 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5427 }
5428
5429 assert(NewOpcode != -1 &&
5430 "Must have a 64-bit opcode to map the 32-bit opcode!");
5431
5435 TRI->getRegClass(MCID.operands()[0].RegClass);
5436
5437 Register SrcReg = MI->getOperand(0).getReg();
5439
5440
5441
5442
5443 if (NewRC == SrcRC)
5444 return;
5445
5447 auto MBB = MI->getParent();
5448
5449
5450
5451
5452
5453
5455 for (unsigned i = 1; i < MI->getNumOperands(); i++) {
5457 if (!Operand.isReg())
5458 continue;
5459
5462 continue;
5463
5465 TRI->getRegClass(MCID.operands()[i].RegClass);
5467 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5468 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5469
5470 Register TmpReg = MRI->createVirtualRegister(NewUsedRegRC);
5471 Register DstTmpReg = MRI->createVirtualRegister(NewUsedRegRC);
5476 .addImm(PPC::sub_32);
5477 PromoteRegs[i] = DstTmpReg;
5478 }
5479 }
5480
5481 Register NewDefinedReg = MRI->createVirtualRegister(NewRC);
5482
5485 --Iter;
5487 for (unsigned i = 1; i < MI->getNumOperands(); i++) {
5488 if (auto It = PromoteRegs.find(i); It != PromoteRegs.end())
5490 else
5492 }
5493
5494 for (unsigned i = 1; i < Iter->getNumOperands(); i++) {
5496 if (!Operand.isReg())
5497 continue;
5500 continue;
5502 }
5503
5504 MI->eraseFromParent();
5505
5506
5507
5508
5509
5513}
5514
5515
5516
5517
5518
5519
5520std::pair<bool, bool>
5522 const unsigned BinOpDepth,
5525 return std::pair<bool, bool>(false, false);
5526
5528 if ()
5529 return std::pair<bool, bool>(false, false);
5530
5533
5534
5535
5536 if (IsSExt && IsZExt)
5537 return std::pair<bool, bool>(IsSExt, IsZExt);
5538
5539 switch (MI->getOpcode()) {
5540 case PPC::COPY: {
5541 Register SrcReg = MI->getOperand(1).getReg();
5542
5543
5544
5546
5548
5550 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5551 SrcExt.second || IsZExt);
5552 }
5553
5554
5556
5557 if (MI->getParent()->getBasicBlock() ==
5559 Register VReg = MI->getOperand(0).getReg();
5563 return std::pair<bool, bool>(IsSExt, IsZExt);
5564 }
5565 }
5566
5567 if (SrcReg != PPC::X3) {
5568
5570 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5571 SrcExt.second || IsZExt);
5572 }
5573
5574
5575
5576
5577
5578
5579
5581 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5584 if (II == MBB->instr_begin() || (--II)->getOpcode() != PPC::ADJCALLSTACKUP)
5585 return IsExtendPair;
5586
5589 return IsExtendPair;
5590
5593 if (!CalleeFn)
5594 return IsExtendPair;
5596 if (IntTy && IntTy->getBitWidth() <= 32) {
5598 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5599 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5600 return std::pair<bool, bool>(IsSExt, IsZExt);
5601 }
5602
5603 return IsExtendPair;
5604 }
5605
5606
5607
5608 case PPC::ORI:
5609 case PPC::XORI:
5610 case PPC::ORI8:
5611 case PPC::XORI8: {
5612 Register SrcReg = MI->getOperand(1).getReg();
5614 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5615 SrcExt.second || IsZExt);
5616 }
5617
5618
5619
5620
5621
5622 case PPC::ORIS:
5623 case PPC::XORIS:
5624 case PPC::ORIS8:
5625 case PPC::XORIS8: {
5626 Register SrcReg = MI->getOperand(1).getReg();
5628 uint16_t Imm = MI->getOperand(2).getImm();
5629 if (Imm & 0x8000)
5630 return std::pair<bool, bool>(false, SrcExt.second || IsZExt);
5631 else
5632 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5633 SrcExt.second || IsZExt);
5634 }
5635
5636
5637
5638 case PPC::OR:
5639 case PPC::OR8:
5640 case PPC::ISEL:
5641 case PPC::PHI: {
5643 return std::pair<bool, bool>(false, false);
5644
5645
5646
5647 unsigned OperandEnd = 3, OperandStride = 1;
5648 if (MI->getOpcode() == PPC::PHI) {
5649 OperandEnd = MI->getNumOperands();
5650 OperandStride = 2;
5651 }
5652
5653 IsSExt = true;
5654 IsZExt = true;
5655 for (unsigned I = 1; I != OperandEnd; I += OperandStride) {
5656 if (->getOperand(I).isReg())
5657 return std::pair<bool, bool>(false, false);
5658
5659 Register SrcReg = MI->getOperand(I).getReg();
5661 IsSExt &= SrcExt.first;
5662 IsZExt &= SrcExt.second;
5663 }
5664 return std::pair<bool, bool>(IsSExt, IsZExt);
5665 }
5666
5667
5668
5669
5670 case PPC::AND:
5671 case PPC::AND8: {
5673 return std::pair<bool, bool>(false, false);
5674
5675 Register SrcReg1 = MI->getOperand(1).getReg();
5676 Register SrcReg2 = MI->getOperand(2).getReg();
5679 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5680 Src1Ext.second || Src2Ext.second);
5681 }
5682
5683 default:
5684 break;
5685 }
5686 return std::pair<bool, bool>(IsSExt, IsZExt);
5687}
5688
5690 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5691}
5692
5693namespace {
5698 int64_t TripCount;
5699
5700public:
5703 : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5705 TII(MF->getSubtarget().getInstrInfo()) {
5706
5707
5708 if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI)
5710 else
5711 TripCount = -1;
5712 }
5713
5714 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
5715
5716 return MI == EndLoop;
5717 }
5718
5719 std::optional createTripCountGreaterCondition(
5720 int TC, MachineBasicBlock &MBB,
5721 SmallVectorImpl &Cond) override {
5722 if (TripCount == -1) {
5723
5724
5727 MF->getSubtarget().isPPC64() ? PPC::CTR8 : PPC::CTR,
5728 true));
5729 return {};
5730 }
5731
5732 return TripCount > TC;
5733 }
5734
5735 void setPreheader(MachineBasicBlock *NewPreheader) override {
5736
5737
5738 }
5739
5740 void adjustTripCount(int TripCountAdjust) override {
5741
5742
5743 if (LoopCount->getOpcode() == PPC::LI8 ||
5744 LoopCount->getOpcode() == PPC::LI) {
5745 int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;
5747 return;
5748 }
5749
5750
5751
5752 }
5753
5754 void disposed(LiveIntervals *LIS) override {
5755 if (LIS) {
5758 }
5760
5762 }
5763};
5764}
5765
5766std::unique_ptrTargetInstrInfo::PipelinerLoopInfo
5768
5771 if (Preheader == LoopBB)
5772 Preheader = *std::next(LoopBB->pred_begin());
5774
5775 if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {
5778 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5780 MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
5781 return std::make_unique(LoopInst, &*I, LoopCount);
5782 }
5783 }
5784 return nullptr;
5785}
5786
5790
5791 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5792
5793
5794 for (auto &I : PreHeader.instrs())
5795 if (I.getOpcode() == LOOPi)
5796 return &I;
5797 return nullptr;
5798}
5799
5800
5801
5806 return false;
5807
5808
5811 return false;
5814 return false;
5815
5817 return false;
5818
5822 return true;
5823}
5824
5829
5832 return false;
5833
5834
5835
5836
5837
5838
5840 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
5841 int64_t OffsetA = 0, OffsetB = 0;
5847 int LowOffset = std::min(OffsetA, OffsetB);
5848 int HighOffset = std::max(OffsetA, OffsetB);
5849 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5851 LowOffset + (int)LowWidth.getValue() <= HighOffset)
5852 return true;
5853 }
5854 }
5855 return false;
5856}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
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")
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:5182
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
Definition PPCInstrInfo.cpp:2181
static bool definedByZeroExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)
Definition PPCInstrInfo.cpp:5237
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:3316
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:5306
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:5190
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:4419
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:3860
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:5172
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:5178
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:5317
bool isTOCSaveMI(const MachineInstr &MI) const
Definition PPCInstrInfo.cpp:5291
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:5689
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:5521
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:3753
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:3417
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const
Definition PPCInstrInfo.cpp:3703
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:5825
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:3686
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:3589
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:5787
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:3798
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:5802
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:3346
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:5767
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:3377
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const
Definition PPCInstrInfo.cpp:3710
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:3997
MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const
Definition PPCInstrInfo.cpp:3400
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.