llvm-6502/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
JF Bastien b18e7bdac8 WebAssembly: basic bitcode → assembly CodeGen test
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
2015-07-22 21:28:15 +00:00

110 lines
3.3 KiB
C++

//- 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;
// Include the pieces autogenerated from the target description.
#include "WebAssemblyGenDAGISel.inc"
private:
// add select functions here...
};
} // end anonymous namespace
SDNode *WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
// 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
/// for instruction scheduling.
FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
CodeGenOpt::Level OptLevel) {
return new WebAssemblyDAGToDAGISel(TM, OptLevel);
}