Skip to content

Commit a70f9c1

Browse files
committed
[WebAssembly] Allocate MCSymbolWasm data on MCContext.
1 parent 192be3c commit a70f9c1

File tree

9 files changed

+89
-74
lines changed

9 files changed

+89
-74
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Support/Compiler.h"
2727
#include "llvm/Support/Error.h"
2828
#include "llvm/Support/MD5.h"
29+
#include "llvm/Support/StringSaver.h"
2930
#include "llvm/Support/raw_ostream.h"
3031
#include <algorithm>
3132
#include <cassert>
@@ -70,6 +71,10 @@ class SMLoc;
7071
class SourceMgr;
7172
enum class EmitDwarfUnwindType;
7273

74+
namespace wasm {
75+
struct WasmSignature;
76+
}
77+
7378
/// Context object for machine code objects. This class owns all of the
7479
/// sections that it creates.
7580
///
@@ -139,6 +144,8 @@ class MCContext {
139144
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
140145
SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
141146

147+
SpecificBumpPtrAllocator<wasm::WasmSignature> WasmSignatureAllocator;
148+
142149
/// Bindings of names to symbols.
143150
SymbolTable Symbols;
144151

@@ -538,6 +545,10 @@ class MCContext {
538545
/// inline assembly.
539546
void registerInlineAsmLabel(MCSymbol *Sym);
540547

548+
/// Allocates and returns a new `WasmSignature` instance (with empty parameter
549+
/// and return type lists).
550+
wasm::WasmSignature *createWasmSignature();
551+
541552
/// @}
542553

543554
/// \name Section Management
@@ -850,6 +861,15 @@ class MCContext {
850861

851862
void deallocate(void *Ptr) {}
852863

864+
/// Allocates the given string on the allocator managed by this context and
865+
/// returns the result.
866+
///
867+
/// Some of the other data structures stored by this context may also
868+
/// (implicitly or explicitly) allocate strings. Use those where appropriate.
869+
StringRef allocateGenericString(StringRef s) {
870+
return StringSaver(Allocator).save(s);
871+
}
872+
853873
bool hadError() { return HadError; }
854874
void diagnose(const SMDiagnostic &SMD);
855875
void reportError(SMLoc L, const Twine &Msg);

llvm/lib/MC/MCContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ void MCContext::reset() {
147147
XCOFFAllocator.DestroyAll();
148148
MCInstAllocator.DestroyAll();
149149
SPIRVAllocator.DestroyAll();
150+
WasmSignatureAllocator.DestroyAll();
150151

151152
MCSubtargetAllocator.DestroyAll();
152153
InlineAsmUsedLabelNames.clear();
@@ -375,6 +376,10 @@ void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
375376
InlineAsmUsedLabelNames[Sym->getName()] = Sym;
376377
}
377378

379+
wasm::WasmSignature *MCContext::createWasmSignature() {
380+
return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature;
381+
}
382+
378383
MCSymbolXCOFF *
379384
MCContext::createXCOFFSymbolImpl(const StringMapEntry<bool> *Name,
380385
bool IsTemporary) {

llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
196196
MCAsmParser &Parser;
197197
MCAsmLexer &Lexer;
198198

199-
// Much like WebAssemblyAsmPrinter in the backend, we have to own these.
200-
std::vector<std::unique_ptr<wasm::WasmSignature>> Signatures;
201-
std::vector<std::unique_ptr<std::string>> Names;
202-
203199
// Order of labels, directives and instructions in a .s file have no
204200
// syntactical enforcement. This class is a callback from the actual parser,
205201
// and yet we have to be feeding data to the streamer in a very particular
@@ -287,16 +283,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
287283
return Parser.Error(Loc.isValid() ? Loc : Lexer.getTok().getLoc(), Msg);
288284
}
289285

290-
void addSignature(std::unique_ptr<wasm::WasmSignature> &&Sig) {
291-
Signatures.push_back(std::move(Sig));
292-
}
293-
294-
StringRef storeName(StringRef Name) {
295-
std::unique_ptr<std::string> N = std::make_unique<std::string>(Name);
296-
Names.push_back(std::move(N));
297-
return *Names.back();
298-
}
299-
300286
std::pair<StringRef, StringRef> nestingString(NestingType NT) {
301287
switch (NT) {
302288
case Function:
@@ -640,21 +626,20 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
640626
// represent as a signature, such that we can re-build this signature,
641627
// attach it to an anonymous symbol, which is what WasmObjectWriter
642628
// expects to be able to recreate the actual unique-ified type indices.
629+
auto &Ctx = getContext();
643630
auto Loc = Parser.getTok();
644-
auto Signature = std::make_unique<wasm::WasmSignature>();
645-
if (parseSignature(Signature.get()))
631+
auto Signature = Ctx.createWasmSignature();
632+
if (parseSignature(Signature))
646633
return true;
647634
// Got signature as block type, don't need more
648-
TC.setLastSig(*Signature.get());
635+
TC.setLastSig(*Signature);
649636
if (ExpectBlockType)
650-
NestingStack.back().Sig = *Signature.get();
637+
NestingStack.back().Sig = *Signature;
651638
ExpectBlockType = false;
652-
auto &Ctx = getContext();
653639
// The "true" here will cause this to be a nameless symbol.
654640
MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true);
655641
auto *WasmSym = cast<MCSymbolWasm>(Sym);
656-
WasmSym->setSignature(Signature.get());
657-
addSignature(std::move(Signature));
642+
WasmSym->setSignature(Signature);
658643
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
659644
const MCExpr *Expr = MCSymbolRefExpr::create(
660645
WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx);
@@ -887,12 +872,11 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
887872
CurrentState = FunctionStart;
888873
LastFunctionLabel = WasmSym;
889874
}
890-
auto Signature = std::make_unique<wasm::WasmSignature>();
891-
if (parseSignature(Signature.get()))
875+
auto Signature = Ctx.createWasmSignature();
876+
if (parseSignature(Signature))
892877
return ParseStatus::Failure;
893878
TC.funcDecl(*Signature);
894-
WasmSym->setSignature(Signature.get());
895-
addSignature(std::move(Signature));
879+
WasmSym->setSignature(Signature);
896880
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
897881
TOut.emitFunctionType(WasmSym);
898882
// TODO: backend also calls TOut.emitIndIdx, but that is not implemented.
@@ -909,7 +893,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
909893
if (ExportName.empty())
910894
return ParseStatus::Failure;
911895
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
912-
WasmSym->setExportName(storeName(ExportName));
896+
WasmSym->setExportName(Ctx.allocateGenericString(ExportName));
913897
TOut.emitExportName(WasmSym, ExportName);
914898
return expect(AsmToken::EndOfStatement, "EOL");
915899
}
@@ -924,7 +908,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
924908
if (ImportModule.empty())
925909
return ParseStatus::Failure;
926910
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
927-
WasmSym->setImportModule(storeName(ImportModule));
911+
WasmSym->setImportModule(Ctx.allocateGenericString(ImportModule));
928912
TOut.emitImportModule(WasmSym, ImportModule);
929913
return expect(AsmToken::EndOfStatement, "EOL");
930914
}
@@ -939,7 +923,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
939923
if (ImportName.empty())
940924
return ParseStatus::Failure;
941925
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
942-
WasmSym->setImportName(storeName(ImportName));
926+
WasmSym->setImportName(Ctx.allocateGenericString(ImportName));
943927
TOut.emitImportName(WasmSym, ImportName);
944928
return expect(AsmToken::EndOfStatement, "EOL");
945929
}
@@ -949,11 +933,10 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
949933
if (SymName.empty())
950934
return ParseStatus::Failure;
951935
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
952-
auto Signature = std::make_unique<wasm::WasmSignature>();
936+
auto Signature = Ctx.createWasmSignature();
953937
if (parseRegTypeList(Signature->Params))
954938
return ParseStatus::Failure;
955-
WasmSym->setSignature(Signature.get());
956-
addSignature(std::move(Signature));
939+
WasmSym->setSignature(Signature);
957940
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TAG);
958941
TOut.emitTagType(WasmSym);
959942
// TODO: backend also calls TOut.emitIndIdx, but that is not implemented.

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ MCSymbol *WebAssemblyAsmPrinter::getOrCreateWasmSymbol(StringRef Name) {
266266
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
267267
WebAssembly::getLibcallSignature(Subtarget, Name, Returns, Params);
268268
}
269-
auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns),
270-
std::move(Params));
271-
WasmSym->setSignature(Signature.get());
272-
addSignature(std::move(Signature));
269+
auto Signature = OutContext.createWasmSignature();
270+
Signature->Returns = std::move(Returns);
271+
Signature->Params = std::move(Params);
272+
WasmSym->setSignature(Signature);
273273

