38 changes: 38 additions & 0 deletions llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// WebAssemblyInstPrinter.h - Print wasm MCInst to assembly syntax -*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This class prints an WebAssembly MCInst to wasm file syntax.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_INSTPRINTER_WEBASSEMBLYINSTPRINTER_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_INSTPRINTER_WEBASSEMBLYINSTPRINTER_H

#include "llvm/MC/MCInstPrinter.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm {

class MCOperand;
class MCSubtargetInfo;

class WebAssemblyInstPrinter : public MCInstPrinter {
public:
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI);

void printRegName(raw_ostream &OS, unsigned RegNo) const override;
void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,
const MCSubtargetInfo &STI) override;
};

} // end namespace llvm

#endif
32 changes: 32 additions & 0 deletions llvm/lib/Target/WebAssembly/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
;===- ./lib/Target/WebAssembly/LLVMBuild.txt -------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[common]
subdirectories = InstPrinter MCTargetDesc TargetInfo

[component_0]
type = TargetGroup
name = WebAssembly
parent = Target
has_asmprinter = 1

[component_1]
type = Library
name = WebAssemblyCodeGen
parent = WebAssembly
required_libraries = Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target WebAssemblyDesc WebAssemblyInfo
add_to_library_groups = WebAssembly
4 changes: 4 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_llvm_library(LLVMWebAssemblyDesc
WebAssemblyMCAsmInfo.cpp
WebAssemblyMCTargetDesc.cpp
)
23 changes: 23 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
;===- ./lib/Target/WebAssembly/MCTargetDesc/LLVMBuild.txt ------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[component_0]
type = Library
name = WebAssemblyDesc
parent = WebAssembly
required_libraries = MC Support WebAssemblyAsmPrinter WebAssemblyInfo
add_to_library_groups = WebAssembly
16 changes: 16 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
##===- lib/Target/WebAssembly/TargetDesc/Makefile ----------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LEVEL = ../../../..
LIBRARYNAME = LLVMWebAssemblyDesc

# Hack: we need to include 'main' target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..

include $(LEVEL)/Makefile.common
53 changes: 53 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===-- WebAssemblyMCAsmInfo.cpp - WebAssembly asm properties -------------===//
//
// 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 the declarations of the WebAssemblyMCAsmInfo
/// properties.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyMCAsmInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-mc-asm-info"

WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() {}

WebAssemblyMCAsmInfo::WebAssemblyMCAsmInfo(const Triple &T) {
PointerSize = CalleeSaveStackSlotSize = T.isArch64Bit();

// TODO: What should MaxInstLength be?

PrivateGlobalPrefix = "";
PrivateLabelPrefix = "";

UseDataRegionDirectives = true;

Data8bitsDirective = "\t.int8\t";
Data16bitsDirective = "\t.int16\t";
Data32bitsDirective = "\t.int32\t";
Data64bitsDirective = "\t.int64\t";

AlignmentIsInBytes = false;
COMMDirectiveAlignmentIsInBytes = false;
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;

HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;

SupportsDebugInformation = true;

// For now, WebAssembly does not support exceptions.
ExceptionsType = ExceptionHandling::None;

// TODO: UseIntegratedAssembler?
}
32 changes: 32 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===-- WebAssemblyMCAsmInfo.h - WebAssembly asm properties -----*- C++ -*-===//
//
// 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 the declaration of the WebAssemblyMCAsmInfo class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H

#include "llvm/MC/MCAsmInfo.h"

namespace llvm {

class Triple;

class WebAssemblyMCAsmInfo final : public MCAsmInfo {
public:
explicit WebAssemblyMCAsmInfo(const Triple &T);
~WebAssemblyMCAsmInfo() override;
};

} // end namespace llvm

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===-- WebAssemblyMCTargetDesc.cpp - WebAssembly Target Descriptions -----===//
//
// 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 provides WebAssembly-specific target descriptions.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyMCTargetDesc.h"
#include "InstPrinter/WebAssemblyInstPrinter.h"
#include "WebAssemblyMCAsmInfo.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-mc-target-desc"

#define GET_SUBTARGETINFO_MC_DESC
#include "WebAssemblyGenSubtargetInfo.inc"

static MCAsmInfo *createWebAssemblyMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT) {
MCAsmInfo *MAI = new WebAssemblyMCAsmInfo(TT);
return MAI;
}

static MCInstPrinter *
createWebAssemblyMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
if (SyntaxVariant == 0 || SyntaxVariant == 1)
return new WebAssemblyInstPrinter(MAI, MII, MRI);
return nullptr;
}

