[llvm] f4517bb - [VE] Implement JumpTable

Kazushi Marukawa via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 17 05:43:18 PST 2020


Author: Kazushi (Jam) Marukawa
Date: 2020-11-17T22:43:10+09:00
New Revision: f4517bbd73401160294d2a17b1d68e5807709710

URL: https://github.com/llvm/llvm-project/commit/f4517bbd73401160294d2a17b1d68e5807709710
DIFF: https://github.com/llvm/llvm-project/commit/f4517bbd73401160294d2a17b1d68e5807709710.diff

LOG: [VE] Implement JumpTable

Implement JumpTable to make BRIND work on VE.  Update an existing
br_jt regression test also.

Reviewed By: simoll

Differential Revision: https://reviews.llvm.org/D91582

Added: 
    

Modified: 
    llvm/lib/Target/VE/VEFrameLowering.cpp
    llvm/lib/Target/VE/VEISelLowering.cpp
    llvm/lib/Target/VE/VEISelLowering.h
    llvm/lib/Target/VE/VEInstrInfo.td
    llvm/lib/Target/VE/VEMCInstLower.cpp
    llvm/test/CodeGen/VE/Scalar/br_jt.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/VEFrameLowering.cpp b/llvm/lib/Target/VE/VEFrameLowering.cpp
index f27a2d08fd6c..ec18bee74329 100644
--- a/llvm/lib/Target/VE/VEFrameLowering.cpp
+++ b/llvm/lib/Target/VE/VEFrameLowering.cpp
@@ -92,8 +92,8 @@ void VEFrameLowering::emitEpilogueInsns(MachineFunction &MF,
   //
   //    or %sp, 0, %fp
   //    ld %s17, 40(,%sp) iff this function is using s17 as BP
-  //    ld %got, 32(,%sp)
-  //    ld %plt, 24(,%sp)
+  //    ld %plt, 32(,%sp)
+  //    ld %got, 24(,%sp)
   //    ld %lr, 8(,%sp)
   //    ld %fp, 0(,%sp)
   BuildMI(MBB, MBBI, DL, TII.get(VE::ORri), VE::SX11).addReg(VE::SX9).addImm(0);

diff  --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index b319b6e6645b..864f097315a2 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
@@ -153,6 +154,7 @@ void VETargetLowering::initSPUActions() {
   setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
   setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
   setOperationAction(ISD::ConstantPool, PtrVT, Custom);
+  setOperationAction(ISD::JumpTable, PtrVT, Custom);
 
   /// VAARG handling {
   setOperationAction(ISD::VASTART, MVT::Other, Custom);
@@ -173,9 +175,7 @@ void VETargetLowering::initSPUActions() {
   // VE doesn't have BRCOND
   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
 
-  // BRIND and BR_JT are not implemented yet.
-  // FIXME: Implement both for the scalar perforamnce.
-  setOperationAction(ISD::BRIND, MVT::Other, Expand);
+  // BR_JT is not implemented yet.
   setOperationAction(ISD::BR_JT, MVT::Other, Expand);
 
   /// } Branch
@@ -929,6 +929,9 @@ SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF,
     return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0),
                                        TF);
 
+  if (const JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op))
+    return DAG.getTargetJumpTable(JT->getIndex(), JT->getValueType(0), TF);
+
   llvm_unreachable("Unhandled address SDNode");
 }
 
@@ -957,7 +960,7 @@ SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
     MFI.setHasCalls(true);
     auto GlobalN = dyn_cast<GlobalAddressSDNode>(Op);
 
