Line data Source code
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 : /// 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"
24 : using 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 : ///
32 : namespace {
33 : class 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 :
40 : public:
41 : WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &tm,
42 : CodeGenOpt::Level OptLevel)
43 305 : : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), ForCodeSize(false) {
44 : }
45 :
46 0 : StringRef getPassName() const override {
47 0 : return "WebAssembly Instruction Selection";
48 : }
49 :
50 2987 : bool runOnMachineFunction(MachineFunction &MF) override {
51 5974 : ForCodeSize = MF.getFunction().hasFnAttribute(Attribute::OptimizeForSize) ||
52 2987 : MF.getFunction().hasFnAttribute(Attribute::MinSize);
53 2987 : Subtarget = &MF.getSubtarget<WebAssemblySubtarget>();
54 2987 : return SelectionDAGISel::runOnMachineFunction(MF);
55 : }
56 :
57 : void Select(SDNode *Node) override;
58 :
59 : bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
60 : std::vector<SDValue> &OutOps) override;
61 :
62 : // Include the pieces autogenerated from the target description.
63 : #include "WebAssemblyGenDAGISel.inc"
64 :
65 : private:
66 : // add select functions here...
67 : };
68 : } // end anonymous namespace
69 :
70 42605 : void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
71 : // If we have a custom node, we already have selected!
72 42605 : if (Node->isMachineOpcode()) {
73 : LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
74 : Node->setNodeId(-1);
75 2 : return;
76 : }
77 :
78 : // Few custom selection stuff. If we need WebAssembly-specific selection,
79 : // uncomment this block add corresponding case statements.
80 : /*
81 : switch (Node->getOpcode()) {
82 : default:
83 : break;
84 : }
85 : */
86 :
87 : // Select the default instruction.
88 : SelectCode(Node);
89 : }
90 :
91 0 : bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand(
92 : const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
93 0 : switch (ConstraintID) {
94 0 : case InlineAsm::Constraint_i:
95 : case InlineAsm::Constraint_m:
96 : // We just support simple memory operands that just have a single address
97 : // operand and need no special handling.
98 0 : OutOps.push_back(Op);
99 0 : return false;
100 : default:
101 : break;
102 : }
103 :
104 : return true;
105 : }
106 :
107 : /// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready
108 : /// for instruction scheduling.
109 305 : FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
110 : CodeGenOpt::Level OptLevel) {
111 305 : return new WebAssemblyDAGToDAGISel(TM, OptLevel);
112 : }
|