41 #define DEBUG_TYPE "ppc-codegen"
49 cl::desc(
"use aggressive ppc isel for bit permutations"),
52 "ppc-bit-perm-rewriter-stress-rotates",
53 cl::desc(
"stress rotate selection in aggressive ppc isel for "
58 "ppc-use-branch-hint",
cl::init(
true),
59 cl::desc(
"Enable static hinting of branches on ppc"),
83 if (!PPCSubTarget->isSVR4ABI())
89 void PreprocessISelDAG()
override;
90 void PostprocessISelDAG()
override;
94 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
95 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
100 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &dl) {
101 return CurDAG->getTargetConstant(Imm, dl,
MVT::i64);
105 inline SDValue getSmallIPtrImm(
unsigned Imm,
const SDLoc &dl) {
106 return CurDAG->getTargetConstant(
107 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
112 static bool isRotateAndMask(
SDNode *
N,
unsigned Mask,
bool isShiftMask,
113 unsigned &SH,
unsigned &MB,
unsigned &ME);
117 SDNode *getGlobalBaseReg();
125 bool tryBitfieldInsert(
SDNode *
N);
126 bool tryBitPermutation(
SDNode *
N);
137 return PPCLowering->SelectAddressRegImm(N, Disp, Base, *CurDAG,
false);
157 return PPCLowering->SelectAddressRegReg(N, Base, Index, *CurDAG);
163 return PPCLowering->SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
170 return PPCLowering->SelectAddressRegImm(N, Disp, Base, *CurDAG,
true);
184 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
185 unsigned ConstraintID,
186 std::vector<SDValue> &OutOps)
override {
188 switch(ConstraintID) {
190 errs() <<
"ConstraintID: " << ConstraintID <<
"\n";
206 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
210 OutOps.push_back(NewOp);
219 return "PowerPC DAG->DAG Pattern Instruction Selection";
223 #include "PPCGenDAGISel.inc"
228 void PeepholePPC64();
229 void PeepholePPC64ZExt();
230 void PeepholeCROps();
235 bool AllUsersSelectZero(
SDNode *N);
236 void SwapAllSelectUsers(
SDNode *N);
251 bool HasVectorVReg =
false;
252 for (
unsigned i = 0, e = RegInfo->getNumVirtRegs();
i != e; ++
i) {
254 if (RegInfo->getRegClass(Reg) == &PPC::VRRCRegClass) {
255 HasVectorVReg =
true;
259 if (!HasVectorVReg)
return;
273 unsigned InVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
274 unsigned UpdatedVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
284 BuildMI(EntryBB, IP, dl, TII.
get(PPC::MFVRSAVE), InVRSAVE);
285 BuildMI(EntryBB, IP, dl, TII.
get(PPC::UPDATE_VRSAVE),
286 UpdatedVRSAVE).addReg(InVRSAVE);
287 BuildMI(EntryBB, IP, dl, TII.
get(PPC::MTVRSAVE)).addReg(UpdatedVRSAVE);
291 if (BB->isReturnBlock()) {
292 IP = BB->end(); --IP;
297 while (I2 != BB->begin() && (--I2)->isTerminator())
301 BuildMI(*BB, IP, dl, TII.
get(PPC::MTVRSAVE)).addReg(InVRSAVE);
310 SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
319 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) ==
MVT::i32) {
320 if (PPCSubTarget->isTargetELF()) {
323 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MoveGOTtoLR));
327 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR));
329 unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
337 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
338 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR));
342 GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
343 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR8));
348 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
360 Imm = (short)cast<ConstantSDNode>(N)->getZExtValue();
362 return Imm == (int32_t)cast<ConstantSDNode>(
N)->getZExtValue();
364 return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
376 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
386 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
400 assert(isa<BasicBlockSDNode>(DestMBB));
430 if (std::max(TProb, FProb) / Threshold <
std::min(TProb, FProb))
435 <<
" -> " << TBB->
getName() <<
": " << TProb <<
"\n"
436 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
442 if (BBDN->getBasicBlock()->getBasicBlock() != TBB)
458 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
463 getSmallIPtrImm(Offset, dl));
465 ReplaceNode(SN, CurDAG->getMachineNode(Opc, dl, N->
getValueType(0), TFI,
466 getSmallIPtrImm(Offset, dl)));
469 bool PPCDAGToDAGISel::isRotateAndMask(
SDNode *N,
unsigned Mask,
470 bool isShiftMask,
unsigned &SH,
471 unsigned &MB,
unsigned &ME) {
478 unsigned Indeterminant = ~0;
486 if (isShiftMask) Mask = Mask << Shift;
488 Indeterminant = ~(0xFFFFFFFFu << Shift);
491 if (isShiftMask) Mask = Mask >> Shift;
493 Indeterminant = ~(0xFFFFFFFFu >> Shift);
503 if (Mask && !(Mask & Indeterminant)) {
513 bool PPCDAGToDAGISel::tryBitfieldInsert(
SDNode *N) {
518 APInt LKZ, LKO, RKZ, RKO;
519 CurDAG->computeKnownBits(Op0, LKZ, LKO);
520 CurDAG->computeKnownBits(Op1, RKZ, RKO);
525 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
528 unsigned Value, SH = 0;
529 TargetMask = ~TargetMask;
530 InsertMask = ~InsertMask;
560 SH = (Op1Opc ==
ISD::SHL) ? Value : 32 - Value;
567 CurDAG->computeKnownBits(Op1.
getOperand(1), MKZ, MKO);
576 SH = (SHOpc ==
ISD::SHL) ? Value : 32 - Value;
581 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
583 ReplaceNode(N, CurDAG->getMachineNode(PPC::RLWIMI, dl,
MVT::i32, Ops));
594 unsigned Remainder = 0;
600 Shift = countTrailingZeros<uint64_t>(Imm);
601 int64_t ImmSh =
static_cast<uint64_t
>(Imm) >> Shift;
619 unsigned Lo = Imm & 0xFFFF;
634 if (!Shift)
return Result;
638 if ((
unsigned)(Imm & 0xFFFFFFFF) == Remainder) {
648 if ((Remainder >> 16) & 0xFFFF)
650 if (Remainder & 0xFFFF)
656 static uint64_t
Rot64(uint64_t Imm,
unsigned R) {
657 return (Imm << R) | (Imm >> (64 - R));
665 for (
unsigned r = 1; r < 63; ++r) {
666 uint64_t RImm =
Rot64(Imm, r);
675 uint64_t OnesMask = -(int64_t) (UINT64_C(1) << (LS+1));
676 uint64_t RImmWithOnes = RImm | OnesMask;
690 unsigned Remainder = 0;
696 Shift = countTrailingZeros<uint64_t>(Imm);
697 int64_t ImmSh =
static_cast<uint64_t
>(Imm) >> Shift;
715 unsigned Lo = Imm & 0xFFFF;
716 unsigned Hi = (Imm >> 16) & 0xFFFF;
718 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
728 unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8;
732 SDValue(Result, 0), getI32Imm(Lo));
739 if (!Shift)
return Result;
743 if ((
unsigned)(Imm & 0xFFFFFFFF) == Remainder) {
745 {
SDValue(Result, 0),
SDValue(Result, 0), getI32Imm(Shift), getI32Imm(0)};
754 getI32Imm(63 - Shift));
758 if ((Hi = (Remainder >> 16) & 0xFFFF)) {
760 SDValue(Result, 0), getI32Imm(Hi));
762 if ((Lo = Remainder & 0xFFFF)) {
764 SDValue(Result, 0), getI32Imm(Lo));
780 for (
unsigned r = 1; r < 63; ++r) {
781 uint64_t RImm =
Rot64(Imm, r);
783 if (RCount < Count) {
802 uint64_t OnesMask = -(int64_t) (UINT64_C(1) << (LS+1));
803 uint64_t RImmWithOnes = RImm | OnesMask;
806 if (RCount < Count) {
809 MatImm = RImmWithOnes;
817 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
823 getI32Imm(64 - RMin), getI32Imm(MaskEnd));
831 int64_t Imm = cast<ConstantSDNode>(
N)->getZExtValue();
836 class BitPermutationSelector {
850 : V(V), Idx(I), K(K) {}
851 ValueBit(
Kind K = Variable)
852 : V(
SDValue(nullptr, 0)), Idx(UINT32_MAX), K(K) {}
855 return K == ConstZero;
858 bool hasValue()
const {
859 return K == Variable;
863 assert(hasValue() &&
"Cannot get the value of a constant bit");
867 unsigned getValueBitIndex()
const {
868 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
877 unsigned StartIdx, EndIdx;
887 bool Repl32Coalesced;
889 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
890 : V(V), RLAmt(R), StartIdx(S), EndIdx(E), Repl32(
false), Repl32CR(
false),
891 Repl32Coalesced(
false) {
893 " [" << S <<
", " << E <<
"]\n");
899 struct ValueRotInfo {
903 unsigned FirstGroupStartIdx;
907 : RLAmt(UINT32_MAX), NumGroups(0), FirstGroupStartIdx(UINT32_MAX),
912 bool operator < (
const ValueRotInfo &Other)
const {
916 if (Repl32 < Other.Repl32)
918 else if (Repl32 > Other.Repl32)
920 else if (NumGroups > Other.NumGroups)
922 else if (NumGroups < Other.NumGroups)
924 else if (FirstGroupStartIdx < Other.FirstGroupStartIdx)
930 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
931 using ValueBitsMemoizer =
933 ValueBitsMemoizer Memoizer;
939 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
941 auto &ValueEntry = Memoizer[V];
943 return std::make_pair(ValueEntry->first, &ValueEntry->second);
944 ValueEntry.reset(
new ValueBitsMemoizedValue());
945 bool &Interesting = ValueEntry->first;
955 const auto &LHSBits = *getValueBits(V.
getOperand(0), NumBits).second;
957 for (
unsigned i = 0;
i < NumBits; ++
i)
958 Bits[
i] = LHSBits[
i < RotAmt ?
i + (NumBits - RotAmt) :
i - RotAmt];
960 return std::make_pair(Interesting =
true, &Bits);
967 const auto &LHSBits = *getValueBits(V.
getOperand(0), NumBits).second;
969 for (
unsigned i = ShiftAmt;
i < NumBits; ++
i)
970 Bits[
i] = LHSBits[
i - ShiftAmt];
972 for (
unsigned i = 0;
i < ShiftAmt; ++
i)
973 Bits[
i] = ValueBit(ValueBit::ConstZero);
975 return std::make_pair(Interesting =
true, &Bits);
982 const auto &LHSBits = *getValueBits(V.
getOperand(0), NumBits).second;
984 for (
unsigned i = 0;
i < NumBits - ShiftAmt; ++
i)
985 Bits[
i] = LHSBits[
i + ShiftAmt];
987 for (
unsigned i = NumBits - ShiftAmt;
i < NumBits; ++
i)
988 Bits[
i] = ValueBit(ValueBit::ConstZero);
990 return std::make_pair(Interesting =
true, &Bits);
1002 std::tie(Interesting, LHSBits) = getValueBits(V.
getOperand(0), NumBits);
1004 for (
unsigned i = 0;
i < NumBits; ++
i)
1005 if (((Mask >>
i) & 1) == 1)
1006 Bits[
i] = (*LHSBits)[
i];
1008 Bits[
i] = ValueBit(ValueBit::ConstZero);
1010 return std::make_pair(Interesting, &Bits);
1014 const auto &LHSBits = *getValueBits(V.
getOperand(0), NumBits).second;
1015 const auto &RHSBits = *getValueBits(V.
getOperand(1), NumBits).second;
1017 bool AllDisjoint =
true;
1018 for (
unsigned i = 0;
i < NumBits; ++
i)
1020 Bits[
i] = RHSBits[
i];
1022 Bits[
i] = LHSBits[
i];
1024 AllDisjoint =
false;
1031 return std::make_pair(Interesting =
true, &Bits);
1035 for (
unsigned i = 0;
i < NumBits; ++
i)
1036 Bits[
i] = ValueBit(V,
i);
1038 return std::make_pair(Interesting =
false, &Bits);
1043 void computeRotationAmounts() {
1045 RLAmt.resize(Bits.
size());
1046 for (
unsigned i = 0;
i < Bits.
size(); ++
i)
1047 if (Bits[
i].hasValue()) {
1048 unsigned VBI = Bits[
i].getValueBitIndex();
1052 RLAmt[
i] = Bits.
size() - (VBI -
i);
1053 }
else if (Bits[
i].
isZero()) {
1055 RLAmt[
i] = UINT32_MAX;
1064 void collectBitGroups(
bool LateMask) {
1067 unsigned LastRLAmt = RLAmt[0];
1068 SDValue LastValue = Bits[0].hasValue() ? Bits[0].getValue() :
SDValue();
1069 unsigned LastGroupStartIdx = 0;
1070 for (
unsigned i = 1;
i < Bits.
size(); ++
i) {
1071 unsigned ThisRLAmt = RLAmt[
i];
1073 if (LateMask && !ThisValue) {
1074 ThisValue = LastValue;
1075 ThisRLAmt = LastRLAmt;
1078 if (BitGroups.empty())
1079 LastGroupStartIdx = 0;
1084 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1088 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1090 LastRLAmt = ThisRLAmt;
1091 LastValue = ThisValue;
1092 LastGroupStartIdx =
i;
1095 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1098 if (BitGroups.empty())
1102 if (BitGroups.size() > 1) {
1106 if (BitGroups[0].StartIdx == 0 &&
1107 BitGroups[BitGroups.size()-1].EndIdx == Bits.
size()-1 &&
1108 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1109 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1110 DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1111 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1112 BitGroups.erase(BitGroups.begin());
1120 void collectValueRotInfo() {
1123 for (
auto &BG : BitGroups) {
1124 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1125 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1127 VRI.RLAmt = BG.RLAmt;
1128 VRI.Repl32 = BG.Repl32;
1130 VRI.FirstGroupStartIdx =
std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1135 ValueRotsVec.clear();
1136 for (
auto &
I : ValueRots) {
1137 ValueRotsVec.push_back(
I.second);
1139 std::sort(ValueRotsVec.begin(), ValueRotsVec.end());
1150 void assignRepl32BitGroups() {
1161 auto IsAllLow32 = [
this](BitGroup & BG) {
1162 if (BG.StartIdx <= BG.EndIdx) {
1163 for (
unsigned i = BG.StartIdx;
i <= BG.EndIdx; ++
i) {
1164 if (!Bits[
i].hasValue())
1166 if (Bits[
i].getValueBitIndex() >= 32)
1170 for (
unsigned i = BG.StartIdx;
i < Bits.
size(); ++
i) {
1171 if (!Bits[
i].hasValue())
1173 if (Bits[
i].getValueBitIndex() >= 32)
1176 for (
unsigned i = 0;
i <= BG.EndIdx; ++
i) {
1177 if (!Bits[
i].hasValue())
1179 if (Bits[
i].getValueBitIndex() >= 32)
1187 for (
auto &BG : BitGroups) {
1188 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
1189 if (IsAllLow32(BG)) {
1190 if (BG.RLAmt >= 32) {
1197 DEBUG(
dbgs() <<
"\t32-bit replicated bit group for " <<
1198 BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
1199 " [" << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
1205 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
1208 auto IP = (
I == BitGroups.begin()) ?
1209 std::prev(BitGroups.end()) : std::prev(
I);
1210 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
1211 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
1213 DEBUG(
dbgs() <<
"\tcombining 32-bit replicated bit group for " <<
1214 I->V.getNode() <<
" RLAmt = " <<
I->RLAmt <<
1215 " [" <<
I->StartIdx <<
", " <<
I->EndIdx <<
1216 "] with group with range [" <<
1217 IP->StartIdx <<
", " << IP->EndIdx <<
"]\n");
1219 IP->EndIdx =
I->EndIdx;
1220 IP->Repl32CR = IP->Repl32CR ||
I->Repl32CR;
1221 IP->Repl32Coalesced =
true;
1222 I = BitGroups.erase(
I);
1231 if (
I->StartIdx == 32 &&
I->EndIdx == 63) {
1232 assert(std::next(
I) == BitGroups.end() &&
1233 "bit group ends at index 63 but there is another?");
1234 auto IN = BitGroups.begin();
1236 if (IP->Repl32 && IN->Repl32 &&
I->V == IP->V &&
I->V == IN->V &&
1237 (
I->RLAmt % 32) == IP->RLAmt && (
I->RLAmt % 32) == IN->RLAmt &&
1238 IP->EndIdx == 31 && IN->StartIdx == 0 &&
I != IP &&
1241 DEBUG(
dbgs() <<
"\tcombining bit group for " <<
1242 I->V.getNode() <<
" RLAmt = " <<
I->RLAmt <<
1243 " [" <<
I->StartIdx <<
", " <<
I->EndIdx <<
1244 "] with 32-bit replicated groups with ranges [" <<
1245 IP->StartIdx <<
", " << IP->EndIdx <<
"] and [" <<
1246 IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
1254 IP->Repl32CR = IP->Repl32CR ||
I->RLAmt >= 32;
1255 IP->Repl32Coalesced =
true;
1256 I = BitGroups.erase(
I);
1261 IP->EndIdx = IN->EndIdx;
1262 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR ||
I->RLAmt >= 32;
1263 IP->Repl32Coalesced =
true;
1264 I = BitGroups.erase(
I);
1265 BitGroups.erase(BitGroups.begin());
1280 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
1283 uint64_t getZerosMask() {
1285 for (
unsigned i = 0;
i < Bits.
size(); ++
i) {
1286 if (Bits[
i].hasValue())
1288 Mask |= (UINT64_C(1) <<
i);
1297 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
1301 for (ValueRotInfo &VRI : ValueRotsVec) {
1303 for (
unsigned i = 0;
i < Bits.
size(); ++
i) {
1304 if (!Bits[
i].hasValue() || Bits[
i].getValue() != VRI.V)
1306 if (RLAmt[
i] != VRI.RLAmt)
1312 unsigned ANDIMask = (Mask & UINT16_MAX), ANDISMask = Mask >> 16;
1313 assert((ANDIMask != 0 || ANDISMask != 0) &&
1314 "No set bits in mask for value bit groups");
1315 bool NeedsRotate = VRI.RLAmt != 0;
1331 unsigned NumAndInsts = (
unsigned) NeedsRotate +
1332 (
unsigned) (ANDIMask != 0) +
1333 (
unsigned) (ANDISMask != 0) +
1334 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
1335 (
unsigned) (
bool) Res;
1337 DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode() <<
1338 " RL: " << VRI.RLAmt <<
":" <<
1339 "\n\t\t\tisel using masking: " << NumAndInsts <<
1340 " using rotates: " << VRI.NumGroups <<
"\n");
1342 if (NumAndInsts >= VRI.NumGroups)
1345 DEBUG(
dbgs() <<
"\t\t\t\tusing masking\n");
1347 if (InstCnt) *InstCnt += NumAndInsts;
1352 { VRI.V, getI32Imm(VRI.RLAmt, dl), getI32Imm(0, dl),
1353 getI32Imm(31, dl) };
1363 VRot, getI32Imm(ANDIMask, dl)), 0);
1366 VRot, getI32Imm(ANDISMask, dl)), 0);
1370 TotalVal = ANDISVal;
1375 ANDIVal, ANDISVal), 0);
1385 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
1386 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
1392 SDNode *Select32(
SDNode *N,
bool LateMask,
unsigned *InstCnt) {
1396 if (InstCnt) *InstCnt = 0;
1399 SelectAndParts32(dl, Res, InstCnt);
1404 if ((!HasZeros || LateMask) && !Res) {
1405 ValueRotInfo &VRI = ValueRotsVec[0];
1407 if (InstCnt) *InstCnt += 1;
1409 { VRI.V, getI32Imm(VRI.RLAmt, dl), getI32Imm(0, dl),
1410 getI32Imm(31, dl) };
1418 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
1419 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
1423 if (InstCnt) *InstCnt += BitGroups.size();
1426 for (
auto &BG : BitGroups) {
1429 { BG.V, getI32Imm(BG.RLAmt, dl),
1430 getI32Imm(Bits.
size() - BG.EndIdx - 1, dl),
1431 getI32Imm(Bits.
size() - BG.StartIdx - 1, dl) };
1432 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, Ops), 0);
1435 { Res, BG.V, getI32Imm(BG.RLAmt, dl),
1436 getI32Imm(Bits.
size() - BG.EndIdx - 1, dl),
1437 getI32Imm(Bits.
size() - BG.StartIdx - 1, dl) };
1438 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl,
MVT::i32, Ops), 0);
1443 unsigned Mask = (
unsigned) getZerosMask();
1445 unsigned ANDIMask = (Mask & UINT16_MAX), ANDISMask = Mask >> 16;
1446 assert((ANDIMask != 0 || ANDISMask != 0) &&
1447 "No set bits in zeros mask?");
1449 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
1451 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
1456 Res, getI32Imm(ANDIMask, dl)), 0);
1459 Res, getI32Imm(ANDISMask, dl)), 0);
1467 ANDIVal, ANDISVal), 0);
1473 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
1474 unsigned MaskStart,
unsigned MaskEnd,
1478 unsigned InstMaskStart = 64 - MaskEnd - 1,
1479 InstMaskEnd = 64 - MaskStart - 1;
1484 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
1485 InstMaskEnd == 63 - RLAmt)
1494 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
1495 unsigned *InstCnt =
nullptr) {
1498 unsigned InstMaskStart = 64 - MaskEnd - 1,
1499 InstMaskEnd = 64 - MaskStart - 1;
1501 if (InstCnt) *InstCnt += 1;
1507 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
1508 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
1510 { V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskStart - 32, dl),
1511 getI32Imm(InstMaskEnd - 32, dl) };
1516 if (InstMaskEnd == 63) {
1518 { V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskStart, dl) };
1519 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl,
MVT::i64, Ops), 0);
1522 if (InstMaskStart == 0) {
1524 { V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskEnd, dl) };
1525 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl,
MVT::i64, Ops), 0);
1528 if (InstMaskEnd == 63 - RLAmt) {
1530 { V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskStart, dl) };
1531 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl,
MVT::i64, Ops), 0);
1540 if (InstCnt) *InstCnt += 1;
1543 unsigned RLAmt2 = MaskStart;
1546 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
1548 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
1549 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
1555 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
1556 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
1559 unsigned InstMaskStart = 64 - MaskEnd - 1,
1560 InstMaskEnd = 64 - MaskStart - 1;
1562 if (InstCnt) *InstCnt += 1;
1568 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
1569 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
1571 { Base, V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskStart - 32, dl),
1572 getI32Imm(InstMaskEnd - 32, dl) };
1577 if (InstMaskEnd == 63 - RLAmt) {
1579 { Base, V, getI32Imm(RLAmt, dl), getI32Imm(InstMaskStart, dl) };
1580 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl,
MVT::i64, Ops), 0);
1589 if (InstCnt) *InstCnt += 1;
1592 unsigned RLAmt2 = MaskStart;
1595 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
1597 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
1598 return SelectRotMaskIns64(Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
1601 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
1614 for (ValueRotInfo &VRI : ValueRotsVec) {
1622 auto MatchingBG = [VRI](
const BitGroup &BG) {
1626 unsigned EffRLAmt = BG.RLAmt;
1627 if (!VRI.Repl32 && BG.Repl32) {
1628 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
1629 !BG.Repl32Coalesced) {
1635 }
else if (VRI.Repl32 != BG.Repl32) {
1639 return VRI.RLAmt == EffRLAmt;
1642 for (
auto &BG : BitGroups) {
1643 if (!MatchingBG(BG))
1646 if (BG.StartIdx <= BG.EndIdx) {
1647 for (
unsigned i = BG.StartIdx;
i <= BG.EndIdx; ++
i)
1648 Mask |= (UINT64_C(1) <<
i);
1650 for (
unsigned i = BG.StartIdx;
i < Bits.
size(); ++
i)
1651 Mask |= (UINT64_C(1) <<
i);
1652 for (
unsigned i = 0;
i <= BG.EndIdx; ++
i)
1653 Mask |= (UINT64_C(1) <<
i);
1662 unsigned ANDIMask = (Mask & UINT16_MAX),
1663 ANDISMask = (Mask >> 16) & UINT16_MAX;
1665 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(
Mask));
1667 unsigned NumAndInsts = (
unsigned) NeedsRotate +
1668 (
unsigned) (
bool) Res;
1671 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
1675 unsigned NumRLInsts = 0;
1676 bool FirstBG =
true;
1677 bool MoreBG =
false;
1678 for (
auto &BG : BitGroups) {
1679 if (!MatchingBG(BG)) {
1684 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
1689 DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode() <<
1690 " RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":") <<
1691 "\n\t\t\tisel using masking: " << NumAndInsts <<
1692 " using rotates: " << NumRLInsts <<
"\n");
1698 if (NumAndInsts > NumRLInsts)
1703 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
1706 DEBUG(
dbgs() <<
"\t\t\t\tusing masking\n");
1708 if (InstCnt) *InstCnt += NumAndInsts;
1715 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
1716 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
1717 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
1722 if (Use32BitInsts) {
1723 assert((ANDIMask != 0 || ANDISMask != 0) &&
1724 "No set bits in mask when using 32-bit ands for 64-bit value");
1729 VRot, getI32Imm(ANDIMask, dl)), 0);
1732 VRot, getI32Imm(ANDISMask, dl)), 0);
1735 TotalVal = ANDISVal;
1740 ANDIVal, ANDISVal), 0);
1745 VRot, TotalVal), 0);
1756 eraseMatchingBitGroups(MatchingBG);
1761 SDNode *Select64(
SDNode *N,
bool LateMask,
unsigned *InstCnt) {
1765 if (InstCnt) *InstCnt = 0;
1768 SelectAndParts64(dl, Res, InstCnt);
1773 if ((!HasZeros || LateMask) && !Res) {
1777 unsigned MaxGroupsIdx = 0;
1778 if (!ValueRotsVec[0].Repl32) {
1779 for (
unsigned i = 0, ie = ValueRotsVec.size();
i < ie; ++
i)
1780 if (ValueRotsVec[
i].Repl32) {
1781 if (ValueRotsVec[
i].NumGroups > ValueRotsVec[0].NumGroups)
1787 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
1788 bool NeedsRotate =
false;
1791 }
else if (VRI.Repl32) {
1792 for (
auto &BG : BitGroups) {
1793 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
1794 BG.Repl32 != VRI.Repl32)
1799 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
1808 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
1809 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
1816 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
1817 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
1818 BG.Repl32 == VRI.Repl32;
1825 for (
auto I = BitGroups.begin(),
IE = BitGroups.end();
I !=
IE; ++
I) {
1826 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
1828 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
1830 if (
I != BitGroups.begin()) {
1833 BitGroups.insert(BitGroups.begin(), BG);
1841 for (
auto &BG : BitGroups) {
1843 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
1844 BG.EndIdx, InstCnt);
1846 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
1847 BG.StartIdx, BG.EndIdx, InstCnt);
1851 uint64_t Mask = getZerosMask();
1858 unsigned ANDIMask = (Mask & UINT16_MAX),
1859 ANDISMask = (Mask >> 16) & UINT16_MAX;
1861 if (Use32BitInsts) {
1862 assert((ANDIMask != 0 || ANDISMask != 0) &&
1863 "No set bits in mask when using 32-bit ands for 64-bit value");
1865 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
1867 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
1872 Res, getI32Imm(ANDIMask, dl)), 0);
1875 Res, getI32Imm(ANDISMask, dl)), 0);
1883 ANDIVal, ANDISVal), 0);
1899 collectBitGroups(LateMask);
1900 if (BitGroups.empty())
1904 if (Bits.
size() == 64)
1905 assignRepl32BitGroups();
1908 collectValueRotInfo();
1910 if (Bits.
size() == 32) {
1911 return Select32(N, LateMask, InstCnt);
1913 assert(Bits.
size() == 64 &&
"Not 64 bits here?");
1914 return Select64(N, LateMask, InstCnt);
1920 void eraseMatchingBitGroups(
function_ref<
bool(
const BitGroup &)>
F) {
1921 BitGroups.erase(
remove_if(BitGroups,
F), BitGroups.end());
1949 Bits = std::move(*Result.second);
1951 DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
1952 " selection for: ");
1956 computeRotationAmounts();
1969 unsigned InstCnt, InstCntLateMask;
1972 DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
1976 DEBUG(
dbgs() <<
"\t\tisel would use " << InstCntLateMask <<
1979 if (InstCnt <= InstCntLateMask) {
1980 DEBUG(
dbgs() <<
"\tUsing early-masking for isel\n");
1984 DEBUG(
dbgs() <<
"\tUsing late-masking for isel\n");
1990 bool PPCDAGToDAGISel::tryBitPermutation(
SDNode *N) {
2005 BitPermutationSelector BPS(CurDAG);
2006 if (
SDNode *New = BPS.Select(N)) {
2007 ReplaceNode(N, New);
2031 getI32Imm(Imm & 0xFFFF, dl)),
2036 getI32Imm(Imm & 0xFFFF, dl)),
2049 getI32Imm(Imm >> 16, dl)), 0);
2051 getI32Imm(Imm & 0xFFFF, dl)), 0);
2057 getI32Imm(Imm & 0xFFFF, dl)), 0);
2063 getI32Imm((
int)SImm & 0xFFFF,
2075 getI32Imm(Imm & 0xFFFF, dl)),
2080 getI32Imm(Imm & 0xFFFF, dl)),
2094 getI64Imm(Imm >> 16, dl)), 0);
2096 getI64Imm(Imm & 0xFFFF, dl)),
2104 getI64Imm(Imm & 0xFFFF, dl)), 0);
2110 getI64Imm(SImm & 0xFFFF, dl)),
2118 Opc = PPCSubTarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
2171 case ISD::SETO: Invert =
true;
return 3;
2187 bool HasVSX,
bool &Swap,
bool &Negate) {
2215 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
2217 return PPC::XVCMPEQDP;
2222 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
2224 return PPC::XVCMPGTDP;
2229 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
2231 return PPC::XVCMPGEDP;
2259 return PPC::VCMPEQUB;
2261 return PPC::VCMPEQUH;
2263 return PPC::VCMPEQUW;
2265 return PPC::VCMPEQUD;
2269 return PPC::VCMPGTSB;
2271 return PPC::VCMPGTSH;
2273 return PPC::VCMPGTSW;
2275 return PPC::VCMPGTSD;
2279 return PPC::VCMPGTUB;
2281 return PPC::VCMPGTUH;
2283 return PPC::VCMPGTUW;
2285 return PPC::VCMPGTUD;
2294 bool PPCDAGToDAGISel::trySETCC(
SDNode *N) {
2300 bool isPPC64 = (PtrVT ==
MVT::i64);
2302 if (!PPCSubTarget->useCRBits() &&
2313 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
2314 getI32Imm(31, dl) };
2322 Op, getI32Imm(~0U, dl)), 0);
2327 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
2328 getI32Imm(31, dl) };
2336 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
2337 getI32Imm(31, dl) };
2342 }
else if (Imm == ~0U) {
2349 Op, getI32Imm(1, dl)), 0);
2360 Op, getI32Imm(~0U, dl));
2367 getI32Imm(1, dl)), 0);
2370 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
2371 getI32Imm(31, dl) };
2376 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
2377 getI32Imm(31, dl) };
2392 if (PPCSubTarget->hasQPX())
2398 PPCSubTarget->hasVSX(), Swap, Negate);
2414 if (PPCSubTarget->useCRBits())
2419 SDValue CCReg = SelectCC(LHS, RHS, CC, dl);
2427 InFlag).getValue(1);
2432 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
2433 getI32Imm(31, dl), getI32Imm(31, dl) };
2446 void PPCDAGToDAGISel::transferMemOperands(
SDNode *N,
SDNode *Result) {
2449 MemOp[0] = cast<MemSDNode>(
N)->getMemOperand();
2450 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
2471 if (tryBitPermutation(N))
2479 ReplaceNode(N,
getInt64(CurDAG, N));
2491 ReplaceNode(N, getGlobalBaseReg());
2495 selectFrameIndex(N, N);
2515 getConstantIntValue(), dl,
2526 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
2553 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
2554 switch (LoadedVT.getSimpleVT().SimpleTy) {
2556 case MVT::f64: Opcode = PPC::LFDU;
break;
2557 case MVT::f32: Opcode = PPC::LFSU;
break;
2558 case MVT::i32: Opcode = PPC::LWZU;
break;
2559 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
2561 case MVT::i8: Opcode = PPC::LBZU;
break;
2565 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
2566 switch (LoadedVT.getSimpleVT().SimpleTy) {
2568 case MVT::i64: Opcode = PPC::LDU;
break;
2569 case MVT::i32: Opcode = PPC::LWZU8;
break;
2570 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
2572 case MVT::i8: Opcode = PPC::LBZU8;
break;
2582 transferMemOperands(N, MN);
2590 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
2591 switch (LoadedVT.getSimpleVT().SimpleTy) {
2593 case MVT::v4f64: Opcode = PPC::QVLFDUX;
break;
2594 case MVT::v4f32: Opcode = PPC::QVLFSUX;
break;
2595 case MVT::f64: Opcode = PPC::LFDUX;
break;
2596 case MVT::f32: Opcode = PPC::LFSUX;
break;
2597 case MVT::i32: Opcode = PPC::LWZUX;
break;
2598 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
2600 case MVT::i8: Opcode = PPC::LBZUX;
break;
2605 "Invalid sext update load");
2606 switch (LoadedVT.getSimpleVT().SimpleTy) {
2608 case MVT::i64: Opcode = PPC::LDUX;
break;
2609 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
2610 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
2612 case MVT::i8: Opcode = PPC::LBZUX8;
break;
2622 transferMemOperands(N, MN);
2629 unsigned Imm, Imm2, SH, MB, ME;
2637 SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
2638 getI32Imm(ME, dl) };
2648 SDValue Ops[] = { Val, getI32Imm(0, dl), getI32Imm(MB, dl),
2649 getI32Imm(ME, dl) };
2672 getI32Imm(1, dl)), 0);
2684 assert(Imm < 64 &&
"Illegal shift amount");
2689 SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) };
2717 if (
isRunOfOnes(~(Imm^Imm2), MB, ME) && !(~Imm & Imm2)) {
2720 getI32Imm(0, dl), getI32Imm(MB, dl),
2721 getI32Imm(ME, dl) };
2732 if (tryBitfieldInsert(N))
2738 APInt LHSKnownZero, LHSKnownOne;
2743 if ((LHSKnownZero.
getZExtValue()|~(uint64_t)Imm) == ~0ULL) {
2763 unsigned Imm, SH, MB, ME;
2765 isRotateAndMask(N, Imm,
true, SH, MB, ME)) {
2767 getI32Imm(SH, dl), getI32Imm(MB, dl),
2768 getI32Imm(ME, dl) };
2777 unsigned Imm, SH, MB, ME;
2779 isRotateAndMask(N, Imm,
true, SH, MB, ME)) {
2781 getI32Imm(SH, dl), getI32Imm(MB, dl),
2782 getI32Imm(ME, dl) };
2798 "Invalid input type for ANDIo_1_EQ_BIT");
2800 unsigned Opcode = (InVT ==
MVT::i64) ? PPC::ANDIo8 : PPC::ANDIo;
2808 PPC::sub_eq : PPC::sub_gt, dl,
MVT::i32);
2811 SRIdxVal,
SDValue(AndI.getNode(), 1) );
2818 bool isPPC64 = (PtrVT ==
MVT::i64);
2821 if (PPCSubTarget->useCRBits() &&
2830 if (N1C->isNullValue() && N3C->isNullValue() &&
2831 N2C->getZExtValue() == 1ULL && CC ==
ISD::SETNE &&
2852 case 0: SRI = PPC::sub_lt;
break;
2853 case 1: SRI = PPC::sub_gt;
break;
2854 case 2: SRI = PPC::sub_eq;
break;
2855 case 3: SRI = PPC::sub_un;
break;
2862 SDValue C = Inv ? NotCCBit : CCBit,
2863 NotC = Inv ? CCBit : NotCCBit;
2876 unsigned SelectCCOp;
2878 SelectCCOp = PPC::SELECT_CC_I4;
2880 SelectCCOp = PPC::SELECT_CC_I8;
2882 if (PPCSubTarget->hasP8Vector())
2883 SelectCCOp = PPC::SELECT_CC_VSSRC;
2885 SelectCCOp = PPC::SELECT_CC_F4;
2887 if (PPCSubTarget->hasVSX())
2888 SelectCCOp = PPC::SELECT_CC_VSFRC;
2890 SelectCCOp = PPC::SELECT_CC_F8;
2892 SelectCCOp = PPC::SELECT_CC_QFRC;
2894 SelectCCOp = PPC::SELECT_CC_QSRC;
2896 SelectCCOp = PPC::SELECT_CC_QBRC;
2899 SelectCCOp = PPC::SELECT_CC_VSRC;
2901 SelectCCOp = PPC::SELECT_CC_VRRC;
2904 getI32Imm(BROpc, dl) };
2909 if (PPCSubTarget->hasVSX()) {
2925 for (
int i = 0;
i < 2; ++
i)
2931 if (Op1 == Op2 && DM[0] == 0 && DM[1] == 0 &&
2933 isa<LoadSDNode>(Op1.getOperand(0))) {
2934 LoadSDNode *LD = cast<LoadSDNode>(Op1.getOperand(0));
2950 if (PPCSubTarget->isLittleEndian()) {
2952 unsigned tmp = DM[0];
2959 SDValue Ops[] = { Op1, Op2, DMV };
2967 bool IsPPC64 = PPCSubTarget->isPPC64();
2971 : (IsPPC64 ? PPC::BDZ8 :
PPC::BDZ),
2982 unsigned PCC = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
2986 SDValue Pred = getI32Imm(PCC, dl);
3001 case PPC::PRED_LT: Opc = PPC::CRANDC; Swap =
true;
break;
3002 case PPC::PRED_LE: Opc = PPC::CRORC; Swap =
true;
break;
3003 case PPC::PRED_EQ: Opc = PPC::CREQV; Swap =
false;
break;
3004 case PPC::PRED_GE: Opc = PPC::CRORC; Swap =
false;
break;
3005 case PPC::PRED_GT: Opc = PPC::CRANDC; Swap =
false;
break;
3006 case PPC::PRED_NE: Opc = PPC::CRXOR; Swap =
false;
break;
3038 assert ((PPCSubTarget->isPPC64() || PPCSubTarget->isSVR4ABI()) &&
3039 "Only supported for 64-bit ABI and 32-bit SVR4");
3040 if (PPCSubTarget->isSVR4ABI() && !PPCSubTarget->isPPC64()) {
3044 transferMemOperands(N, MN);
3066 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA) ||
3070 transferMemOperands(N, MN);
3077 unsigned char GVFlags = PPCSubTarget->classifyGlobalReference(GV);
3081 transferMemOperands(N, MN);
3093 assert(!PPCSubTarget->isPPC64() && PPCSubTarget->isSVR4ABI() &&
3094 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
3105 "Invalid operand on VADD_SPLAT!");
3109 unsigned Opc1, Opc2, Opc3;
3113 Opc1 = PPC::VSPLTISB;
3114 Opc2 = PPC::VADDUBM;
3115 Opc3 = PPC::VSUBUBM;
3117 }
else if (EltSize == 2) {
3118 Opc1 = PPC::VSPLTISH;
3119 Opc2 = PPC::VADDUHM;
3120 Opc3 = PPC::VSUBUHM;
3123 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
3124 Opc1 = PPC::VSPLTISW;
3125 Opc2 = PPC::VADDUWM;
3126 Opc3 = PPC::VSUBUWM;
3130 if ((Elt & 1) == 0) {
3137 SDValue EltVal = getI32Imm(Elt >> 1, dl);
3140 ReplaceNode(N, CurDAG->
getMachineNode(Opc2, dl, VT, TmpVal, TmpVal));
3143 }
else if (Elt > 0) {
3150 SDValue EltVal = getI32Imm(Elt - 16, dl);
3152 EltVal = getI32Imm(-16, dl);
3165 SDValue EltVal = getI32Imm(Elt + 16, dl);
3167 EltVal = getI32Imm(-16, dl);
3189 "Only OR nodes are supported for CMPB");
3192 if (!PPCSubTarget->hasCMPB())
3202 bool BytesFound[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
3203 uint64_t Mask = 0, Alt = 0;
3205 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &b,
3206 uint64_t &
Mask, uint64_t &Alt,
3218 for (b = 0; b < 8; ++b) {
3219 uint64_t Mask = UINT64_C(0xFF) << (8*b);
3220 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
3264 if (ULim != (UINT64_C(1) << b*8))
3325 while (!
Queue.empty()) {
3330 uint64_t M = 0,
A = 0;
3334 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
3338 BytesFound[b] =
true;
3341 }
else if ((LHS == ORHS && RHS == OLHS) ||
3342 (RHS == ORHS && LHS == OLHS)) {
3343 BytesFound[b] =
true;
3355 unsigned LastB = 0, BCnt = 0;
3356 for (
unsigned i = 0;
i < 8; ++
i)
3357 if (BytesFound[LastB]) {
3362 if (!LastB || BCnt < 2)
3367 if (LHS.getValueType() != VT) {
3374 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
3375 if (NonTrivialMask && !Alt) {
3402 void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res,
SDNode *&N) {
3403 if (!PPCSubTarget->useCRBits())
3429 auto TryFold = [
this,
N, User, dl](
SDValue Val) {
3435 User->getValueType(0),
3439 SDValue TrueRes = TryFold(ConstTrue);
3442 SDValue FalseRes = TryFold(ConstFalse);
3448 uint64_t True = cast<ConstantSDNode>(TrueRes)->getZExtValue(),
3449 False = cast<ConstantSDNode>(FalseRes)->getZExtValue();
3455 Res = CurDAG->
getSelect(dl, User->getValueType(0), Cond, TrueRes, FalseRes);
3457 ConstTrue = TrueRes;
3458 ConstFalse = FalseRes;
3462 void PPCDAGToDAGISel::PreprocessISelDAG() {
3466 bool MadeChange =
false;
3468 SDNode *N = &*--Position;
3476 Res = combineToCMPB(N);
3481 foldBoolExts(Res, N);
3484 DEBUG(
dbgs() <<
"PPC DAG preprocessing replacing:\nOld: ");
3501 void PPCDAGToDAGISel::PostprocessISelDAG() {
3509 PeepholePPC64ZExt();
3517 bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *N) {
3519 if (!PPCSubTarget->hasISEL())
3550 void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *N) {
3557 "Must have all select users");
3562 UE = ToReplace.
end(); UI != UE; ++UI) {
3570 DEBUG(
dbgs() <<
"CR Peephole replacing:\nOld: ");
3576 ReplaceUses(User, ResNode);
3580 void PPCDAGToDAGISel::PeepholeCROps() {
3586 if (!MachineNode || MachineNode->
use_empty())
3588 SDNode *ResNode = MachineNode;
3590 bool Op1Set =
false, Op1Unset =
false,
3592 Op2Set =
false, Op2Unset =
false,
3620 case PPC::SELECT_I4:
3621 case PPC::SELECT_I8:
3622 case PPC::SELECT_F4:
3623 case PPC::SELECT_F8:
3624 case PPC::SELECT_QFRC:
3625 case PPC::SELECT_QSRC:
3626 case PPC::SELECT_QBRC:
3627 case PPC::SELECT_VRRC:
3628 case PPC::SELECT_VSFRC:
3629 case PPC::SELECT_VSSRC:
3630 case PPC::SELECT_VSRC: {
3645 bool SelectSwap =
false;
3658 else if (Op1Unset || Op2Unset)
3674 else if (AllUsersSelectZero(MachineNode)) {
3697 else if (Op1Unset || Op2Unset)
3713 else if (AllUsersSelectZero(MachineNode)) {
3724 else if (Op1Set || Op2Set)
3746 else if (AllUsersSelectZero(MachineNode)) {
3786 else if (AllUsersSelectZero(MachineNode)) {
3794 if (Op1Set || Op2Set)
3820 else if (AllUsersSelectZero(MachineNode)) {
3860 else if (AllUsersSelectZero(MachineNode)) {
3877 else if (Op1Unset || Op2Set)
3896 else if (AllUsersSelectZero(MachineNode)) {
3908 else if (Op1Set || Op2Unset)
3932 else if (AllUsersSelectZero(MachineNode)) {
3939 case PPC::SELECT_I4:
3940 case PPC::SELECT_I8:
3941 case PPC::SELECT_F4:
3942 case PPC::SELECT_F8:
3943 case PPC::SELECT_QFRC:
3944 case PPC::SELECT_QSRC:
3945 case PPC::SELECT_QBRC:
3946 case PPC::SELECT_VRRC:
3947 case PPC::SELECT_VSFRC:
3948 case PPC::SELECT_VSSRC:
3949 case PPC::SELECT_VSRC:
3981 SwapAllSelectUsers(MachineNode);
3983 if (ResNode != MachineNode) {
3984 DEBUG(
dbgs() <<
"CR Peephole replacing:\nOld: ");
3990 ReplaceUses(MachineNode, ResNode);
3996 }
while (IsModified);
4107 if (!Op0OK && !Op1OK)
4130 if (!Op0OK && !Op1OK)
4144 void PPCDAGToDAGISel::PeepholePPC64ZExt() {
4145 if (!PPCSubTarget->isPPC64())
4160 bool MadeChange =
false;
4162 SDNode *N = &*--Position;
4206 bool OutsideUse =
false;
4207 for (
SDNode *PN : ToPromote) {
4209 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
4227 for (
SDNode *PN : ToPromote) {
4229 switch (PN->getMachineOpcode()) {
4232 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
4233 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
4234 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
4235 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
4236 case PPC::LI: NewOpcode = PPC::LI8;
break;
4237 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
4238 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
4239 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
4240 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
4241 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
4242 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
4243 case PPC::OR: NewOpcode = PPC::OR8;
break;
4244 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
4245 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
4246 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
4247 case PPC::AND: NewOpcode = PPC::AND8;
break;
4248 case PPC::ANDIo: NewOpcode = PPC::ANDIo8;
break;
4249 case PPC::ANDISo: NewOpcode = PPC::ANDISo8;
break;
4260 !isa<ConstantSDNode>(V)) {
4277 for (
unsigned i = 0, ie = VTs.
NumVTs;
i != ie; ++
i)
4283 DEBUG(
dbgs() <<
"PPC64 ZExt Peephole morphing:\nOld: ");
4284 DEBUG(PN->dump(CurDAG));
4289 DEBUG(PN->dump(CurDAG));
4297 DEBUG(
dbgs() <<
"PPC64 ZExt Peephole replacing:\nOld: ");
4303 ReplaceUses(N, Op32.
getNode());
4310 void PPCDAGToDAGISel::PeepholePPC64() {
4312 if (PPCSubTarget->isDarwin() || !PPCSubTarget->isPPC64())
4319 SDNode *N = &*--Position;
4327 switch (StorageOpcode) {
4362 if (!isa<ConstantSDNode>(N->
getOperand(FirstOp)))
4370 bool ReplaceFlags =
true;
4390 ReplaceFlags =
false;
4394 if ((StorageOpcode == PPC::LWA ||
4396 StorageOpcode == PPC::STD) &&
4401 case PPC::ADDIdtprelL:
4404 case PPC::ADDItlsldL:
4418 int MaxDisplacement = 7;
4424 bool UpdateHBase =
false;
4429 if (Offset < 0 || Offset > MaxDisplacement) {
4444 if (HImmOpnd != ImmOpnd)
4455 if (
auto *C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
4458 if ((StorageOpcode == PPC::LWA || StorageOpcode ==
PPC::LD ||
4459 StorageOpcode == PPC::STD) && (Offset % 4) != 0)
4467 }
else if (Offset != 0) {
4476 DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
4491 (StorageOpcode ==
PPC::LD || StorageOpcode == PPC::STD ||
4492 StorageOpcode == PPC::LWA || (Offset % 4) != 0)) {
4493 DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
4498 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
4528 return new PPCDAGToDAGISel(TM);
constexpr bool isUInt< 32 >(uint64_t x)
bool use_empty() const
Return true if there are no uses of this node.
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
uint64_t getZExtValue() const
Get zero extended value.
static cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
BR_CC - Conditional branch.
GPRC = address of GLOBAL_OFFSET_TABLE.
bool hasOneUse() const
Return true if there is exactly one use of this node.
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
A Module instance is used to store all the information related to an LLVM module. ...
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
SDVTList getVTList() const
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in the KnownZero/KnownO...
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
An efficient, type-erasing, non-owning reference to a callable.
unsigned getID() const
Return the register class ID number.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
unsigned getNumOperands() const
Return the number of values used by this operation.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
constexpr bool isInt< 16 >(int64_t x)
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
const SDValue & getOperand(unsigned Num) const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
void setNodeId(int Id)
Set unique node id.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
const SDValue & getBasePtr() const
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
static SDNode * getInt64(SelectionDAG *CurDAG, const SDLoc &dl, int64_t Imm)
StringRef getName() const
Return a constant reference to the value's name.
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool isVector() const
isVector - Return true if this is a vector value type.
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode * > &ToPromote)
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
struct fuzzer::@269 Flags
const HexagonInstrInfo * TII
Shift and rotation operations.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getMachineOpcode() const
int getMaskElt(unsigned Idx) const
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
iterator_range< allnodes_iterator > allnodes()
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const MachineBasicBlock & front() const
constexpr bool isMask_64(uint64_t Value)
isMask_64 - This function returns true if the argument is a non-empty sequence of ones starting at th...
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
Simple integer binary arithmetic operators.
Function Alias Analysis false
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification, or lowering of the constant.
EVT getMemoryVT() const
Return the type of the in-memory value.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
const DataLayout & getDataLayout() const
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
TargetInstrInfo - Interface to description of machine instruction set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
SDNode * getNode() const
get the SDNode which holds the desired result
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isIntS16Immediate(SDNode *N, short &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate...
initializer< Ty > init(const Ty &Val)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
Subclasses of this class are all able to terminate a basic block.
MVT - Machine Value Type.
LLVM Basic Block Representation.
const SDValue & getOperand(unsigned i) const
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
This is an important base class in LLVM.
MO_NLP_FLAG - If this bit is set, the symbol reference is actually to the non_lazy_ptr for the global...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC)
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isFloatingPoint() const
isFloatingPoint - Return true if this is a FP, or a vector FP type.
static ManagedStatic< OptionRegistry > OR
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
This class provides iterator support for SDUse operands that use a specific SDNode.
const PPCTargetLowering * getTargetLowering() const override
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
Common code between 32-bit and 64-bit PowerPC targets.
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
EVT - Extended Value Type.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
MachineBasicBlock * MBB
MBB - The current block.
const SDValue & getOffset() const
static cl::opt< bool > BPermRewriterNoMasking("ppc-bit-perm-rewriter-stress-rotates", cl::desc("stress rotate selection in aggressive ppc isel for ""bit permutations"), cl::Hidden)
SDValue getTargetConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offset=0, unsigned char TargetFlags=0)
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
void dump() const
Dump this node, for debugging.
constexpr bool isInt< 32 >(int64_t x)
allnodes_const_iterator allnodes_begin() const
static SDNode * getInt64Direct(SelectionDAG *CurDAG, const SDLoc &dl, int64_t Imm)
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDNode * SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
An SDNode that represents everything that will be needed to construct a MachineInstr.
const SDValue & getChain() const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
bool isMachineOpcode() const
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
These values identify relocations on immediates folded into memory operations.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
i1 = ANDIo_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after execu...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
iterator_range< use_iterator > uses()
BranchProbabilityInfo * BPI
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, SDNode *Cst1, SDNode *Cst2)
int64_t getSExtValue() const
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
uint64_t getConstantOperandVal(unsigned i) const
Bitwise operators - logical and, logical or, logical xor.
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
ArrayRef< SDUse > ops() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
The CMPB instruction (takes two operands of i32 or i64).
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static unsigned getInt64Count(int64_t Imm)
constexpr bool isUInt< 16 >(uint64_t x)
EVT getValueType() const
Return the ValueType of the referenced return value.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
unsigned getAlignment() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
bool operator<(int64_t V1, const APSInt &V2)
static uint64_t Rot64(uint64_t Imm, unsigned R)
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, const SDValue &DestMBB)
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
const TargetLowering & getTargetLoweringInfo() const
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.Val alone...
StringRef - Represent a constant reference to a string, i.e.
SetCC operator - This evaluates to a true value iff the condition is true.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
TRUNCATE - Completely drop the high bits.
FunctionPass * createPPCISelDag(PPCTargetMachine &TM)
createPPCISelDag - This pass converts a legalized DAG into a PowerPC-specific DAG, ready for instruction scheduling.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static unsigned getInt64CountDirect(int64_t Imm)
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num)
allocateMemRefsArray - Allocate an array to hold MachineMemOperand pointers.
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
EVT changeVectorElementTypeToInteger() const
changeVectorElementTypeToInteger - Return a vector with the same number of elements as this vector...
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate)
This class is used to represent ISD::LOAD nodes.