WebAssemblyISelDAGToDAG.cpp revision 321369
1//- WebAssemblyISelDAGToDAG.cpp - A dag to dag inst selector for WebAssembly -// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief This file defines an instruction selector for the WebAssembly target. 12/// 13//===----------------------------------------------------------------------===// 14 15#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 16#include "WebAssembly.h" 17#include "WebAssemblyTargetMachine.h" 18#include "llvm/CodeGen/SelectionDAGISel.h" 19#include "llvm/IR/Function.h" // To access function attributes. 20#include "llvm/Support/Debug.h" 21#include "llvm/Support/KnownBits.h" 22#include "llvm/Support/MathExtras.h" 23#include "llvm/Support/raw_ostream.h" 24using namespace llvm; 25 26#define DEBUG_TYPE "wasm-isel" 27 28//===--------------------------------------------------------------------===// 29/// WebAssembly-specific code to select WebAssembly machine instructions for 30/// SelectionDAG operations. 31/// 32namespace { 33class WebAssemblyDAGToDAGISel final : public SelectionDAGISel { 34 /// Keep a pointer to the WebAssemblySubtarget around so that we can make the 35 /// right decision when generating code for different targets. 36 const WebAssemblySubtarget *Subtarget; 37 38 bool ForCodeSize; 39 40public: 41 WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &tm, 42 CodeGenOpt::Level OptLevel) 43 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), ForCodeSize(false) { 44 } 45 46 StringRef getPassName() const override { 47 return "WebAssembly Instruction Selection"; 48 } 49 50 bool runOnMachineFunction(MachineFunction &MF) override { 51 ForCodeSize = 52 MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize) || 53 MF.getFunction()->hasFnAttribute(Attribute::MinSize); 54 Subtarget = &MF.getSubtarget<WebAssemblySubtarget>(); 55 return SelectionDAGISel::runOnMachineFunction(MF); 56 } 57 58 void Select(SDNode *Node) override; 59 60 bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 61 std::vector<SDValue> &OutOps) override; 62 63// Include the pieces autogenerated from the target description. 64#include "WebAssemblyGenDAGISel.inc" 65 66private: 67 // add select functions here... 68}; 69} // end anonymous namespace 70 71void WebAssemblyDAGToDAGISel::Select(SDNode *Node) { 72 // Dump information about the Node being selected. 73 DEBUG(errs() << "Selecting: "); 74 DEBUG(Node->dump(CurDAG)); 75 DEBUG(errs() << "\n"); 76 77 // If we have a custom node, we already have selected! 78 if (Node->isMachineOpcode()) { 79 DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 80 Node->setNodeId(-1); 81 return; 82 } 83 84 // Few custom selection stuff. 85 EVT VT = Node->getValueType(0); 86 87 switch (Node->getOpcode()) { 88 default: 89 break; 90 // If we need WebAssembly-specific selection, it would go here. 91 (void)VT; 92 } 93 94 // Select the default instruction. 95 SelectCode(Node); 96} 97 98bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand( 99 const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { 100 switch (ConstraintID) { 101 case InlineAsm::Constraint_i: 102 case InlineAsm::Constraint_m: 103 // We just support simple memory operands that just have a single address 104 // operand and need no special handling. 105 OutOps.push_back(Op); 106 return false; 107 default: 108 break; 109 } 110 111 return true; 112} 113 114/// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready 115/// for instruction scheduling. 116FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, 117 CodeGenOpt::Level OptLevel) { 118 return new WebAssemblyDAGToDAGISel(TM, OptLevel); 119} 120