// Force static initialization.
extern "C" void LLVMInitializeWebAssemblyTargetMC() {
for (Target *T : {&TheWebAssemblyTarget}) {
// Register the MC asm info.
RegisterMCAsmInfoFn X(*T, createWebAssemblyMCAsmInfo);

// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createWebAssemblyMCInstPrinter);
}
}
52 changes: 52 additions & 0 deletions llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//==- WebAssemblyMCTargetDesc.h - WebAssembly Target Descriptions -*- C++ -*-=//
//
// 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 provides WebAssembly-specific target descriptions.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H

#include "llvm/Support/DataTypes.h"
#include <string>

namespace llvm {

class formatted_raw_ostream;
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
class MCObjectWriter;
class MCStreamer;
class MCSubtargetInfo;
class MCTargetStreamer;
class StringRef;
class Target;
class Triple;
class raw_ostream;

extern Target TheWebAssemblyTarget;

MCAsmBackend *createWebAssemblyAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
StringRef TT, StringRef CPU);

} // end namespace llvm

// Defines symbolic names for WebAssembly registers. This defines a mapping from
// register name to register number.
//
#define GET_SUBTARGETINFO_ENUM
#include "WebAssemblyGenSubtargetInfo.inc"

#endif
19 changes: 19 additions & 0 deletions llvm/lib/Target/WebAssembly/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
##===- lib/Target/WebAssembly/Makefile ---------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LEVEL = ../../..
LIBRARYNAME = LLVMWebAssemblyCodeGen
TARGET = WebAssembly

# Make sure that tblgen is run, first thing.
BUILT_SOURCES = WebAssemblyGenSubtargetInfo.inc WebAssemblyGenMCCodeEmitter.inc

DIRS = InstPrinter TargetInfo MCTargetDesc

include $(LEVEL)/Makefile.common
15 changes: 15 additions & 0 deletions llvm/lib/Target/WebAssembly/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===-- README.txt - Notes for WebAssembly code gen -----------------------===//

This WebAssembly backend is presently in a very early stage of development.
The code should build and not break anything else, but don't expect a lot more
at this point.

For more information on WebAssembly itself, see the design documents:
* https://github.com/WebAssembly/design/blob/master/README.md

The following documents contain some information on the planned semantics and
binary encoding of WebAssembly itself:
* https://github.com/WebAssembly/design/blob/master/AstSemantics.md
* https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md

//===---------------------------------------------------------------------===//
7 changes: 7 additions & 0 deletions llvm/lib/Target/WebAssembly/TargetInfo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )

add_llvm_library(LLVMWebAssemblyInfo
WebAssemblyTargetInfo.cpp
)

add_dependencies(LLVMWebAssemblyInfo WebAssemblyCommonTableGen)
23 changes: 23 additions & 0 deletions llvm/lib/Target/WebAssembly/TargetInfo/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
;===- ./lib/Target/WebAssembly/TargetInfo/LLVMBuild.txt --------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[component_0]
type = Library
name = WebAssemblyInfo
parent = WebAssembly
required_libraries = Support
add_to_library_groups = WebAssembly
15 changes: 15 additions & 0 deletions llvm/lib/Target/WebAssembly/TargetInfo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
##===- lib/Target/WebAssembly/TargetInfo/Makefile ----------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMWebAssemblyInfo

# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..

include $(LEVEL)/Makefile.common
29 changes: 29 additions & 0 deletions llvm/lib/Target/WebAssembly/TargetInfo/WebAssemblyTargetInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- WebAssemblyTargetInfo.cpp - WebAssembly Target 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 registers the WebAssembly target.
///
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-target-info"

Target llvm::TheWebAssemblyTarget;

extern "C" void LLVMInitializeWebAssemblyTargetInfo() {
RegisterTarget<Triple::wasm32> X(TheWebAssemblyTarget, "wasm32",
"WebAssembly 32-bit");
RegisterTarget<Triple::wasm64> Y(TheWebAssemblyTarget, "wasm64",
"WebAssembly 64-bit");
}
31 changes: 31 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssembly.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===-- WebAssembly.h - Top-level interface for WebAssembly ----*- C++ -*-===//
//
// 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 the entry points for global functions defined in
/// the LLVM WebAssembly back-end.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLY_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLY_H

#include "llvm/Support/CodeGen.h"

namespace llvm {

class WebAssemblyTargetMachine;
class FunctionPass;

FunctionPass *createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
CodeGenOpt::Level OptLevel);

} // end namespace llvm

#endif
58 changes: 58 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssembly.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//- WebAssembly.td - Describe the WebAssembly Target Machine --*- tablegen -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a target description file for the WebAssembly architecture, which is
// also known as "wasm".
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Target-independent interfaces which we are implementing
//===----------------------------------------------------------------------===//

include "llvm/Target/Target.td"

//===----------------------------------------------------------------------===//
// WebAssembly Subtarget features.
//===----------------------------------------------------------------------===//

def FeatureSIMD : SubtargetFeature<"simd", "HasSIMD", "true",
"Enable SIMD">;

//===----------------------------------------------------------------------===//
// Architectures.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Register File Description
//===----------------------------------------------------------------------===//

include "WebAssemblyRegisterInfo.td"

//===----------------------------------------------------------------------===//
// Instruction Descriptions
//===----------------------------------------------------------------------===//

include "WebAssemblyInstrInfo.td"

def WebAssemblyInstrInfo : InstrInfo;

//===----------------------------------------------------------------------===//
// WebAssembly Processors supported.
//===----------------------------------------------------------------------===//

def : ProcessorModel<"generic", NoSchedModel, [FeatureSIMD]>;

//===----------------------------------------------------------------------===//
// Target Declaration
//===----------------------------------------------------------------------===//

def WebAssembly : Target {
let InstructionSet = WebAssemblyInstrInfo;
}
74 changes: 74 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//===-- WebAssemblyFrameLowering.cpp - WebAssembly Frame Lowering ----------==//
//
// 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 the WebAssembly implementation of
/// TargetFrameLowering class.
///
/// On WebAssembly, there aren't a lot of things to do here. There are no
/// callee-saved registers to save, and no spill slots.
///
/// The stack grows downward.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyFrameLowering.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
using namespace llvm;

#define DEBUG_TYPE "frame-info"

// TODO: Implement a red zone?

/// 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");
}

/// Under normal circumstances, when a frame pointer is not required, we reserve
/// argument space for call sites in the function immediately on entry to the
/// current function. This eliminates the need for add/sub sp brackets around
/// call sites. Returns true if the call frame is included as part of the stack
/// frame.
bool WebAssemblyFrameLowering::hasReservedCallFrame(
const MachineFunction &MF) const {
return !MF.getFrameInfo()->hasVarSizedObjects();
}

void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
llvm_unreachable("TODO: implement eliminateCallFramePseudoInstr");
}

void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
llvm_unreachable("TODO: implement emitPrologue");
}

void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
llvm_unreachable("TODO: implement emitEpilogue");
}

void WebAssemblyFrameLowering::processFunctionBeforeCalleeSavedScan(
MachineFunction &MF, RegScavenger *RS) const {
llvm_unreachable("TODO: implement processFunctionBeforeCalleeSavedScan");
}
48 changes: 48 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// WebAssemblyFrameLowering.h - TargetFrameLowering for WebAssembly -*- C++ -*-/
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This class implements WebAssembly-specific bits of
/// TargetFrameLowering class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYFRAMELOWERING_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYFRAMELOWERING_H

#include "llvm/Target/TargetFrameLowering.h"

namespace llvm {

class WebAssemblyFrameLowering final : public TargetFrameLowering {
public:
WebAssemblyFrameLowering()
: TargetFrameLowering(StackGrowsDown, /*StackAlignment=*/16,
/*LocalAreaOffset=*/0,
/*TransientStackAlignment=*/16,
/*StackRealignable=*/true) {}

void
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;

/// These methods insert prolog and epilog code into the function.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;

bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;

void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const override;
};

} // end namespace llvm

#endif
73 changes: 73 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//- WebAssemblyISelDAGToDAG.cpp - A dag to dag inst selector for WebAssembly -//
//
// 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 an instruction selector for the WebAssembly target.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Function.h" // To access function attributes.
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-isel"

//===--------------------------------------------------------------------===//
/// WebAssembly-specific code to select WebAssembly machine instructions for
/// SelectionDAG operations.
///
namespace {
class WebAssemblyDAGToDAGISel final : public SelectionDAGISel {
/// 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 ForCodeSize;

public:
WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &tm,
CodeGenOpt::Level OptLevel)
: SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), ForCodeSize(false) {
}

const char *getPassName() const override {
return "WebAssembly Instruction Selection";
}

