45 : MachineEvaluator(tri, mri), MF(mf), MFI(mf.getFrameInfo()),
TII(tii) {
62 unsigned InVirtReg, InPhysReg = 0;
73 if (Width == 0 || Width > 64)
77 InPhysReg = getNextPhysReg(InPhysReg, Width);
80 InVirtReg = getVirtRegFor(InPhysReg);
84 VRX.
insert(std::make_pair(InVirtReg,
ExtType(ExtType::SExt, Width)));
86 VRX.
insert(std::make_pair(InVirtReg,
ExtType(ExtType::ZExt, Width)));
92 return MachineEvaluator::mask(Reg, 0);
99 case Hexagon::DoubleRegsRegClassID:
100 case Hexagon::HvxWRRegClassID:
101 case Hexagon::HvxVQRRegClassID:
103 : BT::BitMask(RW, 2*RW-1);
117 using namespace Hexagon;
119 if (HST.useHVXOps()) {
120 for (
auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass,
122 if (RC.contains(Reg))
130 (
Twine(
"Unhandled physical register") +
TRI.
getName(Reg)).str().c_str());
142 assert(IsSubLo != IsSubHi &&
"Must refer to either low or high subreg");
145 switch (RC.
getID()) {
146 case Hexagon::DoubleRegsRegClassID:
147 return Hexagon::IntRegsRegClass;
148 case Hexagon::HvxWRRegClassID:
149 return Hexagon::HvxVRRegClass;
150 case Hexagon::HvxVQRRegClassID:
151 return Hexagon::HvxWRRegClass;
156 dbgs() <<
"Reg class id: " << RC.
getID() <<
" idx: " << Idx <<
'\n';
164 std::vector<BT::RegisterRef> Vector;
168 for (
unsigned i = 0, n = Vector.size(); i < n; ++i) {
177 size_t size()
const {
return Vector.size(); }
181 assert(n < Vector.size());
191 using namespace Hexagon;
193 unsigned NumDefs = 0;
197 if (!MO.isReg() || !MO.isDef())
200 assert(MO.getSubReg() == 0);
216 return evaluateLoad(MI, Inputs, Outputs);
235 if (evaluateFormalCopy(MI, Inputs, Outputs))
246 if (MO.isGlobal() || MO.isBlockAddress() || MO.isSymbol() || MO.isJTI() ||
251 RegisterRefs
Reg(MI);
252 #define op(i) MI.getOperand(i) 253 #define rc(i) RegisterCell::ref(getCell(Reg[i], Inputs)) 254 #define im(i) MI.getOperand(i).getImm() 267 auto cop = [
this, &
Reg, &
MI, &Inputs](
unsigned N,
281 return eXTR(RC, 0, RW);
288 return eXTR(RC, W-RW, W);
294 return eXTR(RC, N*16, N*16+16);
299 uint16_t
I = Odd, Ws = Rs.
width();
317 unsigned Reg0 = Reg[0].Reg;
326 return rr0(
eIMM(
im(1), W0), Outputs);
332 int FI =
op(1).getIndex();
333 int Off =
op(2).getImm();
338 return rr0(RC, Outputs);
346 return rr0(
rc(1), Outputs);
354 return rr0(RC, Outputs);
361 return rr0(
eINS(RC,
eXTR(
rc(1), 0, PW), 0), Outputs);
373 assert(W0 == 64 && W1 == 32);
376 return rr0(RC, Outputs);
380 return rr0(
eADD(
rc(1),
rc(2)), Outputs);
383 case S4_addi_asl_ri: {
385 return rr0(RC, Outputs);
387 case S4_addi_lsr_ri: {
389 return rr0(RC, Outputs);
393 return rr0(RC, Outputs);
395 case M4_mpyri_addi: {
398 return rr0(RC, Outputs);
400 case M4_mpyrr_addi: {
403 return rr0(RC, Outputs);
405 case M4_mpyri_addr_u2: {
408 return rr0(RC, Outputs);
410 case M4_mpyri_addr: {
413 return rr0(RC, Outputs);
415 case M4_mpyrr_addr: {
418 return rr0(RC, Outputs);
422 return rr0(RC, Outputs);
426 return rr0(RC, Outputs);
430 return rr0(RC, Outputs);
434 return rr0(RC, Outputs);
436 case S2_addasl_rrri: {
438 return rr0(RC, Outputs);
443 return rr0(
eADD(RPC,
eIMM(
im(2), W0)), Outputs);
447 return rr0(
eSUB(
rc(1),
rc(2)), Outputs);
450 case S4_subi_asl_ri: {
452 return rr0(RC, Outputs);
454 case S4_subi_lsr_ri: {
456 return rr0(RC, Outputs);
460 return rr0(RC, Outputs);
464 return rr0(RC, Outputs);
468 return rr0(
eSUB(
eIMM(0, W0),
rc(1)), Outputs);
472 return rr0(hi(M, W0), Outputs);
475 return rr0(
eMLS(
rc(1),
rc(2)), Outputs);
476 case M2_dpmpyss_acc_s0:
478 case M2_dpmpyss_nac_s0:
482 return rr0(lo(M, W0), Outputs);
487 return rr0(RC, Outputs);
492 return rr0(RC, Outputs);
497 return rr0(RC, Outputs);
501 return rr0(lo(M, 32), Outputs);
505 return rr0(lo(M, 32), Outputs);
509 return rr0(lo(M, 32), Outputs);
513 return rr0(hi(M, W0), Outputs);
516 return rr0(
eMLU(
rc(1),
rc(2)), Outputs);
517 case M2_dpmpyuu_acc_s0:
519 case M2_dpmpyuu_nac_s0:
529 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
533 case S4_andi_asl_ri: {
535 return rr0(RC, Outputs);
537 case S4_andi_lsr_ri: {
539 return rr0(RC, Outputs);
553 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
557 case S4_ori_asl_ri: {
559 return rr0(RC, Outputs);
561 case S4_ori_lsr_ri: {
563 return rr0(RC, Outputs);
572 return rr0(RC, Outputs);
576 return rr0(RC, Outputs);
584 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
595 return rr0(
eNOT(
rc(1)), Outputs);
599 return rr0(
eASL(
rc(1),
im(2)), Outputs);
601 return rr0(
eASL(
rc(1), 16), Outputs);
614 case S2_asl_i_r_xacc:
615 case S2_asl_i_p_xacc:
624 return rr0(
eASR(
rc(1),
im(2)), Outputs);
626 return rr0(
eASR(
rc(1), 16), Outputs);
639 case S2_asr_i_r_rnd: {
645 return rr0(
eXTR(RC, 0, W0), Outputs);
647 case S2_asr_i_r_rnd_goodsyntax: {
650 return rr0(
rc(1), Outputs);
654 return rr0(
eXTR(RC, 0, W0), Outputs);
658 case S2_asr_i_svw_trun:
664 return rr0(
eLSR(
rc(1),
im(2)), Outputs);
677 case S2_lsr_i_r_xacc:
678 case S2_lsr_i_p_xacc:
684 return rr0(RC, Outputs);
689 return rr0(RC, Outputs);
691 case S2_togglebit_i: {
697 return rr0(RC, Outputs);
706 .
fill(W1+(W1-BX), W0, Zero);
709 return rr0(RC, Outputs);
715 uint16_t Wd =
im(2), Of =
im(3);
718 return rr0(
eIMM(0, W0), Outputs);
725 if (Opc == S2_extractu || Opc == S2_extractup)
726 return rr0(
eZXT(RC, Wd), Outputs);
727 return rr0(
eSXT(RC, Wd), Outputs);
731 uint16_t Wd =
im(3), Of =
im(4);
732 assert(Wd < W0 && Of < W0);
737 return rr0(
rc(1), Outputs);
738 return rr0(
eINS(
rc(1),
eXTR(
rc(2), 0, Wd), Of), Outputs);
750 return rr0(cop(2, W0/2).cat(cop(1, W0/2)), Outputs);
754 case A2_combine_hh: {
758 unsigned LoH = !(Opc == A2_combine_ll || Opc == A2_combine_hl);
760 unsigned HiH = !(Opc == A2_combine_ll || Opc == A2_combine_lh);
764 return rr0(RC, Outputs);
773 return rr0(RC, Outputs);
777 return rr0(RC, Outputs);
781 return rr0(RC, Outputs);
785 return rr0(RC, Outputs);
789 return rr0(RC, Outputs);
794 assert(WR == 64 && WP == 8);
797 for (uint16_t i = 0; i < WP; ++i) {
800 RC.
fill(i*8, i*8+8, F);
802 return rr0(RC, Outputs);
814 if (PC0.
is(0) || PC0.
is(1))
816 R2.
meet(R3, Reg[0].Reg);
817 return rr0(R2, Outputs);
826 return rr0(
eSXT(
rc(1), 8), Outputs);
828 return rr0(
eSXT(
rc(1), 16), Outputs);
831 assert(W0 == 64 && W1 == 32);
833 return rr0(RC, Outputs);
836 return rr0(
eZXT(
rc(1), 8), Outputs);
838 return rr0(
eZXT(
rc(1), 16), Outputs);
856 return rr0(
eCLB(
rc(1),
false, 32), Outputs);
859 return rr0(
eCLB(
rc(1),
true, 32), Outputs);
865 if (TV.
is(0) || TV.
is(1))
866 return rr0(
eCLB(R1, TV, 32), Outputs);
871 return rr0(
eCTB(
rc(1),
false, 32), Outputs);
874 return rr0(
eCTB(
rc(1),
true, 32), Outputs);
881 bool Has0 =
false, All1 =
true;
882 for (uint16_t i = 0; i < 8; ++i) {
894 return rr0(RC, Outputs);
898 bool Has1 =
false, All0 =
true;
899 for (uint16_t i = 0; i < 8; ++i) {
911 return rr0(RC, Outputs);
914 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
918 return rr0(
eNOT(
rc(1)), Outputs);
920 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
924 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
952 if (V.
is(0) || V.
is(1)) {
954 bool TV = (Opc == S2_tstbit_i);
964 if (
unsigned DefR = getUniqueDefVReg(MI)) {
975 return MachineEvaluator::evaluate(MI, Inputs, Outputs);
986 bool &FallsThru)
const {
990 bool SimpleBranch =
false;
991 bool Negated =
false;
993 case Hexagon::J2_jumpf:
994 case Hexagon::J2_jumpfpt:
995 case Hexagon::J2_jumpfnew:
996 case Hexagon::J2_jumpfnewpt:
999 case Hexagon::J2_jumpt:
1000 case Hexagon::J2_jumptpt:
1001 case Hexagon::J2_jumptnew:
1002 case Hexagon::J2_jumptnewpt:
1005 SimpleBranch =
true;
1007 case Hexagon::J2_jump:
1026 if (!Test.
is(0) && !Test.
is(1))
1030 if (!Test.
is(!Negated)) {
1041 unsigned HexagonEvaluator::getUniqueDefVReg(
const MachineInstr &
MI)
const {
1042 unsigned DefReg = 0;
1044 if (!
Op.isReg() || !
Op.isDef())
1046 unsigned R =
Op.getReg();
1056 bool HexagonEvaluator::evaluateLoad(
const MachineInstr &MI,
1059 using namespace Hexagon;
1075 case L2_loadalignb_pbr:
1076 case L2_loadalignb_pcr:
1077 case L2_loadalignb_pi:
1079 case L2_loadalignh_pbr:
1080 case L2_loadalignh_pcr:
1081 case L2_loadalignh_pi:
1083 case L2_loadbsw2_pbr:
1084 case L2_loadbsw2_pci:
1085 case L2_loadbsw2_pcr:
1086 case L2_loadbsw2_pi:
1087 case L2_loadbsw4_pbr:
1088 case L2_loadbsw4_pci:
1089 case L2_loadbsw4_pcr:
1090 case L2_loadbsw4_pi:
1092 case L2_loadbzw2_pbr:
1093 case L2_loadbzw2_pci:
1094 case L2_loadbzw2_pcr:
1095 case L2_loadbzw2_pi:
1096 case L2_loadbzw4_pbr:
1097 case L2_loadbzw4_pci:
1098 case L2_loadbzw4_pcr:
1099 case L2_loadbzw4_pi:
1118 case L2_loadrub_pbr:
1119 case L2_loadrub_pci:
1120 case L2_loadrub_pcr:
1146 case L2_loadruh_pbr:
1147 case L2_loadruh_pci:
1148 case L2_loadruh_pcr:
1164 case L2_loadw_locked:
1180 case L4_loadd_locked:
1195 assert(W >= BitNum && BitNum > 0);
1198 for (uint16_t i = 0; i < BitNum; ++i)
1203 for (uint16_t i = BitNum; i <
W; ++i)
1206 for (uint16_t i = BitNum; i <
W; ++i)
1214 bool HexagonEvaluator::evaluateFormalCopy(
const MachineInstr &MI,
1230 uint16_t EW = F->second.Width;
1239 if (F->second.Type == ExtType::SExt)
1241 else if (F->second.Type == ExtType::ZExt)
1248 unsigned HexagonEvaluator::getNextPhysReg(
unsigned PReg,
unsigned Width)
const {
1249 using namespace Hexagon;
1251 bool Is64 = DoubleRegsRegClass.contains(PReg);
1252 assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg));
1254 static const unsigned Phys32[] = { R0, R1,
R2, R3,
R4, R5 };
1255 static const unsigned Phys64[] = { D0, D1, D2 };
1256 const unsigned Num32 =
sizeof(Phys32)/
sizeof(
unsigned);
1257 const unsigned Num64 =
sizeof(Phys64)/
sizeof(
unsigned);
1261 return (Width <= 32) ? Phys32[0] : Phys64[0];
1265 unsigned Idx32 = 0, Idx64 = 0;
1267 while (Idx32 < Num32) {
1268 if (Phys32[Idx32] == PReg)
1274 while (Idx64 < Num64) {
1275 if (Phys64[Idx64] == PReg)
1283 return (Idx32+1 < Num32) ? Phys32[Idx32+1] : 0;
1284 return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 0;
1287 unsigned HexagonEvaluator::getVirtRegFor(
unsigned PReg)
const {
1288 for (std::pair<unsigned,unsigned>
P :
MRI.
liveins())
1289 if (
P.first == PReg)
RegisterCell eASL(const RegisterCell &A1, uint16_t Sh) const
This class represents an incoming formal argument to a Function.
const TargetRegisterInfo & TRI
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
RegisterCell & fill(uint16_t B, uint16_t E, const BitValue &V)
This class represents lattice values for constants.
RegisterCell eASR(const RegisterCell &A1, uint16_t Sh) const
BitTracker::RegisterRef RegisterRef
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const
static RegisterCell self(unsigned Reg, uint16_t Width)
BitTracker::BitMask mask(unsigned Reg, unsigned Sub) const override
const HexagonInstrInfo & TII
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
RegisterCell eORL(const RegisterCell &A1, const RegisterCell &A2) const
HexagonEvaluator(const HexagonRegisterInfo &tri, MachineRegisterInfo &mri, const HexagonInstrInfo &tii, MachineFunction &mf)
bool evaluate(const MachineInstr &MI, const CellMapType &Inputs, CellMapType &Outputs) const override
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
BitTracker::CellMapType CellMapType
bool isIntegerTy() const
True if this is an instance of IntegerType.
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
RegisterCell eLSR(const RegisterCell &A1, uint16_t Sh) const
unsigned getID() const
Return the register class ID number.
Type * getType() const
All values are typed, get the type of this value.
bool insert(const value_type &X)
Insert a new element into the SetVector.
RegisterCell eADD(const RegisterCell &A1, const RegisterCell &A2) const
const TargetRegisterClass & composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const override
RegisterCell eCLB(const RegisterCell &A1, bool B, uint16_t W) const
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
RegisterCell eSUB(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eIMM(int64_t V, uint16_t W) const
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
RegisterCell eNOT(const RegisterCell &A1) const
uint16_t getPhysRegBitWidth(unsigned Reg) const override
bool isPointerTy() const
True if this is an instance of PointerType.
RegisterCell eAND(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eINS(const RegisterCell &A1, const RegisterCell &A2, uint16_t AtN) const
BitTracker::RegisterCell RegisterCell
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
RegisterCell eMLS(const RegisterCell &A1, const RegisterCell &A2) const
uint16_t getRegBitWidth(const RegisterRef &RR) const
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
static BitValue self(const BitRef &Self=BitRef())
MachineOperand class - Representation of each machine instruction operand.
RegisterCell eXOR(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eCTB(const RegisterCell &A1, bool B, uint16_t W) const
bool is(unsigned T) const
MachineRegisterInfo & MRI
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const
ArrayRef< std::pair< unsigned, unsigned > > liveins() const
RegisterCell & insert(const RegisterCell &RC, const BitMask &M)
amdgpu Simplify well known AMD library false Value Value * Arg
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
RegisterCell & cat(const RegisterCell &RC)
unsigned getIntegerBitWidth() const
APFloat abs(APFloat X)
Returns the absolute value of the argument.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
RegisterCell eXTR(const RegisterCell &A1, uint16_t B, uint16_t E) const
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RegisterCell eSXT(const RegisterCell &A1, uint16_t FromN) const
RegisterCell eMLU(const RegisterCell &A1, const RegisterCell &A2) const
A vector that has set insertion semantics.
RegisterCell eZXT(const RegisterCell &A1, uint16_t FromN) const
bool meet(const RegisterCell &RC, unsigned SelfR)
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
static RegisterCell ref(const RegisterCell &C)
const MachineOperand & getOperand(unsigned i) const
iterator_range< arg_iterator > args()
static BitValue ref(const BitValue &V)