brendandahl updated this revision to Diff 531014.
brendandahl added a comment.
Fix few remaining issues.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D150803/new/
https://reviews.llvm.org/D150803
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CodeGen/WebAssembly/wasm-custom-attr.c
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/Sema/attr-wasm-custom.c
clang/test/Sema/wasm-custom-support.c
lld/test/wasm/custom-attr.s
lld/test/wasm/custom-undefine.s
lld/test/wasm/merge-custom-attr-section.ll
lld/wasm/InputChunks.cpp
lld/wasm/InputFiles.cpp
llvm/include/llvm/BinaryFormat/WasmRelocs.def
llvm/include/llvm/MC/MCExpr.h
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Object/WasmObjectFile.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
llvm/test/CodeGen/WebAssembly/custom-attr.ll
llvm/test/MC/WebAssembly/custom-attr.s
Index: llvm/test/MC/WebAssembly/custom-attr.s
===================================================================
--- /dev/null
+++ llvm/test/MC/WebAssembly/custom-attr.s
@@ -0,0 +1,21 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
+# Check that it also comiled to object for format.
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o - < %s | obj2yaml | FileCheck -check-prefix=CHECK-OBJ %s
+
+foo:
+ .globl foo
+ .functype foo () -> ()
+ end_function
+
+ .section .custom_section.func_attr.custom0,"",@
+ .int32 foo@FUNCINDEX
+
+# CHECK: .section .custom_section.func_attr.custom0,"",@
+# CHECK-NEXT: .int32 foo@FUNCINDEX
+
+# CHECK-OBJ: - Type: CUSTOM
+# CHECK-OBJ-NEXT: Relocations:
+# CHECK-OBJ-NEXT: - Type: R_WASM_FUNCTION_INDEX_I32
+# CHECK-OBJ-NEXT: Index: 0
+# CHECK-OBJ-NEXT: Offset: 0x0
+# CHECK-OBJ-NEXT: Name: func_attr.custom0
Index: llvm/test/CodeGen/WebAssembly/custom-attr.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/custom-attr.ll
@@ -0,0 +1,24 @@
+; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define void @test0() #0 {
+ ret void
+}
+
+define void @test1() #0 {
+ ret void
+}
+
+define void @test3() #1 {
+ ret void
+}
+
+attributes #0 = { "wasm-custom"="custom0" }
+attributes #1 = { "wasm-custom"="custom1" }
+
+; CHECK: .section .custom_section.func_attr.custom0,"",@
+; CHECK-NEXT: .int32 test0@FUNCINDEX
+; CHECK-NEXT: .int32 test1@FUNCINDEX
+; CHECK: .section .custom_section.func_attr.custom1,"",@
+; CHECK-NEXT: .int32 test3@FUNCINDEX
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
@@ -66,6 +66,7 @@
void emitEndOfAsmFile(Module &M) override;
void EmitProducerInfo(Module &M);
void EmitTargetFeatures(Module &M);
+ void EmitCustomFunctionAttributes(Module &M);
void emitSymbolType(const MCSymbolWasm *Sym);
void emitGlobalVariable(const GlobalVariable *GV) override;
void emitJumpTableInfo() override;
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -25,6 +25,7 @@
#include "WebAssemblyRegisterInfo.h"
#include "WebAssemblyRuntimeLibcallSignatures.h"
#include "WebAssemblyTargetMachine.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Wasm.h"
@@ -438,6 +439,7 @@
EmitProducerInfo(M);
EmitTargetFeatures(M);
+ EmitCustomFunctionAttributes(M);
}
void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -556,6 +558,36 @@
OutStreamer->popSection();
}
+void WebAssemblyAsmPrinter::EmitCustomFunctionAttributes(Module &M) {
+ DenseMap<StringRef, SmallVector<MCSymbol *, 4>> CustomSections;
+ // Group all the custom attributes by name.
+ for (const auto &F : M) {
+ auto *Sym = cast<MCSymbolWasm>(getSymbol(&F));
+ if (F.hasFnAttribute("wasm-custom")) {
+ StringRef Name = F.getFnAttribute("wasm-custom").getValueAsString();
+ if (!CustomSections.contains(Name))
+ CustomSections[Name] = {};
+ CustomSections[Name].push_back(Sym);
+ }
+ }
+
+ // Emit a custom section for each unique attribute.
+ for (auto [Name, Symbols] : CustomSections) {
+ MCSectionWasm *CustomSection = OutContext.getWasmSection(
+ ".custom_section.func_attr." + Name, SectionKind::getMetadata());
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(CustomSection);
+
+ for (auto &Sym : Symbols) {
+ OutStreamer->emitValue(
+ MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_WASM_FUNCINDEX,
+ OutContext),
+ 4);
+ }
+ OutStreamer->popSection();
+ }
+}
+
void WebAssemblyAsmPrinter::emitConstantPool() {
emitDecls(*MMI->getModule());
assert(MF->getConstantPool()->getConstants().empty() &&
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -91,6 +91,8 @@
return wasm::R_WASM_TYPE_INDEX_LEB;
case MCSymbolRefExpr::VK_None:
break;
+ case MCSymbolRefExpr::VK_WASM_FUNCINDEX:
+ return wasm::R_WASM_FUNCTION_INDEX_I32;
default:
report_fatal_error("unknown VariantKind");
break;
Index: llvm/lib/Object/WasmObjectFile.cpp
===================================================================
--- llvm/lib/Object/WasmObjectFile.cpp
+++ llvm/lib/Object/WasmObjectFile.cpp
@@ -948,6 +948,7 @@
Reloc.Index = readVaruint32(Ctx);
switch (type) {
case wasm::R_WASM_FUNCTION_INDEX_LEB:
+ case wasm::R_WASM_FUNCTION_INDEX_I32:
case wasm::R_WASM_TABLE_INDEX_SLEB:
case wasm::R_WASM_TABLE_INDEX_SLEB64:
case wasm::R_WASM_TABLE_INDEX_I32:
@@ -1045,6 +1046,7 @@
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
+ Reloc.Type == wasm::R_WASM_FUNCTION_INDEX_I32 ||
Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
Size = 4;
if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
Index: llvm/lib/MC/WasmObjectWriter.cpp
===================================================================
--- llvm/lib/MC/WasmObjectWriter.cpp
+++ llvm/lib/MC/WasmObjectWriter.cpp
@@ -671,6 +671,7 @@
// Provisional value is same as the index
return getRelocationIndexValue(RelEntry);
case wasm::R_WASM_FUNCTION_INDEX_LEB:
+ case wasm::R_WASM_FUNCTION_INDEX_I32:
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_TAG_INDEX_LEB:
@@ -791,6 +792,7 @@
case wasm::R_WASM_TABLE_INDEX_I32:
case wasm::R_WASM_MEMORY_ADDR_I32:
case wasm::R_WASM_FUNCTION_OFFSET_I32:
+ case wasm::R_WASM_FUNCTION_INDEX_I32:
case wasm::R_WASM_SECTION_OFFSET_I32:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
Index: llvm/lib/MC/MCExpr.cpp
===================================================================
--- llvm/lib/MC/MCExpr.cpp
+++ llvm/lib/MC/MCExpr.cpp
@@ -360,6 +360,7 @@
case VK_WASM_TLSREL: return "TLSREL";
case VK_WASM_TBREL: return "TBREL";
case VK_WASM_GOT_TLS: return "GOT@TLS";
+ case VK_WASM_FUNCINDEX: return "FUNCINDEX";
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
case VK_AMDGPU_REL32_LO: return "rel32@lo";
@@ -503,6 +504,7 @@
.Case("mbrel", VK_WASM_MBREL)
.Case("tlsrel", VK_WASM_TLSREL)
.Case("got@tls", VK_WASM_GOT_TLS)
+ .Case("funcindex", VK_WASM_FUNCINDEX)
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
.Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
.Case("rel32@lo", VK_AMDGPU_REL32_LO)
Index: llvm/include/llvm/MC/MCExpr.h
===================================================================
--- llvm/include/llvm/MC/MCExpr.h
+++ llvm/include/llvm/MC/MCExpr.h
@@ -330,6 +330,7 @@
VK_WASM_MBREL, // Memory address relative to __memory_base
VK_WASM_TBREL, // Table index relative to __table_base
VK_WASM_GOT_TLS, // Wasm global index of TLS symbol.
+ VK_WASM_FUNCINDEX, // Wasm function index.
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
Index: llvm/include/llvm/BinaryFormat/WasmRelocs.def
===================================================================
--- llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -28,3 +28,4 @@
WASM_RELOC(R_WASM_MEMORY_ADDR_LOCREL_I32, 23)
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB64, 24)
WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB64, 25)
+WASM_RELOC(R_WASM_FUNCTION_INDEX_I32, 26)
Index: lld/wasm/InputFiles.cpp
===================================================================
--- lld/wasm/InputFiles.cpp
+++ lld/wasm/InputFiles.cpp
@@ -193,6 +193,7 @@
case R_WASM_TYPE_INDEX_LEB:
return typeMap[reloc.Index];
case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_I32:
return getFunctionSymbol(reloc.Index)->getFunctionIndex();
case R_WASM_GLOBAL_INDEX_LEB:
case R_WASM_GLOBAL_INDEX_I32:
Index: lld/wasm/InputChunks.cpp
===================================================================
--- lld/wasm/InputChunks.cpp
+++ lld/wasm/InputChunks.cpp
@@ -150,6 +150,7 @@
case R_WASM_TABLE_INDEX_I32:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_FUNCTION_INDEX_I32:
case R_WASM_SECTION_OFFSET_I32:
case R_WASM_GLOBAL_INDEX_I32:
case R_WASM_MEMORY_ADDR_LOCREL_I32:
@@ -515,6 +516,10 @@
uint64_t InputSection::getTombstoneForSection(StringRef name) {
// When a function is not live we need to update relocations referring to it.
+ // If the function occurs in an custom attribute section change it to -1 since
+ // 0 is a valid function index.
+ if (name.startswith("func_attr."))
+ return UINT64_C(-1);
// If they occur in DWARF debug symbols, we want to change the pc of the
// function to -1 to avoid overlapping with a valid range. However for the
// debug_ranges and debug_loc sections that would conflict with the existing
Index: lld/test/wasm/merge-custom-attr-section.ll
===================================================================
--- /dev/null
+++ lld/test/wasm/merge-custom-attr-section.ll
@@ -0,0 +1,48 @@
+; RUN: split-file %s %t
+; RUN: llc -filetype=obj %t/a.ll -o %t1.o
+; RUN: llc -filetype=obj %t/b.ll -o %t2.o
+; RUN: wasm-ld -o %t.wasm %t1.o %t2.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; Ensure two custo funct_attr sections are concatenated together.
+
+; CHECK: - Type: CUSTOM
+; CHECK-NEXT: Name: func_attr.custom0
+; CHECK-NEXT: Payload: '000000000100000003000000'
+
+;--- a.ll
+
+target triple = "wasm32-unknown-unknown"
+
+; Function index 3 (after linking)
+declare void @baz()
+
+; Function index 0
+define void @foo() #0 {
+ ret void
+}
+
+; Function index 1
+define void @bar() #0 {
+ ret void
+}
+
+; Function index 2
+define void @_start() {
+ call void @foo()
+ call void @bar()
+ call void @baz()
+ ret void
+}
+
+attributes #0 = { "wasm-custom"="custom0" }
+
+;--- b.ll
+
+target triple = "wasm32-unknown-unknown"
+
+define void @baz() #0 {
+ ret void
+}
+
+attributes #0 = { "wasm-custom"="custom0" }
Index: lld/test/wasm/custom-undefine.s
===================================================================
--- /dev/null
+++ lld/test/wasm/custom-undefine.s
@@ -0,0 +1,34 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld %t.o -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+ .functype foo () -> ()
+ .functype bar () -> ()
+ .functype _start () -> ()
+ .globl foo
+ .type foo,@function
+foo:
+ .functype foo () -> ()
+ end_function
+
+ .section .text.bar,"",@
+ .globl bar
+ .type bar,@function
+bar:
+ .functype bar () -> ()
+ end_function
+
+ .globl _start
+ .type _start,@function
+_start:
+ .functype _start () -> ()
+ call foo
+ end_function
+
+ .section .custom_section.func_attr.custom0,"",@
+ .int32 foo@FUNCINDEX
+ .int32 bar@FUNCINDEX
+
+# CHECK: - Type: CUSTOM
+# CHECK-NEXT: Name: func_attr.custom0
+# CHECK-NEXT: Payload: 00000000FFFFFFFF
Index: lld/test/wasm/custom-attr.s
===================================================================
--- /dev/null
+++ lld/test/wasm/custom-attr.s
@@ -0,0 +1,35 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld %t.o -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+ .functype foo () -> ()
+ .functype bar () -> ()
+ .functype _start () -> ()
+ .globl foo
+ .type foo,@function
+foo:
+ .functype foo () -> ()
+ end_function
+
+ .section .text.bar,"",@
+ .globl bar
+ .type bar,@function
+bar:
+ .functype bar () -> ()
+ end_function
+
+ .globl _start
+ .type _start,@function
+_start:
+ .functype _start () -> ()
+ call foo
+ call bar
+ end_function
+
+ .section .custom_section.func_attr.custom0,"",@
+ .int32 foo@FUNCINDEX
+ .int32 bar@FUNCINDEX
+
+# CHECK: - Type: CUSTOM
+# CHECK-NEXT: Name: func_attr.custom0
+# CHECK-NEXT: Payload: '0000000001000000'
Index: clang/test/Sema/wasm-custom-support.c
===================================================================
--- /dev/null
+++ clang/test/Sema/wasm-custom-support.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -triple armv7 -fsyntax-only -verify
+
+void name_a(void) __attribute__((wasm_custom("name"))); // expected-warning{{unknown attribute 'wasm_custom' ignored}}
Index: clang/test/Sema/attr-wasm-custom.c
===================================================================
--- /dev/null
+++ clang/test/Sema/attr-wasm-custom.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fsyntax-only -verify %s
+
+void name_a(void) __attribute__((wasm_custom("name")));
+
+int name_b __attribute__((wasm_custom("name"))); //expected-error {{'wasm_custom' attribute only applies to functions}}
+
+void name_c(void) __attribute__((wasm_custom)); //expected-error {{'wasm_custom' attribute takes one argument}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -196,6 +196,7 @@
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType, SubjectMatchRule_type_alias)
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function)
+// CHECK-NEXT: WebAssemblyCustom (SubjectMatchRule_function)
// CHECK-NEXT: WebAssemblyExportName (SubjectMatchRule_function)
// CHECK-NEXT: WebAssemblyImportModule (SubjectMatchRule_function)
// CHECK-NEXT: WebAssemblyImportName (SubjectMatchRule_function)
Index: clang/test/CodeGen/WebAssembly/wasm-custom-attr.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-custom-attr.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s
+
+__attribute__((wasm_custom("jspi"))) int foo(void) {
+ return 43;
+}
+
+// CHECK: define i32 @foo() [[A:#[0-9]+]]
+
+// CHECK: attributes [[A]] = {{{.*}} "wasm-custom"="jspi" {{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -7633,6 +7633,15 @@
FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(S.Context, AL, Str));
}
+static void handleWebAssemblyCustomAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+ D->addAttr(::new (S.Context) WebAssemblyCustomAttr(S.Context, AL, Str));
+}
+
static void handleRISCVInterruptAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
// Warn about repeated attributes.
@@ -8739,6 +8748,9 @@
case ParsedAttr::AT_WebAssemblyImportName:
handleWebAssemblyImportNameAttr(S, D, AL);
break;
+ case ParsedAttr::AT_WebAssemblyCustom:
+ handleWebAssemblyCustomAttr(S, D, AL);
+ break;
case ParsedAttr::AT_IBOutlet:
handleIBOutlet(S, D, AL);
break;
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -894,6 +894,12 @@
B.addAttribute("wasm-export-name", Attr->getExportName());
Fn->addFnAttrs(B);
}
+ if (const auto *Attr = FD->getAttr<WebAssemblyCustomAttr>()) {
+ auto *Fn = cast<llvm::Function>(GV);
+ llvm::AttrBuilder B(GV->getContext());
+ B.addAttribute("wasm-custom", Attr->getName());
+ Fn->addFnAttrs(B);
+ }
}
if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -5602,6 +5602,17 @@
}];
}
+def WebAssemblyCustomDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((wasm_custom(<name>)))`` attribute for the
+WebAssembly target. This attribute may be attached to a function to mark it with
+a custom attribute that will be contained in the final Wasm file. The attribute
+causes a custom section named "func_attr.<name>" to be created that will contain
+each function's index value that was marked with <name>.
+ }];
+}
+
def ArtificialDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1979,6 +1979,14 @@
let Subjects = SubjectList<[Function], ErrorDiag>;
}
+def WebAssemblyCustom : InheritableAttr,
+ TargetSpecificAttr<TargetWebAssembly> {
+ let Spellings = [Clang<"wasm_custom">];
+ let Args = [StringArgument<"Name">];
+ let Documentation = [WebAssemblyCustomDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+}
+
def NoSplitStack : InheritableAttr {
let Spellings = [GCC<"no_split_stack">];
let Subjects = SubjectList<[Function], ErrorDiag>;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -556,6 +556,9 @@
WebAssembly Support
^^^^^^^^^^^^^^^^^^^
+- Added ``__attribute__((wasm_custom(<name>)))`` to tag functions with custom
+ attributes in the final Wasm file. This is done by creating a custom section
+ for each unique ``<name>`` attribute and storing the function index in there.
AVR Support
^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits