aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-07-26 19:03:47 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-07-26 19:04:23 +0000
commit7fa27ce4a07f19b07799a767fc29416f3b625afb (patch)
tree27825c83636c4de341eb09a74f49f5d38a15d165 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
parente3b557809604d036af6e00c60f012c2025b59a5e (diff)
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp49
1 files changed, 47 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 60b1b3f5fc27..d492bec97d46 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -25,8 +25,10 @@
#include "WebAssemblyRegisterInfo.h"
#include "WebAssemblyRuntimeLibcallSignatures.h"
#include "WebAssemblyTargetMachine.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/AsmPrinter.h"
@@ -301,8 +303,8 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
// only find symbols that have been used. Unused symbols from globals will
// not be found here.
MachineModuleInfoWasm &MMIW = MMI->getObjFileInfo<MachineModuleInfoWasm>();
- for (const auto &Name : MMIW.MachineSymbolsUsed) {
- auto *WasmSym = cast<MCSymbolWasm>(getOrCreateWasmSymbol(Name.getKey()));
+ for (StringRef Name : MMIW.MachineSymbolsUsed) {
+ auto *WasmSym = cast<MCSymbolWasm>(getOrCreateWasmSymbol(Name));
if (WasmSym->isFunction()) {
// TODO(wvo): is there any case where this overlaps with the call to
// emitFunctionType in the loop below?
@@ -438,6 +440,7 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
EmitProducerInfo(M);
EmitTargetFeatures(M);
+ EmitFunctionAttributes(M);
}
void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -556,6 +559,48 @@ void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) {
OutStreamer->popSection();
}
+void WebAssemblyAsmPrinter::EmitFunctionAttributes(Module &M) {
+ auto V = M.getNamedGlobal("llvm.global.annotations");
+ if (!V)
+ return;
+
+ // Group all the custom attributes by name.
+ MapVector<StringRef, SmallVector<MCSymbol *, 4>> CustomSections;
+ const ConstantArray *CA = cast<ConstantArray>(V->getOperand(0));
+ for (Value *Op : CA->operands()) {
+ auto *CS = cast<ConstantStruct>(Op);
+ // The first field is a pointer to the annotated variable.
+ Value *AnnotatedVar = CS->getOperand(0)->stripPointerCasts();
+ // Only annotated functions are supported for now.
+ if (!isa<Function>(AnnotatedVar))
+ continue;
+ auto *F = cast<Function>(AnnotatedVar);
+
+ // The second field is a pointer to a global annotation string.
+ auto *GV = cast<GlobalVariable>(CS->getOperand(1)->stripPointerCasts());
+ StringRef AnnotationString;
+ getConstantStringInfo(GV, AnnotationString);
+ auto *Sym = cast<MCSymbolWasm>(getSymbol(F));
+ CustomSections[AnnotationString].push_back(Sym);
+ }
+
+ // Emit a custom section for each unique attribute.
+ for (const auto &[Name, Symbols] : CustomSections) {
+ MCSectionWasm *CustomSection = OutContext.getWasmSection(
+ ".custom_section.llvm.func_attr.annotate." + 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() &&