X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FWebAssembly%2FWebAssemblyISelLowering.cpp;h=405a2a977a0ab1bf6743d0344fb792288a623cd3;hp=85a123bdc56f8a2c8fd874a3d355367fde8ccc07;hb=553ab96017d6e77f0529270baa9e508f713b9282;hpb=ccb28273c87438bff4bafc862feef954ce8235dd diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 85a123bdc56..405a2a977a0 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -32,15 +32,15 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" - using namespace llvm; #define DEBUG_TYPE "wasm-lower" namespace { // Diagnostic information for unimplemented or unsupported feature reporting. -// FIXME copied from BPF and AMDGPU. -class DiagnosticInfoUnsupported : public DiagnosticInfo { +// TODO: This code is copied from BPF and AMDGPU; consider factoring it out +// and sharing code. +class DiagnosticInfoUnsupported final : public DiagnosticInfo { private: // Debug location where this diagnostic is triggered. DebugLoc DLoc; @@ -115,6 +115,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}) { @@ -228,6 +229,16 @@ WebAssemblyTargetLowering::getRegForInlineAsmConstraint( return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } +bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const { + // Assume ctz is a relatively cheap operation. + return true; +} + +bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const { + // Assume clz is a relatively cheap operation. + return true; +} + //===----------------------------------------------------------------------===// // WebAssembly Lowering private implementation. //===----------------------------------------------------------------------===// @@ -326,8 +337,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn( const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, SDLoc DL, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - assert(Outs.size() <= 1 && "WebAssembly can only return up to one value"); if (CallConv != CallingConv::C) fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions"); @@ -352,7 +361,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn( fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results"); if (!Out.IsFixed) fail(DL, DAG, "WebAssembly doesn't support non-fixed results yet"); - MF.getInfo()->addResult(Out.VT); } return Chain; @@ -369,7 +377,6 @@ SDValue WebAssemblyTargetLowering::LowerFormalArguments( if (IsVarArg) fail(DL, DAG, "WebAssembly doesn't support varargs yet"); - unsigned ArgNo = 0; for (const ISD::InputArg &In : Ins) { if (In.Flags.isByVal()) fail(DL, DAG, "WebAssembly hasn't implemented byval arguments"); @@ -381,16 +388,16 @@ SDValue WebAssemblyTargetLowering::LowerFormalArguments( fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments"); if (In.Flags.isInConsecutiveRegsLast()) fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments"); - // FIXME Do something with In.getOrigAlign()? + // Ignore In.getOrigAlign() because all our arguments are passed in + // registers. InVals.push_back( In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT, - DAG.getTargetConstant(ArgNo, DL, MVT::i32)) + DAG.getTargetConstant(InVals.size(), DL, MVT::i32)) : DAG.getNode(ISD::UNDEF, DL, In.VT)); // Record the number and types of arguments. MF.getInfo()->addParam(In.VT); - ++ArgNo; } return Chain; @@ -408,6 +415,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: @@ -429,11 +438,21 @@ 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(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 - // table operand into a SWITCH instruction, rather than ever materializing - // it in a register. + // table operand into a TABLESWITCH instruction, rather than ever + // materializing it in a register. const JumpTableSDNode *JT = cast(Op); return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(), JT->getTargetFlags()); @@ -463,7 +482,7 @@ SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op, for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB)); - return DAG.getNode(WebAssemblyISD::SWITCH, DL, MVT::Other, Ops); + return DAG.getNode(WebAssemblyISD::TABLESWITCH, DL, MVT::Other, Ops); } //===----------------------------------------------------------------------===//