Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Line
Count
Source (jump to first uncovered line)
1
// WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file declares WebAssembly-specific per-machine-function
11
/// information.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
16
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
17
18
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
19
#include "llvm/CodeGen/MIRYamlMapping.h"
20
#include "llvm/CodeGen/MachineRegisterInfo.h"
21
#include "llvm/MC/MCSymbolWasm.h"
22
23
namespace llvm {
24
class WebAssemblyTargetLowering;
25
26
struct WasmEHFuncInfo;
27
28
namespace yaml {
29
struct WebAssemblyFunctionInfo;
30
}
31
32
/// This class is derived from MachineFunctionInfo and contains private
33
/// WebAssembly-specific information for each MachineFunction.
34
class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
35
  std::vector<MVT> Params;
36
  std::vector<MVT> Results;
37
  std::vector<MVT> Locals;
38
39
  /// A mapping from CodeGen vreg index to WebAssembly register number.
40
  std::vector<unsigned> WARegs;
41
42
  /// A mapping from CodeGen vreg index to a boolean value indicating whether
43
  /// the given register is considered to be "stackified", meaning it has been
44
  /// determined or made to meet the stack requirements:
45
  ///   - single use (per path)
46
  ///   - single def (per path)
47
  ///   - defined and used in LIFO order with other stack registers
48
  BitVector VRegStackified;
49
50
  // A virtual register holding the pointer to the vararg buffer for vararg
51
  // functions. It is created and set in TLI::LowerFormalArguments and read by
52
  // TLI::LowerVASTART
53
  unsigned VarargVreg = -1U;
54
55
  // A virtual register holding the base pointer for functions that have
56
  // overaligned values on the user stack.
57
  unsigned BasePtrVreg = -1U;
58
  // A virtual register holding the frame base. This is either FP or SP
59
  // after it has been replaced by a vreg
60
  unsigned FrameBaseVreg = -1U;
61
  // The local holding the frame base. This is either FP or SP
62
  // after WebAssemblyExplicitLocals
63
  unsigned FrameBaseLocal = -1U;
64
65
  // Function properties.
66
  bool CFGStackified = false;
67
68
public:
69
  explicit WebAssemblyFunctionInfo(const Function &F,
70
6.72k
                                   const TargetSubtargetInfo *STI) {}
71
  ~WebAssemblyFunctionInfo() override;
72
73
  MachineFunctionInfo *
74
  clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
75
        const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
76
      const override;
77
78
  void initializeBaseYamlFields(MachineFunction &MF,
79
                                const yaml::WebAssemblyFunctionInfo &YamlMFI);
80
81
25.2k
  void addParam(MVT VT) { Params.push_back(VT); }
82
52.2k
  const std::vector<MVT> &getParams() const { return Params; }
83
84
3.76k
  void addResult(MVT VT) { Results.push_back(VT); }
85
14.2k
  const std::vector<MVT> &getResults() const { return Results; }
86
87
0
  void clearParamsAndResults() {
88
0
    Params.clear();
89
0
    Results.clear();
90
0
  }
91
92
6.72k
  void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }
93
1.64k
  void setLocal(size_t i, MVT VT) { Locals[i] = VT; }
94
0
  void addLocal(MVT VT) { Locals.push_back(VT); }
95
13.4k
  const std::vector<MVT> &getLocals() const { return Locals; }
96
97
0
  unsigned getVarargBufferVreg() const {
98
0
    assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
99
0
    return VarargVreg;
100
0
  }
101
0
  void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }
102
103
4
  unsigned getBasePointerVreg() const {
104
4
    assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set");
105
0
    return BasePtrVreg;
106
4
  }
107
408
  void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; }
108
26.0k
  unsigned getFrameBaseVreg() const {
109
26.0k
    assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set");
110
0
    return FrameBaseVreg;
111
26.0k
  }
112
245
  void clearFrameBaseVreg() { FrameBaseVreg = -1U; }
113
  // Return true if the frame base physreg has been replaced by a virtual reg.
114
87.3k
  bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; }
115
155
  void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; }
116
3
  unsigned getFrameBaseLocal() const {
117
3
    assert(FrameBaseLocal != -1U && "Frame base local hasn't been set");
118
0
    return FrameBaseLocal;
119
3
  }
120
5
  void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; }