bool runOnMachineFunction(MachineFunction &MF) override {
ForCodeSize =
MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize) ||
MF.getFunction()->hasFnAttribute(Attribute::MinSize);
Subtarget = &MF.getSubtarget<WebAssemblySubtarget>();
return SelectionDAGISel::runOnMachineFunction(MF);
}

SDNode *Select(SDNode *Node) override;

private:
// add select functions here...
};
} // end anonymous namespace

SDNode *WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
llvm_unreachable("TODO: implement Select");
}

/// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready
/// for instruction scheduling.
FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
CodeGenOpt::Level OptLevel) {
return new WebAssemblyDAGToDAGISel(TM, OptLevel);
}
59 changes: 59 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//=- WebAssemblyISelLowering.cpp - WebAssembly DAG Lowering 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 implements the WebAssemblyTargetLowering class.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyISelLowering.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyTargetObjectFile.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-lower"

WebAssemblyTargetLowering::WebAssemblyTargetLowering(
const TargetMachine &TM, const WebAssemblySubtarget &STI)
: TargetLowering(TM), Subtarget(&STI) {}

//===----------------------------------------------------------------------===//
// WebAssembly Lowering private implementation.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Lowering Code
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Other Lowering Code
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly Optimization Hooks
//===----------------------------------------------------------------------===//

MCSection *WebAssemblyTargetObjectFile::SelectSectionForGlobal(
const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
const TargetMachine &TM) const {
return getDataSection();
}
49 changes: 49 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//- WebAssemblyISelLowering.h - WebAssembly DAG Lowering Interface -*- C++ -*-//
//
// 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 interfaces that WebAssembly uses to lower LLVM
/// code into a selection DAG.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H

#include "llvm/Target/TargetLowering.h"

namespace llvm {

namespace WebAssemblyISD {

enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END,

// add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...
};

} // end namespace WebAssemblyISD

class WebAssemblySubtarget;
class WebAssemblyTargetMachine;

class WebAssemblyTargetLowering final : public TargetLowering {
public:
WebAssemblyTargetLowering(const TargetMachine &TM,
const WebAssemblySubtarget &STI);

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;
};

} // end namespace llvm

#endif
44 changes: 44 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// WebAssemblyInstrAtomics.td-WebAssembly Atomic codegen support-*- tablegen -*-
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// WebAssembly Atomic operand code-gen constructs.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Atomic fences
//===----------------------------------------------------------------------===//

// TODO: add atomic fences here...

//===----------------------------------------------------------------------===//
// Atomic loads
//===----------------------------------------------------------------------===//

// TODO: add atomic loads here...

//===----------------------------------------------------------------------===//
// Atomic stores
//===----------------------------------------------------------------------===//

// TODO: add atomic stores here...

//===----------------------------------------------------------------------===//
// Low-level exclusive operations
//===----------------------------------------------------------------------===//

// TODO: add exclusive operations here...

// Load-exclusives.

// Store-exclusives.

// Store-release-exclusives.

// And clear exclusive.
28 changes: 28 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// WebAssemblyInstrFormats.td - WebAssembly Instruction Formats -*- tblgen -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// WebAssembly instruction format definitions.
//
//===----------------------------------------------------------------------===//

// WebAssembly Instruction Format
class WebAssemblyInst<string cstr> : Instruction {
field bits<0> Inst; // Instruction encoding.
let Namespace = "WebAssembly";
let Pattern = [];
let Constraints = cstr;
}

// Normal instructions
class I<dag oops, dag iops, list<dag> pattern, string cstr = "">
: WebAssemblyInst<cstr> {
dag OutOperandList = oops;
dag InOperandList = iops;
let Pattern = pattern;
}
28 changes: 28 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===//
//
// 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 the WebAssembly implementation of the
/// TargetInstrInfo class.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyInstrInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-instr-info"

WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
: RI(STI.getTargetTriple()) {}
37 changes: 37 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//=- WebAssemblyInstrInfo.h - WebAssembly Instruction Information -*- C++ -*-=//
//
// 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 the WebAssembly implementation of the
/// TargetInstrInfo class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H

#include "WebAssemblyRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"

namespace llvm {

class WebAssemblySubtarget;

class WebAssemblyInstrInfo final {
const WebAssemblyRegisterInfo RI;

public:
explicit WebAssemblyInstrInfo(const WebAssemblySubtarget &STI);

const WebAssemblyRegisterInfo &getRegisterInfo() const { return RI; }
};

} // end namespace llvm

