[WebAssembly] Codegen support for ISD::ExternalSymbol
authorDan Gohman <dan433584@gmail.com>
Wed, 25 Nov 2015 16:44:29 +0000 (16:44 +0000)
committerDan Gohman <dan433584@gmail.com>
Wed, 25 Nov 2015 16:44:29 +0000 (16:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254075 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
lib/Target/WebAssembly/WebAssemblyInstrInfo.td
lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
lib/Target/WebAssembly/WebAssemblyMCInstLower.h
test/CodeGen/WebAssembly/global.ll

index 06a141c..4febdb0 100644 (file)
@@ -114,6 +114,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
   computeRegisterProperties(Subtarget->getRegisterInfo());
 
   setOperationAction(ISD::GlobalAddress, MVTPtr, Custom);
+  setOperationAction(ISD::ExternalSymbol, MVTPtr, Custom);
   setOperationAction(ISD::JumpTable, MVTPtr, Custom);
 
   for (auto T : {MVT::f32, MVT::f64}) {
@@ -412,6 +413,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
     return SDValue();
   case ISD::GlobalAddress:
     return LowerGlobalAddress(Op, DAG);
+  case ISD::ExternalSymbol:
+    return LowerExternalSymbol(Op, DAG);
   case ISD::JumpTable:
     return LowerJumpTable(Op, DAG);
   case ISD::BR_JT:
@@ -433,6 +436,16 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
                      DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT));
 }
 
+SDValue WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
+                                                       SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  const auto *ES = cast<ExternalSymbolSDNode>(Op);
+  EVT VT = Op.getValueType();
+  assert(ES->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
+  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
+                     DAG.getTargetExternalSymbol(ES->getSymbol(), VT));
+}
+
 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
                                                   SelectionDAG &DAG) const {
   // There's no need for a Wrapper node because we always incorporate a jump
index 5922f95..e9a16ce 100644 (file)
@@ -125,8 +125,10 @@ def CONST_F64 : I<(outs F64:$res), (ins f64imm:$imm),
                   [(set F64:$res, fpimm:$imm)],
                   "f64.const\t$res, $imm">;
 
-def : Pat<(i32 (WebAssemblywrapper tglobaladdr :$dst)),
-          (CONST_I32 tglobaladdr :$dst)>;
+def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$dst)),
+          (CONST_I32 tglobaladdr:$dst)>;
+def : Pat<(i32 (WebAssemblywrapper texternalsym:$dst)),
+          (CONST_I32 texternalsym:$dst)>;
 
 def JUMP_TABLE : I<(outs I32:$dst), (ins tjumptable_op:$addr),
                    [(set I32:$dst, (WebAssemblywrapper tjumptable:$addr))],
index 4226a53..0bfef44 100644 (file)
@@ -34,6 +34,11 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
   return Printer.getSymbol(MO.getGlobal());
 }
 
+MCSymbol *
+WebAssemblyMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
+  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
+}
+
 MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
                                                      MCSymbol *Sym) const {
 
@@ -90,6 +95,9 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
     case MachineOperand::MO_GlobalAddress:
       MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
       break;
+    case MachineOperand::MO_ExternalSymbol:
+      MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
+      break;
     }
 
     OutMI.addOperand(MCOp);
index c622c02..03b8268 100644 (file)
@@ -44,6 +44,7 @@ public:
   MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
 
   MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
+  MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
 };
 }
 
index 489e932..4fd1b08 100644 (file)
@@ -18,6 +18,18 @@ define i32 @foo() {
   ret i32 %a
 }
 
+; CHECK-LABEL: call_memcpy:
+; CHECK-NEXT: .param          i32, i32, i32{{$}}
+; CHECK-NEXT: .result         i32{{$}}
+; CHECK-NEXT: i32.const       $push0=, memcpy{{$}}
+; CHECK-NEXT: call_indirect   $pop0, $0, $1, $2{{$}}
+; CHECK-NEXT: return          $0{{$}}
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
+define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
+  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
+  ret i8* %p
+}
+
 ; CHECK: .type   g,@object
 ; CHECK: .align  2{{$}}
 ; CHECK-NEXT: g: