WebAssemblyISelDAGToDAG.cpp revision 321369
1250746Sgabor//- WebAssemblyISelDAGToDAG.cpp - A dag to dag inst selector for WebAssembly -// 2257801Sgabor// 3257801Sgabor// The LLVM Compiler Infrastructure 4250746Sgabor// 5166768Sbmah// This file is distributed under the University of Illinois Open Source 6250746Sgabor// License. See LICENSE.TXT for details. 7166768Sbmah// 8166768Sbmah//===----------------------------------------------------------------------===// 9257801Sgabor/// 10257801Sgabor/// \file 11257801Sgabor/// \brief This file defines an instruction selector for the WebAssembly target. 12166768Sbmah/// 13257801Sgabor//===----------------------------------------------------------------------===// 14166768Sbmah 15183626Ssimon#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 16166768Sbmah#include "WebAssembly.h" 17183626Ssimon#include "WebAssemblyTargetMachine.h" 18183626Ssimon#include "llvm/CodeGen/SelectionDAGISel.h" 19183626Ssimon#include "llvm/IR/Function.h" // To access function attributes. 20183626Ssimon#include "llvm/Support/Debug.h" 21183626Ssimon#include "llvm/Support/KnownBits.h" 22183626Ssimon#include "llvm/Support/MathExtras.h" 23183626Ssimon#include "llvm/Support/raw_ostream.h" 24183626Ssimonusing namespace llvm; 25183626Ssimon 26183626Ssimon#define DEBUG_TYPE "wasm-isel" 27191511Sblackend 28227742Sbrueffer//===--------------------------------------------------------------------===// 29227742Sbrueffer/// WebAssembly-specific code to select WebAssembly machine instructions for 30229977Sbrueffer/// SelectionDAG operations. 31248857Sgjb/// 32265242Sbrueffernamespace { 33316224Sngieclass WebAssemblyDAGToDAGISel final : public SelectionDAGISel { 34316224Sngie /// Keep a pointer to the WebAssemblySubtarget around so that we can make the 35316224Sngie /// right decision when generating code for different targets. 36183626Ssimon const WebAssemblySubtarget *Subtarget; 37183626Ssimon 38166771Sbmah bool ForCodeSize; 39257801Sgabor 40183626Ssimonpublic: 41183626Ssimon WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &tm, 42208459Smarius CodeGenOpt::Level OptLevel) 43183626Ssimon : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), ForCodeSize(false) { 44183626Ssimon } 45183626Ssimon 46183626Ssimon StringRef getPassName() const override { 47183626Ssimon return "WebAssembly Instruction Selection"; 48183626Ssimon } 49172094Sbmah 50257801Sgabor bool runOnMachineFunction(MachineFunction &MF) override { 51172094Sbmah ForCodeSize = 52257801Sgabor MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize) || 53183626Ssimon MF.getFunction()->hasFnAttribute(Attribute::MinSize); 54166768Sbmah Subtarget = &MF.getSubtarget<WebAssemblySubtarget>(); 55183626Ssimon return SelectionDAGISel::runOnMachineFunction(MF); 56183626Ssimon } 57183626Ssimon 58183626Ssimon void Select(SDNode *Node) override; 59183626Ssimon 60183626Ssimon bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 61166768Sbmah std::vector<SDValue> &OutOps) override; 62257801Sgabor 63183626Ssimon// Include the pieces autogenerated from the target description. 64166768Sbmah#include "WebAssemblyGenDAGISel.inc" 65183626Ssimon 66183626Ssimonprivate: 67183626Ssimon // add select functions here... 68166768Sbmah}; 69257801Sgabor} // end anonymous namespace 70183626Ssimon 71166770Sbmahvoid WebAssemblyDAGToDAGISel::Select(SDNode *Node) { 72183626Ssimon // Dump information about the Node being selected. 73183626Ssimon DEBUG(errs() << "Selecting: "); 74183626Ssimon DEBUG(Node->dump(CurDAG)); 75183626Ssimon DEBUG(errs() << "\n"); 76183626Ssimon 77183626Ssimon // If we have a custom node, we already have selected! 78166770Sbmah if (Node->isMachineOpcode()) { 79183626Ssimon DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 80183626Ssimon Node->setNodeId(-1); 81183626Ssimon return; 82273941Sgavin } 83183626Ssimon 84166770Sbmah // Few custom selection stuff. 85183626Ssimon EVT VT = Node->getValueType(0); 86183626Ssimon 87166770Sbmah switch (Node->getOpcode()) { 88183626Ssimon default: 89183626Ssimon break; 90183626Ssimon // If we need WebAssembly-specific selection, it would go here. 91183626Ssimon (void)VT; 92166770Sbmah } 93183626Ssimon 94183626Ssimon // Select the default instruction. 95183626Ssimon SelectCode(Node); 96166770Sbmah} 97183626Ssimon 98273941Sgavinbool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand( 99273941Sgavin const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { 100273941Sgavin switch (ConstraintID) { 101273941Sgavin case InlineAsm::Constraint_i: 102273941Sgavin case InlineAsm::Constraint_m: 103273941Sgavin // We just support simple memory operands that just have a single address 104273941Sgavin // operand and need no special handling. 105273941Sgavin OutOps.push_back(Op); 106273941Sgavin return false; 107273941Sgavin default: 108273941Sgavin break; 109273941Sgavin } 110186204Smurray 111186208Smurray return true; 112183626Ssimon} 113166770Sbmah 114183626Ssimon/// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready 115186204Smurray/// for instruction scheduling. 116186204SmurrayFunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, 117186204Smurray CodeGenOpt::Level OptLevel) { 118186204Smurray return new WebAssemblyDAGToDAGISel(TM, OptLevel); 119183626Ssimon} 120186204Smurray