121
122
102k
  void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg) {
123
102k
    assert(MRI.getUniqueVRegDef(VReg));
124
0
    auto I = Register::virtReg2Index(VReg);
125
102k
    if (I >= VRegStackified.size())
126
44.2k
      VRegStackified.resize(I + 1);
127
102k
    VRegStackified.set(I);
128
102k
  }
129
0
  void unstackifyVReg(unsigned VReg) {
130
0
    auto I = Register::virtReg2Index(VReg);
131
0
    if (I < VRegStackified.size())
132
0
      VRegStackified.reset(I);
133
0
  }
134
853k
  bool isVRegStackified(unsigned VReg) const {
135
853k
    auto I = Register::virtReg2Index(VReg);
136
853k
    if (I >= VRegStackified.size())
137
39.6k
      return false;
138
813k
    return VRegStackified.test(I);
139
853k
  }
140
141
  void initWARegs(MachineRegisterInfo &MRI);
142
67.1k
  void setWAReg(unsigned VReg, unsigned WAReg) {
143
67.1k
    assert(WAReg != WebAssembly::UnusedReg);
144
0
    auto I = Register::virtReg2Index(VReg);
145
67.1k
    assert(I < WARegs.size());
146
0
    WARegs[I] = WAReg;
147
67.1k
  }
148
130k
  unsigned getWAReg(unsigned VReg) const {
149
130k
    auto I = Register::virtReg2Index(VReg);
150
130k
    assert(I < WARegs.size());
151
0
    return WARegs[I];
152
130k
  }
153
154
74.4k
  bool isCFGStackified() const { return CFGStackified; }
155
6.72k
  void setCFGStackified(bool Value = true) { CFGStackified = Value; }
156
};
157
158
void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,
159
                          LLVMContext &Ctx, const DataLayout &DL, Type *Ty,
160
                          SmallVectorImpl<MVT> &ValueVTs);
161
162
void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
163
                          SmallVectorImpl<MVT> &ValueVTs);
164
165
// Compute the signature for a given FunctionType (Ty). Note that it's not the
166
// signature for ContextFunc (ContextFunc is just used to get varous context)
167
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc,
168
                         const Function &ContextFunc, const TargetMachine &TM,
169
                         SmallVectorImpl<MVT> &Params,
170
                         SmallVectorImpl<MVT> &Results);
171
172
void valTypesFromMVTs(const ArrayRef<MVT> &In,
173
                      SmallVectorImpl<wasm::ValType> &Out);
174
175
std::unique_ptr<wasm::WasmSignature>
176
signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
177
                  const SmallVectorImpl<MVT> &Params);
178
179
namespace yaml {
180
181
using BBNumberMap = DenseMap<int, int>;
182
183
struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo {
184
  std::vector<FlowStringValue> Params;
185
  std::vector<FlowStringValue> Results;
186
  bool CFGStackified = false;
187
  // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of
188
  // BB numbers
189
  BBNumberMap SrcToUnwindDest;
190
191
0
  WebAssemblyFunctionInfo() = default;
192
  WebAssemblyFunctionInfo(const llvm::MachineFunction &MF,
193
                          const llvm::WebAssemblyFunctionInfo &MFI);
194
195
  void mappingImpl(yaml::IO &YamlIO) override;
196
0
  ~WebAssemblyFunctionInfo() = default;
197
};
198
199
template <> struct MappingTraits<WebAssemblyFunctionInfo> {
200
0
  static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) {
201
0
    YamlIO.mapOptional("params", MFI.Params, std::vector<FlowStringValue>());
202
0
    YamlIO.mapOptional("results", MFI.Results, std::vector<FlowStringValue>());
203
0
    YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false);
204
0
    YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest);
205
0
  }
206
};
207
208
template <> struct CustomMappingTraits<BBNumberMap> {
209
  static void inputOne(IO &YamlIO, StringRef Key,
210
0
                       BBNumberMap &SrcToUnwindDest) {
211
0
    YamlIO.mapRequired(Key.str().c_str(),
212
0
                       SrcToUnwindDest[std::atoi(Key.str().c_str())]);
213
0
  }
214
215
0
  static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) {
216
0
    for (auto KV : SrcToUnwindDest)
217
0
      YamlIO.mapRequired(std::to_string(KV.first).c_str(), KV.second);
218
0
  }
219
};
220
221
} // end namespace yaml
222
223
} // end namespace llvm
224
225
#endif