274274
return WasmSym;
275275
}
@@ -338,11 +338,11 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
338338
// and thus also contain a signature, but we need to get the signature
339339
// anyway here in case it is an invoke that has not yet been created. We
340340
// will discard it later if it turns out not to be necessary.
341-
auto Signature = signatureFromMVTs(Results, Params);
341+
auto Signature = signatureFromMVTs(OutContext, Results, Params);
342342
bool InvokeDetected = false;
343343
auto *Sym = getMCSymbolForFunction(
344344
&F, WebAssembly::WasmEnableEmEH || WebAssembly::WasmEnableEmSjLj,
345-
Signature.get(), InvokeDetected);
345+
Signature, InvokeDetected);
346346

347347
// Multiple functions can be mapped to the same invoke symbol. For
348348
// example, two IR functions '__invoke_void_i8*' and '__invoke_void_i32'
@@ -353,19 +353,15 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
353353

354354
Sym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
355355
if (!Sym->getSignature()) {
356-
Sym->setSignature(Signature.get());
357-
addSignature(std::move(Signature));
358-
} else {
359-
// This symbol has already been created and had a signature. Discard it.
360-
Signature.reset();
356+
Sym->setSignature(Signature);
361357
}
362358

363359
getTargetStreamer()->emitFunctionType(Sym);
364360

