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');
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 {
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);
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;
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);
3003 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3006 replaceAllRegUsesWith(DefR.Reg, 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);
3069 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3072 replaceAllRegUsesWith(DefR.Reg, 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);
3101 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3104 replaceAllRegUsesWith(DefR.Reg, 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();
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
iterator_range< use_iterator > use_operands(Register Reg) const
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.