From aadc89c25d664d8c52b7a96b1db1d581cd435358 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Tue, 16 Feb 2016 18:18:36 +0000 Subject: [WebAssembly] Insert COPY_LOCAL between CopyToReg and FrameIndex DAG nodes CopyToReg nodes don't support FrameIndex operands. Other targets select the FI to some LEA-like instruction, but since we don't have that, we need to insert some kind of instruction that can take an FI operand and produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy copy_local between Op and its FI operand. This results in a redundant copy which we should optimize away later (maybe in the post-FI-lowering peephole pass). Differential Revision: http://reviews.llvm.org/D17213 llvm-svn: 260987 --- .../Target/WebAssembly/WebAssemblyISelLowering.cpp | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp') diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 436494efd23..2027e8ba678 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -114,6 +114,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setOperationAction(ISD::DYNAMIC_STACKALLOC, MVTPtr, Expand); setOperationAction(ISD::FrameIndex, MVT::i32, Custom); + setOperationAction(ISD::CopyToReg, MVT::Other, Custom); // Expand these forms; we pattern-match the forms that we can handle in isel. for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64}) @@ -544,9 +545,34 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, case ISD::FRAMEADDR: // TODO: Make this return the userspace frame address fail(DL, DAG, "WebAssembly hasn't implemented __builtin_frame_address"); return SDValue(); + case ISD::CopyToReg: + return LowerCopyToReg(Op, DAG); } } +SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op, + SelectionDAG &DAG) const { + SDValue Src = Op.getOperand(2); + if (isa(Src.getNode())) { + // CopyToReg nodes don't support FrameIndex operands. Other targets select + // the FI to some LEA-like instruction, but since we don't have that, we + // need to insert some kind of instruction that can take an FI operand and + // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy + // copy_local between Op and its FI operand. + SDLoc DL(Op); + EVT VT = Src.getValueType(); + SDValue Copy( + DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_LOCAL_I32 + : WebAssembly::COPY_LOCAL_I64, + DL, VT, Src), + 0); + return DAG.getCopyToReg(Op.getOperand(0), DL, + cast(Op.getOperand(1))->getReg(), + Copy); + } + return SDValue(); +} + SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const { int FI = cast(Op)->getIndex(); -- cgit v1.2.3