365361
if (F.hasFnAttribute("wasm-import-module")) {
366362
StringRef Name =
367363
F.getFnAttribute("wasm-import-module").getValueAsString();
368-
Sym->setImportModule(storeName(Name));
364+
Sym->setImportModule(OutContext.allocateGenericString(Name));
369365
getTargetStreamer()->emitImportModule(Sym, Name);
370366
}
371367
if (F.hasFnAttribute("wasm-import-name")) {
@@ -375,14 +371,14 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
375371
InvokeDetected
376372
? Sym->getName()
377373
: F.getFnAttribute("wasm-import-name").getValueAsString();
378-
Sym->setImportName(storeName(Name));
374+
Sym->setImportName(OutContext.allocateGenericString(Name));
379375
getTargetStreamer()->emitImportName(Sym, Name);
380376
}
381377

382378
if (F.hasFnAttribute("wasm-export-name")) {
383379
auto *Sym = cast<MCSymbolWasm>(getSymbol(&F));
384380
StringRef Name = F.getFnAttribute("wasm-export-name").getValueAsString();
385-
Sym->setExportName(storeName(Name));
381+
Sym->setExportName(OutContext.allocateGenericString(Name));
386382
getTargetStreamer()->emitExportName(Sym, Name);
387383
}
388384
}
@@ -618,10 +614,9 @@ void WebAssemblyAsmPrinter::emitFunctionBodyStart() {
618614
SmallVector<MVT, 4> ParamVTs;
619615
computeSignatureVTs(F.getFunctionType(), &F, F, TM, ParamVTs, ResultVTs);
620616

621-
auto Signature = signatureFromMVTs(ResultVTs, ParamVTs);
617+
auto Signature = signatureFromMVTs(OutContext, ResultVTs, ParamVTs);
622618
auto *WasmSym = cast<MCSymbolWasm>(CurrentFnSym);
623-
WasmSym->setSignature(Signature.get());
624-
addSignature(std::move(Signature));
619+
WasmSym->setSignature(Signature);
625620
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
626621

627622
getTargetStreamer()->emitFunctionType(WasmSym);

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
2222
const WebAssemblySubtarget *Subtarget;
2323
const MachineRegisterInfo *MRI;
2424
WebAssemblyFunctionInfo *MFI;
25-
// TODO: Do the uniquing of Signatures here instead of ObjectFileWriter?
26-
std::vector<std::unique_ptr<wasm::WasmSignature>> Signatures;
27-
std::vector<std::unique_ptr<std::string>> Names;
2825
bool signaturesEmitted = false;
2926

30-
StringRef storeName(StringRef Name) {
31-
std::unique_ptr<std::string> N = std::make_unique<std::string>(Name);
32-
Names.push_back(std::move(N));
33-
return *Names.back();
34-
}
35-
3627
public:
3728
explicit WebAssemblyAsmPrinter(TargetMachine &TM,
3829
std::unique_ptr<MCStreamer> Streamer)
@@ -44,9 +35,6 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
4435
}
4536

4637
const WebAssemblySubtarget &getSubtarget() const { return *Subtarget; }
47-
void addSignature(std::unique_ptr<wasm::WasmSignature> &&Sig) {
48-
Signatures.push_back(std::move(Sig));
49-
}
5038

