From 3c334d631e72944b27d7263ab43c656a9b3e2ec7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Aug 2015 18:44:37 +0000 Subject: [PATCH] [WebAssembly] Skeleton FastISel support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245860 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/FastISel.h | 8 +- lib/CodeGen/SelectionDAG/FastISel.cpp | 19 +++++ lib/Target/WebAssembly/CMakeLists.txt | 2 + lib/Target/WebAssembly/Makefile | 1 + .../WebAssembly/WebAssemblyFastISel.cpp | 81 +++++++++++++++++++ .../WebAssembly/WebAssemblyISelLowering.cpp | 5 ++ .../WebAssembly/WebAssemblyISelLowering.h | 8 ++ test/CodeGen/WebAssembly/fast-isel.ll | 20 +++++ 8 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 lib/Target/WebAssembly/WebAssemblyFastISel.cpp create mode 100644 test/CodeGen/WebAssembly/fast-isel.ll diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index f04a7cd6966..30c632f83f7 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -419,8 +419,14 @@ protected: const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm1, uint64_t Imm2); - /// \brief Emit a MachineInstr with two register operands and a result + /// \brief Emit a MachineInstr with a floating point immediate, and a result /// register in the given register class. + unsigned fastEmitInst_f(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + const ConstantFP *FPImm); + + /// \brief Emit a MachineInstr with one register operand, a floating point + /// immediate, and a result register in the given register class. unsigned fastEmitInst_rf(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, const ConstantFP *FPImm); diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 047ea9050a2..8cf859cf517 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1867,6 +1867,25 @@ unsigned FastISel::fastEmitInst_rii(unsigned MachineInstOpcode, return ResultReg; } +unsigned FastISel::fastEmitInst_f(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + const ConstantFP *FPImm) { + const MCInstrDesc &II = TII.get(MachineInstOpcode); + + unsigned ResultReg = createResultReg(RC); + + if (II.getNumDefs() >= 1) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg) + .addFPImm(FPImm); + else { + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) + .addFPImm(FPImm); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]); + } + return ResultReg; +} + unsigned FastISel::fastEmitInst_rf(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, const ConstantFP *FPImm) { diff --git a/lib/Target/WebAssembly/CMakeLists.txt b/lib/Target/WebAssembly/CMakeLists.txt index 66f585ae7ca..61959cf89f4 100644 --- a/lib/Target/WebAssembly/CMakeLists.txt +++ b/lib/Target/WebAssembly/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS WebAssembly.td) tablegen(LLVM WebAssemblyGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM WebAssemblyGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM WebAssemblyGenFastISel.inc -gen-fast-isel) tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info) tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM WebAssemblyGenRegisterInfo.inc -gen-register-info) @@ -11,6 +12,7 @@ add_public_tablegen_target(WebAssemblyCommonTableGen) add_llvm_target(WebAssemblyCodeGen Relooper.cpp WebAssemblyAsmPrinter.cpp + WebAssemblyFastISel.cpp WebAssemblyFrameLowering.cpp WebAssemblyISelDAGToDAG.cpp WebAssemblyISelLowering.cpp diff --git a/lib/Target/WebAssembly/Makefile b/lib/Target/WebAssembly/Makefile index a58e82d0c49..ccf63f0be55 100644 --- a/lib/Target/WebAssembly/Makefile +++ b/lib/Target/WebAssembly/Makefile @@ -15,6 +15,7 @@ TARGET = WebAssembly BUILT_SOURCES = \ WebAssemblyGenAsmWriter.inc \ WebAssemblyGenDAGISel.inc \ + WebAssemblyGenFastISel.inc \ WebAssemblyGenInstrInfo.inc \ WebAssemblyGenMCCodeEmitter.inc \ WebAssemblyGenRegisterInfo.inc \ diff --git a/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/lib/Target/WebAssembly/WebAssemblyFastISel.cpp new file mode 100644 index 00000000000..1b761b1a9d7 --- /dev/null +++ b/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -0,0 +1,81 @@ +//===-- WebAssemblyFastISel.cpp - WebAssembly FastISel implementation -----===// +// +// 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 defines the WebAssembly-specific support for the FastISel +/// class. Some of the target-specific code is generated by tablegen in the file +/// WebAssemblyGenFastISel.inc, which is #included here. +/// +//===----------------------------------------------------------------------===// + +#include "WebAssembly.h" +#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "WebAssemblySubtarget.h" +#include "WebAssemblyTargetMachine.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/CodeGen/FastISel.h" +#include "llvm/CodeGen/FunctionLoweringInfo.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Operator.h" +using namespace llvm; + +#define DEBUG_TYPE "wasm-fastisel" + +namespace { + +class WebAssemblyFastISel final : public FastISel { + /// Keep a pointer to the WebAssemblySubtarget around so that we can make the + /// right decision when generating code for different targets. + const WebAssemblySubtarget *Subtarget; + LLVMContext *Context; + + // Call handling routines. +private: +public: + // Backend specific FastISel code. + WebAssemblyFastISel(FunctionLoweringInfo &FuncInfo, + const TargetLibraryInfo *LibInfo) + : FastISel(FuncInfo, LibInfo, /*SkipTargetIndependentISel=*/true) { + Subtarget = &FuncInfo.MF->getSubtarget(); + Context = &FuncInfo.Fn->getContext(); + } + + bool fastSelectInstruction(const Instruction *I) override; + +#include "WebAssemblyGenFastISel.inc" +}; + +} // end anonymous namespace + +bool WebAssemblyFastISel::fastSelectInstruction(const Instruction *I) { + switch (I->getOpcode()) { + default: + break; + // TODO: add fast-isel selection cases here... + } + + // Fall back to target-independent instruction selection. + return selectOperator(I, I->getOpcode()); +} + +FastISel *WebAssembly::createFastISel(FunctionLoweringInfo &FuncInfo, + const TargetLibraryInfo *LibInfo) { + return new WebAssemblyFastISel(FuncInfo, LibInfo); +} diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 4cb3a3138e8..dfeec770d5a 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -151,6 +151,11 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); } +FastISel *WebAssemblyTargetLowering::createFastISel( + FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const { + return WebAssembly::createFastISel(FuncInfo, LibInfo); +} + MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout &DL, EVT VT) const { return VT.getSimpleVT(); diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/lib/Target/WebAssembly/WebAssemblyISelLowering.h index 9af4e455ad2..ea845cd4031 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -45,6 +45,9 @@ private: /// right decision when generating code for different targets. const WebAssemblySubtarget *Subtarget; + FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, + const TargetLibraryInfo *LibInfo) const override; + MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override; const char *getTargetNodeName(unsigned Opcode) const override; @@ -66,6 +69,11 @@ private: SmallVectorImpl &InVals) const override; }; +namespace WebAssembly { +FastISel *createFastISel(FunctionLoweringInfo &funcInfo, + const TargetLibraryInfo *libInfo); +} // end namespace WebAssembly + } // end namespace llvm #endif diff --git a/test/CodeGen/WebAssembly/fast-isel.ll b/test/CodeGen/WebAssembly/fast-isel.ll new file mode 100644 index 00000000000..c4f1c2fa5e8 --- /dev/null +++ b/test/CodeGen/WebAssembly/fast-isel.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -asm-verbose=false \ +; RUN: -fast-isel -fast-isel-abort=1 -verify-machineinstrs \ +; RUN: | FileCheck %s + +target datalayout = "e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; This tests very minimal fast-isel functionality. + +; CHECK-LABEL: immediate_f32 +; CHECK: (immediate 0x1.4p1) +define float @immediate_f32() { + ret float 2.5 +} + +; CHECK-LABEL: immediate_f64 +; CHECK: (immediate 0x1.4p1) +define double @immediate_f64() { + ret double 2.5 +} -- 2.34.1