diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -53,6 +53,7 @@ Optional parseType(StringRef Type); HeapType parseHeapType(StringRef Type); BlockType parseBlockType(StringRef Type); +MVT parseMVT(StringRef Type); // Convert ValType or a list/signature of ValTypes to a string. diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp @@ -58,6 +58,22 @@ .Default(WebAssembly::BlockType::Invalid); } +MVT WebAssembly::parseMVT(StringRef Type) { + return StringSwitch(Type) + .Case("i32", MVT::i32) + .Case("i64", MVT::i64) + .Case("f32", MVT::f32) + .Case("f64", MVT::f64) + .Case("i64", MVT::i64) + .Case("v16i8", MVT::v16i8) + .Case("v8i16", MVT::v8i16) + .Case("v4i32", MVT::v4i32) + .Case("v2i64", MVT::v2i64) + .Case("funcref", MVT::funcref) + .Case("externref", MVT::externref) + .Default(MVT::INVALID_SIMPLE_VALUE_TYPE); +} + // We have various enums representing a subset of these types, use this // function to convert any of them to text. const char *WebAssembly::anyTypeToString(unsigned Type) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -188,6 +188,8 @@ using BBNumberMap = DenseMap; struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { + std::vector Params; + std::vector Results; bool CFGStackified = false; // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of // BB numbers @@ -202,6 +204,8 @@ template <> struct MappingTraits { static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { + YamlIO.mapOptional("params", MFI.Params, std::vector()); + YamlIO.mapOptional("results", MFI.Results, std::vector()); YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "WebAssemblyMachineFunctionInfo.h" +#include "MCTargetDesc/WebAssemblyInstPrinter.h" #include "Utils/WebAssemblyTypeUtilities.h" #include "WebAssemblyISelLowering.h" #include "WebAssemblySubtarget.h" @@ -109,6 +110,12 @@ : CFGStackified(MFI.isCFGStackified()) { auto *EHInfo = MFI.getWasmEHFuncInfo(); const llvm::MachineFunction &MF = MFI.getMachineFunction(); + + for (auto VT : MFI.getParams()) + Params.push_back(EVT(VT).getEVTString()); + for (auto VT : MFI.getResults()) + Results.push_back(EVT(VT).getEVTString()); + // MFI.getWasmEHFuncInfo() is non-null only for functions with the // personality function. if (EHInfo) { @@ -134,6 +141,10 @@ void WebAssemblyFunctionInfo::initializeBaseYamlFields( const yaml::WebAssemblyFunctionInfo &YamlMFI) { CFGStackified = YamlMFI.CFGStackified; + for (auto VT : YamlMFI.Params) + addParam(WebAssembly::parseMVT(VT.Value)); + for (auto VT : YamlMFI.Results) + addResult(WebAssembly::parseMVT(VT.Value)); if (WasmEHInfo) { for (auto KV : YamlMFI.SrcToUnwindDest) WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first), diff --git a/llvm/test/CodeGen/WebAssembly/function-info.mir b/llvm/test/CodeGen/WebAssembly/function-info.mir --- a/llvm/test/CodeGen/WebAssembly/function-info.mir +++ b/llvm/test/CodeGen/WebAssembly/function-info.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s +# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling,+multivalue,+simd128 -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s --- | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" @@ -12,6 +12,21 @@ define void @wasm_eh_info_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { ret void } + + ;; Param / results tests + define i32 @i32__i64(i64) { + ret i32 0 + } + define void @void__i32_i64_f32_f64() { + ret void + } + define void @void__v16i8_v8i16_v4i32_v2i64(<16 x i8>, <8 x i16>, <4 x i32>, <2 x i64>) { + ret void + } + %pair = type { i32, i64 } + define %pair @i32_i64__i32_i64(%pair %p) { + ret %pair %p + } ... # CHECK-LABEL: name: function_property_test @@ -55,3 +70,68 @@ CATCH_ALL implicit-def $arguments RETHROW 0, implicit-def $arguments ... + +# Param / results tests +--- +# CHECK-LABEL: name: i32__i64 +# CHECK: machineFunctionInfo: +# CHECK: params: [ i64 ] +# CHECK-NEXT: results: [ i32 ] +name: i32__i64 +liveins: + - { reg: '$arguments' } +machineFunctionInfo: + params: [ i64 ] + results: [ i32 ] +body: | + bb.0: + %0:i32 = CONST_I32 3, implicit-def dead $arguments + RETURN %0:i32, implicit-def dead $arguments +... +--- +# CHECK-LABEL: name: void__i32_i64_f32_f64 +# CHECK: machineFunctionInfo: +# CHECK: params: [ i32, i64, f32, f64 ] +# CHECK-NEXT: results: [ ] +name: void__i32_i64_f32_f64 +liveins: + - { reg: '$arguments' } +machineFunctionInfo: + params: [ i32, i64, f32, f64 ] + results: [ ] +body: | + bb.0: + RETURN implicit-def dead $arguments +... +--- +# CHECK-LABEL: name: void__v16i8_v8i16_v4i32_v2i64 +# CHECK: machineFunctionInfo: +# CHECK: params: [ v16i8, v8i16, v4i32, v2i64 ] +# CHECK-NEXT: results: [ ] +name: void__v16i8_v8i16_v4i32_v2i64 +liveins: + - { reg: '$arguments' } +machineFunctionInfo: + params: [ v16i8, v8i16, v4i32, v2i64 ] + results: [ ] +body: | + bb.0: + RETURN implicit-def dead $arguments +... +--- +# CHECK-LABEL: name: i32_i64__i32_i64 +# CHECK: machineFunctionInfo: +# CHECK: params: [ i32, i64 ] +# CHECK-NEXT: results: [ i32, i64 ] +name: i32_i64__i32_i64 +liveins: + - { reg: '$arguments' } +machineFunctionInfo: + params: [ i32, i64 ] + results: [ i32, i64 ] +body: | + bb.0: + %0:i32 = ARGUMENT_i32 0, implicit $arguments + %1:i64 = ARGUMENT_i64 1, implicit $arguments + RETURN %0, %1, implicit-def dead $arguments +...