From a1d97a960e622ee21550d92809512cb0870be499 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 26 Jun 2019 16:17:15 +0000 Subject: [WebAssembly] Implement tail calls and unify tablegen call classes Summary: Implements direct and indirect tail calls enabled by the 'tail-call' feature in both DAG ISel and FastISel. Updates existing call tests and adds new tests including a binary encoding test. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62877 llvm-svn: 364445 --- .../Target/WebAssembly/WebAssemblyISelLowering.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (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 fccb456586e..4064a983099 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -644,13 +644,14 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, if (CLI.IsPatchPoint) fail(DL, DAG, "WebAssembly doesn't support patch point yet"); - // WebAssembly doesn't currently support explicit tail calls. If they are - // required, fail. Otherwise, just disable them. - if ((CallConv == CallingConv::Fast && CLI.IsTailCall && - MF.getTarget().Options.GuaranteedTailCallOpt) || - (CLI.CS && CLI.CS.isMustTailCall())) - fail(DL, DAG, "WebAssembly doesn't support tail call yet"); - CLI.IsTailCall = false; + // Fail if tail calls are required but not enabled + if (!Subtarget->hasTailCall()) { + if ((CallConv == CallingConv::Fast && CLI.IsTailCall && + MF.getTarget().Options.GuaranteedTailCallOpt) || + (CLI.CS && CLI.CS.isMustTailCall())) + fail(DL, DAG, "WebAssembly 'tail-call' feature not enabled"); + CLI.IsTailCall = false; + } SmallVectorImpl &Ins = CLI.Ins; if (Ins.size() > 1) @@ -783,6 +784,13 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, // registers. InTys.push_back(In.VT); } + + if (CLI.IsTailCall) { + // ret_calls do not return values to the current frame + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); + return DAG.getNode(WebAssemblyISD::RET_CALL, DL, NodeTys, Ops); + } + InTys.push_back(MVT::Other); SDVTList InTyList = DAG.getVTList(InTys); SDValue Res = -- cgit v1.2.3