-    if (isa<ConstantPoolSDNode>(Op) ||
+    if (isa<ConstantPoolSDNode>(Op) || isa<JumpTableSDNode>(Op) ||
         (GlobalN && GlobalN->getGlobal()->hasLocalLinkage())) {
       // Create following instructions for local linkage PIC code.
       //     lea %reg, label at gotoff_lo
@@ -1147,6 +1150,10 @@ SDValue VETargetLowering::lowerGlobalTLSAddress(SDValue Op,
   return lowerToTLSGeneralDynamicModel(Op, DAG);
 }
 
+SDValue VETargetLowering::lowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
+  return makeAddress(Op, DAG);
+}
+
 // Lower a f128 load into two f64 loads.
 static SDValue lowerLoadF128(SDValue Op, SelectionDAG &DAG) {
   SDLoc DL(Op);
@@ -1412,6 +1419,8 @@ SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return lowerGlobalAddress(Op, DAG);
   case ISD::GlobalTLSAddress:
     return lowerGlobalTLSAddress(Op, DAG);
+  case ISD::JumpTable:
+    return lowerJumpTable(Op, DAG);
   case ISD::LOAD:
     return lowerLOAD(Op, DAG);
   case ISD::STORE:
@@ -1424,6 +1433,63 @@ SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
 }
 /// } Custom Lower
 
+/// JumpTable for VE.
+///
+///   VE cannot generate relocatable symbol in jump table.  VE cannot
+///   generate expressions using symbols in both text segment and data
+///   segment like below.
+///             .4byte  .LBB0_2-.LJTI0_0
+///   So, we generate offset from the top of function like below as
+///   a custom label.
+///             .4byte  .LBB0_2-<function name>
+
+unsigned VETargetLowering::getJumpTableEncoding() const {
+  // Use custom label for PIC.
+  if (isPositionIndependent())
+    return MachineJumpTableInfo::EK_Custom32;
+
+  // Otherwise, use the normal jump table encoding heuristics.
+  return TargetLowering::getJumpTableEncoding();
+}
+
+const MCExpr *VETargetLowering::LowerCustomJumpTableEntry(
+    const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB,
+    unsigned Uid, MCContext &Ctx) const {
+  assert(isPositionIndependent());
+
+  // Generate custom label for PIC like below.
+  //    .4bytes  .LBB0_2-<function name>
+  const auto *Value = MCSymbolRefExpr::create(MBB->getSymbol(), Ctx);
+  MCSymbol *Sym = Ctx.getOrCreateSymbol(MBB->getParent()->getName().data());
+  const auto *Base = MCSymbolRefExpr::create(Sym, Ctx);
+  return MCBinaryExpr::createSub(Value, Base, Ctx);
+}
+
+SDValue VETargetLowering::getPICJumpTableRelocBase(SDValue Table,
+                                                   SelectionDAG &DAG) const {
+  assert(isPositionIndependent());
+  SDLoc DL(Table);
+  Function *Function = &DAG.getMachineFunction().getFunction();
+  assert(Function != nullptr);
+  auto PtrTy = getPointerTy(DAG.getDataLayout(), Function->getAddressSpace());
+
+  // In the jump table, we have following values in PIC mode.
+  //    .4bytes  .LBB0_2-<function name>
+  // We need to add this value and the address of this function to generate
+  // .LBB0_2 label correctly under PIC mode.  So, we want to generate following
+  // instructions:
+  //     lea %reg, fun at gotoff_lo
+  //     and %reg, %reg, (32)0
+  //     lea.sl %reg, fun at gotoff_hi(%reg, %got)
+  // In order to do so, we need to genarate correctly marked DAG node using
+  // makeHiLoPair.
+  SDValue Op = DAG.getGlobalAddress(Function, DL, PtrTy);
+  SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOTOFF_HI32,
+                              VEMCExpr::VK_VE_GOTOFF_LO32, DAG);
+  SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrTy);
+  return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
+}
+
 static bool isI32Insn(const SDNode *User, const SDNode *N) {
   switch (User->getOpcode()) {
   default:

diff  --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
index 4ac609b73830..050496b9133b 100644
--- a/llvm/lib/Target/VE/VEISelLowering.h
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -92,6 +92,15 @@ class VETargetLowering : public TargetLowering {
 
   /// Custom Lower {
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
+  unsigned getJumpTableEncoding() const override;
+  const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
+                                          const MachineBasicBlock *MBB,
+                                          unsigned Uid,
+                                          MCContext &Ctx) const override;
+  SDValue getPICJumpTableRelocBase(SDValue Table,
+                                   SelectionDAG &DAG) const override;
+  // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only
+  // EK_LabelDifference32.
 
   SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
@@ -99,6 +108,7 @@ class VETargetLowering : public TargetLowering {
   SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
+  SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const;

diff  --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 1a15058cf6c4..0d5bbf282ddf 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -1603,7 +1603,7 @@ def vehi_lo : OutPatFrag<(ops node:$hi, node:$lo),
 def vehi_baselo : OutPatFrag<(ops node:$base, node:$hi, node:$lo),
                              (LEASLrri $base, $lo, $hi)>;
 foreach type = [ "tblockaddress", "tconstpool", "texternalsym", "tglobaladdr",
-                 "tglobaltlsaddr" ] in {
+                 "tglobaltlsaddr", "tjumptable" ] in {
   def : Pat<(VElo !cast<SDNode>(type):$lo), (velo_only $lo)>;
   def : Pat<(VEhi !cast<SDNode>(type):$hi), (vehi_only $hi)>;
   def : Pat<(add (VEhi !cast<SDNode>(type):$hi), I64:$lo), (vehi_lo $hi, $lo)>;

diff  --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp
index c14121d9e18a..bc5577ce4f97 100644
--- a/llvm/lib/Target/VE/VEMCInstLower.cpp
+++ b/llvm/lib/Target/VE/VEMCInstLower.cpp
@@ -63,7 +63,8 @@ static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
     return LowerSymbolOperand(MI, MO, AP.getSymbol(MO.getGlobal()), AP);
   case MachineOperand::MO_Immediate:
     return MCOperand::createImm(MO.getImm());
-
+  case MachineOperand::MO_JumpTableIndex:
+    return LowerSymbolOperand(MI, MO, AP.GetJTISymbol(MO.getIndex()), AP);
   case MachineOperand::MO_MachineBasicBlock:
     return LowerSymbolOperand(MI, MO, MO.getMBB()->getSymbol(), AP);
 

diff  --git a/llvm/test/CodeGen/VE/Scalar/br_jt.ll b/llvm/test/CodeGen/VE/Scalar/br_jt.ll
index 86c089474c9d..a7218965c467 100644
--- a/llvm/test/CodeGen/VE/Scalar/br_jt.ll
+++ b/llvm/test/CodeGen/VE/Scalar/br_jt.ll
@@ -1,36 +1,96 @@
 ; RUN: llc < %s -mtriple=ve | FileCheck %s
+; RUN: llc < %s -mtriple=ve -relocation-model=pic \
+; RUN:     | FileCheck %s -check-prefix=PIC
 
 ; Function Attrs: norecurse nounwind readnone
 define signext i32 @br_jt(i32 signext %0) {
 ; CHECK-LABEL: br_jt:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
-; CHECK-NEXT:    brlt.w 2, %s0, .LBB{{[0-9]+}}_4
+; CHECK-NEXT:    adds.w.sx %s1, -1, %s0
+; CHECK-NEXT:    cmpu.w %s2, 3, %s1
+; CHECK-NEXT:    brgt.w 0, %s2, .LBB{{[0-9]+}}_5
 ; CHECK-NEXT:  # %bb.1:
-; CHECK-NEXT:    breq.w 1, %s0, .LBB{{[0-9]+}}_8
-; CHECK-NEXT:  # %bb.2:
-; CHECK-NEXT:    brne.w 2, %s0, .LBB{{[0-9]+}}_7
-; CHECK-NEXT:  # %bb.3:
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    sll %s0, %s0, 3
+; CHECK-NEXT:    lea %s1, .LJTI0_0 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, .LJTI0_0 at hi(, %s1)
+; CHECK-NEXT:    ld %s1, (%s1, %s0)
+; CHECK-NEXT:    or %s0, 3, (0)1
+; CHECK-NEXT:    b.l.t (, %s1)
+; CHECK-NEXT:  .LBB{{[0-9]+}}_2:
 ; CHECK-NEXT:    or %s0, 0, (0)1
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    b.l.t (, %s10)
-; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
-; CHECK-NEXT:    breq.w 3, %s0, .LBB{{[0-9]+}}_9
-; CHECK-NEXT:  # %bb.5:
-; CHECK-NEXT:    brne.w 4, %s0, .LBB{{[0-9]+}}_7
-; CHECK-NEXT:  # %bb.6:
-; CHECK-NEXT:    or %s0, 7, (0)1
-; CHECK-NEXT:  .LBB{{[0-9]+}}_7:
-; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
-; CHECK-NEXT:    b.l.t (, %s10)
-; CHECK-NEXT:  .LBB{{[0-9]+}}_8:
-; CHECK-NEXT:    or %s0, 3, (0)1
+; CHECK-NEXT:  .LBB{{[0-9]+}}_3:
+; CHECK-NEXT:    or %s0, 4, (0)1
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    b.l.t (, %s10)
-; CHECK-NEXT:  .LBB{{[0-9]+}}_9:
-; CHECK-NEXT:    or %s0, 4, (0)1
+; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
+; CHECK-NEXT:    or %s0, 7, (0)1
+; CHECK-NEXT:  .LBB{{[0-9]+}}_5:
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    b.l.t (, %s10)
+;
+; PIC-LABEL: br_jt:
+; PIC:       # %bb.0:
+; PIC-NEXT:    st %s9, (, %s11)
+; PIC-NEXT:    st %s10, 8(, %s11)
+; PIC-NEXT:    st %s15, 24(, %s11)
+; PIC-NEXT:    st %s16, 32(, %s11)
+; PIC-NEXT:    or %s9, 0, %s11
+; PIC-NEXT:    lea %s13, -176
+; PIC-NEXT:    and %s13, %s13, (32)0
+; PIC-NEXT:    lea.sl %s11, -1(%s13, %s11)
+; PIC-NEXT:    brge.l %s11, %s8, .LBB0_7
+; PIC-NEXT:  # %bb.6:
+; PIC-NEXT:    ld %s61, 24(, %s14)
+; PIC-NEXT:    or %s62, 0, %s0
+; PIC-NEXT:    lea %s63, 315
+; PIC-NEXT:    shm.l %s63, (%s61)
+; PIC-NEXT:    shm.l %s8, 8(%s61)
+; PIC-NEXT:    shm.l %s11, 16(%s61)
+; PIC-NEXT:    monc
+; PIC-NEXT:    or %s0, 0, %s62
+; PIC-NEXT:  .LBB0_7:
+; PIC-NEXT:    adds.w.sx %s0, %s0, (0)1
+; PIC-NEXT:    adds.w.sx %s1, -1, %s0
+; PIC-NEXT:    cmpu.w %s2, 3, %s1
+; PIC-NEXT:    lea %s15, _GLOBAL_OFFSET_TABLE_ at pc_lo(-24)
+; PIC-NEXT:    and %s15, %s15, (32)0
+; PIC-NEXT:    sic %s16
+; PIC-NEXT:    lea.sl %s15, _GLOBAL_OFFSET_TABLE_ at pc_hi(%s16, %s15)
+; PIC-NEXT:    brgt.w 0, %s2, .LBB0_5
+; PIC-NEXT:  # %bb.1:
+; PIC-NEXT:    adds.w.zx %s0, %s1, (0)1
+; PIC-NEXT:    sll %s0, %s0, 2
+; PIC-NEXT:    lea %s1, .LJTI0_0 at gotoff_lo
+; PIC-NEXT:    and %s1, %s1, (32)0
+; PIC-NEXT:    lea.sl %s1, .LJTI0_0 at gotoff_hi(%s1, %s15)
+; PIC-NEXT:    ldl.sx %s0, (%s1, %s0)
+; PIC-NEXT:    lea %s1, br_jt at gotoff_lo
+; PIC-NEXT:    and %s1, %s1, (32)0
+; PIC-NEXT:    lea.sl %s1, br_jt at gotoff_hi(%s1, %s15)
+; PIC-NEXT:    adds.l %s1, %s0, %s1
+; PIC-NEXT:    or %s0, 3, (0)1
+; PIC-NEXT:    b.l.t (, %s1)
+; PIC-NEXT:  .LBB0_2:
+; PIC-NEXT:    or %s0, 0, (0)1
+; PIC-NEXT:    br.l.t .LBB0_5
+; PIC-NEXT:  .LBB0_3:
+; PIC-NEXT:    or %s0, 4, (0)1
+; PIC-NEXT:    br.l.t .LBB0_5
+; PIC-NEXT:  .LBB0_4:
+; PIC-NEXT:    or %s0, 7, (0)1
+; PIC-NEXT:  .LBB0_5:
+; PIC-NEXT:    adds.w.sx %s0, %s0, (0)1
+; PIC-NEXT:    or %s11, 0, %s9
+; PIC-NEXT:    ld %s16, 32(, %s11)
+; PIC-NEXT:    ld %s15, 24(, %s11)
+; PIC-NEXT:    ld %s10, 8(, %s11)
+; PIC-NEXT:    ld %s9, (, %s11)
+; PIC-NEXT:    b.l.t (, %s10)
   switch i32 %0, label %5 [
     i32 1, label %6
     i32 2, label %2


        


More information about the llvm-commits mailing list