#endif
41 changes: 41 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// WebAssemblyInstrInfo.td-Describe the WebAssembly Instructions-*- tablegen -*-
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// WebAssembly Instruction definitions.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly Instruction Predicate Definitions.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Node Types.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Nodes.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly-specific Operands.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly Instruction Format Definitions.
//===----------------------------------------------------------------------===//

include "WebAssemblyInstrFormats.td"

//===----------------------------------------------------------------------===//
// Additional sets of instructions.
//===----------------------------------------------------------------------===//

include "WebAssemblyInstrAtomics.td"
include "WebAssemblyInstrSIMD.td"
15 changes: 15 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// WebAssemblyInstrSIMD.td - WebAssembly SIMD codegen support -*- tablegen -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// WebAssembly SIMD operand code-gen constructs.
//
//===----------------------------------------------------------------------===//

// TODO: Implement SIMD instructions.
// Note: use Requires<[HasSIMD]>.
19 changes: 19 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
//
// 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 implements WebAssembly-specific per-machine-function
/// information.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyMachineFunctionInfo.h"
using namespace llvm;

WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() {}
37 changes: 37 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// WebAssemblyMachineFuctionInfo.h-WebAssembly machine function info -*- C++ -*-
//
// 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 declares WebAssembly-specific per-machine-function
/// information.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H

#include "WebAssemblyRegisterInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"

namespace llvm {

/// This class is derived from MachineFunctionInfo and contains private
/// WebAssembly-specific information for each MachineFunction.
class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
MachineFunction &MF;

public:
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
~WebAssemblyFunctionInfo() override;
};

} // end namespace llvm

#endif
33 changes: 33 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===-- WebAssemblyRegisterInfo.cpp - WebAssembly Register Information ----===//
//
// 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 the WebAssembly implementation of the
/// TargetRegisterInfo class.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyRegisterInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyFrameLowering.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-reg-info"

WebAssemblyRegisterInfo::WebAssemblyRegisterInfo(const Triple &TT) : TT(TT) {}
35 changes: 35 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// WebAssemblyRegisterInfo.h - WebAssembly Register Information Impl -*- C++ -*-
//
// 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 the WebAssembly implementation of the
/// WebAssemblyRegisterInfo class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYREGISTERINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYREGISTERINFO_H

namespace llvm {

class MachineFunction;
class RegScavenger;
class TargetRegisterClass;
class Triple;

class WebAssemblyRegisterInfo final {
const Triple &TT;

public:
explicit WebAssemblyRegisterInfo(const Triple &TT);
};

} // end namespace llvm

#endif
28 changes: 28 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//WebAssemblyRegisterInfo.td-Describe the WebAssembly Registers -*- tablegen -*-
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the WebAssembly register classes and some nominal
// physical registers.
//
//===----------------------------------------------------------------------===//

class WebAssemblyReg<string n> : Register<n> {
let Namespace = "WebAssembly";
}

class WebAssemblyRegClass<list<ValueType> regTypes, int alignment, dag regList>
: RegisterClass<"WebAssembly", regTypes, alignment, regList>;

//===----------------------------------------------------------------------===//
// Registers
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Register classes
//===----------------------------------------------------------------------===//
23 changes: 23 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- WebAssemblySelectionDAGInfo.cpp - WebAssembly SelectionDAG Info ---===//
//
// 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 implements the WebAssemblySelectionDAGInfo class.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyTargetMachine.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-selectiondag-info"

WebAssemblySelectionDAGInfo::WebAssemblySelectionDAGInfo(const DataLayout *DL)
: TargetSelectionDAGInfo(DL) {}

WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() {}
31 changes: 31 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//=- WebAssemblySelectionDAGInfo.h - WebAssembly SelectionDAG Info -*- C++ -*-//
//
// 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 subclass for
/// TargetSelectionDAGInfo.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSELECTIONDAGINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSELECTIONDAGINFO_H

#include "llvm/Target/TargetSelectionDAGInfo.h"

namespace llvm {

class WebAssemblySelectionDAGInfo final : public TargetSelectionDAGInfo {
public:
explicit WebAssemblySelectionDAGInfo(const DataLayout *DL);
~WebAssemblySelectionDAGInfo() override;
};

} // end namespace llvm

#endif
48 changes: 48 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//===-- WebAssemblySubtarget.cpp - WebAssembly Subtarget Information ------===//
//
// 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 implements the WebAssembly-specific subclass of
/// TargetSubtarget.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyInstrInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblySubtarget.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;

#define DEBUG_TYPE "subtarget"

#define GET_SUBTARGETINFO_CTOR
#define GET_SUBTARGETINFO_TARGET_DESC
#include "WebAssemblyGenSubtargetInfo.inc"

WebAssemblySubtarget &
WebAssemblySubtarget::initializeSubtargetDependencies(StringRef FS) {
// Determine default and user-specified characteristics

if (CPUString.empty())
CPUString = "generic";

ParseSubtargetFeatures(CPUString, FS);
return *this;
}

WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT,
const std::string &CPU,
const std::string &FS,
const TargetMachine &TM)
: WebAssemblyGenSubtargetInfo(TT, CPU, FS), HasSIMD(true), CPUString(CPU),
TargetTriple(TT), FrameLowering(),
InstrInfo(initializeSubtargetDependencies(FS)),
TSInfo(TM.getDataLayout()), TLInfo(TM, *this) {}

bool WebAssemblySubtarget::enableMachineScheduler() const { return true; }
78 changes: 78 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//=- WebAssemblySubtarget.h - Define Subtarget for the WebAssembly -*- C++ -*-//
//
// 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 declares the WebAssembly-specific subclass of
/// TargetSubtarget.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSUBTARGET_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSUBTARGET_H

#include "WebAssemblyFrameLowering.h"
#include "WebAssemblyISelLowering.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblySelectionDAGInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>

#define GET_SUBTARGETINFO_HEADER
#include "WebAssemblyGenSubtargetInfo.inc"

namespace llvm {

class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo {
bool HasSIMD;

/// String name of used CPU.
std::string CPUString;

/// What processor and OS we're targeting.
Triple TargetTriple;

WebAssemblyFrameLowering FrameLowering;
WebAssemblyInstrInfo InstrInfo;
WebAssemblySelectionDAGInfo TSInfo;
WebAssemblyTargetLowering TLInfo;

/// Initializes using CPUString and the passed in feature string so that we
/// can use initializer lists for subtarget initialization.
WebAssemblySubtarget &initializeSubtargetDependencies(StringRef FS);

public:
/// This constructor initializes the data members to match that
/// of the specified triple.
WebAssemblySubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const TargetMachine &TM);

const WebAssemblySelectionDAGInfo *getSelectionDAGInfo() const override {
return &TSInfo;
}
const WebAssemblyFrameLowering *getFrameLowering() const override {
return &FrameLowering;
}
const WebAssemblyTargetLowering *getTargetLowering() const override {
return &TLInfo;
}
const Triple &getTargetTriple() const { return TargetTriple; }
bool enableMachineScheduler() const override;
bool useAA() const override { return true; }

// Predicates used by WebAssemblyInstrInfo.td.
bool hasSIMD() const { return HasSIMD; }

/// Parses features string setting specified subtarget options. Definition of
/// function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
};

} // end namespace llvm

#endif
166 changes: 166 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//===- WebAssemblyTargetMachine.cpp - Define TargetMachine for WebAssembly -==//
//
// 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 subclass of TargetMachine.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyTargetObjectFile.h"
#include "WebAssemblyTargetTransformInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

#define DEBUG_TYPE "wasm"

extern "C" void LLVMInitializeWebAssemblyTarget() {
// Register the target.
RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget);
}

//===----------------------------------------------------------------------===//
// WebAssembly Lowering public interface.
//===----------------------------------------------------------------------===//

/// Create an WebAssembly architecture model.
///
WebAssemblyTargetMachine::WebAssemblyTargetMachine(
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT.isArch64Bit()
? "e-p:64:64-i64:64-v128:8:128-n32:64-S128"
: "e-p:32:32-i64:64-v128:8:128-n32:64-S128",
TT, CPU, FS, Options, RM, CM, OL),
TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
initAsmInfo();

// We need a reducible CFG, so disable some optimizations which tend to
// introduce irreducibility.
setRequiresStructuredCFG(true);
}

WebAssemblyTargetMachine::~WebAssemblyTargetMachine() {}

const WebAssemblySubtarget *
WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");

std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
? CPUAttr.getValueAsString().str()
: TargetCPU;
std::string FS = !FSAttr.hasAttribute(Attribute::None)
? FSAttr.getValueAsString().str()
: TargetFS;

auto &I = SubtargetMap[CPU + FS];
if (!I) {
// This needs to be done before we create a new subtarget since any
// creation will depend on the TM and the code generation flags on the
// function that reside in TargetOptions.
resetTargetOptions(F);
I = make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
}
return I.get();
}

