1 //===-- WebAssemblyTypeUtilities - WebAssembly Type Utilities---*- 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 contains the declaration of the WebAssembly-specific type parsing
11 /// utility functions.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYTYPEUTILITIES_H
16 #define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYTYPEUTILITIES_H
17 
18 #include "llvm/BinaryFormat/Wasm.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/MC/MCSymbolWasm.h"
21 #include "llvm/Support/MachineValueType.h"
22 
23 namespace llvm {
24 
25 class TargetRegisterClass;
26 
27 namespace WebAssembly {
28 
29 /// Used as immediate MachineOperands for block signatures
30 enum class BlockType : unsigned {
31   Invalid = 0x00,
32   Void = 0x40,
33   I32 = unsigned(wasm::ValType::I32),
34   I64 = unsigned(wasm::ValType::I64),
35   F32 = unsigned(wasm::ValType::F32),
36   F64 = unsigned(wasm::ValType::F64),
37   V128 = unsigned(wasm::ValType::V128),
38   Externref = unsigned(wasm::ValType::EXTERNREF),
39   Funcref = unsigned(wasm::ValType::FUNCREF),
40   // Multivalue blocks (and other non-void blocks) are only emitted when the
41   // blocks will never be exited and are at the ends of functions (see
42   // WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
43   // to pop values off the stack, so the exact multivalue signature can always
44   // be inferred from the return type of the parent function in MCInstLower.
45   Multivalue = 0xffff,
46 };
47 
48 enum WasmAddressSpace : unsigned {
49   // Default address space, for pointers to linear memory (stack, heap, data).
50   WASM_ADDRESS_SPACE_DEFAULT = 0,
51   // A non-integral address space for pointers to named objects outside of
52   // linear memory: WebAssembly globals or WebAssembly locals.  Loads and stores
53   // to these pointers are lowered to global.get / global.set or local.get /
54   // local.set, as appropriate.
55   WASM_ADDRESS_SPACE_VAR = 1,
56   // A non-integral address space for externref values
57   WASM_ADDRESS_SPACE_EXTERNREF = 10,
58   // A non-integral address space for funcref values
59   WASM_ADDRESS_SPACE_FUNCREF = 20,
60 };
61 
isDefaultAddressSpace(unsigned AS)62 inline bool isDefaultAddressSpace(unsigned AS) {
63   return AS == WASM_ADDRESS_SPACE_DEFAULT;
64 }
isWasmVarAddressSpace(unsigned AS)65 inline bool isWasmVarAddressSpace(unsigned AS) {
66   return AS == WASM_ADDRESS_SPACE_VAR;
67 }
isValidAddressSpace(unsigned AS)68 inline bool isValidAddressSpace(unsigned AS) {
69   return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
70 }
isFuncrefType(const Type * Ty)71 inline bool isFuncrefType(const Type *Ty) {
72   return isa<PointerType>(Ty) &&
73          Ty->getPointerAddressSpace() ==
74              WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
75 }
isExternrefType(const Type * Ty)76 inline bool isExternrefType(const Type *Ty) {
77   return isa<PointerType>(Ty) &&
78          Ty->getPointerAddressSpace() ==
79              WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
80 }
isRefType(const Type * Ty)81 inline bool isRefType(const Type *Ty) {
82   return isFuncrefType(Ty) || isExternrefType(Ty);
83 }
84 
isRefType(wasm::ValType Type)85 inline bool isRefType(wasm::ValType Type) {
86   return Type == wasm::ValType::EXTERNREF || Type == wasm::ValType::FUNCREF;
87 }
88 
89 // Convert StringRef to ValType / HealType / BlockType
90 
91 std::optional<wasm::ValType> parseType(StringRef Type);
92 BlockType parseBlockType(StringRef Type);
93 MVT parseMVT(StringRef Type);
94 
95 // Convert ValType or a list/signature of ValTypes to a string.
96 
97 // Convert an unsinged integer, which can be among wasm::ValType enum, to its
98 // type name string. If the input is not within wasm::ValType, returns
99 // "invalid_type".
100 const char *anyTypeToString(unsigned Type);
101 const char *typeToString(wasm::ValType Type);
102 // Convert a list of ValTypes into a string in the format of
103 // "type0, type1, ... typeN"
104 std::string typeListToString(ArrayRef<wasm::ValType> List);
105 // Convert a wasm signature into a string in the format of
106 // "(params) -> (results)", where params and results are a string of ValType
107 // lists.
108 std::string signatureToString(const wasm::WasmSignature *Sig);
109 
110 // Convert a MVT into its corresponding wasm ValType.
111 wasm::ValType toValType(MVT Type);
112 
113 // Convert a register class ID to a wasm ValType.
114 wasm::ValType regClassToValType(unsigned RC);
115 
116 // Convert a register class to a wasm ValType.
117 wasm::ValType regClassToValType(const TargetRegisterClass *RC);
118 
119 /// Sets a Wasm Symbol Type.
120 void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT,
121                        const SmallVector<MVT, 1> &VTs);
122 
123 } // end namespace WebAssembly
124 } // end namespace llvm
125 
126 #endif
127