46#define DEBUG_TYPE "hcp"
58 class ConstantProperties {
68 NumericProperties = (Zero|NonZero|Finite|Infinity|NaN|SignedZero),
71 SignProperties = (PosOrZero|NegOrZero),
72 Everything = (NumericProperties|SignProperties)
91 enum {
Normal, Top, Bottom };
93 static const unsigned MaxCellSize = 4;
104 const Constant *Values[MaxCellSize];
107 LatticeCell() : Kind(Top),
Size(0), IsSpecial(
false) {
111 bool meet(
const LatticeCell &L);
115 unsigned size()
const {
return Size; }
117 LatticeCell(
const LatticeCell &L) {
120 L.IsSpecial ?
sizeof L.Properties : L.Size *
sizeof(
const Constant *);
121 memcpy(Values, L.Values,
N);
124 IsSpecial = L.IsSpecial;
127 LatticeCell &operator=(
const LatticeCell &L) {
130 uint32_t N = L.IsSpecial ?
sizeof L.Properties
131 : L.Size *
sizeof(
const Constant *);
132 memcpy(Values, L.Values,
N);
135 IsSpecial = L.IsSpecial;
140 bool isSingle()
const {
return size() == 1; }
141 bool isProperty()
const {
return IsSpecial; }
142 bool isTop()
const {
return Kind == Top; }
143 bool isBottom()
const {
return Kind == Bottom; }
146 bool Changed = (Kind != Bottom);
162 bool convertToProperty();
172 class MachineConstEvaluator;
174 class MachineConstPropagator {
176 MachineConstPropagator(MachineConstEvaluator &
E) : MCE(
E) {
197 void clear() { Map.clear(); }
203 MapType::const_iterator
F = Map.find(R);
204 return F != Map.end();
210 MapType::const_iterator
F = Map.find(R);
217 void update(
Register R,
const LatticeCell &L) { Map[R] = L; }
222 using MapType = std::map<Register, LatticeCell>;
228 LatticeCell Top, Bottom;
243 void visitUsesOf(
unsigned R);
252 MachineConstEvaluator &MCE;
254 using CFGEdge = std::pair<unsigned, unsigned>;
255 using SetOfCFGEdge = std::set<CFGEdge>;
256 using SetOfInstr = std::set<const MachineInstr *>;
257 using QueueOfCFGEdge = std::queue<CFGEdge>;
261 SetOfCFGEdge EdgeExec;
262 SetOfInstr InstrExec;
263 QueueOfCFGEdge FlowQ;
269 class MachineConstEvaluator {
274 virtual ~MachineConstEvaluator() =
default;
291 using CellMap = MachineConstPropagator::CellMap;
293 CellMap &Outputs) = 0;
295 LatticeCell &Result) = 0;
298 bool &CanFallThru) = 0;
299 virtual bool rewrite(
MachineInstr &
MI,
const CellMap &Inputs) = 0;
347 const CellMap &Inputs,
bool &Result);
349 const CellMap &Inputs,
bool &Result);
357 bool evaluateCOPY(
const RegSubRegPair &R1,
const CellMap &Inputs,
358 LatticeCell &Result);
362 const CellMap &Inputs, LatticeCell &Result);
364 const CellMap &Inputs, LatticeCell &Result);
367 const CellMap &Inputs, LatticeCell &Result);
369 const CellMap &Inputs, LatticeCell &Result);
372 const CellMap &Inputs, LatticeCell &Result);
374 const CellMap &Inputs, LatticeCell &Result);
378 bool evaluateZEXTr(
const RegSubRegPair &R1,
unsigned Width,
unsigned Bits,
379 const CellMap &Inputs, LatticeCell &Result);
380 bool evaluateZEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
382 bool evaluateSEXTr(
const RegSubRegPair &R1,
unsigned Width,
unsigned Bits,
383 const CellMap &Inputs, LatticeCell &Result);
384 bool evaluateSEXTi(
const APInt &A1,
unsigned Width,
unsigned Bits,
388 bool evaluateCLBr(
const RegSubRegPair &R1,
bool Zeros,
bool Ones,
389 const CellMap &Inputs, LatticeCell &Result);
390 bool evaluateCLBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
391 bool evaluateCTBr(
const RegSubRegPair &R1,
bool Zeros,
bool Ones,
392 const CellMap &Inputs, LatticeCell &Result);
393 bool evaluateCTBi(
const APInt &A1,
bool Zeros,
bool Ones,
APInt &Result);
396 bool evaluateEXTRACTr(
const RegSubRegPair &R1,
unsigned Width,
398 const CellMap &Inputs, LatticeCell &Result);
399 bool evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
unsigned Offset,
403 const CellMap &Inputs, LatticeCell &Result);
404 bool evaluateSplati(
const APInt &A1,
unsigned Bits,
unsigned Count,
414 return Zero | PosOrZero | NegOrZero | Finite;
415 uint32_t Props = (NonZero | Finite);
417 return Props | NegOrZero;
418 return Props | PosOrZero;
423 uint32_t Props = CF->
isNegative() ? (NegOrZero|NonZero)
426 return (Props & ~NumericProperties) | (Zero|Finite);
427 Props = (Props & ~NumericProperties) | NonZero;
429 return (Props & ~NumericProperties) | NaN;
432 return (Props & ~NumericProperties) | Infinity;
442bool LatticeCell::convertToProperty() {
447 uint32_t Everything = ConstantProperties::Everything;
448 uint32_t Ps = !isTop() ? properties()
450 if (Ps != ConstantProperties::Unknown) {
460void LatticeCell::print(raw_ostream &os)
const {
463 uint32_t Ps = properties();
464 if (Ps & ConstantProperties::Zero)
466 if (Ps & ConstantProperties::NonZero)
468 if (Ps & ConstantProperties::Finite)
470 if (Ps & ConstantProperties::Infinity)
472 if (Ps & ConstantProperties::NaN)
474 if (Ps & ConstantProperties::PosOrZero)
476 if (Ps & ConstantProperties::NegOrZero)
485 }
else if (isTop()) {
488 for (
unsigned i = 0; i <
size(); ++i) {
501bool LatticeCell::meet(
const LatticeCell &L) {
505 if (isBottom() ||
L.isTop())
515 return add(
L.properties());
516 for (
unsigned i = 0; i <
L.size(); ++i) {
528bool LatticeCell::add(
const Constant *LC) {
537 while (Index <
Size) {
544 if (Index < MaxCellSize) {
557 uint32_t Ps = properties();
558 uint32_t NewPs = Ps & ConstantProperties::deduce(LC);
559 if (NewPs == ConstantProperties::Unknown) {
572bool LatticeCell::add(uint32_t Property) {
573 bool Changed = convertToProperty();
574 uint32_t Ps = properties();
575 if (Ps == (Ps & Property))
583uint32_t LatticeCell::properties()
const {
586 assert(!isTop() &&
"Should not call this for a top cell");
588 return ConstantProperties::Unknown;
591 uint32_t Ps = ConstantProperties::deduce(Values[0]);
592 for (
unsigned i = 1; i <
size(); ++i) {
593 if (Ps == ConstantProperties::Unknown)
595 Ps &= ConstantProperties::deduce(Values[i]);
601void MachineConstPropagator::CellMap::print(raw_ostream &os,
602 const TargetRegisterInfo &
TRI)
const {
608void MachineConstPropagator::visitPHI(
const MachineInstr &PN) {
609 const MachineBasicBlock *MB = PN.
getParent();
615 assert(DefR.Reg.isVirtual());
622 const LatticeCell &
T = Cells.get(DefR.Reg);
624 Cells.update(DefR.Reg, Bottom);
626 visitUsesOf(DefR.Reg);
630 LatticeCell DefC = Cells.get(DefR.Reg);
634 unsigned PBN =
PB->getNumber();
635 if (!EdgeExec.count(CFGEdge(PBN, MBN))) {
644 if (!UseR.Reg.isVirtual())
647 if (!Cells.has(UseR.Reg))
651 bool Eval = MCE.evaluate(UseR, Cells.get(UseR.Reg), SrcC);
653 <<
printReg(UseR.Reg, &MCE.TRI, UseR.SubReg) << SrcC
655 Changed |= Eval ? DefC.meet(SrcC)
657 Cells.update(DefR.Reg, DefC);
662 visitUsesOf(DefR.Reg);
665void MachineConstPropagator::visitNonBranch(
const MachineInstr &
MI) {
669 bool Eval = MCE.evaluate(
MI, Cells, Outputs);
672 dbgs() <<
" outputs:";
673 for (
auto &
I : Outputs)
674 dbgs() <<
' ' <<
I.second;
681 for (
const MachineOperand &MO :
MI.operands()) {
682 if (!MO.isReg() || !MO.isDef())
686 if (!DefR.Reg.isVirtual())
691 const LatticeCell &
T = Cells.get(DefR.Reg);
693 Cells.update(DefR.Reg, Bottom);
697 if (!Outputs.has(DefR.Reg))
699 LatticeCell RC = Cells.get(DefR.Reg);
700 Changed = RC.meet(Outputs.get(DefR.Reg));
701 Cells.update(DefR.Reg, RC);
704 visitUsesOf(DefR.Reg);
712void MachineConstPropagator::visitBranchesFrom(
const MachineInstr &BrI) {
713 const MachineBasicBlock &
B = *BrI.
getParent();
714 unsigned MBN =
B.getNumber();
718 SetVector<const MachineBasicBlock*> Targets;
719 bool EvalOk =
true, FallsThru =
true;
721 const MachineInstr &
MI = *It;
722 InstrExec.insert(&
MI);
728 EvalOk = EvalOk && MCE.evaluate(
MI, Cells, Targets, FallsThru);
736 if (
B.mayHaveInlineAsmBr())
743 for (
const MachineBasicBlock *SB :
B.successors()) {
748 const MachineFunction &MF = *
B.getParent();
761 LLVM_DEBUG(
dbgs() <<
" failed to evaluate a branch...adding all CFG "
766 for (
const MachineBasicBlock *TB : Targets) {
767 unsigned TBN =
TB->getNumber();
770 FlowQ.push(CFGEdge(MBN, TBN));
774void MachineConstPropagator::visitUsesOf(
unsigned Reg) {
776 << Cells.get(
Reg) <<
'\n');
777 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(
Reg)) {
781 if (!InstrExec.count(&
MI))
785 else if (!
MI.isBranch())
788 visitBranchesFrom(
MI);
792bool MachineConstPropagator::computeBlockSuccessors(
const MachineBasicBlock *MB,
793 SetVector<const MachineBasicBlock*> &Targets) {
797 for (
const MachineInstr &
MI : *MB) {
798 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
800 if (
MI.isDebugInstr())
803 FirstBr =
MI.getIterator();
812 const MachineInstr &
MI = *
I;
814 if (
MI.isDebugInstr())
816 if (!InstrExec.count(&
MI))
818 bool Eval = MCE.evaluate(
MI, Cells, Targets, DoNext);
828 if (NextI != MB->getParent()->end())
833 for (
const MachineBasicBlock *SB : MB->successors())
840void MachineConstPropagator::removeCFGEdge(MachineBasicBlock *From,
841 MachineBasicBlock *To) {
845 for (MachineInstr &PN : To->
phis()) {
858void MachineConstPropagator::propagate(MachineFunction &MF) {
860 unsigned EntryNum =
Entry->getNumber();
863 FlowQ.push(CFGEdge(EntryNum, EntryNum));
865 while (!FlowQ.empty()) {
866 CFGEdge
Edge = FlowQ.front();
870 dbgs() <<
"Picked edge "
873 if (
Edge.first != EntryNum)
874 if (EdgeExec.count(
Edge))
876 EdgeExec.insert(
Edge);
886 while (It != End && It->isPHI()) {
887 InstrExec.insert(&*It);
895 while (It != End && It->isDebugInstr())
897 assert(It == End || !It->isPHI());
899 if (It != End && InstrExec.count(&*It))
903 while (It != End && !It->isBranch()) {
904 if (!It->isDebugInstr()) {
905 InstrExec.insert(&*It);
916 visitBranchesFrom(*It);
921 for (
const MachineBasicBlock *SSB : SB->
successors())
922 FlowQ.push(CFGEdge(SBN, SSB->getNumber()));
927 dbgs() <<
"Cells after propagation:\n";
928 Cells.print(
dbgs(), MCE.TRI);
929 dbgs() <<
"Dead CFG edges:\n";
930 for (
const MachineBasicBlock &
B : MF) {
931 unsigned BN =
B.getNumber();
932 for (
const MachineBasicBlock *SB :
B.successors()) {
934 if (!EdgeExec.count(CFGEdge(BN, SN)))
942bool MachineConstPropagator::rewrite(MachineFunction &MF) {
960 std::vector<MachineBasicBlock*> POT;
965 for (MachineBasicBlock *
B : POT) {
973 SetVector<const MachineBasicBlock*> Targets;
974 bool HaveTargets = computeBlockSuccessors(
B, Targets);
978 if (InstrExec.count(&
MI)) {
979 if (
MI.isBranch() && !HaveTargets)
987 for (
auto I =
B->begin(),
E =
B->end();
I !=
E; ++
I) {
1006 for (MachineBasicBlock *SB :
B->successors()) {
1007 if (!Targets.
count(SB))
1012 removeCFGEdge(
B,
MBB);
1025 for (MachineBasicBlock &
B : MF) {
1027 if (
MI.isBranch() && !InstrExec.count(&
MI))
1035bool MachineConstPropagator::run(MachineFunction &MF) {
1049 dbgs() <<
"End of MachineConstPropagator (Changed=" <<
Changed <<
")\n";
1060 const CellMap &Inputs, LatticeCell &RC) {
1061 if (!
R.Reg.isVirtual())
1063 const LatticeCell &
L = Inputs.get(
R.Reg);
1066 return !RC.isBottom();
1069 return Eval && !RC.isBottom();
1072bool MachineConstEvaluator::constToInt(
const Constant *
C,
1081const ConstantInt *MachineConstEvaluator::intToConst(
const APInt &Val)
const {
1082 return ConstantInt::get(CX, Val);
1085bool MachineConstEvaluator::evaluateCMPrr(uint32_t Cmp,
const RegSubRegPair &R1,
1087 const CellMap &Inputs,
bool &Result) {
1089 LatticeCell LS1, LS2;
1090 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1093 bool IsProp1 = LS1.isProperty();
1094 bool IsProp2 = LS2.isProperty();
1096 uint32_t Prop1 = LS1.properties();
1098 return evaluateCMPpp(Cmp, Prop1, LS2.properties(), Result);
1099 uint32_t NegCmp = Comparison::negate(Cmp);
1100 return evaluateCMPrp(NegCmp,
R2, Prop1, Inputs, Result);
1103 uint32_t Prop2 = LS2.properties();
1104 return evaluateCMPrp(Cmp, R1, Prop2, Inputs, Result);
1108 bool IsTrue =
true, IsFalse =
true;
1109 for (
unsigned i = 0; i < LS2.size(); ++i) {
1111 bool Computed = constToInt(LS2.Values[i],
A) &&
1112 evaluateCMPri(Cmp, R1,
A, Inputs, Res);
1118 assert(!IsTrue || !IsFalse);
1122 return IsTrue || IsFalse;
1125bool MachineConstEvaluator::evaluateCMPri(uint32_t Cmp,
const RegSubRegPair &R1,
1127 const CellMap &Inputs,
bool &Result) {
1130 if (!getCell(R1, Inputs, LS))
1132 if (
LS.isProperty())
1133 return evaluateCMPpi(Cmp,
LS.properties(), A2, Result);
1136 bool IsTrue =
true, IsFalse =
true;
1137 for (
unsigned i = 0; i <
LS.size(); ++i) {
1139 bool Computed = constToInt(
LS.Values[i],
A) &&
1140 evaluateCMPii(Cmp,
A, A2, Res);
1146 assert(!IsTrue || !IsFalse);
1150 return IsTrue || IsFalse;
1153bool MachineConstEvaluator::evaluateCMPrp(uint32_t Cmp,
const RegSubRegPair &R1,
1155 const CellMap &Inputs,
bool &Result) {
1158 if (!getCell(R1, Inputs, LS))
1160 if (
LS.isProperty())
1161 return evaluateCMPpp(Cmp,
LS.properties(), Props2, Result);
1164 uint32_t NegCmp = Comparison::negate(Cmp);
1165 bool IsTrue =
true, IsFalse =
true;
1166 for (
unsigned i = 0; i <
LS.size(); ++i) {
1168 bool Computed = constToInt(
LS.Values[i],
A) &&
1169 evaluateCMPpi(NegCmp, Props2,
A, Res);
1175 assert(!IsTrue || !IsFalse);
1177 return IsTrue || IsFalse;
1180bool MachineConstEvaluator::evaluateCMPii(uint32_t Cmp,
const APInt &A1,
1181 const APInt &A2,
bool &Result) {
1183 if (Cmp == Comparison::NE) {
1187 if (Cmp == Comparison::EQ) {
1191 if (Cmp & Comparison::EQ) {
1193 return (Result =
true);
1195 assert((Cmp & (Comparison::L | Comparison::G)) &&
"Malformed comparison");
1200 unsigned MaxW = (W1 >= W2) ? W1 : W2;
1201 if (Cmp & Comparison::U) {
1202 APInt Zx1 = A1.
zext(MaxW);
1203 APInt Zx2 = A2.
zext(MaxW);
1204 if (Cmp & Comparison::L)
1206 else if (Cmp & Comparison::G)
1212 APInt Sx1 = A1.
sext(MaxW);
1213 APInt Sx2 = A2.
sext(MaxW);
1214 if (Cmp & Comparison::L)
1216 else if (Cmp & Comparison::G)
1221bool MachineConstEvaluator::evaluateCMPpi(uint32_t Cmp, uint32_t Props,
1222 const APInt &A2,
bool &Result) {
1223 if (Props == ConstantProperties::Unknown)
1227 if (Props & ConstantProperties::NaN)
1232 if (!(Props & ConstantProperties::Finite))
1237 if (Cmp & Comparison::U) {
1241 if (Props & ConstantProperties::Zero)
1243 else if (Props & ConstantProperties::NonZero)
1244 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1250 if (Props & ConstantProperties::Zero) {
1251 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1258 if (Props & ConstantProperties::Zero) {
1263 ((Cmp & Comparison::L) && !A2.
isNegative()) ||
1267 if (Props & ConstantProperties::PosOrZero) {
1272 Result = (
Cmp & Comparison::G) || (Cmp == Comparison::NE);
1275 if (Props & ConstantProperties::NegOrZero) {
1280 Result = (
Cmp & Comparison::L) || (Cmp == Comparison::NE);
1287bool MachineConstEvaluator::evaluateCMPpp(uint32_t Cmp, uint32_t Props1,
1288 uint32_t Props2,
bool &Result) {
1289 using P = ConstantProperties;
1291 if ((Props1 & P::NaN) && (Props2 & P::NaN))
1293 if (!(Props1 & P::Finite) || !(Props2 & P::Finite))
1296 bool Zero1 = (Props1 & P::Zero), Zero2 = (Props2 & P::Zero);
1297 bool NonZero1 = (Props1 & P::NonZero), NonZero2 = (Props2 & P::NonZero);
1298 if (Zero1 && Zero2) {
1302 if (Cmp == Comparison::NE) {
1303 if ((Zero1 && NonZero2) || (NonZero1 && Zero2))
1304 return (Result =
true);
1308 if (Cmp & Comparison::U) {
1311 if (Zero1 && NonZero2) {
1315 if (NonZero1 && Zero2) {
1323 bool Poz1 = (Props1 & P::PosOrZero), Poz2 = (Props2 & P::PosOrZero);
1324 bool Nez1 = (Props1 & P::NegOrZero), Nez2 = (Props2 & P::NegOrZero);
1326 if (NonZero1 || NonZero2) {
1331 if ((Cmp & Comparison::EQ) && (Cmp & Comparison::L))
1332 return (Result =
true);
1335 if (NonZero1 || NonZero2) {
1340 if ((Cmp & Comparison::EQ) && (Cmp & Comparison::G))
1341 return (Result =
true);
1347bool MachineConstEvaluator::evaluateCOPY(
const RegSubRegPair &R1,
1348 const CellMap &Inputs,
1349 LatticeCell &Result) {
1350 return getCell(R1, Inputs, Result);
1353bool MachineConstEvaluator::evaluateANDrr(
const RegSubRegPair &R1,
1355 const CellMap &Inputs,
1356 LatticeCell &Result) {
1358 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1359 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1363 if (L2.isBottom()) {
1366 return evaluateANDrr(
R2, R1, Inputs, Result);
1371 if (LS2.isBottom() || LS2.isProperty())
1375 for (
unsigned i = 0; i < LS2.size(); ++i) {
1377 bool Eval = constToInt(LS2.Values[i],
A) &&
1378 evaluateANDri(R1,
A, Inputs, RC);
1383 return !
Result.isBottom();
1386bool MachineConstEvaluator::evaluateANDri(
const RegSubRegPair &R1,
1388 const CellMap &Inputs,
1389 LatticeCell &Result) {
1392 return getCell(R1, Inputs, Result);
1395 RC.add(intToConst(A2));
1401 if (!getCell(R1, Inputs, LS1))
1403 if (LS1.isBottom() || LS1.isProperty())
1407 for (
unsigned i = 0; i < LS1.size(); ++i) {
1408 bool Eval = constToInt(LS1.Values[i],
A) &&
1409 evaluateANDii(
A, A2, ResA);
1415 return !
Result.isBottom();
1418bool MachineConstEvaluator::evaluateANDii(
const APInt &A1,
1419 const APInt &A2, APInt &Result) {
1424bool MachineConstEvaluator::evaluateORrr(
const RegSubRegPair &R1,
1426 const CellMap &Inputs,
1427 LatticeCell &Result) {
1429 const LatticeCell &L1 = Inputs.get(
R2.Reg);
1430 const LatticeCell &L2 = Inputs.get(
R2.Reg);
1434 if (L2.isBottom()) {
1437 return evaluateORrr(
R2, R1, Inputs, Result);
1442 if (LS2.isBottom() || LS2.isProperty())
1446 for (
unsigned i = 0; i < LS2.size(); ++i) {
1448 bool Eval = constToInt(LS2.Values[i],
A) &&
1449 evaluateORri(R1,
A, Inputs, RC);
1454 return !
Result.isBottom();
1457bool MachineConstEvaluator::evaluateORri(
const RegSubRegPair &R1,
1458 const APInt &A2,
const CellMap &Inputs,
1459 LatticeCell &Result) {
1462 return getCell(R1, Inputs, Result);
1465 RC.add(intToConst(A2));
1471 if (!getCell(R1, Inputs, LS1))
1473 if (LS1.isBottom() || LS1.isProperty())
1477 for (
unsigned i = 0; i < LS1.size(); ++i) {
1478 bool Eval = constToInt(LS1.Values[i],
A) &&
1479 evaluateORii(
A, A2, ResA);
1485 return !
Result.isBottom();
1488bool MachineConstEvaluator::evaluateORii(
const APInt &A1,
1489 const APInt &A2, APInt &Result) {
1494bool MachineConstEvaluator::evaluateXORrr(
const RegSubRegPair &R1,
1496 const CellMap &Inputs,
1497 LatticeCell &Result) {
1499 LatticeCell LS1, LS2;
1500 if (!getCell(R1, Inputs, LS1) || !getCell(
R2, Inputs, LS2))
1502 if (LS1.isProperty()) {
1503 if (LS1.properties() & ConstantProperties::Zero)
1504 return !(
Result = LS2).isBottom();
1507 if (LS2.isProperty()) {
1508 if (LS2.properties() & ConstantProperties::Zero)
1509 return !(
Result = LS1).isBottom();
1514 for (
unsigned i = 0; i < LS2.size(); ++i) {
1516 bool Eval = constToInt(LS2.Values[i],
A) &&
1517 evaluateXORri(R1,
A, Inputs, RC);
1522 return !
Result.isBottom();
1525bool MachineConstEvaluator::evaluateXORri(
const RegSubRegPair &R1,
1527 const CellMap &Inputs,
1528 LatticeCell &Result) {
1531 if (!getCell(R1, Inputs, LS1))
1533 if (LS1.isProperty()) {
1534 if (LS1.properties() & ConstantProperties::Zero) {
1537 return !
Result.isBottom();
1543 for (
unsigned i = 0; i < LS1.size(); ++i) {
1544 bool Eval = constToInt(LS1.Values[i],
A) &&
1545 evaluateXORii(
A, A2, XA);
1551 return !
Result.isBottom();
1554bool MachineConstEvaluator::evaluateXORii(
const APInt &A1,
1555 const APInt &A2, APInt &Result) {
1560bool MachineConstEvaluator::evaluateZEXTr(
const RegSubRegPair &R1,
1561 unsigned Width,
unsigned Bits,
1562 const CellMap &Inputs,
1563 LatticeCell &Result) {
1566 if (!getCell(R1, Inputs, LS1))
1568 if (LS1.isProperty())
1572 for (
unsigned i = 0; i < LS1.size(); ++i) {
1573 bool Eval = constToInt(LS1.Values[i],
A) &&
1574 evaluateZEXTi(
A, Width, Bits, XA);
1583bool MachineConstEvaluator::evaluateZEXTi(
const APInt &A1,
unsigned Width,
1584 unsigned Bits, APInt &Result) {
1587 assert(Width >= Bits && BW >= Bits);
1593bool MachineConstEvaluator::evaluateSEXTr(
const RegSubRegPair &R1,
1594 unsigned Width,
unsigned Bits,
1595 const CellMap &Inputs,
1596 LatticeCell &Result) {
1599 if (!getCell(R1, Inputs, LS1))
1601 if (LS1.isBottom() || LS1.isProperty())
1605 for (
unsigned i = 0; i < LS1.size(); ++i) {
1606 bool Eval = constToInt(LS1.Values[i],
A) &&
1607 evaluateSEXTi(
A, Width, Bits, XA);
1616bool MachineConstEvaluator::evaluateSEXTi(
const APInt &A1,
unsigned Width,
1617 unsigned Bits, APInt &Result) {
1619 assert(Width >= Bits && BW >= Bits);
1624 Result = APInt(Width, 0);
1628 if (BW <= 64 && Bits != 0) {
1632 V =
static_cast<int8_t
>(
V);
1635 V =
static_cast<int16_t
>(
V);
1638 V =
static_cast<int32_t
>(
V);
1644 V = (
V << (64-
Bits)) >> (64-Bits);
1649 Result = APInt(Width, V,
true);
1660bool MachineConstEvaluator::evaluateCLBr(
const RegSubRegPair &R1,
bool Zeros,
1661 bool Ones,
const CellMap &Inputs,
1662 LatticeCell &Result) {
1665 if (!getCell(R1, Inputs, LS1))
1667 if (LS1.isBottom() || LS1.isProperty())
1671 for (
unsigned i = 0; i < LS1.size(); ++i) {
1672 bool Eval = constToInt(LS1.Values[i],
A) &&
1673 evaluateCLBi(
A, Zeros, Ones, CA);
1682bool MachineConstEvaluator::evaluateCLBi(
const APInt &A1,
bool Zeros,
1683 bool Ones, APInt &Result) {
1685 if (!Zeros && !Ones)
1688 if (Zeros && (
Count == 0))
1690 if (Ones && (
Count == 0))
1692 Result = APInt(BW,
static_cast<uint64_t
>(
Count),
false);
1696bool MachineConstEvaluator::evaluateCTBr(
const RegSubRegPair &R1,
bool Zeros,
1697 bool Ones,
const CellMap &Inputs,
1698 LatticeCell &Result) {
1701 if (!getCell(R1, Inputs, LS1))
1703 if (LS1.isBottom() || LS1.isProperty())
1707 for (
unsigned i = 0; i < LS1.size(); ++i) {
1708 bool Eval = constToInt(LS1.Values[i],
A) &&
1709 evaluateCTBi(
A, Zeros, Ones, CA);
1718bool MachineConstEvaluator::evaluateCTBi(
const APInt &A1,
bool Zeros,
1719 bool Ones, APInt &Result) {
1721 if (!Zeros && !Ones)
1724 if (Zeros && (
Count == 0))
1726 if (Ones && (
Count == 0))
1728 Result = APInt(BW,
static_cast<uint64_t
>(
Count),
false);
1732bool MachineConstEvaluator::evaluateEXTRACTr(
const RegSubRegPair &R1,
1733 unsigned Width,
unsigned Bits,
1735 const CellMap &Inputs,
1736 LatticeCell &Result) {
1740 if (!getCell(R1, Inputs, LS1))
1744 if (LS1.isProperty()) {
1745 uint32_t Ps = LS1.properties();
1746 if (Ps & ConstantProperties::Zero) {
1747 const Constant *
C = intToConst(APInt(Width, 0,
false));
1755 for (
unsigned i = 0; i < LS1.size(); ++i) {
1756 bool Eval = constToInt(LS1.Values[i],
A) &&
1766bool MachineConstEvaluator::evaluateEXTRACTi(
const APInt &A1,
unsigned Bits,
1781 V =
static_cast<uint64_t
>(
V) >> (64-Bits);
1792bool MachineConstEvaluator::evaluateSplatr(
const RegSubRegPair &R1,
1793 unsigned Bits,
unsigned Count,
1794 const CellMap &Inputs,
1795 LatticeCell &Result) {
1798 if (!getCell(R1, Inputs, LS1))
1800 if (LS1.isBottom() || LS1.isProperty())
1804 for (
unsigned i = 0; i < LS1.size(); ++i) {
1805 bool Eval = constToInt(LS1.Values[i],
A) &&
1806 evaluateSplati(
A, Bits,
Count, SA);
1815bool MachineConstEvaluator::evaluateSplati(
const APInt &A1,
unsigned Bits,
1816 unsigned Count, APInt &Result) {
1819 APInt LoBits = (
Bits < BW) ? A1.
trunc(Bits) : A1.
zext(Bits);
1821 LoBits = LoBits.
zext(SW);
1823 APInt Res(SW, 0,
false);
1824 for (
unsigned i = 0; i <
Count; ++i) {
1837 class HexagonConstEvaluator :
public MachineConstEvaluator {
1839 HexagonConstEvaluator(MachineFunction &Fn);
1841 bool evaluate(
const MachineInstr &
MI,
const CellMap &Inputs,
1842 CellMap &Outputs)
override;
1844 LatticeCell &Result)
override;
1845 bool evaluate(
const MachineInstr &BrI,
const CellMap &Inputs,
1846 SetVector<const MachineBasicBlock*> &Targets,
bool &FallsThru)
1848 bool rewrite(MachineInstr &
MI,
const CellMap &Inputs)
override;
1854 static APInt getCmpImm(
unsigned Opc,
unsigned OpX,
1855 const MachineOperand &MO);
1856 void replaceWithNop(MachineInstr &
MI);
1859 const CellMap &Inputs, LatticeCell &Result);
1860 bool evaluateHexCompare(
const MachineInstr &
MI,
const CellMap &Inputs,
1863 bool evaluateHexCompare2(uint32_t Cmp,
const MachineOperand &Src1,
1864 const MachineOperand &Src2,
const CellMap &Inputs,
bool &Result);
1865 bool evaluateHexLogical(
const MachineInstr &
MI,
const CellMap &Inputs,
1867 bool evaluateHexCondMove(
const MachineInstr &
MI,
const CellMap &Inputs,
1869 bool evaluateHexExt(
const MachineInstr &
MI,
const CellMap &Inputs,
1871 bool evaluateHexVector1(
const MachineInstr &
MI,
const CellMap &Inputs,
1873 bool evaluateHexVector2(
const MachineInstr &
MI,
const CellMap &Inputs,
1877 bool rewriteHexBranch(MachineInstr &BrI,
const CellMap &Inputs);
1878 bool rewriteHexConstDefs(MachineInstr &
MI,
const CellMap &Inputs,
1880 bool rewriteHexConstUses(MachineInstr &
MI,
const CellMap &Inputs);
1882 MachineRegisterInfo *
MRI;
1883 const HexagonInstrInfo &HII;
1884 const HexagonRegisterInfo &HRI;
1887 class HexagonConstPropagation :
public MachineFunctionPass {
1891 HexagonConstPropagation() : MachineFunctionPass(
ID) {}
1893 StringRef getPassName()
const override {
1894 return "Hexagon Constant Propagation";
1897 bool runOnMachineFunction(MachineFunction &MF)
override {
1899 if (skipFunction(
F))
1902 HexagonConstEvaluator HCE(MF);
1903 return MachineConstPropagator(HCE).run(MF);
1909char HexagonConstPropagation::ID = 0;
1912 "Hexagon Constant Propagation",
false,
false)
1915 : MachineConstEvaluator(Fn),
1918 MRI = &Fn.getRegInfo();
1921bool HexagonConstEvaluator::evaluate(
const MachineInstr &
MI,
1922 const CellMap &Inputs, CellMap &Outputs) {
1925 if (
MI.getNumOperands() == 0 || !
MI.getOperand(0).isReg())
1927 const MachineOperand &MD =
MI.getOperand(0);
1931 unsigned Opc =
MI.getOpcode();
1934 if (!DefR.Reg.isVirtual())
1940 bool Eval = evaluateCOPY(SrcR, Inputs, RC);
1943 Outputs.update(DefR.Reg, RC);
1946 if (
MI.isRegSequence()) {
1947 unsigned Sub1 =
MI.getOperand(2).getImm();
1948 unsigned Sub2 =
MI.getOperand(4).getImm();
1949 const TargetRegisterClass &DefRC = *
MRI->getRegClass(DefR.Reg);
1952 if (Sub1 != SubLo && Sub1 != SubHi)
1954 if (Sub2 != SubLo && Sub2 != SubHi)
1957 bool LoIs1 = (Sub1 == SubLo);
1958 const MachineOperand &OpLo = LoIs1 ?
MI.getOperand(1) :
MI.getOperand(3);
1959 const MachineOperand &OpHi = LoIs1 ?
MI.getOperand(3) :
MI.getOperand(1);
1962 bool Eval = evaluateHexRSEQ32(SrcRL, SrcRH, Inputs, RC);
1965 Outputs.update(DefR.Reg, RC);
1968 if (
MI.isCompare()) {
1969 bool Eval = evaluateHexCompare(
MI, Inputs, Outputs);
1976 case Hexagon::A2_tfrsi:
1977 case Hexagon::A2_tfrpi:
1978 case Hexagon::CONST32:
1979 case Hexagon::CONST64:
1981 const MachineOperand &VO =
MI.getOperand(1);
1987 int64_t
V =
MI.getOperand(1).getImm();
1989 if (W != 32 && W != 64)
1991 IntegerType *Ty = (
W == 32) ? Type::getInt32Ty(CX)
1992 : Type::getInt64Ty(CX);
1993 const ConstantInt *CI = ConstantInt::get(Ty, V,
true);
1994 LatticeCell RC = Outputs.get(DefR.Reg);
1996 Outputs.update(DefR.Reg, RC);
2000 case Hexagon::PS_true:
2001 case Hexagon::PS_false:
2003 LatticeCell RC = Outputs.get(DefR.Reg);
2004 bool NonZero = (
Opc == Hexagon::PS_true);
2005 uint32_t
P = NonZero ? ConstantProperties::NonZero
2006 : ConstantProperties::Zero;
2008 Outputs.update(DefR.Reg, RC);
2012 case Hexagon::A2_and:
2013 case Hexagon::A2_andir:
2014 case Hexagon::A2_andp:
2015 case Hexagon::A2_or:
2016 case Hexagon::A2_orir:
2017 case Hexagon::A2_orp:
2018 case Hexagon::A2_xor:
2019 case Hexagon::A2_xorp:
2021 bool Eval = evaluateHexLogical(
MI, Inputs, Outputs);
2027 case Hexagon::A2_combineii:
2028 case Hexagon::A4_combineii:
2030 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isImm())
2032 uint64_t
Hi =
MI.getOperand(1).getImm();
2033 uint64_t
Lo =
MI.getOperand(2).getImm();
2034 uint64_t Res = (
Hi << 32) | (
Lo & 0xFFFFFFFF);
2035 IntegerType *Ty = Type::getInt64Ty(CX);
2036 const ConstantInt *CI = ConstantInt::get(Ty, Res,
false);
2037 LatticeCell RC = Outputs.get(DefR.Reg);
2039 Outputs.update(DefR.Reg, RC);
2043 case Hexagon::S2_setbit_i:
2045 int64_t
B =
MI.getOperand(2).getImm();
2047 APInt
A(32, (1ull <<
B),
false);
2049 LatticeCell RC = Outputs.get(DefR.Reg);
2050 bool Eval = evaluateORri(R,
A, Inputs, RC);
2053 Outputs.update(DefR.Reg, RC);
2057 case Hexagon::C2_mux:
2058 case Hexagon::C2_muxir:
2059 case Hexagon::C2_muxri:
2060 case Hexagon::C2_muxii:
2062 bool Eval = evaluateHexCondMove(
MI, Inputs, Outputs);
2068 case Hexagon::A2_sxtb:
2069 case Hexagon::A2_sxth:
2070 case Hexagon::A2_sxtw:
2071 case Hexagon::A2_zxtb:
2072 case Hexagon::A2_zxth:
2074 bool Eval = evaluateHexExt(
MI, Inputs, Outputs);
2080 case Hexagon::S2_ct0:
2081 case Hexagon::S2_ct0p:
2082 case Hexagon::S2_ct1:
2083 case Hexagon::S2_ct1p:
2085 using namespace Hexagon;
2087 bool Ones = (
Opc == S2_ct1) || (
Opc == S2_ct1p);
2091 bool Eval = evaluateCTBr(R1, !Ones, Ones, Inputs,
T);
2098 LatticeCell RC = Outputs.get(DefR.Reg);
2099 for (
unsigned i = 0; i <
T.size(); ++i) {
2101 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2102 CI = intToConst(
C.trunc(32));
2105 Outputs.update(DefR.Reg, RC);
2109 case Hexagon::S2_cl0:
2110 case Hexagon::S2_cl0p:
2111 case Hexagon::S2_cl1:
2112 case Hexagon::S2_cl1p:
2113 case Hexagon::S2_clb:
2114 case Hexagon::S2_clbp:
2116 using namespace Hexagon;
2118 bool OnlyZeros = (
Opc == S2_cl0) || (
Opc == S2_cl0p);
2119 bool OnlyOnes = (
Opc == S2_cl1) || (
Opc == S2_cl1p);
2123 bool Eval = evaluateCLBr(R1, !OnlyOnes, !OnlyZeros, Inputs,
T);
2130 LatticeCell RC = Outputs.get(DefR.Reg);
2131 for (
unsigned i = 0; i <
T.size(); ++i) {
2133 if (constToInt(CI,
C) &&
C.getBitWidth() > 32)
2134 CI = intToConst(
C.trunc(32));
2137 Outputs.update(DefR.Reg, RC);
2141 case Hexagon::S4_extract:
2142 case Hexagon::S4_extractp:
2143 case Hexagon::S2_extractu:
2144 case Hexagon::S2_extractup:
2146 bool Signed = (
Opc == Hexagon::S4_extract) ||
2147 (
Opc == Hexagon::S4_extractp);
2150 unsigned Bits =
MI.getOperand(2).getImm();
2151 unsigned Offset =
MI.getOperand(3).getImm();
2152 LatticeCell RC = Outputs.get(DefR.Reg);
2154 APInt
Zero(BW, 0,
false);
2155 RC.add(intToConst(Zero));
2165 bool Eval = evaluateEXTRACTr(R1, BW, Bits,
Offset,
Signed, Inputs, RC);
2168 Outputs.update(DefR.Reg, RC);
2172 case Hexagon::S2_vsplatrb:
2173 case Hexagon::S2_vsplatrh:
2183 bool Eval = evaluateHexVector1(
MI, Inputs, Outputs);
2200 const LatticeCell &Input,
2201 LatticeCell &Result) {
2206 const TargetRegisterClass *RC =
MRI->getRegClass(
R.Reg);
2207 if (RC != &Hexagon::DoubleRegsRegClass)
2209 if (
R.SubReg != Hexagon::isub_lo &&
R.SubReg != Hexagon::isub_hi)
2213 if (Input.isBottom())
2216 using P = ConstantProperties;
2218 if (Input.isProperty()) {
2219 uint32_t Ps = Input.properties();
2220 if (Ps & (P::Zero|P::NaN)) {
2221 uint32_t Ns = (Ps & (P::Zero|P::NaN|P::SignProperties));
2225 if (
R.SubReg == Hexagon::isub_hi) {
2226 uint32_t Ns = (Ps & P::SignProperties);
2236 for (
unsigned i = 0; i < Input.size(); ++i) {
2238 if (!constToInt(
C,
A))
2242 uint64_t
U =
A.getZExtValue();
2243 if (
R.SubReg == Hexagon::isub_hi)
2248 memcpy(&V32, &U32,
sizeof V32);
2249 IntegerType *Ty = Type::getInt32Ty(CX);
2250 const ConstantInt *C32 = ConstantInt::get(Ty,
static_cast<int64_t
>(V32));
2256bool HexagonConstEvaluator::evaluate(
const MachineInstr &BrI,
2257 const CellMap &Inputs, SetVector<const MachineBasicBlock*> &Targets,
2262 bool SimpleBranch =
false;
2263 bool Negated =
false;
2265 case Hexagon::J2_jumpf:
2266 case Hexagon::J2_jumpfnew:
2267 case Hexagon::J2_jumpfnewpt:
2270 case Hexagon::J2_jumpt:
2271 case Hexagon::J2_jumptnew:
2272 case Hexagon::J2_jumptnewpt:
2275 SimpleBranch =
true;
2277 case Hexagon::J2_jump:
2290 const MachineOperand &MD = BrI.
getOperand(0);
2296 assert(Inputs.has(PR.Reg));
2297 const LatticeCell &PredC = Inputs.get(PR.Reg);
2298 if (PredC.isBottom())
2301 uint32_t Props = PredC.properties();
2302 bool CTrue =
false, CFalse =
false;
2303 if (Props & ConstantProperties::Zero)
2305 else if (Props & ConstantProperties::NonZero)
2308 if (!CTrue && !CFalse)
2314 if ((!Negated && CTrue) || (Negated && CFalse))
2315 Targets.
insert(BranchTarget);
2316 else if ((!Negated && CFalse) || (Negated && CTrue))
2325bool HexagonConstEvaluator::rewrite(MachineInstr &
MI,
const CellMap &Inputs) {
2327 return rewriteHexBranch(
MI, Inputs);
2329 unsigned Opc =
MI.getOpcode();
2333 case Hexagon::A2_tfrsi:
2334 case Hexagon::A2_tfrpi:
2335 case Hexagon::CONST32:
2336 case Hexagon::CONST64:
2337 case Hexagon::PS_true:
2338 case Hexagon::PS_false:
2342 unsigned NumOp =
MI.getNumOperands();
2347 Changed = rewriteHexConstDefs(
MI, Inputs, AllDefs);
2352 Changed |= rewriteHexConstUses(
MI, Inputs);
2357unsigned HexagonConstEvaluator::getRegBitWidth(
unsigned Reg)
const {
2358 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2359 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC))
2361 if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC))
2363 if (Hexagon::PredRegsRegClass.hasSubClassEq(RC))
2369uint32_t HexagonConstEvaluator::getCmp(
unsigned Opc) {
2371 case Hexagon::C2_cmpeq:
2372 case Hexagon::C2_cmpeqp:
2373 case Hexagon::A4_cmpbeq:
2374 case Hexagon::A4_cmpheq:
2375 case Hexagon::A4_cmpbeqi:
2376 case Hexagon::A4_cmpheqi:
2377 case Hexagon::C2_cmpeqi:
2378 case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
2379 case Hexagon::J4_cmpeqn1_t_jumpnv_t:
2380 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2381 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2382 case Hexagon::J4_cmpeq_t_jumpnv_nt:
2383 case Hexagon::J4_cmpeq_t_jumpnv_t:
2384 return Comparison::EQ;
2386 case Hexagon::C4_cmpneq:
2387 case Hexagon::C4_cmpneqi:
2388 case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
2389 case Hexagon::J4_cmpeqn1_f_jumpnv_t:
2390 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2391 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2392 case Hexagon::J4_cmpeq_f_jumpnv_nt:
2393 case Hexagon::J4_cmpeq_f_jumpnv_t:
2394 return Comparison::NE;
2396 case Hexagon::C2_cmpgt:
2397 case Hexagon::C2_cmpgtp:
2398 case Hexagon::A4_cmpbgt:
2399 case Hexagon::A4_cmphgt:
2400 case Hexagon::A4_cmpbgti:
2401 case Hexagon::A4_cmphgti:
2402 case Hexagon::C2_cmpgti:
2403 case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
2404 case Hexagon::J4_cmpgtn1_t_jumpnv_t:
2405 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2406 case Hexagon::J4_cmpgti_t_jumpnv_t:
2407 case Hexagon::J4_cmpgt_t_jumpnv_nt:
2408 case Hexagon::J4_cmpgt_t_jumpnv_t:
2409 return Comparison::GTs;
2411 case Hexagon::C4_cmplte:
2412 case Hexagon::C4_cmpltei:
2413 case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
2414 case Hexagon::J4_cmpgtn1_f_jumpnv_t:
2415 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2416 case Hexagon::J4_cmpgti_f_jumpnv_t:
2417 case Hexagon::J4_cmpgt_f_jumpnv_nt:
2418 case Hexagon::J4_cmpgt_f_jumpnv_t:
2419 return Comparison::LEs;
2421 case Hexagon::C2_cmpgtu:
2422 case Hexagon::C2_cmpgtup:
2423 case Hexagon::A4_cmpbgtu:
2424 case Hexagon::A4_cmpbgtui:
2425 case Hexagon::A4_cmphgtu:
2426 case Hexagon::A4_cmphgtui:
2427 case Hexagon::C2_cmpgtui:
2428 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2429 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2430 case Hexagon::J4_cmpgtu_t_jumpnv_nt:
2431 case Hexagon::J4_cmpgtu_t_jumpnv_t:
2432 return Comparison::GTu;
2434 case Hexagon::J4_cmpltu_f_jumpnv_nt:
2435 case Hexagon::J4_cmpltu_f_jumpnv_t:
2436 return Comparison::GEu;
2438 case Hexagon::J4_cmpltu_t_jumpnv_nt:
2439 case Hexagon::J4_cmpltu_t_jumpnv_t:
2440 return Comparison::LTu;
2442 case Hexagon::J4_cmplt_f_jumpnv_nt:
2443 case Hexagon::J4_cmplt_f_jumpnv_t:
2444 return Comparison::GEs;
2446 case Hexagon::C4_cmplteu:
2447 case Hexagon::C4_cmplteui:
2448 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2449 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2450 case Hexagon::J4_cmpgtu_f_jumpnv_nt:
2451 case Hexagon::J4_cmpgtu_f_jumpnv_t:
2452 return Comparison::LEu;
2454 case Hexagon::J4_cmplt_t_jumpnv_nt:
2455 case Hexagon::J4_cmplt_t_jumpnv_t:
2456 return Comparison::LTs;
2461 return Comparison::Unk;
2464APInt HexagonConstEvaluator::getCmpImm(
unsigned Opc,
unsigned OpX,
2465 const MachineOperand &MO) {
2468 case Hexagon::A4_cmpbgtui:
2469 case Hexagon::A4_cmphgtui:
2471 case Hexagon::A4_cmpheqi:
2472 case Hexagon::C4_cmpneqi:
2475 case Hexagon::A4_cmpbeqi:
2477 case Hexagon::C2_cmpgtui:
2478 case Hexagon::C4_cmplteui:
2480 case Hexagon::C2_cmpeqi:
2481 case Hexagon::C2_cmpgti:
2482 case Hexagon::C4_cmpltei:
2485 case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2486 case Hexagon::J4_cmpeqi_f_jumpnv_t:
2487 case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2488 case Hexagon::J4_cmpeqi_t_jumpnv_t:
2489 case Hexagon::J4_cmpgti_f_jumpnv_nt:
2490 case Hexagon::J4_cmpgti_f_jumpnv_t:
2491 case Hexagon::J4_cmpgti_t_jumpnv_nt:
2492 case Hexagon::J4_cmpgti_t_jumpnv_t:
2493 case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2494 case Hexagon::J4_cmpgtui_f_jumpnv_t:
2495 case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2496 case Hexagon::J4_cmpgtui_t_jumpnv_t:
2503 uint64_t Val = MO.
getImm();
2505 return APInt(32, Val,
Signed,
true);
2508void HexagonConstEvaluator::replaceWithNop(MachineInstr &
MI) {
2509 MI.setDesc(HII.get(Hexagon::A2_nop));
2510 while (
MI.getNumOperands() > 0)
2511 MI.removeOperand(0);
2514bool HexagonConstEvaluator::evaluateHexRSEQ32(
RegSubRegPair RL,
2516 const CellMap &Inputs,
2517 LatticeCell &Result) {
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) {
2541 APInt HV = HiVs[i].zext(64) << 32;
2542 for (
unsigned j = 0;
j < LoVs.size(); ++
j) {
2543 APInt LV = LoVs[
j].zext(64);
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:
2576 const MachineOperand &Src1 =
MI.getOperand(1);
2577 const MachineOperand &Src2 =
MI.getOperand(2);
2580 unsigned Opc =
MI.getOpcode();
2581 bool Computed = evaluateHexCompare2(
Opc, Src1, Src2, Inputs, Result);
2586 LatticeCell
L = Outputs.get(DefR.Reg);
2587 uint32_t
P =
Result ? ConstantProperties::NonZero
2588 : ConstantProperties::Zero;
2590 Outputs.update(DefR.Reg, L);
2598bool HexagonConstEvaluator::evaluateHexCompare2(
unsigned Opc,
2599 const MachineOperand &Src1,
const MachineOperand &Src2,
2600 const CellMap &Inputs,
bool &Result) {
2602 bool Reg1 = Src1.
isReg(), Reg2 = Src2.
isReg();
2603 bool Imm1 = Src1.
isImm(), Imm2 = Src2.
isImm();
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);
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)
2633 const MachineOperand &Src1 =
MI.getOperand(1);
2634 const MachineOperand &Src2 =
MI.getOperand(2);
2641 case Hexagon::A2_and:
2642 case Hexagon::A2_andp:
2646 case Hexagon::A2_andir: {
2649 APInt
A(32, Src2.
getImm(),
true);
2650 Eval = evaluateANDri(R1,
A, Inputs, RC);
2653 case Hexagon::A2_or:
2654 case Hexagon::A2_orp:
2658 case Hexagon::A2_orir: {
2661 APInt
A(32, Src2.
getImm(),
true);
2662 Eval = evaluateORri(R1,
A, Inputs, RC);
2665 case Hexagon::A2_xor:
2666 case Hexagon::A2_xorp:
2673 Outputs.update(DefR.Reg, RC);
2678bool HexagonConstEvaluator::evaluateHexCondMove(
const MachineInstr &
MI,
2679 const CellMap &Inputs, CellMap &Outputs) {
2682 assert(Inputs.has(CR.Reg));
2684 if (!getCell(CR, Inputs, LS))
2686 uint32_t Ps =
LS.properties();
2688 if (Ps & ConstantProperties::Zero)
2690 else if (Ps & ConstantProperties::NonZero)
2695 const MachineOperand &ValOp =
MI.getOperand(TakeOp);
2697 LatticeCell RC = Outputs.get(DefR.Reg);
2699 if (ValOp.
isImm()) {
2702 APInt
A(W, V,
true);
2705 Outputs.update(DefR.Reg, RC);
2708 if (ValOp.
isReg()) {
2710 const LatticeCell &LR = Inputs.get(
R.Reg);
2715 Outputs.update(DefR.Reg, RC);
2721bool HexagonConstEvaluator::evaluateHexExt(
const MachineInstr &
MI,
2722 const CellMap &Inputs, CellMap &Outputs) {
2727 unsigned Opc =
MI.getOpcode();
2730 case Hexagon::A2_sxtb:
2731 case Hexagon::A2_zxtb:
2734 case Hexagon::A2_sxth:
2735 case Hexagon::A2_zxth:
2738 case Hexagon::A2_sxtw:
2747 case Hexagon::A2_sxtb:
2748 case Hexagon::A2_sxth:
2749 case Hexagon::A2_sxtw:
2756 LatticeCell RC = Outputs.get(DefR.Reg);
2757 bool Eval =
Signed ? evaluateSEXTr(R1, BW, Bits, Inputs, RC)
2758 : evaluateZEXTr(R1, BW,
Bits, Inputs, RC);
2761 Outputs.update(DefR.Reg, RC);
2765bool HexagonConstEvaluator::evaluateHexVector1(
const MachineInstr &
MI,
2766 const CellMap &Inputs, CellMap &Outputs) {
2771 LatticeCell RC = Outputs.get(DefR.Reg);
2774 unsigned Opc =
MI.getOpcode();
2776 case Hexagon::S2_vsplatrb:
2778 Eval = evaluateSplatr(R1, 8, 4, Inputs, RC);
2780 case Hexagon::S2_vsplatrh:
2782 Eval = evaluateSplatr(R1, 16, 4, Inputs, RC);
2790 Outputs.update(DefR.Reg, RC);
2794bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &
MI,
2795 const CellMap &Inputs,
bool &AllDefs) {
2803 bool Const =
true, HasUse =
false;
2804 for (
const MachineOperand &MO :
MI.operands()) {
2808 if (!
R.Reg.isVirtual())
2812 if (!
MI.isPHI() && !Inputs.has(
R.Reg)) {
2814 <<
" in MI: " <<
MI;
2817 const LatticeCell &
L = Inputs.get(
R.Reg);
2822 if (HasUse && Const) {
2824 dbgs() <<
"CONST: " <<
MI;
2825 for (
const MachineOperand &MO :
MI.operands()) {
2841 MachineFunction *MF =
MI.getParent()->getParent();
2845 SmallVector<unsigned,2> DefRegs;
2846 for (
const MachineOperand &MO :
MI.operands()) {
2854 DefRegs.push_back(R);
2857 MachineBasicBlock &
B = *
MI.getParent();
2859 unsigned ChangedNum = 0;
2867 for (
unsigned R : DefRegs) {
2868 const LatticeCell &
L = Inputs.get(R);
2871 const TargetRegisterClass *RC =
MRI->getRegClass(R);
2874 if (!
L.isSingle()) {
2877 using P = ConstantProperties;
2879 uint64_t Ps =
L.properties();
2880 if (!(Ps & (P::Zero|P::NonZero)))
2882 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
2885 const MCInstrDesc *NewD = (Ps & P::Zero) ?
2886 &HII.get(Hexagon::PS_false) :
2887 &HII.get(Hexagon::PS_true);
2888 Register NewR =
MRI->createVirtualRegister(PredRC);
2889 const MachineInstrBuilder &MIB =
BuildMI(
B, At,
DL, *NewD, NewR);
2894 replaceAllRegUsesWith(R, NewR);
2898 if (!constToInt(
L.Value,
A) || !
A.isSignedIntN(64))
2900 const TargetRegisterClass *NewRC;
2901 const MCInstrDesc *NewD;
2904 int64_t
V =
A.getSExtValue();
2905 assert(W == 32 || W == 64);
2907 NewRC = &Hexagon::IntRegsRegClass;
2909 NewRC = &Hexagon::DoubleRegsRegClass;
2910 Register NewR =
MRI->createVirtualRegister(NewRC);
2911 const MachineInstr *NewMI;
2914 NewD = &HII.get(Hexagon::A2_tfrsi);
2918 if (
A.isSignedIntN(8)) {
2919 NewD = &HII.get(Hexagon::A2_tfrpi);
2923 int32_t
Hi =
V >> 32;
2924 int32_t
Lo =
V & 0xFFFFFFFFLL;
2926 NewD = &HII.get(Hexagon::A2_combineii);
2932 NewD = &HII.get(Hexagon::CONST64);
2943 replaceAllRegUsesWith(R, NewR);
2949 if (!NewInstrs.
empty()) {
2950 MachineFunction &MF = *
MI.getParent()->getParent();
2951 dbgs() <<
"In function: " << MF.
getName() <<
"\n";
2952 dbgs() <<
"Rewrite: for " <<
MI <<
" created " << *NewInstrs[0];
2953 for (
unsigned i = 1; i < NewInstrs.size(); ++i)
2954 dbgs() <<
" " << *NewInstrs[i];
2958 AllDefs = (ChangedNum == DefRegs.size());
2959 return ChangedNum > 0;
2962bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &
MI,
2963 const CellMap &Inputs) {
2965 unsigned Opc =
MI.getOpcode();
2966 MachineBasicBlock &
B = *
MI.getParent();
2969 MachineInstr *NewMI =
nullptr;
2972 case Hexagon::M2_maci:
2981 assert(Inputs.has(
R2.Reg) && Inputs.has(R3.Reg));
2982 LatticeCell LS2, LS3;
2985 bool HasC2 = getCell(
R2, Inputs, LS2), HasC3 = getCell(R3, Inputs, LS3);
2986 if (!HasC2 && !HasC3)
2988 bool Zero = ((HasC2 && (LS2.properties() & ConstantProperties::Zero)) ||
2989 (HasC3 && (LS3.properties() & ConstantProperties::Zero)));
2993 MachineOperand &Acc =
MI.getOperand(1);
2995 unsigned NewR = R1.
Reg;
2998 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
2999 NewR =
MRI->createVirtualRegister(RC);
3000 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3003 replaceAllRegUsesWith(DefR.Reg, NewR);
3004 MRI->clearKillFlags(NewR);
3010 if (!LS3.isSingle()) {
3011 if (!LS2.isSingle())
3015 const LatticeCell &LI = Swap ? LS2 : LS3;
3016 const MachineOperand &OpR2 = Swap ?
MI.getOperand(3)
3020 if (!constToInt(LI.Value,
A) || !
A.isSignedIntN(8))
3022 int64_t
V =
A.getSExtValue();
3023 const MCInstrDesc &
D = (
V >= 0) ? HII.get(Hexagon::M2_macsip)
3024 : HII.get(Hexagon::M2_macsin);
3027 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3029 const MachineOperand &Src1 =
MI.getOperand(1);
3034 replaceAllRegUsesWith(DefR.Reg, NewR);
3039 case Hexagon::A2_and:
3044 LatticeCell LS1, LS2;
3045 unsigned CopyOf = 0;
3047 if (getCell(R1, Inputs, LS1) && LS1.isSingle()) {
3049 if (constToInt(LS1.Value,
M1) && !~
M1)
3052 else if (getCell(
R2, Inputs, LS2) && LS2.isSingle()) {
3054 if (constToInt(LS2.Value,
M1) && !~
M1)
3059 MachineOperand &SO =
MI.getOperand(CopyOf);
3062 unsigned NewR = SR.Reg;
3064 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3065 NewR =
MRI->createVirtualRegister(RC);
3066 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3069 replaceAllRegUsesWith(DefR.Reg, NewR);
3070 MRI->clearKillFlags(NewR);
3075 case Hexagon::A2_or:
3080 LatticeCell LS1, LS2;
3081 unsigned CopyOf = 0;
3083 using P = ConstantProperties;
3085 if (getCell(R1, Inputs, LS1) && (LS1.properties() & P::Zero))
3087 else if (getCell(
R2, Inputs, LS2) && (LS2.properties() & P::Zero))
3091 MachineOperand &SO =
MI.getOperand(CopyOf);
3094 unsigned NewR = SR.Reg;
3096 const TargetRegisterClass *RC =
MRI->getRegClass(DefR.Reg);
3097 NewR =
MRI->createVirtualRegister(RC);
3098 NewMI =
BuildMI(
B, At,
DL, HII.get(TargetOpcode::COPY), NewR)
3101 replaceAllRegUsesWith(DefR.Reg, NewR);
3102 MRI->clearKillFlags(NewR);
3110 for (MachineOperand &MO : NewMI->
operands())
3117 dbgs() <<
"Rewrite: for " <<
MI;
3119 dbgs() <<
" created " << *NewMI;
3121 dbgs() <<
" modified the instruction itself and created:" << *NewMI;
3128void HexagonConstEvaluator::replaceAllRegUsesWith(
Register FromReg,
3132 for (MachineOperand &O :
3137bool HexagonConstEvaluator::rewriteHexBranch(MachineInstr &BrI,
3138 const CellMap &Inputs) {
3145 SetVector<const MachineBasicBlock*> Targets;
3146 bool Eval =
evaluate(BrI, Inputs, Targets, FallsThru);
3147 unsigned NumTargets = Targets.
size();
3148 if (!Eval || NumTargets > 1 || (NumTargets == 1 && FallsThru))
3150 if (BrI.
getOpcode() == Hexagon::J2_jump)
3154 bool Rewritten =
false;
3155 if (NumTargets > 0) {
3156 assert(!FallsThru &&
"This should have been checked before");
3158 MachineBasicBlock *TargetB =
const_cast<MachineBasicBlock*
>(Targets[0]);
3159 bool Moot =
B.isLayoutSuccessor(TargetB);
3165 const MCInstrDesc &JD = HII.get(Hexagon::J2_jump);
3173 for (
auto &
Op : NI->operands())
3175 NI->eraseFromParent();
3184 replaceWithNop(BrI);
3189 return new HexagonConstPropagation();
unsigned const MachineRegisterInfo * MRI
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned countl_one() const
Count the number of leading one bits.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static 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.
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.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
This is an important class for using LLVM in a threaded context.
MachineInstrBundleIterator< const MachineInstr > const_iterator
iterator_range< iterator > phis()
Returns a range that iterates over the phis in the basic block.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
void print(raw_ostream &OS, const SlotIndexes *=nullptr) const
print - Print out the MachineFunction in a format suitable for debugging to the specified stream.
BasicBlockListType::const_iterator const_iterator
const MachineInstrBuilder & 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.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
A vector that has set insertion semantics.
bool remove(const value_type &X)
Remove an item from the set vector.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
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)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
LLVM Value Representation.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ Undetermined
It is up to the client to interpret diagnostics as error, warning, info or hint.
This is an optimization pass for GlobalISel generic memory operations.
TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)
Create RegSubRegPair from a register MachineOperand.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI bool isCurrentDebugType(const char *Type, int Level=0)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator_range< po_iterator< T > > post_order(const T &G)
FunctionPass * createHexagonConstPropagationPass()
unsigned M1(unsigned Val)
LLVM_ABI bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
static NodeRef getEntryNode(MachineFunction *F)
A pair composed of a register and a sub-register index.