namespace {
/// WebAssembly Code Generator Pass Configuration Options.
class WebAssemblyPassConfig final : public TargetPassConfig {
public:
WebAssemblyPassConfig(WebAssemblyTargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}

WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
return getTM<WebAssemblyTargetMachine>();
}

FunctionPass *createTargetRegisterAllocator(bool) override;
void addFastRegAlloc(FunctionPass *RegAllocPass) override;
void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override;

void addIRPasses() override;
bool addPreISel() override;
bool addInstSelector() override;
bool addILPOpts() override;
void addPreRegAlloc() override;
void addRegAllocPasses(bool Optimized);
void addPostRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
};
} // end anonymous namespace

TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
return TargetIRAnalysis([this](Function &F) {
return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
});
}

TargetPassConfig *
WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
return new WebAssemblyPassConfig(this, PM);
}

FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
return nullptr; // No reg alloc
}

void WebAssemblyPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
assert(!RegAllocPass && "WebAssembly uses no regalloc!");
addRegAllocPasses(false);
}

void WebAssemblyPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
assert(!RegAllocPass && "WebAssembly uses no regalloc!");
addRegAllocPasses(true);
}

//===----------------------------------------------------------------------===//
// The following functions are called from lib/CodeGen/Passes.cpp to modify
// the CodeGen pass sequence.
//===----------------------------------------------------------------------===//

void WebAssemblyPassConfig::addIRPasses() {
// Expand some atomic operations. WebAssemblyTargetLowering has hooks which
// control specifically what gets lowered.
addPass(createAtomicExpandPass(&getTM<WebAssemblyTargetMachine>()));

TargetPassConfig::addIRPasses();
}

bool WebAssemblyPassConfig::addPreISel() { return false; }

bool WebAssemblyPassConfig::addInstSelector() {
addPass(
createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
return false;
}

bool WebAssemblyPassConfig::addILPOpts() { return true; }

void WebAssemblyPassConfig::addPreRegAlloc() {}

void WebAssemblyPassConfig::addRegAllocPasses(bool Optimized) {}

void WebAssemblyPassConfig::addPostRegAlloc() {}

void WebAssemblyPassConfig::addPreSched2() {}

void WebAssemblyPassConfig::addPreEmitPass() {}
51 changes: 51 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// WebAssemblyTargetMachine.h - Define TargetMachine for WebAssembly -*- C++ -*-
//
// 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 declares the WebAssembly-specific subclass of
/// TargetMachine.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETMACHINE_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETMACHINE_H

#include "WebAssemblySubtarget.h"
#include "llvm/Target/TargetMachine.h"

namespace llvm {

class WebAssemblyTargetMachine final : public LLVMTargetMachine {
std::unique_ptr<TargetLoweringObjectFile> TLOF;
mutable StringMap<std::unique_ptr<WebAssemblySubtarget>> SubtargetMap;

public:
WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);

~WebAssemblyTargetMachine() override;
const WebAssemblySubtarget *
getSubtargetImpl(const Function &F) const override;

// Pass Pipeline Configuration
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;

TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}

/// \brief Get the TargetIRAnalysis for this target.
TargetIRAnalysis getTargetIRAnalysis() override;
};

} // end namespace llvm

#endif
67 changes: 67 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetObjectFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//===-- WebAssemblyTargetObjectFile.h - WebAssembly Object Info -*- C++ -*-===//
//
// 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 declares the WebAssembly-specific subclass of
/// TargetLoweringObjectFile.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETOBJECTFILE_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETOBJECTFILE_H

#include "llvm/Target/TargetLoweringObjectFile.h"

namespace llvm {

class GlobalVariable;

class WebAssemblyTargetObjectFile final : public TargetLoweringObjectFile {
public:
WebAssemblyTargetObjectFile() {
TextSection = nullptr;
DataSection = nullptr;
BSSSection = nullptr;
ReadOnlySection = nullptr;

StaticCtorSection = nullptr;
StaticDtorSection = nullptr;
LSDASection = nullptr;
EHFrameSection = nullptr;
DwarfAbbrevSection = nullptr;
DwarfInfoSection = nullptr;
DwarfLineSection = nullptr;
DwarfFrameSection = nullptr;
DwarfPubTypesSection = nullptr;
DwarfDebugInlineSection = nullptr;
DwarfStrSection = nullptr;
DwarfLocSection = nullptr;
DwarfARangesSection = nullptr;
DwarfRangesSection = nullptr;
}

MCSection *getSectionForConstant(SectionKind Kind,
const Constant *C) const override {
return ReadOnlySection;
}

MCSection *getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler &Mang,
const TargetMachine &TM) const override {
return DataSection;
}

MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler &Mang,
const TargetMachine &TM) const override;
};

} // end namespace llvm

