From b18e7bdac85c58f5b3389e579b3abe9e78ad3f9a Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 22 Jul 2015 21:28:15 +0000 Subject: [PATCH] =?utf8?q?WebAssembly:=20basic=20bitcode=20=E2=86=92=20ass?= =?utf8?q?embly=20CodeGen=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Summary: Add a basic CodeGen bitcode test which (for now) only prints out the function name and nothing else. The current code merely implements the basic needed for the test run to not crash / assert. Getting to that point required: - Basic InstPrinter. - Basic AsmPrinter. - DiagnosticInfoUnsupported (not strictly required, but nice to have, duplicated from AMDGPU/BPF's ISelLowering). - Some SP and register setup in WebAssemblyTargetLowering. - Basic LowerFormalArguments. - GenInstrInfo. - Placeholder LowerFormalArguments. - Placeholder CanLowerReturn and LowerReturn. - Basic DAGToDAGISel::Select, which requiresGenDAGISel.inc as well as GET_INSTRINFO_ENUM with GenInstrInfo.inc. - Remove WebAssemblyFrameLowering::determineCalleeSaves and rely on default. - Implement WebAssemblyFrameLowering::hasFP, same as AArch64's implementation. Follow-up patches will implement a real AsmPrinter, which will require adding MI opcodes specific to WebAssembly. Reviewers: sunfish Subscribers: aemerson, jfb, llvm-commits Differential Revision: http://reviews.llvm.org/D11369 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242939 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/WebAssembly/CMakeLists.txt | 6 +- .../InstPrinter/WebAssemblyInstPrinter.cpp | 7 +- .../InstPrinter/WebAssemblyInstPrinter.h | 4 + .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp | 3 + .../MCTargetDesc/WebAssemblyMCTargetDesc.h | 5 + lib/Target/WebAssembly/Makefile | 9 +- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 91 ++++++++++++++ .../WebAssembly/WebAssemblyFrameLowering.cpp | 15 ++- .../WebAssembly/WebAssemblyFrameLowering.h | 3 - .../WebAssembly/WebAssemblyISelDAGToDAG.cpp | 38 +++++- .../WebAssembly/WebAssemblyISelLowering.cpp | 117 ++++++++++++++++++ .../WebAssembly/WebAssemblyISelLowering.h | 16 +++ .../WebAssembly/WebAssemblyInstrInfo.cpp | 3 + lib/Target/WebAssembly/WebAssemblyInstrInfo.h | 5 +- lib/Target/WebAssembly/WebAssemblySubtarget.h | 6 + test/CodeGen/WebAssembly/integer.ll | 10 ++ 16 files changed, 320 insertions(+), 18 deletions(-) create mode 100644 lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp create mode 100644 test/CodeGen/WebAssembly/integer.ll diff --git a/lib/Target/WebAssembly/CMakeLists.txt b/lib/Target/WebAssembly/CMakeLists.txt index 25de9eee083..a1099c535b1 100644 --- a/lib/Target/WebAssembly/CMakeLists.txt +++ b/lib/Target/WebAssembly/CMakeLists.txt @@ -1,15 +1,19 @@ set(LLVM_TARGET_DEFINITIONS WebAssembly.td) +tablegen(LLVM WebAssemblyGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM WebAssemblyGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info) tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM WebAssemblyGenRegisterInfo.inc -gen-register-info) tablegen(LLVM WebAssemblyGenSubtargetInfo.inc -gen-subtarget) add_public_tablegen_target(WebAssemblyCommonTableGen) add_llvm_target(WebAssemblyCodeGen + WebAssemblyAsmPrinter.cpp WebAssemblyFrameLowering.cpp - WebAssemblyInstrInfo.cpp WebAssemblyISelDAGToDAG.cpp WebAssemblyISelLowering.cpp + WebAssemblyInstrInfo.cpp WebAssemblyMachineFunctionInfo.cpp WebAssemblyRegisterInfo.cpp WebAssemblySelectionDAGInfo.cpp diff --git a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index fbb985aaafb..0c5792c6b51 100644 --- a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -26,6 +26,8 @@ using namespace llvm; #define DEBUG_TYPE "asm-printer" +#include "WebAssemblyGenAsmWriter.inc" + WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) @@ -33,11 +35,12 @@ WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI, void WebAssemblyInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { - llvm_unreachable("TODO: implement printRegName"); + OS << getRegisterName(RegNo); } void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) { - llvm_unreachable("TODO: implement printInst"); + printInstruction(MI, OS); + printAnnotation(OS, Annot); } diff --git a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h index 70fcef214ce..4c54a525577 100644 --- a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -31,6 +31,10 @@ public: void printRegName(raw_ostream &OS, unsigned RegNo) const override; void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) override; + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); }; } // end namespace llvm diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp index 224aa773a80..d1616907fb4 100644 --- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -26,6 +26,9 @@ using namespace llvm; #define DEBUG_TYPE "wasm-mc-target-desc" +#define GET_INSTRINFO_MC_DESC +#include "WebAssemblyGenInstrInfo.inc" + #define GET_SUBTARGETINFO_MC_DESC #include "WebAssemblyGenSubtargetInfo.inc" diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index eebf5b72f62..bb788dce03c 100644 --- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -50,6 +50,11 @@ MCAsmBackend *createWebAssemblyAsmBackend(const Target &T, #define GET_REGINFO_ENUM #include "WebAssemblyGenRegisterInfo.inc" +// Defines symbolic names for the WebAssembly instructions. +// +#define GET_INSTRINFO_ENUM +#include "WebAssemblyGenInstrInfo.inc" + #define GET_SUBTARGETINFO_ENUM #include "WebAssemblyGenSubtargetInfo.inc" diff --git a/lib/Target/WebAssembly/Makefile b/lib/Target/WebAssembly/Makefile index f102d73f6e8..a58e82d0c49 100644 --- a/lib/Target/WebAssembly/Makefile +++ b/lib/Target/WebAssembly/Makefile @@ -12,8 +12,13 @@ LIBRARYNAME = LLVMWebAssemblyCodeGen TARGET = WebAssembly # Make sure that tblgen is run, first thing. -BUILT_SOURCES = WebAssemblyGenRegisterInfo.inc WebAssemblyGenSubtargetInfo.inc \ - WebAssemblyGenMCCodeEmitter.inc +BUILT_SOURCES = \ + WebAssemblyGenAsmWriter.inc \ + WebAssemblyGenDAGISel.inc \ + WebAssemblyGenInstrInfo.inc \ + WebAssemblyGenMCCodeEmitter.inc \ + WebAssemblyGenRegisterInfo.inc \ + WebAssemblyGenSubtargetInfo.inc DIRS = InstPrinter TargetInfo MCTargetDesc diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp new file mode 100644 index 00000000000..7a6c7784c54 --- /dev/null +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -0,0 +1,91 @@ +//===-- WebAssemblyAsmPrinter.cpp - WebAssembly LLVM assembly writer ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file contains a printer that converts from our internal +/// representation of machine-dependent LLVM code to the WebAssembly assembly +/// language. +/// +//===----------------------------------------------------------------------===// + +#include "WebAssembly.h" +#include "WebAssemblyMachineFunctionInfo.h" +#include "WebAssemblyRegisterInfo.h" +#include "WebAssemblySubtarget.h" +#include "InstPrinter/WebAssemblyInstPrinter.h" +#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +namespace { + +class WebAssemblyAsmPrinter final : public AsmPrinter { +public: + WebAssemblyAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)) {} + +private: + const char *getPassName() const override { + return "WebAssembly Assembly Printer"; + } + + //===------------------------------------------------------------------===// + // MachineFunctionPass Implementation. + //===------------------------------------------------------------------===// + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AsmPrinter::getAnalysisUsage(AU); + } + + bool runOnMachineFunction(MachineFunction &F) override { + return AsmPrinter::runOnMachineFunction(F); + } + + //===------------------------------------------------------------------===// + // AsmPrinter Implementation. + //===------------------------------------------------------------------===// + + void EmitInstruction(const MachineInstr *MI) override; +}; + +} // end anonymous namespace + +//===----------------------------------------------------------------------===// + +void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { + SmallString<128> Str; + raw_svector_ostream OS(Str); + + switch (MI->getOpcode()) { + default: + DEBUG(MI->print(dbgs())); + llvm_unreachable("Unhandled instruction"); + break; + } + + OutStreamer->EmitRawText(OS.str()); +} + +// Force static initialization. +extern "C" void LLVMInitializeWebAssemblyAsmPrinter() { + RegisterAsmPrinter X(TheWebAssemblyTarget32); + RegisterAsmPrinter Y(TheWebAssemblyTarget64); +} diff --git a/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp index 3d9050ae216..fec94554833 100644 --- a/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -39,7 +39,12 @@ using namespace llvm; /// Return true if the specified function should have a dedicated frame pointer /// register. bool WebAssemblyFrameLowering::hasFP(const MachineFunction &MF) const { - llvm_unreachable("TODO: implement hasFP"); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const auto *RegInfo = static_cast( + MF.getSubtarget().getRegisterInfo()); + return MFI->hasCalls() || MFI->hasVarSizedObjects() || + MFI->isFrameAddressTaken() || MFI->hasStackMap() || + MFI->hasPatchPoint() || RegInfo->needsStackRealignment(MF); } /// Under normal circumstances, when a frame pointer is not required, we reserve @@ -60,16 +65,10 @@ void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr( void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { - llvm_unreachable("TODO: implement emitPrologue"); + // FIXME: Implement WebAssemblyFrameLowering::emitPrologue. } void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { llvm_unreachable("TODO: implement emitEpilogue"); } - -void WebAssemblyFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - llvm_unreachable("TODO: implement determineCalleeSaves"); -} diff --git a/lib/Target/WebAssembly/WebAssemblyFrameLowering.h b/lib/Target/WebAssembly/WebAssemblyFrameLowering.h index 704f892bbaa..5f4708fe77e 100644 --- a/lib/Target/WebAssembly/WebAssemblyFrameLowering.h +++ b/lib/Target/WebAssembly/WebAssemblyFrameLowering.h @@ -38,9 +38,6 @@ public: bool hasFP(const MachineFunction &MF) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; - - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; }; } // end namespace llvm diff --git a/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index 518ef332a6c..58a23756bdc 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -56,13 +56,49 @@ public: SDNode *Select(SDNode *Node) override; +// Include the pieces autogenerated from the target description. +#include "WebAssemblyGenDAGISel.inc" + private: // add select functions here... }; } // end anonymous namespace SDNode *WebAssemblyDAGToDAGISel::Select(SDNode *Node) { - llvm_unreachable("TODO: implement Select"); + // Dump information about the Node being selected. + DEBUG(errs() << "Selecting: "); + DEBUG(Node->dump(CurDAG)); + DEBUG(errs() << "\n"); + + // If we have a custom node, we already have selected! + if (Node->isMachineOpcode()) { + DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); + Node->setNodeId(-1); + return nullptr; + } + + // Few custom selection stuff. + SDNode *ResNode = nullptr; + EVT VT = Node->getValueType(0); + + switch (Node->getOpcode()) { + default: + break; + // FIXME: Implement WebAssembly-specific selection. + (void)VT; + } + + // Select the default instruction. + ResNode = SelectCode(Node); + + DEBUG(errs() << "=> "); + if (ResNode == nullptr || ResNode == Node) + DEBUG(Node->dump(CurDAG)); + else + DEBUG(ResNode->dump(CurDAG)); + DEBUG(errs() << "\n"); + + return ResNode; } /// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 4184eb6dc5a..b1bb4deb626 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -21,6 +21,8 @@ #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Function.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/CommandLine.h" @@ -28,10 +30,65 @@ #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 { +private: + // Debug location where this diagnostic is triggered. + DebugLoc DLoc; + const Twine &Description; + const Function &Fn; + SDValue Value; + + static int KindID; + + static int getKindID() { + if (KindID == 0) + KindID = llvm::getNextAvailablePluginDiagnosticKind(); + return KindID; + } + +public: + DiagnosticInfoUnsupported(SDLoc DLoc, const Function &Fn, const Twine &Desc, + SDValue Value) + : DiagnosticInfo(getKindID(), DS_Error), DLoc(DLoc.getDebugLoc()), + Description(Desc), Fn(Fn), Value(Value) {} + + void print(DiagnosticPrinter &DP) const override { + std::string Str; + raw_string_ostream OS(Str); + + if (DLoc) { + auto DIL = DLoc.get(); + StringRef Filename = DIL->getFilename(); + unsigned Line = DIL->getLine(); + unsigned Column = DIL->getColumn(); + OS << Filename << ':' << Line << ':' << Column << ' '; + } + + OS << "in function " << Fn.getName() << ' ' << *Fn.getFunctionType() << '\n' + << Description; + if (Value) + Value->print(OS); + OS << '\n'; + OS.flush(); + DP << Str; + } + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == getKindID(); + } +}; + +int DiagnosticInfoUnsupported::KindID = 0; +} // end anonymous namespace + WebAssemblyTargetLowering::WebAssemblyTargetLowering( const TargetMachine &TM, const WebAssemblySubtarget &STI) : TargetLowering(TM), Subtarget(&STI) { @@ -40,6 +97,18 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setHasFloatingPointExceptions(false); // We don't know the microarchitecture here, so just reduce register pressure. setSchedulingPreference(Sched::RegPressure); + // Tell ISel that we have a stack pointer. + setStackPointerRegisterToSaveRestore( + Subtarget->hasAddr64() ? WebAssembly::SP64 : WebAssembly::SP32); + // Set up the register classes. + addRegisterClass(MVT::i32, &WebAssembly::Int32RegClass); + addRegisterClass(MVT::i64, &WebAssembly::Int64RegClass); + addRegisterClass(MVT::f32, &WebAssembly::Float32RegClass); + addRegisterClass(MVT::f64, &WebAssembly::Float64RegClass); + // Compute derived properties from the register classes. + computeRegisterProperties(Subtarget->getRegisterInfo()); + + // FIXME: setOperationAction... } //===----------------------------------------------------------------------===// @@ -50,6 +119,54 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( // Lowering Code //===----------------------------------------------------------------------===// +static void fail(SDLoc DL, SelectionDAG &DAG, const char *msg) { + MachineFunction &MF = DAG.getMachineFunction(); + DAG.getContext()->diagnose( + DiagnosticInfoUnsupported(DL, *MF.getFunction(), msg, SDValue())); +} + +bool WebAssemblyTargetLowering::CanLowerReturn( + CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, + const SmallVectorImpl &Outs, LLVMContext &Context) const { + // WebAssembly can't currently handle returning tuples. + return Outs.size() <= 1; +} + +SDValue WebAssemblyTargetLowering::LowerReturn( + SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, SDLoc DL, + SelectionDAG &DAG) const { + + 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"); + + // FIXME: Implement LowerReturn. + + return Chain; +} + +SDValue WebAssemblyTargetLowering::LowerFormalArguments( + SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Ins, SDLoc DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const { + MachineFunction &MF = DAG.getMachineFunction(); + + if (CallConv != CallingConv::C) + fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions"); + if (IsVarArg) + fail(DL, DAG, "WebAssembly doesn't support varargs yet"); + if (MF.getFunction()->hasStructRetAttr()) + fail(DL, DAG, "WebAssembly doesn't support struct return yet"); + + // FIXME: Implement LowerFormalArguments. + for (const ISD::InputArg &In : Ins) + InVals.push_back(DAG.getNode(ISD::UNDEF, DL, In.VT)); + + return Chain; +} + //===----------------------------------------------------------------------===// // Other Lowering Code //===----------------------------------------------------------------------===// diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/lib/Target/WebAssembly/WebAssemblyISelLowering.h index efd60a7bacd..0254544b404 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -42,6 +42,22 @@ private: /// Keep a pointer to the WebAssemblySubtarget around so that we can make the /// right decision when generating code for different targets. const WebAssemblySubtarget *Subtarget; + + bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool isVarArg, + const SmallVectorImpl &Outs, + LLVMContext &Context) const override; + + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, SDLoc dl, + SelectionDAG &DAG) const override; + + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Ins, + SDLoc DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const override; }; } // end namespace llvm diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index ea8937c8f9f..d4c65a4b98c 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -24,5 +24,8 @@ using namespace llvm; #define DEBUG_TYPE "wasm-instr-info" +#define GET_INSTRINFO_CTOR_DTOR +#include "WebAssemblyGenInstrInfo.inc" + WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI) : RI(STI.getTargetTriple()) {} diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInfo.h b/lib/Target/WebAssembly/WebAssemblyInstrInfo.h index 1c4ae22f16d..29fdcb0e6cb 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.h @@ -19,11 +19,14 @@ #include "WebAssemblyRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" +#define GET_INSTRINFO_HEADER +#include "WebAssemblyGenInstrInfo.inc" + namespace llvm { class WebAssemblySubtarget; -class WebAssemblyInstrInfo final { +class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo { const WebAssemblyRegisterInfo RI; public: diff --git a/lib/Target/WebAssembly/WebAssemblySubtarget.h b/lib/Target/WebAssembly/WebAssemblySubtarget.h index 6f176194093..9b17300e497 100644 --- a/lib/Target/WebAssembly/WebAssemblySubtarget.h +++ b/lib/Target/WebAssembly/WebAssemblySubtarget.h @@ -61,6 +61,12 @@ public: const WebAssemblyTargetLowering *getTargetLowering() const override { return &TLInfo; } + const WebAssemblyInstrInfo *getInstrInfo() const override { + return &InstrInfo; + } + const WebAssemblyRegisterInfo *getRegisterInfo() const override { + return &getInstrInfo()->getRegisterInfo(); + } const Triple &getTargetTriple() const { return TargetTriple; } bool enableMachineScheduler() const override; bool useAA() const override { return true; } diff --git a/test/CodeGen/WebAssembly/integer.ll b/test/CodeGen/WebAssembly/integer.ll new file mode 100644 index 00000000000..0910ba11842 --- /dev/null +++ b/test/CodeGen/WebAssembly/integer.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -asm-verbose=false | FileCheck %s + +target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: add32: +define i32 @add32(i32 %x, i32 %y) { + %a = add i32 %x, %y + ret i32 %a +} -- 2.34.1