5139
//===------------------------------------------------------------------===//
5240
// MachineFunctionPass Implementation.

llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,13 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
7373
SmallVector<MVT, 4> ParamMVTs;
7474
const auto *const F = dyn_cast<Function>(Global);
7575
computeSignatureVTs(FuncTy, F, CurrentFunc, TM, ParamMVTs, ResultMVTs);
76-
auto Signature = signatureFromMVTs(ResultMVTs, ParamMVTs);
76+
auto Signature = signatureFromMVTs(Ctx, ResultMVTs, ParamMVTs);
7777

7878
bool InvokeDetected = false;
7979
auto *WasmSym = Printer.getMCSymbolForFunction(
8080
F, WebAssembly::WasmEnableEmEH || WebAssembly::WasmEnableEmSjLj,
81-
Signature.get(), InvokeDetected);
82-
WasmSym->setSignature(Signature.get());
83-
Printer.addSignature(std::move(Signature));
81+
Signature, InvokeDetected);
82+
WasmSym->setSignature(Signature);
8483
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
8584
return WasmSym;
8685
}
@@ -142,12 +141,12 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
142141
MCOperand WebAssemblyMCInstLower::lowerTypeIndexOperand(
143142
SmallVectorImpl<wasm::ValType> &&Returns,
144143
SmallVectorImpl<wasm::ValType> &&Params) const {
145-
auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns),
146-
std::move(Params));
144+
auto Signature = Ctx.createWasmSignature();
145+
Signature->Returns = std::move(Returns);
146+
Signature->Params = std::move(Params);
147147
MCSymbol *Sym = Printer.createTempSymbol("typeindex");
148148
auto *WasmSym = cast<MCSymbolWasm>(Sym);
149-
WasmSym->setSignature(Signature.get());
150-
Printer.addSignature(std::move(Signature));
149+
WasmSym->setSignature(Signature);
151150
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
152151
const MCExpr *Expr =
153152
MCSymbolRefExpr::create(WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx);

llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
111111
Out.push_back(WebAssembly::toValType(Ty));
112112
}
113113

114-
std::unique_ptr<wasm::WasmSignature>
115-
llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
114+
wasm::WasmSignature *
115+
llvm::signatureFromMVTs(MCContext &Ctx, const SmallVectorImpl<MVT> &Results,
116116
const SmallVectorImpl<MVT> &Params) {
117-
auto Sig = std::make_unique<wasm::WasmSignature>();
117+
auto Sig = Ctx.createWasmSignature();
118118
valTypesFromMVTs(Results, Sig->Returns);
119119
valTypesFromMVTs(Params, Sig->Params);
120120
return Sig;

llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc,
172172
void valTypesFromMVTs(const ArrayRef<MVT> &In,
173173
SmallVectorImpl<wasm::ValType> &Out);
174174

175-
std::unique_ptr<wasm::WasmSignature>
176-
signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
177-
const SmallVectorImpl<MVT> &Params);
175+
wasm::WasmSignature *signatureFromMVTs(MCContext &Ctx,
176+
const SmallVectorImpl<MVT> &Results,
177+
const SmallVectorImpl<MVT> &Params);
178178

179179
namespace yaml {
180180

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; Ensure that symbols from module ASM are properly exported.
2+
;
3+
; Regression test for https://github.com/llvm/llvm-project/issues/85578.
4+
5+
; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %s -o - | obj2yaml | FileCheck %s
6+
7+
module asm "test_func:"
8+
module asm " .globl test_func"
9+
module asm " .functype test_func (i32) -> (i32)"
10+
module asm " .export_name test_func, test_export"
11+
module asm " end_function"
12+
13+
; CHECK: - Type: TYPE
14+
; CHECK-NEXT: Signatures:
15+
; CHECK-NEXT: - Index: 0
16+
; CHECK-NEXT: ParamTypes:
17+
; CHECK-NEXT: - I32
18+
; CHECK-NEXT: ReturnTypes:
19+
; CHECK-NEXT: - I32
20+
21+
; CHECK: - Type: EXPORT
22+
; CHECK-NEXT: Exports:
23+
; CHECK-NEXT: - Name: test_export
24+
; CHECK-NEXT: Kind: FUNCTION
25+
; CHECK-NEXT: Index: 0

0 commit comments

Comments
 (0)