#endif
28 changes: 28 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- WebAssemblyTargetTransformInfo.cpp - WebAssembly-specific TTI -----===//
//
// 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 TargetTransformInfo
/// implementation.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyTargetTransformInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/CostTable.h"
using namespace llvm;

#define DEBUG_TYPE "wasmtti"

TargetTransformInfo::PopcntSupportKind
WebAssemblyTTIImpl::getPopcntSupport(unsigned TyWidth) {
assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
// TODO: Make Math.popcount32 happen in WebAssembly.
return TTI::PSK_Software;
}
87 changes: 87 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//==- WebAssemblyTargetTransformInfo.h - WebAssembly-specific TTI -*- C++ -*-=//
//
// 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 a TargetTransformInfo::Concept conforming object specific
/// to the WebAssembly target machine.
///
/// It uses the target's detailed information to provide more precise answers to
/// certain TTI queries, while letting the target independent and default TTI
/// implementations handle the rest.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETTRANSFORMINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYTARGETTRANSFORMINFO_H

#include "WebAssemblyTargetMachine.h"
#include "llvm/CodeGen/BasicTTIImpl.h"
#include <algorithm>

namespace llvm {

class WebAssemblyTTIImpl final : public BasicTTIImplBase<WebAssemblyTTIImpl> {
typedef BasicTTIImplBase<WebAssemblyTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
friend BaseT;

const WebAssemblyTargetMachine *TM;
const WebAssemblySubtarget *ST;
const WebAssemblyTargetLowering *TLI;

const WebAssemblySubtarget *getST() const { return ST; }
const WebAssemblyTargetLowering *getTLI() const { return TLI; }

public:
WebAssemblyTTIImpl(const WebAssemblyTargetMachine *TM, Function &F)
: BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
TLI(ST->getTargetLowering()) {}

// Provide value semantics. MSVC requires that we spell all of these out.
WebAssemblyTTIImpl(const WebAssemblyTTIImpl &Arg)
: BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
TLI(Arg.TLI) {}
WebAssemblyTTIImpl(WebAssemblyTTIImpl &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
WebAssemblyTTIImpl &operator=(const WebAssemblyTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
TM = RHS.TM;
ST = RHS.ST;
TLI = RHS.TLI;
return *this;
}
WebAssemblyTTIImpl &operator=(WebAssemblyTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
TLI = std::move(RHS.TLI);
return *this;
}

/// \name Scalar TTI Implementations
/// @{

// TODO: Implement more Scalar TTI for WebAssembly

TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);

/// @}

/// \name Vector TTI Implementations
/// @{

// TODO: Implement Vector TTI for WebAssembly

/// @}
};

} // end namespace llvm

#endif
30 changes: 30 additions & 0 deletions llvm/unittests/ADT/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::CloudABI, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());

T = Triple("wasm32-unknown-wasm");
EXPECT_EQ(Triple::wasm32, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::WebAssembly, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());

T = Triple("wasm64-unknown-wasm");
EXPECT_EQ(Triple::wasm64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::WebAssembly, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());

T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
}
Expand Down Expand Up @@ -439,6 +451,16 @@ TEST(TripleTest, BitWidthPredicates) {
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());

T.setArch(Triple::wasm32);
EXPECT_FALSE(T.isArch16Bit());
EXPECT_TRUE(T.isArch32Bit());
EXPECT_FALSE(T.isArch64Bit());

T.setArch(Triple::wasm64);
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
}

TEST(TripleTest, BitWidthArchVariants) {
Expand Down Expand Up @@ -521,6 +543,14 @@ TEST(TripleTest, BitWidthArchVariants) {
T.setArch(Triple::spir64);
EXPECT_EQ(Triple::spir, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::spir64, T.get64BitArchVariant().getArch());

T.setArch(Triple::wasm32);
EXPECT_EQ(Triple::wasm32, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::wasm64, T.get64BitArchVariant().getArch());

T.setArch(Triple::wasm64);
EXPECT_EQ(Triple::wasm32, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::wasm64, T.get64BitArchVariant().getArch());
}

TEST(TripleTest, getOSVersion) {
Expand Down