summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2016-02-16 18:18:36 +0000
committerDerek Schuff <dschuff@google.com>2016-02-16 18:18:36 +0000
commitaadc89c25d664d8c52b7a96b1db1d581cd435358 (patch)
tree1bcfd5585267ea813c4d88d9ef15b04dbb5d5659 /llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
parentcc4c8718ed09b783a03f93500b96aea41f8273b4 (diff)
downloadbcm5719-llvm-aadc89c25d664d8c52b7a96b1db1d581cd435358.tar.gz
bcm5719-llvm-aadc89c25d664d8c52b7a96b1db1d581cd435358.zip
[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
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp26
1 files changed, 26 insertions, 0 deletions
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<FrameIndexSDNode>(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<RegisterSDNode>(Op.getOperand(1))->getReg(),
+ Copy);
+ }
+ return SDValue();
+}
+
SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
SelectionDAG &DAG) const {
int FI = cast<FrameIndexSDNode>(Op)->getIndex();
OpenPOWER on IntegriCloud