| Nick Lewycky | c3890d2 | 2015-07-29 22:32:47 +0000 | [diff] [blame] | 1 | // WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*- | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | /// | 
|  | 9 | /// \file | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 10 | /// This file declares WebAssembly-specific per-machine-function | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 11 | /// information. | 
|  | 12 | /// | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
|  | 15 | #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H | 
|  | 16 | #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H | 
|  | 17 |  | 
| Derek Schuff | 9769deb | 2015-12-11 23:49:46 +0000 | [diff] [blame] | 18 | #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 19 | #include "llvm/BinaryFormat/Wasm.h" | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MIRYamlMapping.h" | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 22 | #include "llvm/MC/MCSymbolWasm.h" | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 23 |  | 
|  | 24 | namespace llvm { | 
|  | 25 |  | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 26 | namespace yaml { | 
|  | 27 | struct WebAssemblyFunctionInfo; | 
|  | 28 | } | 
|  | 29 |  | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 30 | /// This class is derived from MachineFunctionInfo and contains private | 
|  | 31 | /// WebAssembly-specific information for each MachineFunction. | 
|  | 32 | class WebAssemblyFunctionInfo final : public MachineFunctionInfo { | 
|  | 33 | MachineFunction &MF; | 
|  | 34 |  | 
| Dan Gohman | 754cd11 | 2015-11-11 01:33:02 +0000 | [diff] [blame] | 35 | std::vector<MVT> Params; | 
| Dan Gohman | 2726b88 | 2016-10-06 22:29:32 +0000 | [diff] [blame] | 36 | std::vector<MVT> Results; | 
| Dan Gohman | 3acb187 | 2016-10-24 23:27:49 +0000 | [diff] [blame] | 37 | std::vector<MVT> Locals; | 
| Dan Gohman | e51c058 | 2015-10-06 00:27:55 +0000 | [diff] [blame] | 38 |  | 
| Dan Gohman | cf4748f | 2015-11-12 17:04:33 +0000 | [diff] [blame] | 39 | /// A mapping from CodeGen vreg index to WebAssembly register number. | 
|  | 40 | std::vector<unsigned> WARegs; | 
|  | 41 |  | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 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) | 
| Dan Gohman | 53d1399 | 2015-12-02 18:08:49 +0000 | [diff] [blame] | 47 | ///   - defined and used in LIFO order with other stack registers | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 48 | BitVector VRegStackified; | 
|  | 49 |  | 
| Derek Schuff | 27501e2 | 2016-02-10 19:51:04 +0000 | [diff] [blame] | 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 |  | 
| Derek Schuff | 0d41b7b | 2016-11-07 22:00:48 +0000 | [diff] [blame] | 55 | // A virtual register holding the base pointer for functions that have | 
|  | 56 | // overaligned values on the user stack. | 
|  | 57 | unsigned BasePtrVreg = -1U; | 
|  | 58 |  | 
| Heejin Ahn | 1aaa481 | 2019-03-26 17:46:14 +0000 | [diff] [blame] | 59 | // Function properties. | 
|  | 60 | bool CFGStackified = false; | 
|  | 61 |  | 
| Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 62 | public: | 
| Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 63 | explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {} | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 64 | ~WebAssemblyFunctionInfo() override; | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 65 | void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI); | 
| Dan Gohman | e51c058 | 2015-10-06 00:27:55 +0000 | [diff] [blame] | 66 |  | 
| Dan Gohman | 754cd11 | 2015-11-11 01:33:02 +0000 | [diff] [blame] | 67 | void addParam(MVT VT) { Params.push_back(VT); } | 
|  | 68 | const std::vector<MVT> &getParams() const { return Params; } | 
|  | 69 |  | 
| Dan Gohman | 2726b88 | 2016-10-06 22:29:32 +0000 | [diff] [blame] | 70 | void addResult(MVT VT) { Results.push_back(VT); } | 
|  | 71 | const std::vector<MVT> &getResults() const { return Results; } | 
|  | 72 |  | 
| Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 73 | void clearParamsAndResults() { | 
|  | 74 | Params.clear(); | 
|  | 75 | Results.clear(); | 
|  | 76 | } | 
| Dan Gohman | b818482 | 2018-05-22 04:58:36 +0000 | [diff] [blame] | 77 |  | 
| Dan Gohman | d934cb8 | 2017-02-24 23:18:00 +0000 | [diff] [blame] | 78 | void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } | 
|  | 79 | void setLocal(size_t i, MVT VT) { Locals[i] = VT; } | 
| Dan Gohman | 3acb187 | 2016-10-24 23:27:49 +0000 | [diff] [blame] | 80 | void addLocal(MVT VT) { Locals.push_back(VT); } | 
|  | 81 | const std::vector<MVT> &getLocals() const { return Locals; } | 
|  | 82 |  | 
| Derek Schuff | 27501e2 | 2016-02-10 19:51:04 +0000 | [diff] [blame] | 83 | unsigned getVarargBufferVreg() const { | 
|  | 84 | assert(VarargVreg != -1U && "Vararg vreg hasn't been set"); | 
|  | 85 | return VarargVreg; | 
|  | 86 | } | 
|  | 87 | void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; } | 
|  | 88 |  | 
| Derek Schuff | 0d41b7b | 2016-11-07 22:00:48 +0000 | [diff] [blame] | 89 | unsigned getBasePointerVreg() const { | 
|  | 90 | assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set"); | 
|  | 91 | return BasePtrVreg; | 
|  | 92 | } | 
|  | 93 | void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; } | 
|  | 94 |  | 
| Dan Gohman | 058fce5 | 2015-11-13 00:21:05 +0000 | [diff] [blame] | 95 | static const unsigned UnusedReg = -1u; | 
|  | 96 |  | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 97 | void stackifyVReg(unsigned VReg) { | 
| Dan Gohman | 4fc4e42 | 2016-10-24 19:49:43 +0000 | [diff] [blame] | 98 | assert(MF.getRegInfo().getUniqueVRegDef(VReg)); | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 99 | auto I = Register::virtReg2Index(VReg); | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 100 | if (I >= VRegStackified.size()) | 
|  | 101 | VRegStackified.resize(I + 1); | 
|  | 102 | VRegStackified.set(I); | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 103 | } | 
| Heejin Ahn | 61d5c76 | 2019-10-01 06:21:53 +0000 | [diff] [blame] | 104 | void unstackifyVReg(unsigned VReg) { | 
|  | 105 | auto I = Register::virtReg2Index(VReg); | 
|  | 106 | if (I < VRegStackified.size()) | 
|  | 107 | VRegStackified.reset(I); | 
|  | 108 | } | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 109 | bool isVRegStackified(unsigned VReg) const { | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 110 | auto I = Register::virtReg2Index(VReg); | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 111 | if (I >= VRegStackified.size()) | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 112 | return false; | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 113 | return VRegStackified.test(I); | 
| Dan Gohman | 1462faa | 2015-11-16 16:18:28 +0000 | [diff] [blame] | 114 | } | 
|  | 115 |  | 
| Dan Gohman | 058fce5 | 2015-11-13 00:21:05 +0000 | [diff] [blame] | 116 | void initWARegs(); | 
| Dan Gohman | cf4748f | 2015-11-12 17:04:33 +0000 | [diff] [blame] | 117 | void setWAReg(unsigned VReg, unsigned WAReg) { | 
| Dan Gohman | 058fce5 | 2015-11-13 00:21:05 +0000 | [diff] [blame] | 118 | assert(WAReg != UnusedReg); | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 119 | auto I = Register::virtReg2Index(VReg); | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 120 | assert(I < WARegs.size()); | 
|  | 121 | WARegs[I] = WAReg; | 
| Dan Gohman | cf4748f | 2015-11-12 17:04:33 +0000 | [diff] [blame] | 122 | } | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 123 | unsigned getWAReg(unsigned VReg) const { | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 124 | auto I = Register::virtReg2Index(VReg); | 
| Wouter van Oortmerssen | 78c6296 | 2018-06-18 20:45:49 +0000 | [diff] [blame] | 125 | assert(I < WARegs.size()); | 
|  | 126 | return WARegs[I]; | 
| Dan Gohman | cf4748f | 2015-11-12 17:04:33 +0000 | [diff] [blame] | 127 | } | 
| Dan Gohman | b7c2400 | 2016-05-21 00:21:56 +0000 | [diff] [blame] | 128 |  | 
|  | 129 | // For a given stackified WAReg, return the id number to print with push/pop. | 
|  | 130 | static unsigned getWARegStackId(unsigned Reg) { | 
|  | 131 | assert(Reg & INT32_MIN); | 
|  | 132 | return Reg & INT32_MAX; | 
|  | 133 | } | 
| Heejin Ahn | 1aaa481 | 2019-03-26 17:46:14 +0000 | [diff] [blame] | 134 |  | 
|  | 135 | bool isCFGStackified() const { return CFGStackified; } | 
|  | 136 | void setCFGStackified(bool Value = true) { CFGStackified = Value; } | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 137 | }; | 
|  | 138 |  | 
| Heejin Ahn | 18c56a0 | 2019-02-04 19:13:39 +0000 | [diff] [blame] | 139 | void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, | 
| Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 140 | SmallVectorImpl<MVT> &ValueVTs); | 
| Dan Gohman | 2726b88 | 2016-10-06 22:29:32 +0000 | [diff] [blame] | 141 |  | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 142 | // Compute the signature for a given FunctionType (Ty). Note that it's not the | 
|  | 143 | // signature for F (F is just used to get varous context) | 
| Heejin Ahn | 18c56a0 | 2019-02-04 19:13:39 +0000 | [diff] [blame] | 144 | void computeSignatureVTs(const FunctionType *Ty, const Function &F, | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 145 | const TargetMachine &TM, SmallVectorImpl<MVT> &Params, | 
| Dan Gohman | 2726b88 | 2016-10-06 22:29:32 +0000 | [diff] [blame] | 146 | SmallVectorImpl<MVT> &Results); | 
|  | 147 |  | 
| Heejin Ahn | 18c56a0 | 2019-02-04 19:13:39 +0000 | [diff] [blame] | 148 | void valTypesFromMVTs(const ArrayRef<MVT> &In, | 
| Wouter van Oortmerssen | 49482f8 | 2018-11-19 17:10:36 +0000 | [diff] [blame] | 149 | SmallVectorImpl<wasm::ValType> &Out); | 
|  | 150 |  | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 151 | std::unique_ptr<wasm::WasmSignature> | 
| Heejin Ahn | 18c56a0 | 2019-02-04 19:13:39 +0000 | [diff] [blame] | 152 | signatureFromMVTs(const SmallVectorImpl<MVT> &Results, | 
| Derek Schuff | 77a7a38 | 2018-10-03 22:22:48 +0000 | [diff] [blame] | 153 | const SmallVectorImpl<MVT> &Params); | 
|  | 154 |  | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 155 | namespace yaml { | 
|  | 156 |  | 
|  | 157 | struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { | 
| Heejin Ahn | 1aaa481 | 2019-03-26 17:46:14 +0000 | [diff] [blame] | 158 | bool CFGStackified = false; | 
|  | 159 |  | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 160 | WebAssemblyFunctionInfo() = default; | 
|  | 161 | WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI); | 
|  | 162 |  | 
|  | 163 | void mappingImpl(yaml::IO &YamlIO) override; | 
|  | 164 | ~WebAssemblyFunctionInfo() = default; | 
|  | 165 | }; | 
|  | 166 |  | 
|  | 167 | template <> struct MappingTraits<WebAssemblyFunctionInfo> { | 
| Heejin Ahn | 1aaa481 | 2019-03-26 17:46:14 +0000 | [diff] [blame] | 168 | static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { | 
|  | 169 | YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); | 
|  | 170 | } | 
| Heejin Ahn | 52221d5 | 2019-03-26 17:35:35 +0000 | [diff] [blame] | 171 | }; | 
|  | 172 |  | 
|  | 173 | } // end namespace yaml | 
|  | 174 |  | 
| Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 175 | } // end namespace llvm | 
|  | 176 |  | 
|  | 177 | #endif |