Skip to content

Commit 9ac5df2

Browse files
committed
[WebAssembly] Add a new wasm_multivalue calling convention
This is an implementation of WebAssembly/tool-conventions#268 here in LLVM. This adds a new calling convention to Clang, named `wasm_multivalue`, which is intended to be used on WebAssembly targets to configure multiple return values and slightly tweak the ABI. Changes here are: * Parsing/validation of `__attribute__((wasm_multivalue))`. Note that validation here means that it's not only well-formed but on wasm targets the `multivalue` target feature is additionally enabled. * Clang-level ABI adjustments for the `wasm_multivalue` calling convention. These are defined by WebAssembly/tool-conventions#268 and notably includes expanding structs with exactly 2 scalar fields in parameter-position and directly returning structs with any number of scalar fields in return-position. * A new `wasm_multivaluecc` keyword/calling convention for LLVM IR. This is what Clang lowers to when using the `wasm_multivalue` calling convention. * Adjustments at the LLVM ABI layer to support returning multiple values with the `wasm_multivaluecc` calling convention. My goal after this would be to start integrating this into Rust next, under and unstable feature, and then further continue testing/vetting/etc for component model usage.
1 parent 60bd8f8 commit 9ac5df2

33 files changed

Lines changed: 509 additions & 75 deletions

clang/include/clang-c/Index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,6 +3086,7 @@ enum CXCallingConv {
30863086
CXCallingConv_RISCVVLSCall_16384 = 31,
30873087
CXCallingConv_RISCVVLSCall_32768 = 32,
30883088
CXCallingConv_RISCVVLSCall_65536 = 33,
3089+
CXCallingConv_WasmMultivalue = 34,
30893090

30903091
CXCallingConv_Invalid = 100,
30913092
CXCallingConv_Unexposed = 200

clang/include/clang/Basic/Attr.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,6 +3555,12 @@ def M68kRTD: DeclOrTypeAttr {
35553555
let Documentation = [M68kRTDDocs];
35563556
}
35573557

3558+
def WasmMultivalue : DeclOrTypeAttr,
3559+
TargetSpecificAttr<TargetWebAssembly> {
3560+
let Spellings = [Clang<"wasm_multivalue">];
3561+
let Documentation = [WasmMultivalueDocs];
3562+
}
3563+
35583564
def PreserveNone : DeclOrTypeAttr,
35593565
TargetSpecificAttr<TargetArch<!listconcat(TargetAArch64.Arches, TargetAnyX86.Arches)>> {
35603566
let Spellings = [Clang<"preserve_none">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3732,6 +3732,21 @@ using the `rtd` instruction.
37323732
}];
37333733
}
37343734

3735+
def WasmMultivalueDocs : Documentation {
3736+
let Category = DocCatCallingConvs;
3737+
let Content = [{
3738+
On WebAssembly targets, this attribute selects the ``wasm-multivalue`` calling
3739+
convention as defined in the WebAssembly/tool-conventions repository. Relative
3740+
to the default calling convention this takes advantage of the multi-value
3741+
proposal in its ABI definition.
3742+
3743+
This calling convention requires the ``multivalue`` target feature. Using the
3744+
attribute without this feature enabled is a compile-time error. Enabling
3745+
``multivalue`` does not change the default calling convention; this attribute
3746+
must be used to opt in to the new behavior on a per-function basis.
3747+
}];
3748+
}
3749+
37353750
def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
37363751
let Content = [{
37373752
Clang supports additional attributes for checking basic resource management

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13832,7 +13832,7 @@ def err_builtin_pass_in_regs_non_class : Error<
1383213832
"argument %0 is not an unqualified class type">;
1383313833

1383413834

13835-
// WebAssembly reference type and table diagnostics.
13835+
// WebAssembly-related diagnostics.
1383613836
def err_wasm_reference_pr : Error<
1383713837
"%select{pointer|reference}0 to WebAssembly reference type is not allowed">;
1383813838
def err_wasm_ca_reference : Error<
@@ -13875,6 +13875,9 @@ def err_wasm_builtin_test_fp_sig_cannot_include_struct_or_union
1387513875
: Error<"not supported with the multivalue ABI for "
1387613876
"function pointers with a struct/union as %select{return "
1387713877
"value|parameter}0">;
13878+
def err_wasm_multivalue_requires_feature : Error<
13879+
"the 'wasm_multivalue' calling convention requires the 'multivalue' target "
13880+
"feature to be enabled">;
1387813881

1387913882
// OpenACC diagnostics.
1388013883
def warn_acc_routine_unimplemented

clang/include/clang/Basic/Specifiers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ namespace clang {
316316
CC_RISCVVLSCall_16384, // __attribute__((riscv_vls_cc(16384)))
317317
CC_RISCVVLSCall_32768, // __attribute__((riscv_vls_cc(32768)))
318318
CC_RISCVVLSCall_65536, // __attribute__((riscv_vls_cc(65536)))
319+
CC_WasmMultivalue, // __attribute__((wasm_multivalue))
319320
};
320321

321322
/// Checks whether the given calling convention supports variadic

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3534,6 +3534,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
35343534
case CC_PreserveMost:
35353535
case CC_PreserveAll:
35363536
case CC_M68kRTD:
3537+
case CC_WasmMultivalue:
35373538
case CC_PreserveNone:
35383539
case CC_RISCVVectorCall:
35393540
#define CC_VLS_CASE(ABI_VLEN) case CC_RISCVVLSCall_##ABI_VLEN:

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,8 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
37413741
return "preserve_all";
37423742
case CC_M68kRTD:
37433743
return "m68k_rtd";
3744+
case CC_WasmMultivalue:
3745+
return "wasm_multivalue";
37443746
case CC_PreserveNone:
37453747
return "preserve_none";
37463748
// clang-format off
@@ -4552,6 +4554,7 @@ bool AttributedType::isCallingConv() const {
45524554
case attr::PreserveMost:
45534555
case attr::PreserveAll:
45544556
case attr::M68kRTD:
4557+
case attr::WasmMultivalue:
45554558
case attr::PreserveNone:
45564559
case attr::RISCVVectorCC:
45574560
case attr::RISCVVLSCC:

clang/lib/AST/TypePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
11731173
case CC_M68kRTD:
11741174
OS << " __attribute__((m68k_rtd))";
11751175
break;
1176+
case CC_WasmMultivalue:
1177+
OS << " __attribute__((wasm_multivalue))";
1178+
break;
11761179
case CC_PreserveNone:
11771180
OS << " __attribute__((preserve_none))";
11781181
break;
@@ -2088,6 +2091,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
20882091
case attr::M68kRTD:
20892092
OS << "m68k_rtd";
20902093
break;
2094+
case attr::WasmMultivalue:
2095+
OS << "wasm_multivalue";
2096+
break;
20912097
case attr::RISCVVectorCC:
20922098
OS << "riscv_vector_cc";
20932099
break;

clang/lib/Basic/Targets/WebAssembly.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
184184
switch (CC) {
185185
case CC_C:
186186
case CC_Swift:
187+
case CC_WasmMultivalue:
187188
return CCCR_OK;
188189
case CC_SwiftAsync:
189190
return CCCR_Error;

clang/lib/CodeGen/CGCall.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
103103
return llvm::CallingConv::SwiftTail;
104104
case CC_M68kRTD:
105105
return llvm::CallingConv::M68k_RTD;
106+
case CC_WasmMultivalue:
107+
return llvm::CallingConv::WASM_Multivalue;
106108
case CC_PreserveNone:
107109
return llvm::CallingConv::PreserveNone;
108110
// clang-format off

0 commit comments

Comments
 (0)