46#define DEBUG_TYPE "hcp"
58 class ConstantProperties {
68 NumericProperties = (Zero|NonZero|Finite|Infinity|NaN|SignedZero),
71 SignProperties = (PosOrZero|NegOrZero),
72 Everything = (NumericProperties|SignProperties)
91 enum {
Normal, Top, Bottom };
93 static const unsigned MaxCellSize = 4;
104 const Constant *Values[MaxCellSize];
107 LatticeCell() : Kind(Top),
Size(0), IsSpecial(
false) {
111 bool meet(
const LatticeCell &L);
115 unsigned size()
const {
return Size; }
117 LatticeCell(
const LatticeCell &L) {
120 L.IsSpecial ?
sizeof L.Properties : L.Size *
sizeof(
const Constant *);
121 memcpy(Values, L.Values,
N);
124 IsSpecial = L.IsSpecial;
127 LatticeCell &operator=(
const LatticeCell &L) {
130 uint32_t N = L.IsSpecial ?
sizeof L.Properties
131 : L.Size *
sizeof(
const Constant *);
132 memcpy(Values, L.Values,
N);
135 IsSpecial = L.IsSpecial;
140 bool isSingle()
const {
return size() == 1; }
141 bool isProperty()
const {
return IsSpecial; }
142 bool isTop()
const {
return Kind == Top; }
143 bool isBottom()
const {
return Kind == Bottom; }
146 bool Changed = (Kind != Bottom);
162 bool convertToProperty();
172 class MachineConstEvaluator;
174 class MachineConstPropagator {
176 MachineConstPropagator(MachineConstEvaluator &
E) : MCE(
E) {
197 void clear() { Map.clear(); }
203 MapType::const_iterator
F = Map.find(R);
204 return F != Map.end();
210 MapType::const_iterator
F = Map.find(R);
217 void update(
Register R,
const LatticeCell &L) { Map[R] = L; }
222 using MapType = std::map<Register, LatticeCell>;
228 LatticeCell Top, Bottom;
243 void visitUsesOf(
unsigned R);
252 MachineConstEvaluator &MCE;
254 using CFGEdge = std::pair<unsigned, unsigned>;
255 using SetOfCFGEdge = std::set<CFGEdge>;
256 using SetOfInstr = std::set<const MachineInstr *>;
257 using QueueOfCFGEdge = std::queue<CFGEdge>;
261 SetOfCFGEdge EdgeExec;
262 SetOfInstr InstrExec;
263 QueueOfCFGEdge FlowQ;
269 class MachineConstEvaluator {
274 virtual ~MachineConstEvaluator() =
default;
291 using CellMap = MachineConstPropagator::CellMap;
293 CellMap &Outputs) = 0;
295 LatticeCell &Result) = 0;
298 bool &CanFallThru) = 0;
299 virtual bool rewrite(
MachineInstr &
MI,
const CellMap &Inputs) = 0;
347 const CellMap &Inputs,
bool &Result);
349 const CellMap &Inputs,
bool &Result);
357 bool evaluateCOPY(
const RegSubRegPair &R1,
const CellMap &Inputs,
358 LatticeCell &Result);
362 const CellMap &Inputs, LatticeCell &Result);
364 const CellMap &Inputs, LatticeCell &Result);
367 const CellMap &Inputs, LatticeCell &Result);
369 const CellMap &Inputs, LatticeCell &Result);
372 const CellMap &Inputs, LatticeCell &Result);
374 const CellMap &Inputs, LatticeCell &Result);
378 bool evaluateZEXTr(
const RegSubRegPair &R1,
unsigned Width,
unsigned Bits,
379 const CellMap &Inputs, LatticeCell &Result);
380 bool evaluateZEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
382 bool evaluateSEXTr(
const RegSubRegPair &R1,
unsigned Width,
unsigned Bits,
383 const CellMap &Inputs, LatticeCell &Result);
384 bool evaluateSEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
388 bool evaluateCLBr(
const RegSubRegPair &R1,
bool Zeros,
bool Ones,
389 const CellMap &Inputs, LatticeCell &Result);
390 bool evaluateCLBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
391 bool evaluateCTBr(
const RegSubRegPair &R1,
bool Zeros,
bool Ones,
392 const CellMap &Inputs, LatticeCell &Result);
393 bool evaluateCTBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
396 bool evaluateEXTRACTr(
const RegSubRegPair &R1,
unsigned Width,
398 const CellMap &Inputs, LatticeCell &Result);
399 bool evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
unsigned Offset,
403 const CellMap &Inputs, LatticeCell &Result);
404 bool evaluateSplati(
const APInt &A1,
unsigned Bits,
unsigned Count,
414 return Zero | PosOrZero | NegOrZero | Finite;
415 uint32_t Props = (NonZero | Finite);
417 return Props | NegOrZero;
418 return Props | PosOrZero;
423 uint32_t Props = CF->
isNegative() ? (NegOrZero|NonZero)
426 return (Props & ~NumericProperties) | (Zero|Finite);
427 Props = (Props & ~NumericProperties) | NonZero;
429 return (Props & ~NumericProperties) | NaN;
432 return (Props & ~NumericProperties) | Infinity;
442bool LatticeCell::convertToProperty() {
447 uint32_t Everything = ConstantProperties::Everything;
448 uint32_t Ps = !isTop() ? properties()
450 if (Ps != ConstantProperties::Unknown) {
460void LatticeCell::print(raw_ostream &os)
const {
463 uint32_t Ps = properties();
464 if (Ps & ConstantProperties::Zero)
466 if (Ps & ConstantProperties::NonZero)
468 if (Ps & ConstantProperties::Finite)
470 if (Ps & ConstantProperties::Infinity)
472 if (Ps & ConstantProperties::NaN)
474 if (Ps & ConstantProperties::PosOrZero)
476 if (Ps & ConstantProperties::NegOrZero)
485 }
else if (isTop()) {
488 for (
unsigned i = 0; i <
size(); ++i) {
501bool LatticeCell::meet(
const LatticeCell &L) {
505 if (isBottom() ||
L.isTop())
515 return add(
L.properties());
516 for (
unsigned i = 0; i <
L.size(); ++i) {
528bool LatticeCell::add(
const Constant *LC) {
537 while (Index <
Size) {
544 if (Index < MaxCellSize) {
557 uint32_t Ps = properties();
558 uint32_t NewPs = Ps & ConstantProperties::deduce(LC);
559 if (NewPs == ConstantProperties::Unknown) {
572bool LatticeCell::add(uint32_t Property) {
573 bool Changed = convertToProperty();
574 uint32_t Ps = properties();
575 if (Ps == (Ps & Property))
583uint32_t LatticeCell::properties()
const {
586 assert(!isTop() &&
"Should not call this for a top cell");
588 return ConstantProperties::Unknown;
591 uint32_t Ps = ConstantProperties::deduce(Values[0]);
592 for (
unsigned i = 1; i <
size(); ++i) {
593 if (Ps == ConstantProperties::Unknown)
595 Ps &= ConstantProperties::deduce(Values[i]);
601void MachineConstPropagator::CellMap::print(raw_ostream &os,
602 const TargetRegisterInfo &
TRI)
const {
608void MachineConstPropagator::visitPHI(
const MachineInstr &PN) {
609 const MachineBasicBlock *MB = PN.
getParent();
615 assert(DefR.Reg.isVirtual());
622 const LatticeCell &
T = Cells.get(DefR.Reg);
624 Cells.update(DefR.Reg, Bottom);
626 visitUsesOf(DefR.Reg);
630 LatticeCell DefC = Cells.get(DefR.Reg);
634 unsigned PBN =
PB->getNumber();
635 if (!EdgeExec.count(CFGEdge(PBN, MBN))) {
644 if (!UseR.Reg.isVirtual())
647 if (!Cells.has(UseR.Reg))
651 bool Eval = MCE.evaluate(UseR, Cells.get(UseR.Reg), SrcC);
653 <<
printReg(UseR.Reg, &MCE.TRI, UseR.SubReg) << SrcC
655 Changed |= Eval ? DefC.meet(SrcC)
657 Cells.update(DefR.Reg, DefC);
662 visitUsesOf(DefR.Reg);
665void MachineConstPropagator::visitNonBranch(
const MachineInstr &
MI) {
669 bool Eval = MCE.evaluate(
MI, Cells, Outputs);
672 dbgs() <<
" outputs:";
673 for (
auto &
I : Outputs)
674 dbgs() <<
' ' <<
I.second;
681 for (
const MachineOperand &MO :
MI.operands()) {
682 if (!MO.isReg() || !MO.isDef())
686 if (!DefR.Reg.isVirtual())
691 const LatticeCell &
T = Cells.get(DefR.Reg);
693 Cells.update(DefR.Reg, Bottom);
697 if (!Outputs.has(DefR.Reg))
699 LatticeCell RC = Cells.get(DefR.Reg);
700 Changed = RC.meet(Outputs.get(DefR.Reg));
701 Cells.update(DefR.Reg, RC);
704 visitUsesOf(DefR.Reg);
712void MachineConstPropagator::visitBranchesFrom(
const MachineInstr &BrI) {
713 const MachineBasicBlock &
B = *BrI.
getParent();
714 unsigned MBN =
B.getNumber();
718 SetVector<const MachineBasicBlock*> Targets;
719 bool EvalOk =
true, FallsThru =
true;
721 const MachineInstr &
MI = *It;
722 InstrExec.insert(&
MI);
728 EvalOk = EvalOk && MCE.evaluate(
MI, Cells, Targets, FallsThru);
736 if (
B.mayHaveInlineAsmBr())
743 for (
const MachineBasicBlock *SB :
B.successors()) {
748 const MachineFunction &MF = *
B.getParent();
761 LLVM_DEBUG(
dbgs() <<
" failed to evaluate a branch...adding all CFG "
766 for (
const MachineBasicBlock *TB : Targets) {
767 unsigned TBN =
TB->getNumber();
770 FlowQ.push(CFGEdge(MBN, TBN));
774void MachineConstPropagator::visitUsesOf(
unsigned Reg) {
776 << Cells.get(
Reg) <<
'\n');
777 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(
Reg)) {
781 if (!InstrExec.count(&
MI))
785 else if (!
MI.isBranch())
788 visitBranchesFrom(
MI);
792bool MachineConstPropagator::computeBlockSuccessors(
const MachineBasicBlock *MB,
793 SetVector<const MachineBasicBlock*> &Targets) {
797 for (
const MachineInstr &
MI : *MB) {
798 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
800 if (
MI.isDebugInstr())
803 FirstBr =
MI.getIterator();
812 const MachineInstr &
MI = *
I;
814 if (
MI.isDebugInstr())
816 if (!InstrExec.count(&
MI))
818 bool Eval = MCE.evaluate(
MI, Cells, Targets, DoNext);
828 if (NextI != MB->getParent()->end())
833 for (
const MachineBasicBlock *SB : MB->successors())
840void MachineConstPropagator::removeCFGEdge(MachineBasicBlock *From,
841 MachineBasicBlock *To) {
845 for (MachineInstr &PN : To->
phis()) {
858void MachineConstPropagator::propagate(MachineFunction &MF) {
860 unsigned EntryNum =
Entry->getNumber();
863 FlowQ.push(CFGEdge(EntryNum, EntryNum));
865 while (!FlowQ.empty()) {
866 CFGEdge
Edge = FlowQ.front();
870 dbgs() <<
"Picked edge "
873 if (
Edge.first != EntryNum)
874 if (EdgeExec.count(
Edge))
876 EdgeExec.insert(
Edge);
886 while (It != End && It->isPHI()) {
887 InstrExec.insert(&*It);
895 while (It != End && It->isDebugInstr())
897 assert(It == End || !It->isPHI());
899 if (It != End && InstrExec.count(&*It))
903 while (It != End && !It->isBranch()) {
904 if (!It->isDebugInstr()) {
905 InstrExec.insert(&*It);
916 visitBranchesFrom(*It);
921 for (
const MachineBasicBlock *SSB : SB->
successors())
922 FlowQ.push(CFGEdge(SBN, SSB->getNumber()));
927 dbgs() <<
"Cells after propagation:\n";
928 Cells.print(
dbgs(), MCE.TRI);
929 dbgs() <<
"Dead CFG edges:\n";
930 for (
const MachineBasicBlock &
B : MF) {
931 unsigned BN =
B.getNumber();
932 for (
const MachineBasicBlock *SB :
B.successors()) {
934 if (!EdgeExec.count(CFGEdge(BN, SN)))
942bool MachineConstPropagator::rewrite(MachineFunction &MF) {
960 std::vector<MachineBasicBlock*> POT;
965 for (MachineBasicBlock *
B : POT) {
973 SetVector<const MachineBasicBlock*> Targets;
974 bool HaveTargets = computeBlockSuccessors(
B, Targets);
978 if (InstrExec.count(&
MI)) {
979 if (
MI.isBranch() && !HaveTargets)
987 for (
auto I =
B->begin(),
E =
B->end();
I !=
E; ++
I) {
1006 for (MachineBasicBlock *SB :
B->successors()) {
1007 if (!Targets.
count(SB))
1012 removeCFGEdge(
B,
MBB);
1025 for (MachineBasicBlock &
B : MF) {
1027 if (
MI.isBranch() && !InstrExec.count(&
MI))
1035bool MachineConstPropagator::run(MachineFunction &MF) {
1049 dbgs() <<
"End of MachineConstPropagator (Changed=" <<
Changed <<
")\n";
1060 const CellMap &Inputs, LatticeCell &RC) {
1061 if (!
R.Reg.isVirtual())
1063 const LatticeCell &
L = Inputs.get(
R.Reg);
1066 return !RC.isBottom();
1069 return Eval && !RC.isBottom();
1072bool MachineConstEvaluator::constToInt(
const Constant *
C,
1081const ConstantInt *MachineConstEvaluator::intToConst(
const APInt &Val)
const {
1082 return ConstantInt::get(CX, Val);
1085bool MachineConstEvaluator::evaluateCMPrr(uint32_t Cmp,
const RegSubRegPair &R1,
1087 const CellMap &Inputs,
bool &Result) {
1089 LatticeCell LS1, LS2;
1090 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1093 bool IsProp1 = LS1.isProperty();
1094 bool IsProp2 = LS2.isProperty();
1096 uint32_t Prop1 = LS1.properties();
1098 return evaluateCMPpp(Cmp, Prop1, LS2.properties(), Result);
1099 uint32_t NegCmp = Comparison::negate(Cmp);
1100 return evaluateCMPrp(NegCmp,
R2, Prop1, Inputs, Result);
1103 uint32_t Prop2 = LS2.properties();
1104 return evaluateCMPrp(Cmp, R1, Prop2, Inputs, Result);
1108 bool IsTrue =
true, IsFalse =
true;
1109 for (
unsigned i = 0; i < LS2.size(); ++i) {
1111 bool Computed = constToInt(LS2.Values[i],
A) &&
1112 evaluateCMPri(Cmp, R1,
A, Inputs, Res);
1118 assert(!IsTrue || !IsFalse);
1122 return IsTrue || IsFalse;
1125bool MachineConstEvaluator::evaluateCMPri(uint32_t Cmp,
const RegSubRegPair &R1,
1127 const CellMap &Inputs,
bool &Result) {
1130 if (!getCell(R1, Inputs, LS))
1132 if (
LS.isProperty())
1133 return evaluateCMPpi(Cmp,
LS.properties(), A2, Result);
1136 bool IsTrue =
true, IsFalse =
true;
1137 for (
unsigned i = 0; i <
LS.size(); ++i) {
1139 bool Computed = constToInt(
LS.Values[i],
A) &&
1140 evaluateCMPii(Cmp,
A, A2, Res);
1146 assert(!IsTrue || !IsFalse);
1150 return IsTrue || IsFalse;
1153bool MachineConstEvaluator::evaluateCMPrp(uint32_t Cmp,
const RegSubRegPair &R1,
1155 const CellMap &Inputs,
bool &Result) {
1158 if (!getCell(R1, Inputs, LS))
1160 if (
LS.isProperty())
1161 return evaluateCMPpp(Cmp,
LS.properties(), Props2, Result);
1164 uint32_t NegCmp = Comparison::negate(Cmp);
1165 bool IsTrue =
true, IsFalse =
true;
1166 for (
unsigned i = 0; i <
LS.size(); ++i) {
1168 bool Computed = constToInt(
LS.Values[i],
A) &&
1169 evaluateCMPpi(NegCmp, Props2,
A, Res);
1175 assert(!IsTrue || !IsFalse);
1177 return IsTrue || IsFalse;
1180bool MachineConstEvaluator::evaluateCMPii(uint32_t Cmp,
const APInt &A1,
1181 const APInt &A2,
bool &Result) {
1183 if (Cmp == Comparison::NE) {
1187 if (Cmp == Comparison::EQ) {
1191 if (Cmp & Comparison::EQ) {
1193 return (Result =
true);
1195 assert((Cmp & (Comparison::L | Comparison::G)) &&
"Malformed comparison");
1200 unsigned MaxW = (W1 >= W2) ? W1 : W2;
1201 if (Cmp & Comparison::U) {
1202 APInt Zx1 = A1.
zext(MaxW);
1203 APInt Zx2 = A2.
zext(MaxW);
1204 if (Cmp & Comparison::L)
1206 else if (Cmp & Comparison::G)
1212 APInt Sx1 = A1.
sext(MaxW);
1213 APInt Sx2 = A2.
sext(MaxW);
1214 if (Cmp & Comparison::L)
1216 else if (Cmp & Comparison::G)
1221bool MachineConstEvaluator::evaluateCMPpi(uint32_t Cmp, uint32_t Props,
1222 const APInt &A2,
bool &Result) {
1223 if (Props == ConstantProperties::Unknown)
1227 if (Props & ConstantProperties::NaN)
1232 if (!(Props & ConstantProperties::Finite))
1237 if (Cmp & Comparison::U) {
1241 if (Props & ConstantProperties::Zero)
1243 else if (Props & ConstantProperties::NonZero)
1244 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1250 if (Props & ConstantProperties::Zero) {
1251 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1258 if (Props & ConstantProperties::Zero) {
1263 ((Cmp & Comparison::L) && !A2.
isNegative()) ||
1267 if (Props & ConstantProperties::PosOrZero) {
1272 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1275 if (Props & ConstantProperties::NegOrZero) {
1280 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1287bool MachineConstEvaluator::evaluateCMPpp(uint32_t Cmp, uint32_t Props1,
1288 uint32_t Props2,
bool &Result) {
1289 using P = ConstantProperties;
1291 if ((Props1 & P::NaN) && (Props2 & P::NaN))
1293 if (!(Props1 & P::Finite) || !(Props2 & P::Finite))
1296 bool Zero1 = (Props1 & P::Zero), Zero2 = (Props2 & P::Zero);
1297 bool NonZero1 = (Props1 & P::NonZero), NonZero2 = (Props2 & P::NonZero);
1298 if (Zero1 && Zero2) {
1302 if (Cmp == Comparison::NE) {
1303 if ((Zero1 && NonZero2) || (NonZero1 && Zero2))
1304 return (Result =
true);
1308 if (Cmp & Comparison::U) {
1311 if (Zero1 && NonZero2) {
1315 if (NonZero1 && Zero2) {
1323 bool Poz1 = (Props1 & P::PosOrZero), Poz2 = (Props2 & P::PosOrZero);
1324 bool Nez1 = (Props1 & P::NegOrZero), Nez2 = (Props2 & P::NegOrZero);
1326 if (NonZero1 || NonZero2) {
1331 if ((Cmp & Comparison::EQ) && (Cmp & Comparison::L))
1332 return (Result =
true);
1335 if (NonZero1 || NonZero2) {
1340 if ((Cmp & Comparison::EQ) && (Cmp & Comparison::G))
1341 return (Result =
true);
1347bool MachineConstEvaluator::evaluateCOPY(
const RegSubRegPair &R1,
1348 const CellMap &Inputs,
1349 LatticeCell &Result) {
1350 return getCell(R1, Inputs, Result);
1353bool MachineConstEvaluator::evaluateANDrr(
const RegSubRegPair &R1,
1355 const CellMap &Inputs,
1356 LatticeCell &Result) {
1358 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1359 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1363 if (L2.isBottom()) {
1366 return evaluateANDrr(
R2, R1, Inputs, Result);
1371 if (LS2.isBottom() || LS2.isProperty())
1375 for (
unsigned i = 0; i < LS2.size(); ++i) {
1377 bool Eval = constToInt(LS2.Values[i],
A) &&
1378 evaluateANDri(R1,
A, Inputs, RC);
1383 return !
Result.isBottom();
1386bool MachineConstEvaluator::evaluateANDri(
const RegSubRegPair &R1,
1388 const CellMap &Inputs,
1389 LatticeCell &Result) {
1392 return getCell(R1, Inputs, Result);
1395 RC.add(intToConst(A2));
1401 if (!getCell(R1, Inputs, LS1))
1403 if (LS1.isBottom() || LS1.isProperty())
1407 for (
unsigned i = 0; i < LS1.size(); ++i) {
1408 bool Eval = constToInt(LS1.Values[i],
A) &&
1409 evaluateANDii(
A, A2, ResA);
1415 return !
Result.isBottom();
1418bool MachineConstEvaluator::evaluateANDii(
const APInt &A1,
1419 const APInt &A2, APInt &Result) {
1424bool MachineConstEvaluator::evaluateORrr(
const RegSubRegPair &R1,
1426 const CellMap &Inputs,
1427 LatticeCell &Result) {
1429 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1430 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1434 if (L2.isBottom()) {
1437 return evaluateORrr(
R2, R1, Inputs, Result);
1442 if (LS2.isBottom() || LS2.isProperty())
1446 for (
unsigned i = 0; i < LS2.size(); ++i) {
1448 bool Eval = constToInt(LS2.Values[i],
A) &&
1449 evaluateORri(R1,
A, Inputs, RC);
1454 return !
Result.isBottom();
1457bool MachineConstEvaluator::evaluateORri(
const RegSubRegPair &R1,
1458 const APInt &A2,
const CellMap &Inputs,
1459 LatticeCell &Result) {
1462 return getCell(R1, Inputs, Result);
1465 RC.add(intToConst(A2));
1471 if (!getCell(R1, Inputs, LS1))
1473 if (LS1.isBottom() || LS1.isProperty())
1477 for (
unsigned i = 0; i < LS1.size(); ++i) {
1478 bool Eval = constToInt(LS1.Values[i],
A) &&
1479 evaluateORii(
A, A2, ResA);
1485 return !
Result.isBottom();
1488bool MachineConstEvaluator::evaluateORii(
const APInt &A1,
1489 const APInt &A2, APInt &Result) {
1494bool MachineConstEvaluator::evaluateXORrr(
const RegSubRegPair &R1,
1496 const CellMap &Inputs,
1497 LatticeCell &Result) {
1499 LatticeCell LS1, LS2;
1500 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1502 if (LS1.isProperty()) {
1503 if (LS1.properties() & ConstantProperties::Zero)
1504 return !(
Result = LS2).isBottom();
1507 if (LS2.isProperty()) {
1508 if (LS2.properties() & ConstantProperties::Zero)
1509 return !(
Result = LS1).isBottom();
1514 for (
unsigned i = 0; i < LS2.size(); ++i) {
1516 bool Eval = constToInt(LS2.Values[i],
A) &&
1517 evaluateXORri(R1,
A, Inputs, RC);
1522 return !
Result.isBottom();
1525bool MachineConstEvaluator::evaluateXORri(
const RegSubRegPair &R1,
1527 const CellMap &Inputs,
1528 LatticeCell &Result) {
1531 if (!getCell(R1, Inputs, LS1))
1533 if (LS1.isProperty()) {
1534 if (LS1.properties() & ConstantProperties::Zero) {
1537 return !
Result.isBottom();
1543 for (
unsigned i = 0; i < LS1.size(); ++i) {
1544 bool Eval = constToInt(LS1.Values[i],
A) &&
1545 evaluateXORii(
A, A2, XA);
1551 return !
Result.isBottom();
1554bool MachineConstEvaluator::evaluateXORii(
const APInt &A1,
1555 const APInt &A2, APInt &Result) {
1560bool MachineConstEvaluator::evaluateZEXTr(
const RegSubRegPair &R1,
1561 unsigned Width,
unsigned Bits,
1562 const CellMap &Inputs,
1563 LatticeCell &Result) {
1566 if (!getCell(R1, Inputs, LS1))
1568 if (LS1.isProperty())
1572 for (
unsigned i = 0; i < LS1.size(); ++i) {
1573 bool Eval = constToInt(LS1.Values[i],
A) &&
1574 evaluateZEXTi(
A, Width, Bits, XA);
1583bool MachineConstEvaluator::evaluateZEXTi(
const APInt &A1,
unsigned Width,
1584 unsigned Bits, APInt &Result) {
1587 assert(Width >= Bits && BW >= Bits);
1593bool MachineConstEvaluator::evaluateSEXTr(
const RegSubRegPair &R1,
1594 unsigned Width,
unsigned Bits,
1595 const CellMap &Inputs,
1596 LatticeCell &Result) {
1599 if (!getCell(R1, Inputs, LS1))
1601 if (LS1.isBottom() || LS1.isProperty())
1605 for (
unsigned i = 0; i < LS1.size(); ++i) {
1606 bool Eval = constToInt(LS1.Values[i],
A) &&
1607 evaluateSEXTi(
A, Width, Bits, XA);
1616bool MachineConstEvaluator::evaluateSEXTi(
const APInt &A1,
unsigned Width,
1617 unsigned Bits, APInt &Result) {
1619 assert(Width >= Bits && BW >= Bits);
1624 Result = APInt(Width, 0);
1628 if (BW <= 64 && Bits != 0) {
1632 V =
static_cast<int8_t
>(
V);
1635 V =
static_cast<int16_t
>(
V);
1638 V =
static_cast<int32_t
>(
V);
1644 V = (
V << (64-
Bits)) >> (64-Bits);
1649 Result = APInt(Width, V,
true);
1660bool MachineConstEvaluator::evaluateCLBr(
const RegSubRegPair &R1,
bool Zeros,
1661 bool Ones,
const CellMap &Inputs,
1662 LatticeCell &Result) {
1665 if (!getCell(R1, Inputs, LS1))
1667 if (LS1.isBottom() || LS1.isProperty())
1671 for (
unsigned i = 0; i < LS1.size(); ++i) {
1672 bool Eval = constToInt(LS1.Values[i],
A) &&
1673 evaluateCLBi(
A, Zeros, Ones, CA);
1682bool MachineConstEvaluator::evaluateCLBi(
const APInt &A1,
bool Zeros,
1683 bool Ones, APInt &Result) {
1685 if (!Zeros && !Ones)
1688 if (Zeros && (
Count == 0))
1690 if (Ones && (
Count == 0))
1692 Result = APInt(BW,
static_cast<uint64_t
>(
Count),
false);
1696bool MachineConstEvaluator::evaluateCTBr(
const RegSubRegPair &R1,
bool Zeros,
1697 bool Ones,
const CellMap &Inputs,
1698 LatticeCell &Result) {
1701 if (!getCell(R1, Inputs, LS1))
1703 if (LS1.isBottom() || LS1.isProperty())
1707 for (
unsigned i = 0; i < LS1.size(); ++i) {
1708 bool Eval = constToInt(LS1.Values[i],
A) &&
1709 evaluateCTBi(
A, Zeros, Ones, CA);
1718bool MachineConstEvaluator::evaluateCTBi(
const APInt &A1,
bool Zeros,
1719 bool Ones, APInt &Result) {
1721 if (!Zeros && !Ones)
1724 if (Zeros && (
Count == 0))
1726 if (Ones && (
Count == 0))
1728 Result = APInt(BW,
static_cast<uint64_t
>(
Count),
false);
1732bool MachineConstEvaluator::evaluateEXTRACTr(
const RegSubRegPair &R1,
1733 unsigned Width,
unsigned Bits,
1735 const CellMap &Inputs,
1736 LatticeCell &Result) {
1740 if (!getCell(R1, Inputs, LS1))
1744 if (LS1.isProperty()) {
1745 uint32_t Ps = LS1.properties();
1746 if (Ps & ConstantProperties::Zero) {
1747 const Constant *
C = intToConst(APInt(Width, 0,
false));
1755 for (
unsigned i = 0; i < LS1.size(); ++i) {
1756 bool Eval = constToInt(LS1.Values[i],
A) &&
1766bool MachineConstEvaluator::evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
1780 V =
static_cast<int64_t
>(
U) >> (64 - Bits);
1782 V =
static_cast<int64_t
>(
U >> (64 -
Bits));
1793bool MachineConstEvaluator::evaluateSplatr(
const RegSubRegPair &R1,
1794 unsigned Bits,
unsigned Count,
1795 const CellMap &Inputs,
1796 LatticeCell &Result) {
1799 if (!getCell(R1, Inputs, LS1))
1801 if (LS1.isBottom() || LS1.isProperty())
1805 for (
unsigned i = 0; i < LS1.size(); ++i) {
1806 bool Eval = constToInt(LS1.Values[i],
A) &&
1807 evaluateSplati(
A, Bits,
Count, SA);
1816bool MachineConstEvaluator::evaluateSplati(
const APInt &A1,
unsigned Bits,
1817 unsigned Count, APInt &Result) {
1820 APInt LoBits = (
Bits < BW) ? A1.
trunc(Bits) : A1.
zext(Bits);
1822 LoBits = LoBits.
zext(SW);
1824 APInt Res(SW, 0,
false);
1825 for (
unsigned i = 0; i <
Count; ++i) {
1838 class HexagonConstEvaluator :
public MachineConstEvaluator {
1840 HexagonConstEvaluator(MachineFunction &Fn);
1842 bool evaluate(
const MachineInstr &
MI,
const CellMap &Inputs,
1843 CellMap &Outputs)
override;
1845 LatticeCell &Result)
override;
1846 bool evaluate(
const MachineInstr &BrI,
const CellMap &Inputs,
1847 SetVector<const MachineBasicBlock*> &Targets,
bool &FallsThru)
1849 bool rewrite(MachineInstr &
MI,
const CellMap &Inputs)
override;
1855 static APInt getCmpImm(
unsigned Opc,
unsigned OpX,
1856 const MachineOperand &MO);
1857 void replaceWithNop(MachineInstr &
MI);
1860 const CellMap &Inputs, LatticeCell &Result);
1861 bool evaluateHexCompare(
const MachineInstr &
MI,
const CellMap &Inputs,
1864 bool evaluateHexCompare2(uint32_t Cmp,
const MachineOperand &Src1,
1865 const MachineOperand &Src2,
const CellMap &Inputs,
bool &Result);
1866 bool evaluateHexLogical(
const MachineInstr &
MI,
const CellMap &Inputs,
1868 bool evaluateHexCondMove(
const MachineInstr &
MI,
const CellMap &Inputs,
1870 bool evaluateHexExt(
const MachineInstr &
MI,
const CellMap &Inputs,
1872 bool evaluateHexVector1(
const MachineInstr &
MI,
const CellMap &Inputs,
1874 bool evaluateHexVector2(
const MachineInstr &
MI,
const CellMap &Inputs,
1878 bool rewriteHexBranch(MachineInstr &BrI,
const CellMap &Inputs);
1879 bool rewriteHexConstDefs(MachineInstr &
MI,
const CellMap &Inputs,
1881 bool rewriteHexConstUses(MachineInstr &
MI,
const CellMap &Inputs);
1883 MachineRegisterInfo *
MRI;
1884 const HexagonInstrInfo &HII;
1885 const HexagonRegisterInfo &HRI;
1888 class HexagonConstPropagation :
public MachineFunctionPass {
1892 HexagonConstPropagation() : MachineFunctionPass(
ID) {}
1894 StringRef getPassName()
const override {
1895 return "Hexagon Constant Propagation";
1898 bool runOnMachineFunction(MachineFunction &MF)
override {
1900 if (skipFunction(
F))
1903 HexagonConstEvaluator HCE(MF);
1904 return MachineConstPropagator(HCE).run(MF);
1910char HexagonConstPropagation::ID = 0;
1913 "Hexagon Constant Propagation",
false,
false)
1916 : MachineConstEvaluator(Fn),
1919 MRI = &Fn.getRegInfo();
1922bool HexagonConstEvaluator::evaluate(
const MachineInstr &
MI,
1923 const CellMap &Inputs, CellMap &Outputs) {
1926 if (
MI.getNumOperands() == 0 || !
MI.getOperand(0).isReg())
1928 const MachineOperand &MD =
MI.getOperand(0);
1932 unsigned Opc =
MI.getOpcode();
1935 if (!DefR.Reg.isVirtual())
1941 bool Eval = evaluateCOPY(SrcR, Inputs, RC);
1944 Outputs.update(DefR.Reg, RC);
1947 if (
MI.isRegSequence()) {
1948 unsigned Sub1 =
MI.getOperand(2).getImm();
1949 unsigned Sub2 =
MI.getOperand(4).getImm();
1950 const TargetRegisterClass &DefRC = *
MRI->getRegClass(DefR.Reg);
1953 if (Sub1 != SubLo && Sub1 != SubHi)
1955 if (Sub2 != SubLo && Sub2 != SubHi)
1958 bool LoIs1 = (Sub1 == SubLo);
1959 const MachineOperand &OpLo = LoIs1 ?
MI.getOperand(1) :
MI.getOperand(3);
1960 const MachineOperand &OpHi = LoIs1 ?
MI.getOperand(3) :
MI.getOperand(1);
1963 bool Eval = evaluateHexRSEQ32(SrcRL, SrcRH, Inputs, RC);
1966 Outputs.update(DefR.Reg, RC);
1969 if (
MI.isCompare()) {
1970 bool Eval = evaluateHexCompare(
MI, Inputs, Outputs);
1977 case Hexagon::A2_tfrsi:
1978 case Hexagon::A2_tfrpi:
1979 case Hexagon::CONST32:
1980 case Hexagon::CONST64:
1982 const MachineOperand &VO =
MI.getOperand(1);
1988 int64_t
V =
MI.getOperand(1).getImm();
1990 if (W != 32 && W != 64)
1992 IntegerType *Ty = (
W == 32) ? Type::getInt32Ty(CX)
1993 : Type::getInt64Ty(CX);
1994 const ConstantInt *CI =
1995 ConstantInt::get(Ty, V,
true,
true);
1996 LatticeCell RC = Outputs.get(DefR.Reg);
1998 Outputs.update(DefR.Reg, RC);
2002 case Hexagon::PS_true:
2003 case Hexagon::PS_false:
2005 LatticeCell RC = Outputs.get(DefR.Reg);
2006 bool NonZero = (
Opc == Hexagon::PS_true);
2007 uint32_t
P = NonZero ? ConstantProperties::NonZero
2008 : ConstantProperties::Zero;
2010 Outputs.update(DefR.Reg, RC);
2014 case Hexagon::A2_and:
2015 case Hexagon::A2_andir:
2016 case Hexagon::A2_andp:
2017 case Hexagon::A2_or:
2018 case Hexagon::A2_orir:
2019 case Hexagon::A2_orp:
2020 case Hexagon::A2_xor:
2021 case Hexagon::A2_xorp:
2023 bool Eval = evaluateHexLogical(
MI, Inputs, Outputs);
2029 case Hexagon::A2_combineii:
2030 case Hexagon::A4_combineii:
2032 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isImm())
2034 uint64_t
Hi =
MI.getOperand(1).getImm();
2035 uint64_t
Lo =
MI.getOperand(2).getImm();
2036 uint64_t Res = (
Hi << 32) | (
Lo & 0xFFFFFFFF);
2037 IntegerType *Ty = Type::getInt64Ty(CX);
2038 const ConstantInt *CI = ConstantInt::get(Ty, Res,
false);
2039 LatticeCell RC = Outputs.get(DefR.Reg);
2041 Outputs.update(DefR.Reg, RC);
2045 case Hexagon::S2_setbit_i:
2047 int64_t
B =
MI.getOperand(2).getImm();
2049 APInt
A(32, (1ull <<
B),
false);
2051 LatticeCell RC = Outputs.get(DefR.Reg);
2052 bool Eval = evaluateORri(R,
A, Inputs, RC);
2055 Outputs.update(DefR.Reg, RC);
2059 case Hexagon::C2_mux:
2060 case Hexagon::C2_muxir:
2061 case Hexagon::C2_muxri:
2062 case Hexagon::C2_muxii:
2064 bool Eval = evaluateHexCondMove(
MI, Inputs, Outputs);
2070 case Hexagon::A2_sxtb:
2071 case Hexagon::A2_sxth:
2072 case Hexagon::A2_sxtw:
2073 case Hexagon::A2_zxtb:
2074 case Hexagon::A2_zxth:
2076 bool Eval = evaluateHexExt(
MI, Inputs, Outputs);
2082 case Hexagon::S2_ct0:
2083 case Hexagon::S2_ct0p:
2084 case Hexagon::S2_ct1:
2085 case Hexagon::S2_ct1p:
2087 using namespace Hexagon;
2089 bool Ones = (
Opc == S2_ct1) || (
Opc == S2_ct1p);
2093 bool Eval = evaluateCTBr(R1, !Ones, Ones, Inputs,
T);
2100 LatticeCell RC = Outputs.get(DefR.Reg);
2101 for (
unsigned i = 0; i <
T.size(); ++i) {
2103 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2104 CI = intToConst(
C.trunc(32));
2107 Outputs.update(DefR.Reg, RC);
2111 case Hexagon::S2_cl0:
2112 case Hexagon::S2_cl0p:
2113 case Hexagon::S2_cl1:
2114 case Hexagon::S2_cl1p:
2115 case Hexagon::S2_clb:
2116 case Hexagon::S2_clbp:
2118 using namespace Hexagon;
2120 bool OnlyZeros = (
Opc == S2_cl0) || (
Opc == S2_cl0p);
2121 bool OnlyOnes = (
Opc == S2_cl1) || (
Opc == S2_cl1p);
2125 bool Eval = evaluateCLBr(R1, !OnlyOnes, !OnlyZeros, Inputs,
T);
2132 LatticeCell RC = Outputs.get(DefR.Reg);
2133 for (
unsigned i = 0; i <
T.size(); ++i) {
2135 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2136 CI = intToConst(
C.trunc(32));
2139 Outputs.update(DefR.Reg, RC);
2143 case Hexagon::S4_extract:
2144 case Hexagon::S4_extractp:
2145 case Hexagon::S2_extractu:
2146 case Hexagon::S2_extractup:
2148 bool Signed = (
Opc == Hexagon::S4_extract) ||
2149 (
Opc == Hexagon::S4_extractp);
2152 unsigned Bits =
MI.getOperand(2).getImm();
2153 unsigned Offset =
MI.getOperand(3).getImm();
2154 LatticeCell RC = Outputs.get(DefR.Reg);
2156 APInt
Zero(BW, 0,
false);
2157 RC.add(intToConst(Zero));
2167 bool Eval = evaluateEXTRACTr(R1, BW, Bits,
Offset,
Signed, Inputs, RC);
2170 Outputs.update(DefR.Reg, RC);
2174 case Hexagon::S2_vsplatrb:
2175 case Hexagon::S2_vsplatrh:
2185 bool Eval = evaluateHexVector1(
MI, Inputs, Outputs);
2202 const LatticeCell &Input,
2203 LatticeCell &Result) {
2208 const TargetRegisterClass *RC =
MRI->getRegClass(
R.Reg);
2209 if (RC != &Hexagon::DoubleRegsRegClass)
2211 if (
R.SubReg != Hexagon::isub_lo &&
R.SubReg != Hexagon::isub_hi)
2215 if (Input.isBottom())
2218 using P = ConstantProperties;
2220 if (Input.isProperty()) {
2221 uint32_t Ps = Input.properties();
2222 if (Ps & (P::Zero|P::NaN)) {
2223 uint32_t Ns = (Ps & (P::Zero|P::NaN|P::SignProperties));
2227 if (
R.SubReg == Hexagon::isub_hi) {
2228 uint32_t Ns = (Ps & P::SignProperties);
2238 for (
unsigned i = 0; i < Input.size(); ++i) {
2240 if (!constToInt(
C,
A))
2244 uint64_t
U =
A.getZExtValue();
2245 if (
R.SubReg == Hexagon::isub_hi)
2250 memcpy(&V32, &U32,
sizeof V32);
2251 IntegerType *Ty = Type::getInt32Ty(CX);
2252 const ConstantInt *C32 =
2259bool HexagonConstEvaluator::evaluate(
const MachineInstr &BrI,
2260 const CellMap &Inputs, SetVector<const MachineBasicBlock*> &Targets,
2265 bool SimpleBranch =
false;
2266 bool Negated =
false;
2268 case Hexagon::J2_jumpf:
2269 case Hexagon::J2_jumpfnew:
2270 case Hexagon::J2_jumpfnewpt:
2273 case Hexagon::J2_jumpt:
2274 case Hexagon::J2_jumptnew:
2275 case Hexagon::J2_jumptnewpt:
2278 SimpleBranch =
true;
2280 case Hexagon::J2_jump:
2293 const MachineOperand &MD = BrI.
getOperand(0);
2299 assert(Inputs.has(PR.Reg));
2300 const LatticeCell &PredC = Inputs.get(PR.Reg);
2301 if (PredC.isBottom())
2304 uint32_t Props = PredC.properties();
2305 bool CTrue =
false, CFalse =
false;
2306 if (Props & ConstantProperties::Zero)
2308 else if (Props & ConstantProperties::NonZero)
2311 if (!CTrue && !CFalse)
2317 if ((!Negated && CTrue) || (Negated && CFalse))
2318 Targets.
insert(BranchTarget);
2319 else if ((!Negated && CFalse) || (Negated && CTrue))
2328bool HexagonConstEvaluator::rewrite(MachineInstr &
MI,
const CellMap &Inputs) {
2330 return rewriteHexBranch(
MI, Inputs);
2332 unsigned Opc =
MI.getOpcode();
2336 case Hexagon::A2_tfrsi:
2337 case Hexagon::A2_tfrpi:
2338 case Hexagon::CONST32:
2339 case Hexagon::CONST64:
2340 case Hexagon::PS_true:
2341 case Hexagon::PS_false:
2345 unsigned NumOp =
MI.getNumOperands();
2350 Changed = rewriteHexConstDefs(
MI, Inputs, AllDefs);
2355 Changed |= rewriteHexConstUses(
MI, Inputs);
2360unsigned HexagonConstEvaluator::getRegBitWidth(
unsigned Reg)
const {
2361 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2362 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC))
2364 if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC))
2366 if (Hexagon::PredRegsRegClass.hasSubClassEq(RC))
2372uint32_t HexagonConstEvaluator::getCmp(
unsigned Opc) {
2374 case Hexagon::C2_cmpeq:
2375 case Hexagon::C2_cmpeqp:
2376 case Hexagon::A4_cmpbeq:
2377 case Hexagon::A4_cmpheq:
2378 case Hexagon::A4_cmpbeqi:
2379 case Hexagon::A4_cmpheqi:
2380 case Hexagon::C2_cmpeqi:
2381 case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
2382 case Hexagon::J4_cmpeqn1_t_jumpnv_t:
2383 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2384 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2385 case Hexagon::J4_cmpeq_t_jumpnv_nt:
2386 case Hexagon::J4_cmpeq_t_jumpnv_t:
2387 return Comparison::EQ;
2389 case Hexagon::C4_cmpneq:
2390 case Hexagon::C4_cmpneqi:
2391 case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
2392 case Hexagon::J4_cmpeqn1_f_jumpnv_t:
2393 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2394 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2395 case Hexagon::J4_cmpeq_f_jumpnv_nt:
2396 case Hexagon::J4_cmpeq_f_jumpnv_t:
2397 return Comparison::NE;
2399 case Hexagon::C2_cmpgt:
2400 case Hexagon::C2_cmpgtp:
2401 case Hexagon::A4_cmpbgt:
2402 case Hexagon::A4_cmphgt:
2403 case Hexagon::A4_cmpbgti:
2404 case Hexagon::A4_cmphgti:
2405 case Hexagon::C2_cmpgti:
2406 case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
2407 case Hexagon::J4_cmpgtn1_t_jumpnv_t:
2408 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2409 case Hexagon::J4_cmpgti_t_jumpnv_t:
2410 case Hexagon::J4_cmpgt_t_jumpnv_nt:
2411 case Hexagon::J4_cmpgt_t_jumpnv_t:
2412 return Comparison::GTs;
2414 case Hexagon::C4_cmplte:
2415 case Hexagon::C4_cmpltei:
2416 case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
2417 case Hexagon::J4_cmpgtn1_f_jumpnv_t:
2418 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2419 case Hexagon::J4_cmpgti_f_jumpnv_t:
2420 case Hexagon::J4_cmpgt_f_jumpnv_nt:
2421 case Hexagon::J4_cmpgt_f_jumpnv_t:
2422 return Comparison::LEs;
2424 case Hexagon::C2_cmpgtu:
2425 case Hexagon::C2_cmpgtup:
2426 case Hexagon::A4_cmpbgtu:
2427 case Hexagon::A4_cmpbgtui:
2428 case Hexagon::A4_cmphgtu:
2429 case Hexagon::A4_cmphgtui:
2430 case Hexagon::C2_cmpgtui:
2431 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2432 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2433 case Hexagon::J4_cmpgtu_t_jumpnv_nt:
2434 case Hexagon::J4_cmpgtu_t_jumpnv_t:
2435 return Comparison::GTu;
2437 case Hexagon::J4_cmpltu_f_jumpnv_nt:
2438 case Hexagon::J4_cmpltu_f_jumpnv_t:
2439 return Comparison::GEu;
2441 case Hexagon::J4_cmpltu_t_jumpnv_nt:
2442 case Hexagon::J4_cmpltu_t_jumpnv_t:
2443 return Comparison::LTu;
2445 case Hexagon::J4_cmplt_f_jumpnv_nt:
2446 case Hexagon::J4_cmplt_f_jumpnv_t:
2447 return Comparison::GEs;
2449 case Hexagon::C4_cmplteu:
2450 case Hexagon::C4_cmplteui:
2451 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2452 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2453 case Hexagon::J4_cmpgtu_f_jumpnv_nt:
2454 case Hexagon::J4_cmpgtu_f_jumpnv_t:
2455 return Comparison::LEu;
2457 case Hexagon::J4_cmplt_t_jumpnv_nt:
2458 case Hexagon::J4_cmplt_t_jumpnv_t:
2459 return Comparison::LTs;
2464 return Comparison::Unk;
2467APInt HexagonConstEvaluator::getCmpImm(
unsigned Opc,
unsigned OpX,
2468 const MachineOperand &MO) {
2471 case Hexagon::A4_cmpbgtui:
2472 case Hexagon::A4_cmphgtui:
2474 case Hexagon::A4_cmpheqi:
2475 case Hexagon::C4_cmpneqi:
2478 case Hexagon::A4_cmpbeqi:
2480 case Hexagon::C2_cmpgtui:
2481 case Hexagon::C4_cmplteui:
2483 case Hexagon::C2_cmpeqi:
2484 case Hexagon::C2_cmpgti:
2485 case Hexagon::C4_cmpltei:
2488 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2489 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2490 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2491 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2492 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2493 case Hexagon::J4_cmpgti_f_jumpnv_t:
2494 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2495 case Hexagon::J4_cmpgti_t_jumpnv_t:
2496 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2497 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2498 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2499 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2506 uint64_t Val = MO.
getImm();
2508 return APInt(32, Val,
Signed,
true);
2511void HexagonConstEvaluator::replaceWithNop(MachineInstr &
MI) {
2512 MI.setDesc(HII.get(Hexagon::A2_nop));
2513 while (
MI.getNumOperands() > 0)
2514 MI.removeOperand(0);
2517bool HexagonConstEvaluator::evaluateHexRSEQ32(
RegSubRegPair RL,
2519 const CellMap &Inputs,
2520 LatticeCell &Result) {
2522 LatticeCell
LSL, LSH;
2523 if (!getCell(RL, Inputs, LSL) || !getCell(RH, Inputs, LSH))
2525 if (
LSL.isProperty() || LSH.isProperty())
2528 unsigned LN =
LSL.size(), HN = LSH.size();
2530 for (
unsigned i = 0; i < LN; ++i) {
2531 bool Eval = constToInt(
LSL.Values[i], LoVs[i]);
2536 for (
unsigned i = 0; i < HN; ++i) {
2537 bool Eval = constToInt(LSH.Values[i], HiVs[i]);
2543 for (
unsigned i = 0; i < HiVs.size(); ++i) {
2544 APInt HV = HiVs[i].zext(64) << 32;
2545 for (
unsigned j = 0;
j < LoVs.size(); ++
j) {
2546 APInt LV = LoVs[
j].zext(64);
2547 const Constant *
C = intToConst(HV | LV);
2553 return !
Result.isBottom();
2556bool HexagonConstEvaluator::evaluateHexCompare(
const MachineInstr &
MI,
2557 const CellMap &Inputs, CellMap &Outputs) {
2558 unsigned Opc =
MI.getOpcode();
2559 bool Classic =
false;
2561 case Hexagon::C2_cmpeq:
2562 case Hexagon::C2_cmpeqp:
2563 case Hexagon::C2_cmpgt:
2564 case Hexagon::C2_cmpgtp:
2565 case Hexagon::C2_cmpgtu:
2566 case Hexagon::C2_cmpgtup:
2567 case Hexagon::C2_cmpeqi:
2568 case Hexagon::C2_cmpgti:
2569 case Hexagon::C2_cmpgtui:
2579 const MachineOperand &Src1 =
MI.getOperand(1);
2580 const MachineOperand &Src2 =
MI.getOperand(2);
2583 unsigned Opc =
MI.getOpcode();
2584 bool Computed = evaluateHexCompare2(
Opc, Src1, Src2, Inputs, Result);
2589 LatticeCell
L = Outputs.get(DefR.Reg);
2590 uint32_t
P =
Result ? ConstantProperties::NonZero
2591 : ConstantProperties::Zero;
2593 Outputs.update(DefR.Reg, L);
2601bool HexagonConstEvaluator::evaluateHexCompare2(
unsigned Opc,
2602 const MachineOperand &Src1,
const MachineOperand &Src2,
2603 const CellMap &Inputs,
bool &Result) {
2605 bool Reg1 = Src1.
isReg(), Reg2 = Src2.
isReg();
2606 bool Imm1 = Src1.
isImm(), Imm2 = Src2.
isImm();
2611 return evaluateCMPrr(Cmp, R1,
R2, Inputs, Result);
2613 APInt A2 = getCmpImm(
Opc, 2, Src2);
2614 return evaluateCMPri(Cmp, R1, A2, Inputs, Result);
2617 APInt A1 = getCmpImm(
Opc, 1, Src1);
2620 uint32_t NegCmp = Comparison::negate(Cmp);
2621 return evaluateCMPri(NegCmp,
R2, A1, Inputs, Result);
2623 APInt A2 = getCmpImm(
Opc, 2, Src2);
2624 return evaluateCMPii(Cmp, A1, A2, Result);
2631bool HexagonConstEvaluator::evaluateHexLogical(
const MachineInstr &
MI,
2632 const CellMap &Inputs, CellMap &Outputs) {
2633 unsigned Opc =
MI.getOpcode();
2634 if (
MI.getNumOperands() != 3)
2636 const MachineOperand &Src1 =
MI.getOperand(1);
2637 const MachineOperand &Src2 =
MI.getOperand(2);
2644 case Hexagon::A2_and:
2645 case Hexagon::A2_andp:
2649 case Hexagon::A2_andir: {
2652 APInt
A(32, Src2.
getImm(),
true);
2653 Eval = evaluateANDri(R1,
A, Inputs, RC);
2656 case Hexagon::A2_or:
2657 case Hexagon::A2_orp:
2661 case Hexagon::A2_orir: {
2664 APInt
A(32, Src2.
getImm(),
true);
2665 Eval = evaluateORri(R1,
A, Inputs, RC);
2668 case Hexagon::A2_xor:
2669 case Hexagon::A2_xorp:
2676 Outputs.update(DefR.Reg, RC);
2681bool HexagonConstEvaluator::evaluateHexCondMove(
const MachineInstr &
MI,
2682 const CellMap &Inputs, CellMap &Outputs) {
2685 assert(Inputs.has(CR.Reg));
2687 if (!getCell(CR, Inputs, LS))
2689 uint32_t Ps =
LS.properties();
2691 if (Ps & ConstantProperties::Zero)
2693 else if (Ps & ConstantProperties::NonZero)
2698 const MachineOperand &ValOp =
MI.getOperand(TakeOp);
2700 LatticeCell RC = Outputs.get(DefR.Reg);
2702 if (ValOp.
isImm()) {
2705 APInt
A(W, V,
true);
2708 Outputs.update(DefR.Reg, RC);
2711 if (ValOp.
isReg()) {
2713 const LatticeCell &LR = Inputs.get(
R.Reg);
2718 Outputs.update(DefR.Reg, RC);
2724bool HexagonConstEvaluator::evaluateHexExt(
const MachineInstr &
MI,
2725 const CellMap &Inputs, CellMap &Outputs) {
2730 unsigned Opc =
MI.getOpcode();
2733 case Hexagon::A2_sxtb:
2734 case Hexagon::A2_zxtb:
2737 case Hexagon::A2_sxth:
2738 case Hexagon::A2_zxth:
2741 case Hexagon::A2_sxtw:
2750 case Hexagon::A2_sxtb:
2751 case Hexagon::A2_sxth:
2752 case Hexagon::A2_sxtw:
2759 LatticeCell RC = Outputs.get(DefR.Reg);
2760 bool Eval =
Signed ? evaluateSEXTr(R1, BW, Bits, Inputs, RC)
2761 : evaluateZEXTr(R1, BW,
Bits, Inputs, RC);
2764 Outputs.update(DefR.Reg, RC);
2768bool HexagonConstEvaluator::evaluateHexVector1(
const MachineInstr &
MI,
2769 const CellMap &Inputs, CellMap &Outputs) {
2774 LatticeCell RC = Outputs.get(DefR.Reg);
2777 unsigned Opc =
MI.getOpcode();
2779 case Hexagon::S2_vsplatrb:
2781 Eval = evaluateSplatr(R1, 8, 4, Inputs, RC);
2783 case Hexagon::S2_vsplatrh:
2785 Eval = evaluateSplatr(R1, 16, 4, Inputs, RC);
2793 Outputs.update(DefR.Reg, RC);
2797bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &
MI,
2798 const CellMap &Inputs,
bool &AllDefs) {
2806 bool Const =
true, HasUse =
false;
2807 for (
const MachineOperand &MO :
MI.operands()) {
2811 if (!
R.Reg.isVirtual())
2815 if (!
MI.isPHI() && !Inputs.has(
R.Reg)) {
2817 <<
" in MI: " <<
MI;
2820 const LatticeCell &
L = Inputs.get(
R.Reg);
2825 if (HasUse && Const) {
2827 dbgs() <<
"CONST: " <<
MI;
2828 for (
const MachineOperand &MO :
MI.operands()) {
2844 MachineFunction *MF =
MI.getParent()->getParent();
2848 SmallVector<unsigned,2> DefRegs;
2849 for (
const MachineOperand &MO :
MI.operands()) {
2857 DefRegs.push_back(R);
2860 MachineBasicBlock &
B = *
MI.getParent();
2862 unsigned ChangedNum = 0;
2870 for (
unsigned R : DefRegs) {
2871 const LatticeCell &
L = Inputs.get(R);
2874 const TargetRegisterClass *RC =
MRI->getRegClass(R);
2877 if (!
L.isSingle()) {
2880 using P = ConstantProperties;
2882 uint64_t Ps =
L.properties();
2883 if (!(Ps & (P::Zero|P::NonZero)))
2885 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
2888 const MCInstrDesc *NewD = (Ps & P::Zero) ?
2889 &HII.get(Hexagon::PS_false) :
2890 &HII.get(Hexagon::PS_true);
2891 Register NewR =
MRI->createVirtualRegister(PredRC);
2892 const MachineInstrBuilder &MIB =
BuildMI(
B, At,
DL, *NewD, NewR);
2897 replaceAllRegUsesWith(R, NewR);
2901 if (!constToInt(
L.Value,
A) || !
A.isSignedIntN(64))
2903 const TargetRegisterClass *NewRC;
2904 const MCInstrDesc *NewD;
2907 int64_t
V =
A.getSExtValue();
2908 assert(W == 32 || W == 64);
2910 NewRC = &Hexagon::IntRegsRegClass;
2912 NewRC = &Hexagon::DoubleRegsRegClass;
2913 Register NewR =
MRI->createVirtualRegister(NewRC);
2914 const MachineInstr *NewMI;
2917 NewD = &HII.get(Hexagon::A2_tfrsi);
2921 if (
A.isSignedIntN(8)) {
2922 NewD = &HII.get(Hexagon::A2_tfrpi);
2926 int32_t
Hi =
V >> 32;
2927 int32_t
Lo =
V & 0xFFFFFFFFLL;
2929 NewD = &HII.get(Hexagon::A2_combineii);
2935 NewD = &HII.get(Hexagon::CONST64);
2946 replaceAllRegUsesWith(R, NewR);
2952 if (!NewInstrs.
empty()) {
2953 MachineFunction &MF = *
MI.getParent()->getParent();
2954 dbgs() <<
"In function: " << MF.
getName() <<
"\n";
2955 dbgs() <<
"Rewrite: for " <<
MI <<
" created " << *NewInstrs[0];
2956 for (
unsigned i = 1; i < NewInstrs.size(); ++i)
2957 dbgs() <<
" " << *NewInstrs[i];
2961 AllDefs = (ChangedNum == DefRegs.size());
2962 return ChangedNum > 0;
2965bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &
MI,
2966 const CellMap &Inputs) {
2968 unsigned Opc =
MI.getOpcode();
2969 MachineBasicBlock &
B = *
MI.getParent();
2972 MachineInstr *NewMI =
nullptr;
2975 case Hexagon::M2_maci:
2984 assert(Inputs.has(
R2.Reg) && Inputs.has(R3.Reg));
2985 LatticeCell LS2, LS3;
2988 bool HasC2 = getCell(
R2, Inputs, LS2), HasC3 = getCell(R3, Inputs, LS3);
2989 if (!HasC2 && !HasC3)
2991 bool Zero = ((HasC2 && (LS2.properties() & ConstantProperties::Zero)) ||
2992 (HasC3 && (LS3.properties() & ConstantProperties::Zero)));
2996 MachineOperand &Acc =
MI.getOperand(1);
2998 unsigned NewR = R1.
Reg;
3001 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3002 NewR =
MRI->createVirtualRegister(RC);
3003 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3006 replaceAllRegUsesWith(DefR.Reg, NewR);
3007 MRI->clearKillFlags(NewR);
3013 if (!LS3.isSingle()) {
3014 if (!LS2.isSingle())
3018 const LatticeCell &LI = Swap ? LS2 : LS3;
3019 const MachineOperand &OpR2 = Swap ?
MI.getOperand(3)
3023 if (!constToInt(LI.Value,
A) || !
A.isSignedIntN(8))
3025 int64_t
V =
A.getSExtValue();
3026 const MCInstrDesc &
D = (
V >= 0) ? HII.get(Hexagon::M2_macsip)
3027 : HII.get(Hexagon::M2_macsin);
3030 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3032 const MachineOperand &Src1 =
MI.getOperand(1);
3037 replaceAllRegUsesWith(DefR.Reg, NewR);
3042 case Hexagon::A2_and:
3047 LatticeCell LS1, LS2;
3048 unsigned CopyOf = 0;
3050 if (getCell(R1, Inputs, LS1) && LS1.isSingle()) {
3052 if (constToInt(LS1.Value,
M1) && !~
M1)
3055 else if (getCell(
R2, Inputs, LS2) && LS2.isSingle()) {
3057 if (constToInt(LS2.Value,
M1) && !~
M1)
3062 MachineOperand &SO =
MI.getOperand(CopyOf);
3065 unsigned NewR = SR.Reg;
3067 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3068 NewR =
MRI->createVirtualRegister(RC);
3069 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3072 replaceAllRegUsesWith(DefR.Reg, NewR);
3073 MRI->clearKillFlags(NewR);
3078 case Hexagon::A2_or:
3083 LatticeCell LS1, LS2;
3084 unsigned CopyOf = 0;
3086 using P = ConstantProperties;
3088 if (getCell(R1, Inputs, LS1) && (LS1.properties() & P::Zero))
3090 else if (getCell(
R2, Inputs, LS2) && (LS2.properties() & P::Zero))
3094 MachineOperand &SO =
MI.getOperand(CopyOf);
3097 unsigned NewR = SR.Reg;
3099 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3100 NewR =
MRI->createVirtualRegister(RC);
3101 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3104 replaceAllRegUsesWith(DefR.Reg, NewR);
3105 MRI->clearKillFlags(NewR);
3113 for (MachineOperand &MO : NewMI->
operands())
3120 dbgs() <<
"Rewrite: for " <<
MI;
3122 dbgs() <<
" created " << *NewMI;
3124 dbgs() <<
" modified the instruction itself and created:" << *NewMI;
3131void HexagonConstEvaluator::replaceAllRegUsesWith(
Register FromReg,
3135 for (MachineOperand &O :
3140bool HexagonConstEvaluator::rewriteHexBranch(MachineInstr &BrI,
3141 const CellMap &Inputs) {
3148 SetVector<const MachineBasicBlock*> Targets;
3149 bool Eval =
evaluate(BrI, Inputs, Targets, FallsThru);
3150 unsigned NumTargets = Targets.
size();
3151 if (!Eval || NumTargets > 1 || (NumTargets == 1 && FallsThru))
3153 if (BrI.
getOpcode() == Hexagon::J2_jump)
3157 bool Rewritten =
false;
3158 if (NumTargets > 0) {
3159 assert(!FallsThru &&
"This should have been checked before");
3161 MachineBasicBlock *TargetB =
const_cast<MachineBasicBlock*
>(Targets[0]);
3162 bool Moot =
B.isLayoutSuccessor(TargetB);
3168 const MCInstrDesc &JD = HII.get(Hexagon::J2_jump);
3176 for (
auto &
Op : NI->operands())
3178 NI->eraseFromParent();
3187 replaceWithNop(BrI);
3192 return new HexagonConstPropagation();
unsigned const MachineRegisterInfo * MRI
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static bool isSameValue(const APInt &I1, const APInt &I2, bool SignedCompare=false)
Determine if two APInts have the same value, after zero-extending or sign-extending (if SignedCompare...
unsigned countl_one() const
Count the number of leading one bits.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
int64_t getSExtValue() const
Get sign extended value.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned countr_one() const
Count the number of trailing one bits.
const APFloat & getValueAPF() const
bool isNegative() const
Return true if the sign bit is set.
bool isNaN() const
Return true if the value is a NaN.
bool isZero() const
Return true if the value is positive or negative zero.
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
This is an important class for using LLVM in a threaded context.
MachineInstrBundleIterator< const MachineInstr > const_iterator
iterator_range< iterator > phis()
Returns a range that iterates over the phis in the basic block.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
void print(raw_ostream &OS, const SlotIndexes *=nullptr) const
print - Print out the MachineFunction in a format suitable for debugging to the specified stream.
BasicBlockListType::const_iterator const_iterator
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
A vector that has set insertion semantics.
bool remove(const value_type &X)
Remove an item from the set vector.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
LLVM Value Representation.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ Undetermined
It is up to the client to interpret diagnostics as error, warning, info or hint.
This is an optimization pass for GlobalISel generic memory operations.
TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)
Create RegSubRegPair from a register MachineOperand.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI bool isCurrentDebugType(const char *Type, int Level=0)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...
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<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator_range< po_iterator< T > > post_order(const T &G)
FunctionPass * createHexagonConstPropagationPass()
unsigned M1(unsigned Val)
LLVM_ABI bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
auto reverse(ContainerTy &&C)
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.
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
static NodeRef getEntryNode(MachineFunction *F)
A pair composed of a register and a sub-register index.