@@ -819,23 +819,12 @@ const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
819819 return nullptr ;
820820}
821821
822- static SDValue getTargetNode (GlobalAddressSDNode *N, const SDLoc &DL, EVT Ty,
823- SelectionDAG &DAG, unsigned Flags) {
824- return DAG.getTargetGlobalAddress (N->getGlobal (), DL, Ty, 0 , Flags);
825- }
826-
827822static SDValue getTargetNode (ConstantPoolSDNode *N, const SDLoc &DL, EVT Ty,
828823 SelectionDAG &DAG, unsigned Flags) {
829824 return DAG.getTargetConstantPool (N->getConstVal (), Ty, N->getAlign (),
830825 N->getOffset (), Flags);
831826}
832827
833- static SDValue getTargetNode (BlockAddressSDNode *N, const SDLoc &DL, EVT Ty,
834- SelectionDAG &DAG, unsigned Flags) {
835- return DAG.getTargetBlockAddress (N->getBlockAddress (), Ty, N->getOffset (),
836- Flags);
837- }
838-
839828static SDValue getTargetNode (JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
840829 SelectionDAG &DAG, unsigned Flags) {
841830 return DAG.getTargetJumpTable (N->getIndex (), Ty, Flags);
@@ -857,7 +846,15 @@ SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
857846 if (N->getOffset () != 0 )
858847 report_fatal_error (" invalid offset for global address: " +
859848 Twine (N->getOffset ()));
860- return getAddr (N, DAG);
849+
850+ const GlobalValue *GVal = N->getGlobal ();
851+ SDLoc DL (Op);
852+
853+ // Wrap it in a TargetGlobalAddress
854+ SDValue Addr = DAG.getTargetGlobalAddress (GVal, DL, MVT::i64 );
855+
856+ // Emit pseudo instruction
857+ return SDValue (DAG.getMachineNode (BPF::LDIMM64, DL, MVT::i64 , Addr), 0 );
861858}
862859
863860SDValue BPFTargetLowering::LowerConstantPool (SDValue Op,
@@ -869,8 +866,14 @@ SDValue BPFTargetLowering::LowerConstantPool(SDValue Op,
869866
870867SDValue BPFTargetLowering::LowerBlockAddress (SDValue Op,
871868 SelectionDAG &DAG) const {
872- BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
873- return getAddr (N, DAG);
869+ const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress ();
870+ SDLoc DL (Op);
871+
872+ // Wrap it in a TargetBlockAddress
873+ SDValue Addr = DAG.getTargetBlockAddress (BA, MVT::i64 );
874+
875+ // Emit pseudo instruction
876+ return SDValue (DAG.getMachineNode (BPF::LDIMM64, DL, MVT::i64 , Addr), 0 );
874877}
875878
876879unsigned
@@ -936,6 +939,86 @@ BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
936939 return BB;
937940}
938941
942+ MachineBasicBlock *BPFTargetLowering::EmitInstrWithCustomInserterLDimm64 (
943+ MachineInstr &MI, MachineBasicBlock *BB) const {
944+ MachineFunction *MF = BB->getParent ();
945+ const BPFInstrInfo *TII = MF->getSubtarget <BPFSubtarget>().getInstrInfo ();
946+ const TargetRegisterClass *RC = getRegClassFor (MVT::i64 );
947+ MachineRegisterInfo &RegInfo = MF->getRegInfo ();
948+ DebugLoc DL = MI.getDebugLoc ();
949+
950+ // Build address taken map for Global Varaibles and BlockAddresses
951+ DenseMap<const BasicBlock *, MachineBasicBlock *> AddressTakenBBs;
952+ for (MachineBasicBlock &MBB : *MF) {
953+ if (const BasicBlock *BB = MBB.getBasicBlock ())
954+ if (BB->hasAddressTaken ())
955+ AddressTakenBBs[BB] = &MBB;
956+ }
957+
958+ MachineOperand &MO = MI.getOperand (1 );
959+ assert (MO.isBlockAddress () || MO.isGlobal ());
960+
961+ MCRegister ResultReg = MI.getOperand (0 ).getReg ();
962+ Register TmpReg = RegInfo.createVirtualRegister (RC);
963+
964+ std::vector<MachineBasicBlock *> Targets;
965+ unsigned JTI;
966+
967+ if (MO.isBlockAddress ()) {
968+ auto *BA = MO.getBlockAddress ();
969+ MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock ()];
970+ assert (TgtMBB);
971+
972+ Targets.push_back (TgtMBB);
973+ JTI = MF->getOrCreateJumpTableInfo (getJumpTableEncoding ())
974+ ->createJumpTableIndex (Targets);
975+
976+ BuildMI (*BB, MI, DL, TII->get (BPF::LD_imm64), TmpReg)
977+ .addJumpTableIndex (JTI);
978+ BuildMI (*BB, MI, DL, TII->get (BPF::LDD), ResultReg)
979+ .addReg (TmpReg)
980+ .addImm (0 );
981+ MI.eraseFromParent ();
982+ return BB;
983+ }
984+
985+ // Helper: emit LD_imm64 with operand GlobalAddress or JumpTable
986+ auto emitLDImm64 = [&](const GlobalValue *GV = nullptr , unsigned JTI = -1 ) {
987+ auto MIB = BuildMI (*BB, MI, DL, TII->get (BPF::LD_imm64), ResultReg);
988+ if (GV)
989+ MIB.addGlobalAddress (GV);
990+ else
991+ MIB.addJumpTableIndex (JTI);
992+ MI.eraseFromParent ();
993+ return BB;
994+ };
995+
996+ // Must be a global at this point
997+ const GlobalValue *GVal = MO.getGlobal ();
998+ const auto *GV = dyn_cast<GlobalVariable>(GVal);
999+
1000+ if (!GV || GV->getLinkage () != GlobalValue::PrivateLinkage ||
1001+ !GV->isConstant () || !GV->hasInitializer ())
1002+ return emitLDImm64 (GVal);
1003+
1004+ const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer ());
1005+ if (!CA)
1006+ return emitLDImm64 (GVal);
1007+
1008+ for (const Use &Op : CA->operands ()) {
1009+ if (!isa<BlockAddress>(Op))
1010+ return emitLDImm64 (GVal);
1011+ auto *BA = cast<BlockAddress>(Op);
1012+ MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock ()];
1013+ assert (TgtMBB);
1014+ Targets.push_back (TgtMBB);
1015+ }
1016+
1017+ JTI = MF->getOrCreateJumpTableInfo (getJumpTableEncoding ())
1018+ ->createJumpTableIndex (Targets);
1019+ return emitLDImm64 (nullptr , JTI);
1020+ }
1021+
9391022MachineBasicBlock *
9401023BPFTargetLowering::EmitInstrWithCustomInserter (MachineInstr &MI,
9411024 MachineBasicBlock *BB) const {
@@ -948,20 +1031,24 @@ BPFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
9481031 Opc == BPF::Select_32_64);
9491032
9501033 bool isMemcpyOp = Opc == BPF::MEMCPY;
1034+ bool isLDimm64Op = Opc == BPF::LDIMM64;
9511035
9521036#ifndef NDEBUG
9531037 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
9541038 Opc == BPF::Select_Ri_64_32 ||
9551039 Opc == BPF::Select_Ri_32 ||
9561040 Opc == BPF::Select_Ri_32_64);
9571041
958- if (!(isSelectRROp || isSelectRIOp || isMemcpyOp))
1042+ if (!(isSelectRROp || isSelectRIOp || isMemcpyOp || isLDimm64Op ))
9591043 report_fatal_error (" unhandled instruction type: " + Twine (Opc));
9601044#endif
9611045
9621046 if (isMemcpyOp)
9631047 return EmitInstrWithCustomInserterMemcpy (MI, BB);
9641048
1049+ if (isLDimm64Op)
1050+ return EmitInstrWithCustomInserterLDimm64 (MI, BB);
1051+
9651052 bool is32BitCmp = (Opc == BPF::Select_32 ||
9661053 Opc == BPF::Select_32_64 ||
9671054 Opc == BPF::Select_Ri_32 ||
0 commit comments