51 unsigned InVirtReg, InPhysReg = 0;
53 for (
const Argument &Arg :
MF.getFunction().args()) {
54 Type *ATy = Arg.getType();
56 if (ATy->isIntegerTy())
57 Width = ATy->getIntegerBitWidth();
58 else if (ATy->isPointerTy())
62 if (Width == 0 || Width > 64)
64 if (Arg.hasAttribute(Attribute::ByVal))
66 InPhysReg = getNextPhysReg(InPhysReg, Width);
69 InVirtReg = getVirtRegFor(InPhysReg);
72 if (Arg.hasAttribute(Attribute::SExt))
73 VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width)));
74 else if (Arg.hasAttribute(Attribute::ZExt))
75 VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width)));
81 return MachineEvaluator::mask(Reg, 0);
86 if (Hexagon::DoubleRegsRegClass.hasSubClassEq(&RC) ||
87 Hexagon::HvxWRRegClass.hasSubClassEq(&RC) ||
88 Hexagon::HvxVQRRegClass.hasSubClassEq(&RC) ||
89 Hexagon::CircRegsRegClass.hasSubClassEq(&RC))
93 <<
TRI.getRegClassName(&RC) <<
'\n';
101 if (HST.useHVXOps()) {
103 {&HvxVRRegClass, &HvxWRRegClass, &HvxQRRegClass, &HvxVQRRegClass})
104 if (RC->contains(Reg))
105 return TRI.getRegSizeInBits(*RC);
109 return TRI.getRegSizeInBits(*RC);
112 (
Twine(
"Unhandled physical register") +
TRI.getName(Reg)).str().c_str());
124 assert(IsSubLo != IsSubHi &&
"Must refer to either low or high subreg");
127 if (Hexagon::DoubleRegsRegClass.hasSubClassEq(&RC) ||
128 Hexagon::CircRegsRegClass.hasSubClassEq(&RC))
129 return Hexagon::IntRegsRegClass;
130 if (Hexagon::HvxWRRegClass.hasSubClassEq(&RC))
131 return Hexagon::HvxVRRegClass;
132 if (Hexagon::HvxVQRRegClass.hasSubClassEq(&RC))
133 return Hexagon::HvxWRRegClass;
135 dbgs() <<
"Reg class id: " << RC.
getID() <<
" idx: " << Idx <<
'\n';
143 std::vector<BT::RegisterRef>
Vector;
147 for (
unsigned i = 0, n =
Vector.size(); i < n; ++i) {
148 const MachineOperand &MO = MI.getOperand(i);
150 Vector[i] = BT::RegisterRef(MO);
158 const BT::RegisterRef &operator[](
unsigned n)
const {
172 unsigned NumDefs = 0;
176 if (!MO.isReg() || !MO.isDef())
179 assert(MO.getSubReg() == 0);
185 unsigned Opc =
MI.getOpcode();
195 return evaluateLoad(
MI, Inputs, Outputs);
214 if (evaluateFormalCopy(
MI, Inputs, Outputs))
225 if (MO.isGlobal() || MO.isBlockAddress() || MO.isSymbol() || MO.isJTI() ||
230 RegisterRefs
Reg(
MI);
231#define op(i) MI.getOperand(i)
232#define rc(i) RegisterCell::ref(getCell(Reg[i], Inputs))
233#define im(i) MI.getOperand(i).getImm()
246 auto cop = [
this, &Reg, &
MI, &Inputs](
unsigned N,
250 return eIMM(
Op.getImm(), W);
260 return eXTR(RC, 0, RW);
265 uint16_t W = RC.
width();
267 return eXTR(RC, W-RW, W);
273 return eXTR(RC,
N*16,
N*16+16);
278 uint16_t
I = Odd, Ws = Rs.
width();
296 unsigned Reg0 = Reg[0].Reg;
305 return rr0(
eIMM(
im(1), W0), Outputs);
311 int FI =
op(1).getIndex();
312 int Off =
op(2).getImm();
313 unsigned A =
MFI.getObjectAlign(FI).value() + std::abs(
Off);
316 RC.
fill(0, L, BT::BitValue::Zero);
317 return rr0(RC, Outputs);
325 return rr0(
rc(1), Outputs);
332 RC.
fill(PW, RW, BT::BitValue::Zero);
333 return rr0(RC, Outputs);
339 RC.
fill(PW, RW, BT::BitValue::Zero);
340 return rr0(
eINS(RC,
eXTR(
rc(1), 0, PW), 0), Outputs);
352 assert(W0 == 64 && W1 == 32);
355 return rr0(RC, Outputs);
359 return rr0(
eADD(
rc(1),
rc(2)), Outputs);
362 case S4_addi_asl_ri: {
364 return rr0(RC, Outputs);
366 case S4_addi_lsr_ri: {
368 return rr0(RC, Outputs);
372 return rr0(RC, Outputs);
374 case M4_mpyri_addi: {
377 return rr0(RC, Outputs);
379 case M4_mpyrr_addi: {
382 return rr0(RC, Outputs);
384 case M4_mpyri_addr_u2: {
387 return rr0(RC, Outputs);
389 case M4_mpyri_addr: {
392 return rr0(RC, Outputs);
394 case M4_mpyrr_addr: {
397 return rr0(RC, Outputs);
401 return rr0(RC, Outputs);
405 return rr0(RC, Outputs);
409 return rr0(RC, Outputs);
413 return rr0(RC, Outputs);
415 case S2_addasl_rrri: {
417 return rr0(RC, Outputs);
421 RPC.
fill(0, 2, BT::BitValue::Zero);
422 return rr0(
eADD(RPC,
eIMM(
im(2), W0)), Outputs);
426 return rr0(
eSUB(
rc(1),
rc(2)), Outputs);
429 case S4_subi_asl_ri: {
431 return rr0(RC, Outputs);
433 case S4_subi_lsr_ri: {
435 return rr0(RC, Outputs);
439 return rr0(RC, Outputs);
443 return rr0(RC, Outputs);
447 return rr0(
eSUB(
eIMM(0, W0),
rc(1)), Outputs);
451 return rr0(hi(M, W0), Outputs);
454 return rr0(
eMLS(
rc(1),
rc(2)), Outputs);
455 case M2_dpmpyss_acc_s0:
457 case M2_dpmpyss_nac_s0:
461 return rr0(lo(M, W0), Outputs);
466 return rr0(RC, Outputs);
471 return rr0(RC, Outputs);
476 return rr0(RC, Outputs);
481 return rr0(RC, Outputs);
485 return rr0(lo(M, 32), Outputs);
489 return rr0(lo(M, 32), Outputs);
493 return rr0(lo(M, 32), Outputs);
497 return rr0(hi(M, W0), Outputs);
500 return rr0(
eMLU(
rc(1),
rc(2)), Outputs);
501 case M2_dpmpyuu_acc_s0:
503 case M2_dpmpyuu_nac_s0:
513 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
517 case S4_andi_asl_ri: {
519 return rr0(RC, Outputs);
521 case S4_andi_lsr_ri: {
523 return rr0(RC, Outputs);
537 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
541 case S4_ori_asl_ri: {
543 return rr0(RC, Outputs);
545 case S4_ori_lsr_ri: {
547 return rr0(RC, Outputs);
556 return rr0(RC, Outputs);
560 return rr0(RC, Outputs);
568 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
579 return rr0(
eNOT(
rc(1)), Outputs);
583 return rr0(
eASL(
rc(1),
im(2)), Outputs);
585 return rr0(
eASL(
rc(1), 16), Outputs);
598 case S2_asl_i_r_xacc:
599 case S2_asl_i_p_xacc:
608 return rr0(
eASR(
rc(1),
im(2)), Outputs);
610 return rr0(
eASR(
rc(1), 16), Outputs);
623 case S2_asr_i_r_rnd: {
629 return rr0(
eXTR(RC, 0, W0), Outputs);
631 case S2_asr_i_r_rnd_goodsyntax: {
634 return rr0(
rc(1), Outputs);
638 return rr0(
eXTR(RC, 0, W0), Outputs);
642 case S2_asr_i_svw_trun:
648 return rr0(
eLSR(
rc(1),
im(2)), Outputs);
661 case S2_lsr_i_r_xacc:
662 case S2_lsr_i_p_xacc:
667 RC[
im(2)] = BT::BitValue::Zero;
668 return rr0(RC, Outputs);
672 RC[
im(2)] = BT::BitValue::One;
673 return rr0(RC, Outputs);
675 case S2_togglebit_i: {
678 RC[BX] = RC[BX].is(0) ? BT::BitValue::One
679 : RC[BX].is(1) ? BT::BitValue::Zero
680 : BT::BitValue::self();
681 return rr0(RC, Outputs);
690 .
fill(W1+(W1-BX), W0, Zero);
693 return rr0(RC, Outputs);
699 uint16_t Wd =
im(2), Of =
im(3);
702 return rr0(
eIMM(0, W0), Outputs);
709 if (
Opc == S2_extractu ||
Opc == S2_extractup)
710 return rr0(
eZXT(RC, Wd), Outputs);
711 return rr0(
eSXT(RC, Wd), Outputs);
715 uint16_t Wd =
im(3), Of =
im(4);
716 assert(Wd < W0 && Of < W0);
721 return rr0(
rc(1), Outputs);
722 return rr0(
eINS(
rc(1),
eXTR(
rc(2), 0, Wd), Of), Outputs);
734 return rr0(cop(2, W0/2).cat(cop(1, W0/2)), Outputs);
738 case A2_combine_hh: {
742 unsigned LoH = !(
Opc == A2_combine_ll ||
Opc == A2_combine_hl);
744 unsigned HiH = !(
Opc == A2_combine_ll ||
Opc == A2_combine_lh);
748 return rr0(RC, Outputs);
757 return rr0(RC, Outputs);
761 return rr0(RC, Outputs);
765 return rr0(RC, Outputs);
769 return rr0(RC, Outputs);
773 return rr0(RC, Outputs);
778 assert(WR == 64 && WP == 8);
781 for (uint16_t i = 0; i < WP; ++i) {
783 BT::BitValue F = (V.is(0) || V.is(1)) ? V : BT::BitValue::self();
784 RC.
fill(i*8, i*8+8,
F);
786 return rr0(RC, Outputs);
798 if (PC0.
is(0) || PC0.
is(1))
800 R2.meet(R3, Reg[0].Reg);
801 return rr0(
R2, Outputs);
810 return rr0(
eSXT(
rc(1), 8), Outputs);
812 return rr0(
eSXT(
rc(1), 16), Outputs);
815 assert(W0 == 64 && W1 == 32);
817 return rr0(RC, Outputs);
820 return rr0(
eZXT(
rc(1), 8), Outputs);
822 return rr0(
eZXT(
rc(1), 16), Outputs);
840 return rr0(
eCLB(
rc(1),
false, 32), Outputs);
843 return rr0(
eCLB(
rc(1),
true, 32), Outputs);
849 if (TV.
is(0) || TV.
is(1))
850 return rr0(
eCLB(R1, TV, 32), Outputs);
855 return rr0(
eCTB(
rc(1),
false, 32), Outputs);
858 return rr0(
eCTB(
rc(1),
true, 32), Outputs);
865 bool Has0 =
false, All1 =
true;
866 for (uint16_t i = 0; i < 8; ++i) {
877 RC.
fill(0, W0, (All1 ? BT::BitValue::One : BT::BitValue::Zero));
878 return rr0(RC, Outputs);
882 bool Has1 =
false, All0 =
true;
883 for (uint16_t i = 0; i < 8; ++i) {
894 RC.
fill(0, W0, (Has1 ? BT::BitValue::One : BT::BitValue::Zero));
895 return rr0(RC, Outputs);
898 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
902 return rr0(
eNOT(
rc(1)), Outputs);
904 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
908 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
936 if (V.is(0) || V.is(1)) {
938 bool TV = (
Opc == S2_tstbit_i);
939 BT::BitValue F = V.is(TV) ? BT::BitValue::One : BT::BitValue::Zero;
948 if (
unsigned DefR = getUniqueDefVReg(
MI)) {
949 if (
MRI.getRegClass(DefR) == &Hexagon::PredRegsRegClass) {
954 RC.
fill(PW, RW, BT::BitValue::Zero);
959 return MachineEvaluator::evaluate(
MI, Inputs, Outputs);
970 bool &FallsThru)
const {
974 bool SimpleBranch =
false;
975 bool Negated =
false;
977 case Hexagon::J2_jumpf:
978 case Hexagon::J2_jumpfpt:
979 case Hexagon::J2_jumpfnew:
980 case Hexagon::J2_jumpfnewpt:
983 case Hexagon::J2_jumpt:
984 case Hexagon::J2_jumptpt:
985 case Hexagon::J2_jumptnew:
986 case Hexagon::J2_jumptnewpt:
991 case Hexagon::J2_jump:
1014 if (!
Test.is(!Negated)) {
1025unsigned HexagonEvaluator::getUniqueDefVReg(
const MachineInstr &
MI)
const {
1026 unsigned DefReg = 0;
1028 if (!
Op.isReg() || !
Op.isDef())
1041 const CellMapType &Inputs,
1042 CellMapType &Outputs)
const {
1043 using namespace Hexagon;
1045 if (
TII.isPredicated(
MI))
1047 assert(
MI.mayLoad() &&
"A load that mayn't?");
1048 unsigned Opc =
MI.getOpcode();
1059 case L2_loadalignb_pbr:
1060 case L2_loadalignb_pcr:
1061 case L2_loadalignb_pi:
1063 case L2_loadalignh_pbr:
1064 case L2_loadalignh_pcr:
1065 case L2_loadalignh_pi:
1067 case L2_loadbsw2_pbr:
1068 case L2_loadbsw2_pci:
1069 case L2_loadbsw2_pcr:
1070 case L2_loadbsw2_pi:
1071 case L2_loadbsw4_pbr:
1072 case L2_loadbsw4_pci:
1073 case L2_loadbsw4_pcr:
1074 case L2_loadbsw4_pi:
1076 case L2_loadbzw2_pbr:
1077 case L2_loadbzw2_pci:
1078 case L2_loadbzw2_pcr:
1079 case L2_loadbzw2_pi:
1080 case L2_loadbzw4_pbr:
1081 case L2_loadbzw4_pci:
1082 case L2_loadbzw4_pcr:
1083 case L2_loadbzw4_pi:
1102 case L2_loadrub_pbr:
1103 case L2_loadrub_pci:
1104 case L2_loadrub_pcr:
1130 case L2_loadruh_pbr:
1131 case L2_loadruh_pci:
1132 case L2_loadruh_pcr:
1148 case L2_loadw_locked:
1164 case L4_loadd_locked:
1174 const MachineOperand &MD =
MI.getOperand(0);
1179 assert(W >= BitNum && BitNum > 0);
1182 for (uint16_t i = 0; i < BitNum; ++i)
1183 Res[i] = BT::BitValue::self(
BT::BitRef(RD.Reg, i));
1187 for (uint16_t i = BitNum; i <
W; ++i)
1188 Res[i] = BT::BitValue::ref(Sign);
1190 for (uint16_t i = BitNum; i <
W; ++i)
1191 Res[i] = BT::BitValue::Zero;
1199 const CellMapType &Inputs,
1200 CellMapType &Outputs)
const {
1208 if (!
RS.Reg.isPhysical())
1214 uint16_t EW =
F->second.Width;
1223 if (
F->second.Type == ExtType::SExt)
1225 else if (
F->second.Type == ExtType::ZExt)
1232unsigned HexagonEvaluator::getNextPhysReg(
unsigned PReg,
unsigned Width)
const {
1233 using namespace Hexagon;
1235 bool Is64 = DoubleRegsRegClass.contains(PReg);
1236 assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg));
1238 static const unsigned Phys32[] = { R0, R1,
R2, R3,
R4, R5 };
1239 static const unsigned Phys64[] = { D0, D1, D2 };
1240 const unsigned Num32 =
sizeof(Phys32)/
sizeof(
unsigned);
1241 const unsigned Num64 =
sizeof(Phys64)/
sizeof(
unsigned);
1245 return (Width <= 32) ? Phys32[0] : Phys64[0];
1249 unsigned Idx32 = 0, Idx64 = 0;
1251 while (Idx32 < Num32) {
1252 if (Phys32[Idx32] == PReg)
1258 while (Idx64 < Num64) {
1259 if (Phys64[Idx64] == PReg)
1267 return (Idx32+1 < Num32) ? Phys32[Idx32+1] : 0;
1268 return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 0;
1271unsigned HexagonEvaluator::getVirtRegFor(
unsigned PReg)
const {
1272 for (std::pair<MCRegister, Register>
P :
MRI.liveins())
1273 if (
P.first == PReg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This class represents an incoming formal argument to a Function.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
unsigned getID() const
getID() - Return the register class ID number.
Wrapper class representing physical registers. Should be passed by value.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
bool insert(const value_type &X)
Insert a new element into the SetVector.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
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.
void shuffle(Iterator first, Iterator last, RNG &&g)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
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.
MCRegisterClass TargetRegisterClass
bool is(unsigned T) const
RegisterCell eXOR(const RegisterCell &A1, const RegisterCell &A2) const
MachineEvaluator(const TargetRegisterInfo &T, MachineRegisterInfo &M)
const TargetRegisterInfo & TRI
RegisterCell eNOT(const RegisterCell &A1) const
RegisterCell eIMM(int64_t V, uint16_t W) const
RegisterCell eLSR(const RegisterCell &A1, uint16_t Sh) const
RegisterCell eMLU(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eZXT(const RegisterCell &A1, uint16_t FromN) const
RegisterCell eMLS(const RegisterCell &A1, const RegisterCell &A2) const
uint16_t getRegBitWidth(const RegisterRef &RR) const
RegisterCell eCLB(const RegisterCell &A1, bool B, uint16_t W) const
MachineRegisterInfo & MRI
RegisterCell eASR(const RegisterCell &A1, uint16_t Sh) const
RegisterCell eASL(const RegisterCell &A1, uint16_t Sh) const
void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const
RegisterCell eCTB(const RegisterCell &A1, bool B, uint16_t W) const
RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const
RegisterCell eAND(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eORL(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eSXT(const RegisterCell &A1, uint16_t FromN) const
RegisterCell eINS(const RegisterCell &A1, const RegisterCell &A2, uint16_t AtN) const
RegisterCell eADD(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eSUB(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eXTR(const RegisterCell &A1, uint16_t B, uint16_t E) const
RegisterCell & cat(const RegisterCell &RC)
static RegisterCell self(unsigned Reg, uint16_t Width)
static RegisterCell ref(const RegisterCell &C)
RegisterCell & fill(uint16_t B, uint16_t E, const BitValue &V)
RegisterCell & insert(const RegisterCell &RC, const BitMask &M)
BitTracker::BitMask mask(Register Reg, unsigned Sub) const override
uint16_t getPhysRegBitWidth(MCRegister Reg) const override
BitTracker::BranchTargetList BranchTargetList
bool evaluate(const MachineInstr &MI, const CellMapType &Inputs, CellMapType &Outputs) const override
HexagonEvaluator(const HexagonRegisterInfo &tri, MachineRegisterInfo &mri, const HexagonInstrInfo &tii, MachineFunction &mf)
BitTracker::RegisterCell RegisterCell
const HexagonInstrInfo & TII
const TargetRegisterClass & composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const override
BitTracker::CellMapType CellMapType
BitTracker::RegisterRef RegisterRef