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;
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) {
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))
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:
2510 MI.setDesc(HII.get(Hexagon::A2_nop));
2511 while (
MI.getNumOperands() > 0)
2512 MI.removeOperand(0);
2515bool HexagonConstEvaluator::evaluateHexRSEQ32(RegisterSubReg RL, RegisterSubReg RH,
2516 const CellMap &Inputs, LatticeCell &Result) {
2517 assert(Inputs.has(RL.Reg) && Inputs.has(RH.Reg));
2518 LatticeCell
LSL, LSH;
2519 if (!getCell(RL, Inputs, LSL) || !getCell(RH, Inputs, LSH))
2521 if (
LSL.isProperty() || LSH.isProperty())
2524 unsigned LN =
LSL.size(), HN = LSH.size();
2526 for (
unsigned i = 0; i < LN; ++i) {
2527 bool Eval = constToInt(
LSL.Values[i], LoVs[i]);
2532 for (
unsigned i = 0; i < HN; ++i) {
2533 bool Eval = constToInt(LSH.Values[i], HiVs[i]);
2539 for (
unsigned i = 0; i < HiVs.size(); ++i) {
2541 for (
unsigned j = 0;
j < LoVs.size(); ++
j) {
2543 const Constant *
C = intToConst(HV | LV);
2549 return !
Result.isBottom();
2552bool HexagonConstEvaluator::evaluateHexCompare(
const MachineInstr &
MI,
2553 const CellMap &Inputs, CellMap &Outputs) {
2554 unsigned Opc =
MI.getOpcode();
2555 bool Classic =
false;
2557 case Hexagon::C2_cmpeq:
2558 case Hexagon::C2_cmpeqp:
2559 case Hexagon::C2_cmpgt:
2560 case Hexagon::C2_cmpgtp:
2561 case Hexagon::C2_cmpgtu:
2562 case Hexagon::C2_cmpgtup:
2563 case Hexagon::C2_cmpeqi:
2564 case Hexagon::C2_cmpgti:
2565 case Hexagon::C2_cmpgtui:
2579 unsigned Opc =
MI.getOpcode();
2580 bool Computed = evaluateHexCompare2(Opc, Src1, Src2, Inputs, Result);
2584 RegisterSubReg DefR(
MI.getOperand(0));
2585 LatticeCell
L = Outputs.get(DefR.Reg);
2587 : ConstantProperties::Zero;
2589 Outputs.update(DefR.Reg, L);
2597bool HexagonConstEvaluator::evaluateHexCompare2(
unsigned Opc,
2599 const CellMap &Inputs,
bool &Result) {
2601 bool Reg1 = Src1.
isReg(), Reg2 = Src2.
isReg();
2602 bool Imm1 = Src1.
isImm(), Imm2 = Src2.
isImm();
2604 RegisterSubReg R1(Src1);
2606 RegisterSubReg
R2(Src2);
2607 return evaluateCMPrr(Cmp, R1,
R2, Inputs, Result);
2609 APInt A2 = getCmpImm(Opc, 2, Src2);
2610 return evaluateCMPri(Cmp, R1, A2, Inputs, Result);
2613 APInt A1 = getCmpImm(Opc, 1, Src1);
2615 RegisterSubReg
R2(Src2);
2616 uint32_t NegCmp = Comparison::negate(Cmp);
2617 return evaluateCMPri(NegCmp,
R2, A1, Inputs, Result);
2619 APInt A2 = getCmpImm(Opc, 2, Src2);
2620 return evaluateCMPii(Cmp, A1, A2, Result);
2627bool HexagonConstEvaluator::evaluateHexLogical(
const MachineInstr &
MI,
2628 const CellMap &Inputs, CellMap &Outputs) {
2629 unsigned Opc =
MI.getOpcode();
2630 if (
MI.getNumOperands() != 3)
2634 RegisterSubReg R1(Src1);
2640 case Hexagon::A2_and:
2641 case Hexagon::A2_andp:
2642 Eval = evaluateANDrr(R1, RegisterSubReg(Src2), Inputs, RC);
2644 case Hexagon::A2_andir: {
2648 Eval = evaluateANDri(R1,
A, Inputs, RC);
2651 case Hexagon::A2_or:
2652 case Hexagon::A2_orp:
2653 Eval = evaluateORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2655 case Hexagon::A2_orir: {
2659 Eval = evaluateORri(R1,
A, Inputs, RC);
2662 case Hexagon::A2_xor:
2663 case Hexagon::A2_xorp:
2664 Eval = evaluateXORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2668 RegisterSubReg DefR(
MI.getOperand(0));
2669 Outputs.update(DefR.Reg, RC);
2674bool HexagonConstEvaluator::evaluateHexCondMove(
const MachineInstr &
MI,
2675 const CellMap &Inputs, CellMap &Outputs) {
2677 RegisterSubReg CR(
MI.getOperand(1));
2678 assert(Inputs.has(CR.Reg));
2680 if (!getCell(CR, Inputs, LS))
2684 if (Ps & ConstantProperties::Zero)
2686 else if (Ps & ConstantProperties::NonZero)
2692 RegisterSubReg DefR(
MI.getOperand(0));
2693 LatticeCell RC = Outputs.get(DefR.Reg);
2695 if (ValOp.
isImm()) {
2701 Outputs.update(DefR.Reg, RC);
2704 if (ValOp.
isReg()) {
2705 RegisterSubReg
R(ValOp);
2706 const LatticeCell &LR = Inputs.get(
R.Reg);
2708 if (!evaluate(R, LR, LSR))
2711 Outputs.update(DefR.Reg, RC);
2717bool HexagonConstEvaluator::evaluateHexExt(
const MachineInstr &
MI,
2718 const CellMap &Inputs, CellMap &Outputs) {
2720 RegisterSubReg R1(
MI.getOperand(1));
2721 assert(Inputs.has(R1.Reg));
2723 unsigned Opc =
MI.getOpcode();
2726 case Hexagon::A2_sxtb:
2727 case Hexagon::A2_zxtb:
2730 case Hexagon::A2_sxth:
2731 case Hexagon::A2_zxth:
2734 case Hexagon::A2_sxtw:
2743 case Hexagon::A2_sxtb:
2744 case Hexagon::A2_sxth:
2745 case Hexagon::A2_sxtw:
2750 RegisterSubReg DefR(
MI.getOperand(0));
2752 LatticeCell RC = Outputs.get(DefR.Reg);
2753 bool Eval =
Signed ? evaluateSEXTr(R1, BW, Bits, Inputs, RC)
2754 : evaluateZEXTr(R1, BW,
Bits, Inputs, RC);
2757 Outputs.update(DefR.Reg, RC);
2761bool HexagonConstEvaluator::evaluateHexVector1(
const MachineInstr &
MI,
2762 const CellMap &Inputs, CellMap &Outputs) {
2764 RegisterSubReg DefR(
MI.getOperand(0));
2765 RegisterSubReg R1(
MI.getOperand(1));
2766 assert(Inputs.has(R1.Reg));
2767 LatticeCell RC = Outputs.get(DefR.Reg);
2770 unsigned Opc =
MI.getOpcode();
2772 case Hexagon::S2_vsplatrb:
2774 Eval = evaluateSplatr(R1, 8, 4, Inputs, RC);
2776 case Hexagon::S2_vsplatrh:
2778 Eval = evaluateSplatr(R1, 16, 4, Inputs, RC);
2786 Outputs.update(DefR.Reg, RC);
2791 const CellMap &Inputs,
bool &AllDefs) {
2799 bool Const =
true, HasUse =
false;
2803 RegisterSubReg
R(MO);
2804 if (!
R.Reg.isVirtual())
2808 if (!
MI.isPHI() && !Inputs.has(
R.Reg)) {
2810 <<
" in MI: " <<
MI;
2813 const LatticeCell &
L = Inputs.get(
R.Reg);
2818 if (HasUse && Const) {
2820 dbgs() <<
"CONST: " <<
MI;
2850 DefRegs.push_back(R);
2855 unsigned ChangedNum = 0;
2863 for (
unsigned R : DefRegs) {
2864 const LatticeCell &
L = Inputs.get(R);
2870 if (!
L.isSingle()) {
2873 using P = ConstantProperties;
2876 if (!(Ps & (P::Zero|P::NonZero)))
2882 &HII.get(Hexagon::PS_false) :
2883 &HII.get(Hexagon::PS_true);
2884 Register NewR =
MRI->createVirtualRegister(PredRC);
2890 replaceAllRegUsesWith(R, NewR);
2894 if (!constToInt(
L.Value,
A) || !
A.isSignedIntN(64))
2900 int64_t
V =
A.getSExtValue();
2901 assert(W == 32 || W == 64);
2903 NewRC = &Hexagon::IntRegsRegClass;
2905 NewRC = &Hexagon::DoubleRegsRegClass;
2906 Register NewR =
MRI->createVirtualRegister(NewRC);
2910 NewD = &HII.get(Hexagon::A2_tfrsi);
2914 if (
A.isSignedIntN(8)) {
2915 NewD = &HII.get(Hexagon::A2_tfrpi);
2919 int32_t
Hi =
V >> 32;
2920 int32_t
Lo =
V & 0xFFFFFFFFLL;
2921 if (isInt<8>(
Hi) && isInt<8>(
Lo)) {
2922 NewD = &HII.get(Hexagon::A2_combineii);
2928 NewD = &HII.get(Hexagon::CONST64);
2939 replaceAllRegUsesWith(R, NewR);
2945 if (!NewInstrs.
empty()) {
2946 MachineFunction &MF = *MI.getParent()->getParent();
2947 dbgs() <<
"In function: " << MF.getName() <<
"\n";
2948 dbgs() <<
"Rewrite: for " << MI <<
" created " << *NewInstrs[0];
2949 for (unsigned i = 1; i < NewInstrs.size(); ++i)
2950 dbgs() <<
" " << *NewInstrs[i];
2954 AllDefs = (ChangedNum == DefRegs.size());
2955 return ChangedNum > 0;
2959 const CellMap &Inputs) {
2960 bool Changed =
false;
2961 unsigned Opc =
MI.getOpcode();
2968 case Hexagon::M2_maci:
2973 RegisterSubReg DefR(
MI.getOperand(0));
2975 RegisterSubReg
R2(
MI.getOperand(2));
2976 RegisterSubReg R3(
MI.getOperand(3));
2977 assert(Inputs.has(
R2.Reg) && Inputs.has(R3.Reg));
2978 LatticeCell LS2, LS3;
2981 bool HasC2 = getCell(
R2, Inputs, LS2), HasC3 = getCell(R3, Inputs, LS3);
2982 if (!HasC2 && !HasC3)
2984 bool Zero = ((HasC2 && (LS2.properties() & ConstantProperties::Zero)) ||
2985 (HasC3 && (LS3.properties() & ConstantProperties::Zero)));
2990 RegisterSubReg R1(Acc);
2991 unsigned NewR = R1.Reg;
2995 NewR =
MRI->createVirtualRegister(RC);
2996 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
2999 replaceAllRegUsesWith(DefR.Reg, NewR);
3000 MRI->clearKillFlags(NewR);
3006 if (!LS3.isSingle()) {
3007 if (!LS2.isSingle())
3011 const LatticeCell &LI = Swap ? LS2 : LS3;
3016 if (!constToInt(LI.Value,
A) || !
A.isSignedIntN(8))
3018 int64_t
V =
A.getSExtValue();
3019 const MCInstrDesc &
D = (
V >= 0) ? HII.get(Hexagon::M2_macsip)
3020 : HII.get(Hexagon::M2_macsin);
3030 replaceAllRegUsesWith(DefR.Reg, NewR);
3035 case Hexagon::A2_and:
3037 RegisterSubReg R1(
MI.getOperand(1));
3038 RegisterSubReg
R2(
MI.getOperand(2));
3039 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
3040 LatticeCell LS1, LS2;
3041 unsigned CopyOf = 0;
3043 if (getCell(R1, Inputs, LS1) && LS1.isSingle()) {
3045 if (constToInt(LS1.Value,
M1) && !~
M1)
3048 else if (getCell(
R2, Inputs, LS2) && LS2.isSingle()) {
3050 if (constToInt(LS2.Value,
M1) && !~
M1)
3056 RegisterSubReg SR(SO);
3057 RegisterSubReg DefR(
MI.getOperand(0));
3058 unsigned NewR = SR.Reg;
3061 NewR =
MRI->createVirtualRegister(RC);
3062 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3065 replaceAllRegUsesWith(DefR.Reg, NewR);
3066 MRI->clearKillFlags(NewR);
3071 case Hexagon::A2_or:
3073 RegisterSubReg R1(
MI.getOperand(1));
3074 RegisterSubReg
R2(
MI.getOperand(2));
3075 assert(Inputs.has(R1.Reg) && Inputs.has(
R2.Reg));
3076 LatticeCell LS1, LS2;
3077 unsigned CopyOf = 0;
3079 using P = ConstantProperties;
3081 if (getCell(R1, Inputs, LS1) && (LS1.properties() & P::Zero))
3083 else if (getCell(
R2, Inputs, LS2) && (LS2.properties() & P::Zero))
3088 RegisterSubReg SR(SO);
3089 RegisterSubReg DefR(
MI.getOperand(0));
3090 unsigned NewR = SR.Reg;
3093 NewR =
MRI->createVirtualRegister(RC);
3094 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3097 replaceAllRegUsesWith(DefR.Reg, NewR);
3098 MRI->clearKillFlags(NewR);
3113 dbgs() <<
"Rewrite: for " <<
MI;
3115 dbgs() <<
" created " << *NewMI;
3117 dbgs() <<
" modified the instruction itself and created:" << *NewMI;
3124void HexagonConstEvaluator::replaceAllRegUsesWith(
Register FromReg,
3133bool HexagonConstEvaluator::rewriteHexBranch(
MachineInstr &BrI,
3134 const CellMap &Inputs) {
3142 bool Eval = evaluate(BrI, Inputs, Targets, FallsThru);
3143 unsigned NumTargets = Targets.
size();
3144 if (!Eval || NumTargets > 1 || (NumTargets == 1 && FallsThru))
3146 if (BrI.
getOpcode() == Hexagon::J2_jump)
3150 bool Rewritten =
false;
3151 if (NumTargets > 0) {
3152 assert(!FallsThru &&
"This should have been checked before");
3155 bool Moot =
B.isLayoutSuccessor(TargetB);
3161 const MCInstrDesc &JD = HII.get(Hexagon::J2_jump);
3169 for (
auto &
Op : NI->operands())
3171 NI->eraseFromParent();
3180 replaceWithNop(BrI);
3185 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...
static void clear(coro::Shape &Shape)
unsigned const TargetRegisterInfo * TRI
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool rewrite(Function &F)
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.
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...
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.