46#define DEBUG_TYPE "hcp"
58 class ConstantProperties {
68 NumericProperties = (Zero|NonZero|Finite|Infinity|NaN|SignedZero),
71 SignProperties = (PosOrZero|NegOrZero),
72 Everything = (NumericProperties|SignProperties)
85 struct RegisterSubReg {
89 explicit RegisterSubReg(
unsigned R,
unsigned SR = 0) : Reg(R),
SubReg(SR) {}
97 bool operator== (
const RegisterSubReg &R)
const {
98 return (Reg == R.Reg) && (
SubReg == R.SubReg);
111 enum { Normal, Top, Bottom };
113 static const unsigned MaxCellSize = 4;
117 unsigned IsSpecial:1;
124 const Constant *Values[MaxCellSize];
127 LatticeCell() : Kind(Top), Size(0), IsSpecial(
false) {
132 bool meet(
const LatticeCell &L);
136 unsigned size()
const {
return Size; }
138 LatticeCell(
const LatticeCell &L) {
141 L.IsSpecial ?
sizeof L.Properties : L.Size *
sizeof(
const Constant *);
142 memcpy(Values, L.Values,
N);
145 IsSpecial = L.IsSpecial;
148 LatticeCell &operator=(
const LatticeCell &L) {
151 uint32_t N = L.IsSpecial ?
sizeof L.Properties
152 : L.Size *
sizeof(
const Constant *);
153 memcpy(Values, L.Values,
N);
156 IsSpecial = L.IsSpecial;
161 bool isSingle()
const {
return size() == 1; }
162 bool isProperty()
const {
return IsSpecial; }
163 bool isTop()
const {
return Kind == Top; }
164 bool isBottom()
const {
return Kind == Bottom; }
167 bool Changed = (Kind != Bottom);
183 bool convertToProperty();
193 class MachineConstEvaluator;
195 class MachineConstPropagator {
197 MachineConstPropagator(MachineConstEvaluator &E) : MCE(E) {
218 void clear() { Map.clear(); }
224 MapType::const_iterator
F = Map.find(R);
225 return F != Map.end();
231 MapType::const_iterator
F = Map.find(R);
238 void update(
Register R,
const LatticeCell &L) { Map[R] = L; }
243 using MapType = std::map<Register, LatticeCell>;
249 LatticeCell Top, Bottom;
264 void visitUsesOf(
unsigned R);
273 MachineConstEvaluator &MCE;
275 using CFGEdge = std::pair<unsigned, unsigned>;
276 using SetOfCFGEdge = std::set<CFGEdge>;
277 using SetOfInstr = std::set<const MachineInstr *>;
278 using QueueOfCFGEdge = std::queue<CFGEdge>;
282 SetOfCFGEdge EdgeExec;
283 SetOfInstr InstrExec;
284 QueueOfCFGEdge FlowQ;
290 class MachineConstEvaluator {
295 virtual ~MachineConstEvaluator() =
default;
312 using CellMap = MachineConstPropagator::CellMap;
313 virtual bool evaluate(
const MachineInstr &
MI,
const CellMap &Inputs,
314 CellMap &Outputs) = 0;
315 virtual bool evaluate(
const RegisterSubReg &R,
const LatticeCell &SrcC,
316 LatticeCell &Result) = 0;
317 virtual bool evaluate(
const MachineInstr &BrI,
const CellMap &Inputs,
319 bool &CanFallThru) = 0;
320 virtual bool rewrite(
MachineInstr &
MI,
const CellMap &Inputs) = 0;
358 bool getCell(
const RegisterSubReg &R,
const CellMap &Inputs, LatticeCell &RC);
363 bool evaluateCMPrr(
uint32_t Cmp,
const RegisterSubReg &R1,
const RegisterSubReg &
R2,
364 const CellMap &Inputs,
bool &Result);
365 bool evaluateCMPri(
uint32_t Cmp,
const RegisterSubReg &R1,
const APInt &A2,
366 const CellMap &Inputs,
bool &Result);
368 const CellMap &Inputs,
bool &Result);
376 bool evaluateCOPY(
const RegisterSubReg &R1,
const CellMap &Inputs,
377 LatticeCell &Result);
380 bool evaluateANDrr(
const RegisterSubReg &R1,
const RegisterSubReg &
R2,
381 const CellMap &Inputs, LatticeCell &Result);
382 bool evaluateANDri(
const RegisterSubReg &R1,
const APInt &A2,
383 const CellMap &Inputs, LatticeCell &Result);
385 bool evaluateORrr(
const RegisterSubReg &R1,
const RegisterSubReg &
R2,
386 const CellMap &Inputs, LatticeCell &Result);
387 bool evaluateORri(
const RegisterSubReg &R1,
const APInt &A2,
388 const CellMap &Inputs, LatticeCell &Result);
390 bool evaluateXORrr(
const RegisterSubReg &R1,
const RegisterSubReg &
R2,
391 const CellMap &Inputs, LatticeCell &Result);
392 bool evaluateXORri(
const RegisterSubReg &R1,
const APInt &A2,
393 const CellMap &Inputs, LatticeCell &Result);
397 bool evaluateZEXTr(
const RegisterSubReg &R1,
unsigned Width,
unsigned Bits,
398 const CellMap &Inputs, LatticeCell &Result);
399 bool evaluateZEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
401 bool evaluateSEXTr(
const RegisterSubReg &R1,
unsigned Width,
unsigned Bits,
402 const CellMap &Inputs, LatticeCell &Result);
403 bool evaluateSEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
407 bool evaluateCLBr(
const RegisterSubReg &R1,
bool Zeros,
bool Ones,
408 const CellMap &Inputs, LatticeCell &Result);
409 bool evaluateCLBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
410 bool evaluateCTBr(
const RegisterSubReg &R1,
bool Zeros,
bool Ones,
411 const CellMap &Inputs, LatticeCell &Result);
412 bool evaluateCTBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
415 bool evaluateEXTRACTr(
const RegisterSubReg &R1,
unsigned Width,
unsigned Bits,
417 LatticeCell &Result);
418 bool evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
unsigned Offset,
421 bool evaluateSplatr(
const RegisterSubReg &R1,
unsigned Bits,
unsigned Count,
422 const CellMap &Inputs, LatticeCell &Result);
423 bool evaluateSplati(
const APInt &A1,
unsigned Bits,
unsigned Count,
430 if (isa<ConstantInt>(
C)) {
433 return Zero | PosOrZero | NegOrZero | Finite;
434 uint32_t Props = (NonZero | Finite);
436 return Props | NegOrZero;
437 return Props | PosOrZero;
440 if (isa<ConstantFP>(
C)) {
445 return (Props & ~NumericProperties) | (
Zero|Finite);
446 Props = (Props & ~NumericProperties) | NonZero;
448 return (Props & ~NumericProperties) | NaN;
451 return (Props & ~NumericProperties) | Infinity;
461bool LatticeCell::convertToProperty() {
466 uint32_t Everything = ConstantProperties::Everything;
467 uint32_t Ps = !isTop() ? properties()
469 if (Ps != ConstantProperties::Unknown) {
483 if (Ps & ConstantProperties::Zero)
485 if (Ps & ConstantProperties::NonZero)
487 if (Ps & ConstantProperties::Finite)
489 if (Ps & ConstantProperties::Infinity)
491 if (Ps & ConstantProperties::NaN)
493 if (Ps & ConstantProperties::PosOrZero)
495 if (Ps & ConstantProperties::NegOrZero)
504 }
else if (isTop()) {
507 for (
unsigned i = 0; i <
size(); ++i) {
520bool LatticeCell::meet(
const LatticeCell &L) {
521 bool Changed =
false;
523 Changed = setBottom();
524 if (isBottom() ||
L.isTop())
534 return add(
L.properties());
535 for (
unsigned i = 0; i <
L.size(); ++i) {
547bool LatticeCell::add(
const Constant *LC) {
556 while (Index <
Size) {
563 if (Index < MaxCellSize) {
571 bool Changed =
false;
575 Changed = convertToProperty();
577 uint32_t NewPs = Ps & ConstantProperties::deduce(LC);
578 if (NewPs == ConstantProperties::Unknown) {
591bool LatticeCell::add(
uint32_t Property) {
592 bool Changed = convertToProperty();
594 if (Ps == (Ps & Property))
596 Properties = Property & Ps;
602uint32_t LatticeCell::properties()
const {
605 assert(!isTop() &&
"Should not call this for a top cell");
607 return ConstantProperties::Unknown;
610 uint32_t Ps = ConstantProperties::deduce(Values[0]);
611 for (
unsigned i = 1; i <
size(); ++i) {
612 if (Ps == ConstantProperties::Unknown)
614 Ps &= ConstantProperties::deduce(Values[i]);
620void MachineConstPropagator::CellMap::print(
raw_ostream &os,
627void MachineConstPropagator::visitPHI(
const MachineInstr &PN) {
633 RegisterSubReg DefR(MD);
634 assert(DefR.Reg.isVirtual());
636 bool Changed =
false;
641 const LatticeCell &
T = Cells.get(DefR.Reg);
642 Changed = !
T.isBottom();
643 Cells.update(DefR.Reg, Bottom);
645 visitUsesOf(DefR.Reg);
649 LatticeCell DefC = Cells.get(DefR.Reg);
653 unsigned PBN =
PB->getNumber();
654 if (!EdgeExec.count(CFGEdge(PBN, MBN))) {
660 RegisterSubReg UseR(SO);
663 if (!UseR.Reg.isVirtual())
666 if (!Cells.has(UseR.Reg))
670 bool Eval = MCE.evaluate(UseR, Cells.get(UseR.Reg), SrcC);
672 <<
printReg(UseR.Reg, &MCE.TRI, UseR.SubReg) << SrcC
674 Changed |= Eval ? DefC.meet(SrcC)
676 Cells.update(DefR.Reg, DefC);
681 visitUsesOf(DefR.Reg);
684void MachineConstPropagator::visitNonBranch(
const MachineInstr &
MI) {
688 bool Eval = MCE.evaluate(
MI, Cells, Outputs);
691 dbgs() <<
" outputs:";
692 for (
auto &
I : Outputs)
693 dbgs() <<
' ' <<
I.second;
701 if (!MO.isReg() || !MO.isDef())
703 RegisterSubReg DefR(MO);
705 if (!DefR.Reg.isVirtual())
707 bool Changed =
false;
710 const LatticeCell &
T = Cells.get(DefR.Reg);
711 Changed = !
T.isBottom();
712 Cells.update(DefR.Reg, Bottom);
716 if (!Outputs.has(DefR.Reg))
718 LatticeCell RC = Cells.get(DefR.Reg);
719 Changed = RC.meet(Outputs.get(DefR.Reg));
720 Cells.update(DefR.Reg, RC);
723 visitUsesOf(DefR.Reg);
731void MachineConstPropagator::visitBranchesFrom(
const MachineInstr &BrI) {
733 unsigned MBN =
B.getNumber();
738 bool EvalOk =
true, FallsThru =
true;
741 InstrExec.insert(&
MI);
747 EvalOk = EvalOk && MCE.evaluate(
MI, Cells, Targets, FallsThru);
755 if (
B.mayHaveInlineAsmBr())
770 if (Next != MF.
end())
780 LLVM_DEBUG(
dbgs() <<
" failed to evaluate a branch...adding all CFG "
787 unsigned TBN =
TB->getNumber();
790 FlowQ.push(CFGEdge(MBN, TBN));
794void MachineConstPropagator::visitUsesOf(
unsigned Reg) {
796 << Cells.get(Reg) <<
'\n');
801 if (!InstrExec.count(&
MI))
805 else if (!
MI.isBranch())
808 visitBranchesFrom(
MI);
818 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
820 if (
MI.isDebugInstr())
823 FirstBr =
MI.getIterator();
834 if (
MI.isDebugInstr())
836 if (!InstrExec.count(&
MI))
838 bool Eval = MCE.evaluate(
MI, Cells, Targets, DoNext);
848 if (NextI != MB->getParent()->end())
863 From->removeSuccessor(To);
880 unsigned EntryNum =
Entry->getNumber();
883 FlowQ.push(CFGEdge(EntryNum, EntryNum));
885 while (!FlowQ.empty()) {
886 CFGEdge Edge = FlowQ.front();
890 dbgs() <<
"Picked edge "
893 if (Edge.first != EntryNum)
894 if (EdgeExec.count(Edge))
896 EdgeExec.insert(Edge);
906 while (It !=
End && It->isPHI()) {
907 InstrExec.insert(&*It);
915 while (It !=
End && It->isDebugInstr())
919 if (It !=
End && InstrExec.count(&*It))
923 while (It !=
End && !It->isBranch()) {
924 if (!It->isDebugInstr()) {
925 InstrExec.insert(&*It);
936 visitBranchesFrom(*It);
942 FlowQ.push(CFGEdge(SBN, SSB->getNumber()));
947 dbgs() <<
"Cells after propagation:\n";
948 Cells.print(
dbgs(), MCE.TRI);
949 dbgs() <<
"Dead CFG edges:\n";
951 unsigned BN =
B.getNumber();
954 if (!EdgeExec.count(CFGEdge(BN, SN)))
963 bool Changed =
false;
980 std::vector<MachineBasicBlock*> POT;
994 bool HaveTargets = computeBlockSuccessors(
B, Targets);
998 if (InstrExec.count(&
MI)) {
999 if (
MI.isBranch() && !HaveTargets)
1001 Changed |= MCE.rewrite(
MI, Cells);
1007 for (
auto I =
B->begin(), E =
B->end();
I != E; ++
I) {
1027 if (!Targets.
count(SB))
1032 removeCFGEdge(
B,
MBB);
1047 if (
MI.isBranch() && !InstrExec.count(&
MI))
1066 bool Changed = rewrite(MF);
1069 dbgs() <<
"End of MachineConstPropagator (Changed=" << Changed <<
")\n";
1079bool MachineConstEvaluator::getCell(
const RegisterSubReg &R,
const CellMap &Inputs,
1081 if (!
R.Reg.isVirtual())
1083 const LatticeCell &
L = Inputs.get(
R.Reg);
1086 return !RC.isBottom();
1088 bool Eval = evaluate(R, L, RC);
1089 return Eval && !RC.isBottom();
1092bool MachineConstEvaluator::constToInt(
const Constant *
C,
1101const ConstantInt *MachineConstEvaluator::intToConst(
const APInt &Val)
const {
1102 return ConstantInt::get(CX, Val);
1105bool MachineConstEvaluator::evaluateCMPrr(
uint32_t Cmp,
const RegisterSubReg &R1,
1106 const RegisterSubReg &
R2,
const CellMap &Inputs,
bool &Result) {
1107 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
1108 LatticeCell LS1, LS2;
1109 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1112 bool IsProp1 = LS1.isProperty();
1113 bool IsProp2 = LS2.isProperty();
1117 return evaluateCMPpp(Cmp, Prop1, LS2.properties(), Result);
1118 uint32_t NegCmp = Comparison::negate(Cmp);
1119 return evaluateCMPrp(NegCmp,
R2, Prop1, Inputs, Result);
1123 return evaluateCMPrp(Cmp, R1, Prop2, Inputs, Result);
1127 bool IsTrue =
true, IsFalse =
true;
1128 for (
unsigned i = 0; i < LS2.size(); ++i) {
1130 bool Computed = constToInt(LS2.Values[i],
A) &&
1131 evaluateCMPri(Cmp, R1,
A, Inputs, Res);
1137 assert(!IsTrue || !IsFalse);
1141 return IsTrue || IsFalse;
1144bool MachineConstEvaluator::evaluateCMPri(
uint32_t Cmp,
const RegisterSubReg &R1,
1145 const APInt &A2,
const CellMap &Inputs,
bool &Result) {
1146 assert(Inputs.has(R1.Reg));
1148 if (!getCell(R1, Inputs, LS))
1150 if (
LS.isProperty())
1151 return evaluateCMPpi(Cmp,
LS.properties(), A2, Result);
1154 bool IsTrue =
true, IsFalse =
true;
1155 for (
unsigned i = 0; i <
LS.size(); ++i) {
1157 bool Computed = constToInt(
LS.Values[i],
A) &&
1158 evaluateCMPii(Cmp,
A, A2, Res);
1164 assert(!IsTrue || !IsFalse);
1168 return IsTrue || IsFalse;
1171bool MachineConstEvaluator::evaluateCMPrp(
uint32_t Cmp,
const RegisterSubReg &R1,
1172 uint64_t Props2,
const CellMap &Inputs,
bool &Result) {
1173 assert(Inputs.has(R1.Reg));
1175 if (!getCell(R1, Inputs, LS))
1177 if (
LS.isProperty())
1178 return evaluateCMPpp(Cmp,
LS.properties(), Props2, Result);
1181 uint32_t NegCmp = Comparison::negate(Cmp);
1182 bool IsTrue =
true, IsFalse =
true;
1183 for (
unsigned i = 0; i <
LS.size(); ++i) {
1185 bool Computed = constToInt(
LS.Values[i],
A) &&
1186 evaluateCMPpi(NegCmp, Props2,
A, Res);
1192 assert(!IsTrue || !IsFalse);
1194 return IsTrue || IsFalse;
1197bool MachineConstEvaluator::evaluateCMPii(
uint32_t Cmp,
const APInt &A1,
1198 const APInt &A2,
bool &Result) {
1200 if (Cmp == Comparison::NE) {
1204 if (Cmp == Comparison::EQ) {
1208 if (Cmp & Comparison::EQ) {
1210 return (Result =
true);
1212 assert((Cmp & (Comparison::L | Comparison::G)) &&
"Malformed comparison");
1217 unsigned MaxW = (W1 >= W2) ? W1 : W2;
1218 if (Cmp & Comparison::U) {
1221 if (Cmp & Comparison::L)
1223 else if (Cmp & Comparison::G)
1231 if (Cmp & Comparison::L)
1233 else if (Cmp & Comparison::G)
1239 const APInt &A2,
bool &Result) {
1240 if (Props == ConstantProperties::Unknown)
1244 if (Props & ConstantProperties::NaN)
1249 if (!(Props & ConstantProperties::Finite))
1254 if (Cmp & Comparison::U) {
1258 if (Props & ConstantProperties::Zero)
1260 else if (Props & ConstantProperties::NonZero)
1261 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1267 if (Props & ConstantProperties::Zero) {
1268 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1275 if (Props & ConstantProperties::Zero) {
1280 ((Cmp & Comparison::L) && !A2.
isNegative()) ||
1284 if (Props & ConstantProperties::PosOrZero) {
1289 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1292 if (Props & ConstantProperties::NegOrZero) {
1297 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1306 using P = ConstantProperties;
1308 if ((Props1 & P::NaN) && (Props2 & P::NaN))
1310 if (!(Props1 & P::Finite) || !(Props2 & P::Finite))
1313 bool Zero1 = (Props1 & P::Zero), Zero2 = (Props2 & P::Zero);
1314 bool NonZero1 = (Props1 & P::NonZero), NonZero2 = (Props2 & P::NonZero);
1315 if (Zero1 && Zero2) {
1319 if (Cmp == Comparison::NE) {
1320 if ((Zero1 && NonZero2) || (NonZero1 && Zero2))
1321 return (Result =
true);
1325 if (Cmp & Comparison::U) {
1328 if (Zero1 && NonZero2) {
1332 if (NonZero1 && Zero2) {
1340 bool Poz1 = (Props1 & P::PosOrZero), Poz2 = (Props2 & P::PosOrZero);
1341 bool Nez1 = (Props1 & P::NegOrZero), Nez2 = (Props2 & P::NegOrZero);
1343 if (NonZero1 || NonZero2) {
1348 if ((Cmp & Comparison::EQ) && (
Cmp & Comparison::L))
1349 return (Result =
true);
1352 if (NonZero1 || NonZero2) {
1357 if ((Cmp & Comparison::EQ) && (
Cmp & Comparison::G))
1358 return (Result =
true);
1364bool MachineConstEvaluator::evaluateCOPY(
const RegisterSubReg &R1,
1365 const CellMap &Inputs, LatticeCell &Result) {
1366 return getCell(R1, Inputs, Result);
1369bool MachineConstEvaluator::evaluateANDrr(
const RegisterSubReg &R1,
1370 const RegisterSubReg &
R2,
const CellMap &Inputs, LatticeCell &Result) {
1371 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
1372 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1373 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1377 if (L2.isBottom()) {
1380 return evaluateANDrr(
R2, R1, Inputs, Result);
1383 if (!evaluate(
R2, L2, LS2))
1385 if (LS2.isBottom() || LS2.isProperty())
1389 for (
unsigned i = 0; i < LS2.size(); ++i) {
1391 bool Eval = constToInt(LS2.Values[i],
A) &&
1392 evaluateANDri(R1,
A, Inputs, RC);
1397 return !
Result.isBottom();
1400bool MachineConstEvaluator::evaluateANDri(
const RegisterSubReg &R1,
1401 const APInt &A2,
const CellMap &Inputs, LatticeCell &Result) {
1402 assert(Inputs.has(R1.Reg));
1404 return getCell(R1, Inputs, Result);
1407 RC.add(intToConst(A2));
1413 if (!getCell(R1, Inputs, LS1))
1415 if (LS1.isBottom() || LS1.isProperty())
1419 for (
unsigned i = 0; i < LS1.size(); ++i) {
1420 bool Eval = constToInt(LS1.Values[i],
A) &&
1421 evaluateANDii(
A, A2, ResA);
1427 return !
Result.isBottom();
1430bool MachineConstEvaluator::evaluateANDii(
const APInt &A1,
1436bool MachineConstEvaluator::evaluateORrr(
const RegisterSubReg &R1,
1437 const RegisterSubReg &
R2,
const CellMap &Inputs, LatticeCell &Result) {
1438 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
1439 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1440 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1444 if (L2.isBottom()) {
1447 return evaluateORrr(
R2, R1, Inputs, Result);
1450 if (!evaluate(
R2, L2, LS2))
1452 if (LS2.isBottom() || LS2.isProperty())
1456 for (
unsigned i = 0; i < LS2.size(); ++i) {
1458 bool Eval = constToInt(LS2.Values[i],
A) &&
1459 evaluateORri(R1,
A, Inputs, RC);
1464 return !
Result.isBottom();
1467bool MachineConstEvaluator::evaluateORri(
const RegisterSubReg &R1,
1468 const APInt &A2,
const CellMap &Inputs, LatticeCell &Result) {
1469 assert(Inputs.has(R1.Reg));
1471 return getCell(R1, Inputs, Result);
1474 RC.add(intToConst(A2));
1480 if (!getCell(R1, Inputs, LS1))
1482 if (LS1.isBottom() || LS1.isProperty())
1486 for (
unsigned i = 0; i < LS1.size(); ++i) {
1487 bool Eval = constToInt(LS1.Values[i],
A) &&
1488 evaluateORii(
A, A2, ResA);
1494 return !
Result.isBottom();
1497bool MachineConstEvaluator::evaluateORii(
const APInt &A1,
1503bool MachineConstEvaluator::evaluateXORrr(
const RegisterSubReg &R1,
1504 const RegisterSubReg &
R2,
const CellMap &Inputs, LatticeCell &Result) {
1505 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
1506 LatticeCell LS1, LS2;
1507 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1509 if (LS1.isProperty()) {
1510 if (LS1.properties() & ConstantProperties::Zero)
1511 return !(
Result = LS2).isBottom();
1514 if (LS2.isProperty()) {
1515 if (LS2.properties() & ConstantProperties::Zero)
1516 return !(Result = LS1).isBottom();
1521 for (
unsigned i = 0; i < LS2.size(); ++i) {
1523 bool Eval = constToInt(LS2.Values[i],
A) &&
1524 evaluateXORri(R1,
A, Inputs, RC);
1529 return !
Result.isBottom();
1532bool MachineConstEvaluator::evaluateXORri(
const RegisterSubReg &R1,
1533 const APInt &A2,
const CellMap &Inputs, LatticeCell &Result) {
1534 assert(Inputs.has(R1.Reg));
1536 if (!getCell(R1, Inputs, LS1))
1538 if (LS1.isProperty()) {
1539 if (LS1.properties() & ConstantProperties::Zero) {
1542 return !
Result.isBottom();
1548 for (
unsigned i = 0; i < LS1.size(); ++i) {
1549 bool Eval = constToInt(LS1.Values[i],
A) &&
1550 evaluateXORii(
A, A2, XA);
1556 return !
Result.isBottom();
1559bool MachineConstEvaluator::evaluateXORii(
const APInt &A1,
1565bool MachineConstEvaluator::evaluateZEXTr(
const RegisterSubReg &R1,
unsigned Width,
1566 unsigned Bits,
const CellMap &Inputs, LatticeCell &Result) {
1567 assert(Inputs.has(R1.Reg));
1569 if (!getCell(R1, Inputs, LS1))
1571 if (LS1.isProperty())
1575 for (
unsigned i = 0; i < LS1.size(); ++i) {
1576 bool Eval = constToInt(LS1.Values[i],
A) &&
1577 evaluateZEXTi(
A, Width, Bits, XA);
1586bool MachineConstEvaluator::evaluateZEXTi(
const APInt &A1,
unsigned Width,
1587 unsigned Bits,
APInt &Result) {
1590 assert(Width >= Bits && BW >= Bits);
1596bool MachineConstEvaluator::evaluateSEXTr(
const RegisterSubReg &R1,
unsigned Width,
1597 unsigned Bits,
const CellMap &Inputs, LatticeCell &Result) {
1598 assert(Inputs.has(R1.Reg));
1600 if (!getCell(R1, Inputs, LS1))
1602 if (LS1.isBottom() || LS1.isProperty())
1606 for (
unsigned i = 0; i < LS1.size(); ++i) {
1607 bool Eval = constToInt(LS1.Values[i],
A) &&
1608 evaluateSEXTi(
A, Width, Bits, XA);
1617bool MachineConstEvaluator::evaluateSEXTi(
const APInt &A1,
unsigned Width,
1618 unsigned Bits,
APInt &Result) {
1620 assert(Width >= Bits && BW >= Bits);
1629 if (BW <= 64 && Bits != 0) {
1633 V =
static_cast<int8_t
>(
V);
1636 V =
static_cast<int16_t
>(
V);
1639 V =
static_cast<int32_t
>(
V);
1661bool MachineConstEvaluator::evaluateCLBr(
const RegisterSubReg &R1,
bool Zeros,
1662 bool Ones,
const CellMap &Inputs, LatticeCell &Result) {
1663 assert(Inputs.has(R1.Reg));
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))
1696bool MachineConstEvaluator::evaluateCTBr(
const RegisterSubReg &R1,
bool Zeros,
1697 bool Ones,
const CellMap &Inputs, LatticeCell &Result) {
1698 assert(Inputs.has(R1.Reg));
1700 if (!getCell(R1, Inputs, LS1))
1702 if (LS1.isBottom() || LS1.isProperty())
1706 for (
unsigned i = 0; i < LS1.size(); ++i) {
1707 bool Eval = constToInt(LS1.Values[i],
A) &&
1708 evaluateCTBi(
A, Zeros, Ones, CA);
1717bool MachineConstEvaluator::evaluateCTBi(
const APInt &A1,
bool Zeros,
1718 bool Ones,
APInt &Result) {
1720 if (!Zeros && !Ones)
1723 if (Zeros && (Count == 0))
1725 if (Ones && (Count == 0))
1731bool MachineConstEvaluator::evaluateEXTRACTr(
const RegisterSubReg &R1,
1732 unsigned Width,
unsigned Bits,
unsigned Offset,
bool Signed,
1733 const CellMap &Inputs, LatticeCell &Result) {
1734 assert(Inputs.has(R1.Reg));
1737 if (!getCell(R1, Inputs, LS1))
1741 if (LS1.isProperty()) {
1743 if (Ps & ConstantProperties::Zero) {
1752 for (
unsigned i = 0; i < LS1.size(); ++i) {
1753 bool Eval = constToInt(LS1.Values[i],
A) &&
1763bool MachineConstEvaluator::evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
1789bool MachineConstEvaluator::evaluateSplatr(
const RegisterSubReg &R1,
1790 unsigned Bits,
unsigned Count,
const CellMap &Inputs,
1791 LatticeCell &Result) {
1792 assert(Inputs.has(R1.Reg));
1794 if (!getCell(R1, Inputs, LS1))
1796 if (LS1.isBottom() || LS1.isProperty())
1800 for (
unsigned i = 0; i < LS1.size(); ++i) {
1801 bool Eval = constToInt(LS1.Values[i],
A) &&
1802 evaluateSplati(
A, Bits, Count, SA);
1811bool MachineConstEvaluator::evaluateSplati(
const APInt &A1,
unsigned Bits,
1812 unsigned Count,
APInt &Result) {
1817 LoBits = LoBits.
zext(SW);
1819 APInt Res(SW, 0,
false);
1820 for (
unsigned i = 0; i < Count; ++i) {
1840 class HexagonConstEvaluator :
public MachineConstEvaluator {
1845 CellMap &Outputs)
override;
1846 bool evaluate(
const RegisterSubReg &R,
const LatticeCell &SrcC,
1847 LatticeCell &Result)
override;
1848 bool evaluate(
const MachineInstr &BrI,
const CellMap &Inputs,
1854 unsigned getRegBitWidth(
unsigned Reg)
const;
1857 static APInt getCmpImm(
unsigned Opc,
unsigned OpX,
1861 bool evaluateHexRSEQ32(RegisterSubReg RL, RegisterSubReg RH,
const CellMap &Inputs,
1862 LatticeCell &Result);
1863 bool evaluateHexCompare(
const MachineInstr &
MI,
const CellMap &Inputs,
1867 const MachineOperand &Src2,
const CellMap &Inputs,
bool &Result);
1868 bool evaluateHexLogical(
const MachineInstr &
MI,
const CellMap &Inputs,
1870 bool evaluateHexCondMove(
const MachineInstr &
MI,
const CellMap &Inputs,
1872 bool evaluateHexExt(
const MachineInstr &
MI,
const CellMap &Inputs,
1874 bool evaluateHexVector1(
const MachineInstr &
MI,
const CellMap &Inputs,
1876 bool evaluateHexVector2(
const MachineInstr &
MI,
const CellMap &Inputs,
1880 bool rewriteHexBranch(
MachineInstr &BrI,
const CellMap &Inputs);
1881 bool rewriteHexConstDefs(
MachineInstr &
MI,
const CellMap &Inputs,
1883 bool rewriteHexConstUses(
MachineInstr &
MI,
const CellMap &Inputs);
1897 return "Hexagon Constant Propagation";
1905 HexagonConstEvaluator HCE(MF);
1906 return MachineConstPropagator(HCE).run(MF);
1912char HexagonConstPropagation::ID = 0;
1915 "Hexagon Constant Propagation",
false,
false)
1918 : MachineConstEvaluator(Fn),
1921 MRI = &Fn.getRegInfo();
1925 const CellMap &Inputs, CellMap &Outputs) {
1928 if (
MI.getNumOperands() == 0 || !
MI.getOperand(0).isReg())
1934 unsigned Opc =
MI.getOpcode();
1935 RegisterSubReg DefR(MD);
1937 if (!DefR.Reg.isVirtual())
1942 RegisterSubReg SrcR(
MI.getOperand(1));
1943 bool Eval = evaluateCOPY(SrcR, Inputs, RC);
1946 Outputs.update(DefR.Reg, RC);
1949 if (
MI.isRegSequence()) {
1950 unsigned Sub1 =
MI.getOperand(2).getImm();
1951 unsigned Sub2 =
MI.getOperand(4).getImm();
1955 if (Sub1 != SubLo && Sub1 != SubHi)
1957 if (Sub2 != SubLo && Sub2 != SubHi)
1960 bool LoIs1 = (Sub1 == SubLo);
1964 RegisterSubReg SrcRL(OpLo), SrcRH(OpHi);
1965 bool Eval = evaluateHexRSEQ32(SrcRL, SrcRH, Inputs, RC);
1968 Outputs.update(DefR.Reg, RC);
1971 if (
MI.isCompare()) {
1972 bool Eval = evaluateHexCompare(
MI, Inputs, Outputs);
1979 case Hexagon::A2_tfrsi:
1980 case Hexagon::A2_tfrpi:
1981 case Hexagon::CONST32:
1982 case Hexagon::CONST64:
1990 int64_t
V =
MI.getOperand(1).getImm();
1992 if (W != 32 && W != 64)
1996 const ConstantInt *CI = ConstantInt::get(Ty, V,
true);
1997 LatticeCell RC = Outputs.get(DefR.Reg);
1999 Outputs.update(DefR.Reg, RC);
2003 case Hexagon::PS_true:
2004 case Hexagon::PS_false:
2006 LatticeCell RC = Outputs.get(DefR.Reg);
2007 bool NonZero = (Opc == Hexagon::PS_true);
2008 uint32_t P = NonZero ? ConstantProperties::NonZero
2009 : ConstantProperties::Zero;
2011 Outputs.update(DefR.Reg, RC);
2015 case Hexagon::A2_and:
2016 case Hexagon::A2_andir:
2017 case Hexagon::A2_andp:
2018 case Hexagon::A2_or:
2019 case Hexagon::A2_orir:
2020 case Hexagon::A2_orp:
2021 case Hexagon::A2_xor:
2022 case Hexagon::A2_xorp:
2024 bool Eval = evaluateHexLogical(
MI, Inputs, Outputs);
2030 case Hexagon::A2_combineii:
2031 case Hexagon::A4_combineii:
2033 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isImm())
2039 const ConstantInt *CI = ConstantInt::get(Ty, Res,
false);
2040 LatticeCell RC = Outputs.get(DefR.Reg);
2042 Outputs.update(DefR.Reg, RC);
2046 case Hexagon::S2_setbit_i:
2048 int64_t
B =
MI.getOperand(2).getImm();
2050 APInt A(32, (1ull <<
B),
false);
2051 RegisterSubReg
R(
MI.getOperand(1));
2052 LatticeCell RC = Outputs.get(DefR.Reg);
2053 bool Eval = evaluateORri(R,
A, Inputs, RC);
2056 Outputs.update(DefR.Reg, RC);
2060 case Hexagon::C2_mux:
2061 case Hexagon::C2_muxir:
2062 case Hexagon::C2_muxri:
2063 case Hexagon::C2_muxii:
2065 bool Eval = evaluateHexCondMove(
MI, Inputs, Outputs);
2071 case Hexagon::A2_sxtb:
2072 case Hexagon::A2_sxth:
2073 case Hexagon::A2_sxtw:
2074 case Hexagon::A2_zxtb:
2075 case Hexagon::A2_zxth:
2077 bool Eval = evaluateHexExt(
MI, Inputs, Outputs);
2083 case Hexagon::S2_ct0:
2084 case Hexagon::S2_ct0p:
2085 case Hexagon::S2_ct1:
2086 case Hexagon::S2_ct1p:
2088 using namespace Hexagon;
2090 bool Ones = (Opc == S2_ct1) || (Opc == S2_ct1p);
2091 RegisterSubReg R1(
MI.getOperand(1));
2092 assert(Inputs.has(R1.Reg));
2094 bool Eval = evaluateCTBr(R1, !Ones, Ones, Inputs,
T);
2101 LatticeCell RC = Outputs.get(DefR.Reg);
2102 for (
unsigned i = 0; i <
T.size(); ++i) {
2104 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2105 CI = intToConst(
C.trunc(32));
2108 Outputs.update(DefR.Reg, RC);
2112 case Hexagon::S2_cl0:
2113 case Hexagon::S2_cl0p:
2114 case Hexagon::S2_cl1:
2115 case Hexagon::S2_cl1p:
2116 case Hexagon::S2_clb:
2117 case Hexagon::S2_clbp:
2119 using namespace Hexagon;
2121 bool OnlyZeros = (Opc == S2_cl0) || (Opc == S2_cl0p);
2122 bool OnlyOnes = (Opc == S2_cl1) || (Opc == S2_cl1p);
2123 RegisterSubReg R1(
MI.getOperand(1));
2124 assert(Inputs.has(R1.Reg));
2126 bool Eval = evaluateCLBr(R1, !OnlyOnes, !OnlyZeros, Inputs,
T);
2133 LatticeCell RC = Outputs.get(DefR.Reg);
2134 for (
unsigned i = 0; i <
T.size(); ++i) {
2136 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2137 CI = intToConst(
C.trunc(32));
2140 Outputs.update(DefR.Reg, RC);
2144 case Hexagon::S4_extract:
2145 case Hexagon::S4_extractp:
2146 case Hexagon::S2_extractu:
2147 case Hexagon::S2_extractup:
2149 bool Signed = (Opc == Hexagon::S4_extract) ||
2150 (Opc == Hexagon::S4_extractp);
2151 RegisterSubReg R1(
MI.getOperand(1));
2153 unsigned Bits =
MI.getOperand(2).getImm();
2154 unsigned Offset =
MI.getOperand(3).getImm();
2155 LatticeCell RC = Outputs.get(DefR.Reg);
2158 RC.add(intToConst(Zero));
2168 bool Eval = evaluateEXTRACTr(R1, BW, Bits,
Offset,
Signed, Inputs, RC);
2171 Outputs.update(DefR.Reg, RC);
2175 case Hexagon::S2_vsplatrb:
2176 case Hexagon::S2_vsplatrh:
2186 bool Eval = evaluateHexVector1(
MI, Inputs, Outputs);
2202bool HexagonConstEvaluator::evaluate(
const RegisterSubReg &R,
2203 const LatticeCell &Input, LatticeCell &Result) {
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()) {
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))
2245 if (
R.SubReg == Hexagon::isub_hi)
2250 memcpy(&V32, &U32,
sizeof V32);
2252 const ConstantInt *C32 = ConstantInt::get(Ty,
static_cast<int64_t
>(V32));
2258bool HexagonConstEvaluator::evaluate(
const MachineInstr &BrI,
2264 bool SimpleBranch =
false;
2265 bool Negated =
false;
2267 case Hexagon::J2_jumpf:
2268 case Hexagon::J2_jumpfnew:
2269 case Hexagon::J2_jumpfnewpt:
2272 case Hexagon::J2_jumpt:
2273 case Hexagon::J2_jumptnew:
2274 case Hexagon::J2_jumptnewpt:
2277 SimpleBranch =
true;
2279 case Hexagon::J2_jump:
2293 RegisterSubReg PR(MD);
2298 assert(Inputs.has(PR.Reg));
2299 const LatticeCell &PredC = Inputs.get(PR.Reg);
2300 if (PredC.isBottom())
2303 uint32_t Props = PredC.properties();
2304 bool CTrue =
false, CFalse =
false;
2305 if (Props & ConstantProperties::Zero)
2307 else if (Props & ConstantProperties::NonZero)
2310 if (!CTrue && !CFalse)
2316 if ((!Negated && CTrue) || (Negated && CFalse))
2317 Targets.
insert(BranchTarget);
2318 else if ((!Negated && CFalse) || (Negated && CTrue))
2327bool HexagonConstEvaluator::rewrite(
MachineInstr &
MI,
const CellMap &Inputs) {
2329 return rewriteHexBranch(
MI, Inputs);
2331 unsigned Opc =
MI.getOpcode();
2335 case Hexagon::A2_tfrsi:
2336 case Hexagon::A2_tfrpi:
2337 case Hexagon::CONST32:
2338 case Hexagon::CONST64:
2339 case Hexagon::PS_true:
2340 case Hexagon::PS_false:
2344 unsigned NumOp =
MI.getNumOperands();
2348 bool AllDefs, Changed;
2349 Changed = rewriteHexConstDefs(
MI, Inputs, AllDefs);
2354 Changed |= rewriteHexConstUses(
MI, Inputs);
2359unsigned HexagonConstEvaluator::getRegBitWidth(
unsigned Reg)
const {
2361 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC))
2363 if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC))
2365 if (Hexagon::PredRegsRegClass.hasSubClassEq(RC))
2371uint32_t HexagonConstEvaluator::getCmp(
unsigned Opc) {
2373 case Hexagon::C2_cmpeq:
2374 case Hexagon::C2_cmpeqp:
2375 case Hexagon::A4_cmpbeq:
2376 case Hexagon::A4_cmpheq:
2377 case Hexagon::A4_cmpbeqi:
2378 case Hexagon::A4_cmpheqi:
2379 case Hexagon::C2_cmpeqi:
2380 case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
2381 case Hexagon::J4_cmpeqn1_t_jumpnv_t:
2382 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2383 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2384 case Hexagon::J4_cmpeq_t_jumpnv_nt:
2385 case Hexagon::J4_cmpeq_t_jumpnv_t:
2386 return Comparison::EQ;
2388 case Hexagon::C4_cmpneq:
2389 case Hexagon::C4_cmpneqi:
2390 case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
2391 case Hexagon::J4_cmpeqn1_f_jumpnv_t:
2392 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2393 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2394 case Hexagon::J4_cmpeq_f_jumpnv_nt:
2395 case Hexagon::J4_cmpeq_f_jumpnv_t:
2396 return Comparison::NE;
2398 case Hexagon::C2_cmpgt:
2399 case Hexagon::C2_cmpgtp:
2400 case Hexagon::A4_cmpbgt:
2401 case Hexagon::A4_cmphgt:
2402 case Hexagon::A4_cmpbgti:
2403 case Hexagon::A4_cmphgti:
2404 case Hexagon::C2_cmpgti:
2405 case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
2406 case Hexagon::J4_cmpgtn1_t_jumpnv_t:
2407 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2408 case Hexagon::J4_cmpgti_t_jumpnv_t:
2409 case Hexagon::J4_cmpgt_t_jumpnv_nt:
2410 case Hexagon::J4_cmpgt_t_jumpnv_t:
2411 return Comparison::GTs;
2413 case Hexagon::C4_cmplte:
2414 case Hexagon::C4_cmpltei:
2415 case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
2416 case Hexagon::J4_cmpgtn1_f_jumpnv_t:
2417 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2418 case Hexagon::J4_cmpgti_f_jumpnv_t:
2419 case Hexagon::J4_cmpgt_f_jumpnv_nt:
2420 case Hexagon::J4_cmpgt_f_jumpnv_t:
2421 return Comparison::LEs;
2423 case Hexagon::C2_cmpgtu:
2424 case Hexagon::C2_cmpgtup:
2425 case Hexagon::A4_cmpbgtu:
2426 case Hexagon::A4_cmpbgtui:
2427 case Hexagon::A4_cmphgtu:
2428 case Hexagon::A4_cmphgtui:
2429 case Hexagon::C2_cmpgtui:
2430 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2431 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2432 case Hexagon::J4_cmpgtu_t_jumpnv_nt:
2433 case Hexagon::J4_cmpgtu_t_jumpnv_t:
2434 return Comparison::GTu;
2436 case Hexagon::J4_cmpltu_f_jumpnv_nt:
2437 case Hexagon::J4_cmpltu_f_jumpnv_t:
2438 return Comparison::GEu;
2440 case Hexagon::J4_cmpltu_t_jumpnv_nt:
2441 case Hexagon::J4_cmpltu_t_jumpnv_t:
2442 return Comparison::LTu;
2444 case Hexagon::J4_cmplt_f_jumpnv_nt:
2445 case Hexagon::J4_cmplt_f_jumpnv_t:
2446 return Comparison::GEs;
2448 case Hexagon::C4_cmplteu:
2449 case Hexagon::C4_cmplteui:
2450 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2451 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2452 case Hexagon::J4_cmpgtu_f_jumpnv_nt:
2453 case Hexagon::J4_cmpgtu_f_jumpnv_t:
2454 return Comparison::LEu;
2456 case Hexagon::J4_cmplt_t_jumpnv_nt:
2457 case Hexagon::J4_cmplt_t_jumpnv_t:
2458 return Comparison::LTs;
2463 return Comparison::Unk;
2466APInt HexagonConstEvaluator::getCmpImm(
unsigned Opc,
unsigned OpX,
2470 case Hexagon::A4_cmpbgtui:
2471 case Hexagon::A4_cmphgtui:
2473 case Hexagon::A4_cmpheqi:
2474 case Hexagon::C4_cmpneqi:
2477 case Hexagon::A4_cmpbeqi:
2479 case Hexagon::C2_cmpgtui:
2480 case Hexagon::C4_cmplteui:
2482 case Hexagon::C2_cmpeqi:
2483 case Hexagon::C2_cmpgti:
2484 case Hexagon::C4_cmpltei:
2487 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2488 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2489 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2490 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2491 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2492 case Hexagon::J4_cmpgti_f_jumpnv_t:
2493 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2494 case Hexagon::J4_cmpgti_t_jumpnv_t:
2495 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2496 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2497 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2498 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2511 MI.setDesc(HII.get(Hexagon::A2_nop));
2512 while (
MI.getNumOperands() > 0)
2513 MI.removeOperand(0);
2516bool HexagonConstEvaluator::evaluateHexRSEQ32(RegisterSubReg RL, RegisterSubReg RH,
2517 const CellMap &Inputs, LatticeCell &Result) {
2518 assert(Inputs.has(RL.Reg) && Inputs.has(RH.Reg));
2519 LatticeCell
LSL, LSH;
2520 if (!getCell(RL, Inputs, LSL) || !getCell(RH, Inputs, LSH))
2522 if (
LSL.isProperty() || LSH.isProperty())
2525 unsigned LN =
LSL.size(), HN = LSH.size();
2527 for (
unsigned i = 0; i < LN; ++i) {
2528 bool Eval = constToInt(
LSL.Values[i], LoVs[i]);
2533 for (
unsigned i = 0; i < HN; ++i) {
2534 bool Eval = constToInt(LSH.Values[i], HiVs[i]);
2540 for (
unsigned i = 0; i < HiVs.size(); ++i) {
2542 for (
unsigned j = 0;
j < LoVs.size(); ++
j) {
2544 const Constant *
C = intToConst(HV | LV);
2550 return !
Result.isBottom();
2553bool HexagonConstEvaluator::evaluateHexCompare(
const MachineInstr &
MI,
2554 const CellMap &Inputs, CellMap &Outputs) {
2555 unsigned Opc =
MI.getOpcode();
2556 bool Classic =
false;
2558 case Hexagon::C2_cmpeq:
2559 case Hexagon::C2_cmpeqp:
2560 case Hexagon::C2_cmpgt:
2561 case Hexagon::C2_cmpgtp:
2562 case Hexagon::C2_cmpgtu:
2563 case Hexagon::C2_cmpgtup:
2564 case Hexagon::C2_cmpeqi:
2565 case Hexagon::C2_cmpgti:
2566 case Hexagon::C2_cmpgtui:
2580 unsigned Opc =
MI.getOpcode();
2581 bool Computed = evaluateHexCompare2(Opc, Src1, Src2, Inputs, Result);
2585 RegisterSubReg DefR(
MI.getOperand(0));
2586 LatticeCell
L = Outputs.get(DefR.Reg);
2588 : ConstantProperties::Zero;
2590 Outputs.update(DefR.Reg, L);
2598bool HexagonConstEvaluator::evaluateHexCompare2(
unsigned Opc,
2600 const CellMap &Inputs,
bool &Result) {
2602 bool Reg1 = Src1.
isReg(), Reg2 = Src2.
isReg();
2603 bool Imm1 = Src1.
isImm(), Imm2 = Src2.
isImm();
2605 RegisterSubReg R1(Src1);
2607 RegisterSubReg
R2(Src2);
2608 return evaluateCMPrr(Cmp, R1,
R2, Inputs, Result);
2610 APInt A2 = getCmpImm(Opc, 2, Src2);
2611 return evaluateCMPri(Cmp, R1, A2, Inputs, Result);
2614 APInt A1 = getCmpImm(Opc, 1, Src1);
2616 RegisterSubReg
R2(Src2);
2617 uint32_t NegCmp = Comparison::negate(Cmp);
2618 return evaluateCMPri(NegCmp,
R2, A1, Inputs, Result);
2620 APInt A2 = getCmpImm(Opc, 2, Src2);
2621 return evaluateCMPii(Cmp, A1, A2, Result);
2628bool HexagonConstEvaluator::evaluateHexLogical(
const MachineInstr &
MI,
2629 const CellMap &Inputs, CellMap &Outputs) {
2630 unsigned Opc =
MI.getOpcode();
2631 if (
MI.getNumOperands() != 3)
2635 RegisterSubReg R1(Src1);
2641 case Hexagon::A2_and:
2642 case Hexagon::A2_andp:
2643 Eval = evaluateANDrr(R1, RegisterSubReg(Src2), Inputs, RC);
2645 case Hexagon::A2_andir: {
2649 Eval = evaluateANDri(R1,
A, Inputs, RC);
2652 case Hexagon::A2_or:
2653 case Hexagon::A2_orp:
2654 Eval = evaluateORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2656 case Hexagon::A2_orir: {
2660 Eval = evaluateORri(R1,
A, Inputs, RC);
2663 case Hexagon::A2_xor:
2664 case Hexagon::A2_xorp:
2665 Eval = evaluateXORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2669 RegisterSubReg DefR(
MI.getOperand(0));
2670 Outputs.update(DefR.Reg, RC);
2675bool HexagonConstEvaluator::evaluateHexCondMove(
const MachineInstr &
MI,
2676 const CellMap &Inputs, CellMap &Outputs) {
2678 RegisterSubReg CR(
MI.getOperand(1));
2679 assert(Inputs.has(CR.Reg));
2681 if (!getCell(CR, Inputs, LS))
2685 if (Ps & ConstantProperties::Zero)
2687 else if (Ps & ConstantProperties::NonZero)
2693 RegisterSubReg DefR(
MI.getOperand(0));
2694 LatticeCell RC = Outputs.get(DefR.Reg);
2696 if (ValOp.
isImm()) {
2702 Outputs.update(DefR.Reg, RC);
2705 if (ValOp.
isReg()) {
2706 RegisterSubReg
R(ValOp);
2707 const LatticeCell &LR = Inputs.get(
R.Reg);
2709 if (!evaluate(R, LR, LSR))
2712 Outputs.update(DefR.Reg, RC);
2718bool HexagonConstEvaluator::evaluateHexExt(
const MachineInstr &
MI,
2719 const CellMap &Inputs, CellMap &Outputs) {
2721 RegisterSubReg R1(
MI.getOperand(1));
2722 assert(Inputs.has(R1.Reg));
2724 unsigned Opc =
MI.getOpcode();
2727 case Hexagon::A2_sxtb:
2728 case Hexagon::A2_zxtb:
2731 case Hexagon::A2_sxth:
2732 case Hexagon::A2_zxth:
2735 case Hexagon::A2_sxtw:
2744 case Hexagon::A2_sxtb:
2745 case Hexagon::A2_sxth:
2746 case Hexagon::A2_sxtw:
2751 RegisterSubReg DefR(
MI.getOperand(0));
2753 LatticeCell RC = Outputs.get(DefR.Reg);
2754 bool Eval =
Signed ? evaluateSEXTr(R1, BW, Bits, Inputs, RC)
2755 : evaluateZEXTr(R1, BW,
Bits, Inputs, RC);
2758 Outputs.update(DefR.Reg, RC);
2762bool HexagonConstEvaluator::evaluateHexVector1(
const MachineInstr &
MI,
2763 const CellMap &Inputs, CellMap &Outputs) {
2765 RegisterSubReg DefR(
MI.getOperand(0));
2766 RegisterSubReg R1(
MI.getOperand(1));
2767 assert(Inputs.has(R1.Reg));
2768 LatticeCell RC = Outputs.get(DefR.Reg);
2771 unsigned Opc =
MI.getOpcode();
2773 case Hexagon::S2_vsplatrb:
2775 Eval = evaluateSplatr(R1, 8, 4, Inputs, RC);
2777 case Hexagon::S2_vsplatrh:
2779 Eval = evaluateSplatr(R1, 16, 4, Inputs, RC);
2787 Outputs.update(DefR.Reg, RC);
2792 const CellMap &Inputs,
bool &AllDefs) {
2800 bool Const =
true, HasUse =
false;
2804 RegisterSubReg
R(MO);
2805 if (!
R.Reg.isVirtual())
2809 if (!
MI.isPHI() && !Inputs.has(
R.Reg)) {
2811 <<
" in MI: " <<
MI;
2814 const LatticeCell &
L = Inputs.get(
R.Reg);
2819 if (HasUse && Const) {
2821 dbgs() <<
"CONST: " <<
MI;
2851 DefRegs.push_back(R);
2856 unsigned ChangedNum = 0;
2864 for (
unsigned R : DefRegs) {
2865 const LatticeCell &
L = Inputs.get(R);
2871 if (!
L.isSingle()) {
2874 using P = ConstantProperties;
2877 if (!(Ps & (P::Zero|P::NonZero)))
2883 &HII.get(Hexagon::PS_false) :
2884 &HII.get(Hexagon::PS_true);
2885 Register NewR =
MRI->createVirtualRegister(PredRC);
2891 replaceAllRegUsesWith(R, NewR);
2895 if (!constToInt(
L.Value,
A) || !
A.isSignedIntN(64))
2901 int64_t
V =
A.getSExtValue();
2902 assert(W == 32 || W == 64);
2904 NewRC = &Hexagon::IntRegsRegClass;
2906 NewRC = &Hexagon::DoubleRegsRegClass;
2907 Register NewR =
MRI->createVirtualRegister(NewRC);
2911 NewD = &HII.get(Hexagon::A2_tfrsi);
2915 if (
A.isSignedIntN(8)) {
2916 NewD = &HII.get(Hexagon::A2_tfrpi);
2920 int32_t
Hi =
V >> 32;
2921 int32_t
Lo =
V & 0xFFFFFFFFLL;
2922 if (isInt<8>(
Hi) && isInt<8>(
Lo)) {
2923 NewD = &HII.get(Hexagon::A2_combineii);
2929 NewD = &HII.get(Hexagon::CONST64);
2940 replaceAllRegUsesWith(R, NewR);
2946 if (!NewInstrs.
empty()) {
2947 MachineFunction &MF = *MI.getParent()->getParent();
2948 dbgs() <<
"In function: " << MF.getName() <<
"\n";
2949 dbgs() <<
"Rewrite: for " << MI <<
" created " << *NewInstrs[0];
2950 for (unsigned i = 1; i < NewInstrs.size(); ++i)
2951 dbgs() <<
" " << *NewInstrs[i];
2955 AllDefs = (ChangedNum == DefRegs.size());
2956 return ChangedNum > 0;
2960 const CellMap &Inputs) {
2961 bool Changed =
false;
2962 unsigned Opc =
MI.getOpcode();
2969 case Hexagon::M2_maci:
2974 RegisterSubReg DefR(
MI.getOperand(0));
2976 RegisterSubReg
R2(
MI.getOperand(2));
2977 RegisterSubReg R3(
MI.getOperand(3));
2978 assert(Inputs.has(
R2.Reg) && Inputs.has(R3.Reg));
2979 LatticeCell LS2, LS3;
2982 bool HasC2 = getCell(
R2, Inputs, LS2), HasC3 = getCell(R3, Inputs, LS3);
2983 if (!HasC2 && !HasC3)
2985 bool Zero = ((HasC2 && (LS2.properties() & ConstantProperties::Zero)) ||
2986 (HasC3 && (LS3.properties() & ConstantProperties::Zero)));
2991 RegisterSubReg R1(Acc);
2992 unsigned NewR = R1.Reg;
2996 NewR =
MRI->createVirtualRegister(RC);
2997 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3000 replaceAllRegUsesWith(DefR.Reg, NewR);
3001 MRI->clearKillFlags(NewR);
3007 if (!LS3.isSingle()) {
3008 if (!LS2.isSingle())
3012 const LatticeCell &LI = Swap ? LS2 : LS3;
3017 if (!constToInt(LI.Value,
A) || !
A.isSignedIntN(8))
3019 int64_t
V =
A.getSExtValue();
3020 const MCInstrDesc &
D = (
V >= 0) ? HII.get(Hexagon::M2_macsip)
3021 : HII.get(Hexagon::M2_macsin);
3031 replaceAllRegUsesWith(DefR.Reg, NewR);
3036 case Hexagon::A2_and:
3038 RegisterSubReg R1(
MI.getOperand(1));
3039 RegisterSubReg
R2(
MI.getOperand(2));
3040 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
3041 LatticeCell LS1, LS2;
3042 unsigned CopyOf = 0;
3044 if (getCell(R1, Inputs, LS1) && LS1.isSingle()) {
3046 if (constToInt(LS1.Value,
M1) && !~
M1)
3049 else if (getCell(
R2, Inputs, LS2) && LS2.isSingle()) {
3051 if (constToInt(LS2.Value,
M1) && !~
M1)
3057 RegisterSubReg SR(SO);
3058 RegisterSubReg DefR(
MI.getOperand(0));
3059 unsigned NewR = SR.Reg;
3062 NewR =
MRI->createVirtualRegister(RC);
3063 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3066 replaceAllRegUsesWith(DefR.Reg, NewR);
3067 MRI->clearKillFlags(NewR);
3072 case Hexagon::A2_or:
3074 RegisterSubReg R1(
MI.getOperand(1));
3075 RegisterSubReg
R2(
MI.getOperand(2));
3076 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
3077 LatticeCell LS1, LS2;
3078 unsigned CopyOf = 0;
3080 using P = ConstantProperties;
3082 if (getCell(R1, Inputs, LS1) && (LS1.properties() & P::Zero))
3084 else if (getCell(
R2, Inputs, LS2) && (LS2.properties() & P::Zero))
3089 RegisterSubReg SR(SO);
3090 RegisterSubReg DefR(
MI.getOperand(0));
3091 unsigned NewR = SR.Reg;
3094 NewR =
MRI->createVirtualRegister(RC);
3095 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3098 replaceAllRegUsesWith(DefR.Reg, NewR);
3099 MRI->clearKillFlags(NewR);
3114 dbgs() <<
"Rewrite: for " <<
MI;
3116 dbgs() <<
" created " << *NewMI;
3118 dbgs() <<
" modified the instruction itself and created:" << *NewMI;
3125void HexagonConstEvaluator::replaceAllRegUsesWith(
Register FromReg,
3134bool HexagonConstEvaluator::rewriteHexBranch(
MachineInstr &BrI,
3135 const CellMap &Inputs) {
3143 bool Eval = evaluate(BrI, Inputs, Targets, FallsThru);
3144 unsigned NumTargets = Targets.
size();
3145 if (!Eval || NumTargets > 1 || (NumTargets == 1 && FallsThru))
3147 if (BrI.
getOpcode() == Hexagon::J2_jump)
3151 bool Rewritten =
false;
3152 if (NumTargets > 0) {
3153 assert(!FallsThru &&
"This should have been checked before");
3156 bool Moot =
B.isLayoutSuccessor(TargetB);
3162 const MCInstrDesc &JD = HII.get(Hexagon::J2_jump);
3170 for (
auto &
Op : NI->operands())
3172 NI->eraseFromParent();
3181 replaceWithNop(BrI);
3186 return new HexagonConstPropagation();
unsigned const MachineRegisterInfo * MRI
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...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned const TargetRegisterInfo * TRI
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
support::ulittle16_t & Lo
support::ulittle16_t & Hi
Class for arbitrary precision integers.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
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.
unsigned countl_one() const
Count the number of leading one bits.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static bool isSameValue(const APInt &I1, const APInt &I2)
Determine if two APInts have the same value, after zero-extending one of them (if needed!...
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.
ConstantFP - Floating Point Values [float, double].
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.
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.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
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.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
Describe properties that are true of each instruction in the target description file.
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...
iterator_range< succ_iterator > successors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
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.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
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.
iterator_range< mop_iterator > operands()
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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
MachineOperand class - Representation of each machine instruction operand.
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,...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
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 global registry used in conjunction with static constructors to make pluggable components (like tar...
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 clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
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.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
This is an optimization pass for GlobalISel generic memory operations.
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.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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)
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isCurrentDebugType(const char *Type)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
void initializeHexagonConstPropagationPass(PassRegistry &Registry)
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.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.