Skip to content

Commit ce491c5

Browse files
Partial support for common linkage for WebAssembly
Emulate common linkage through weak linkage, the only difference between the two being mostly similar according to langref, with the notable exception that common linkage implies zero initializer. This is needed for fortran-to-web-assembly projects used in the python community, esp. https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/libflang
1 parent c10736a commit ce491c5

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

llvm/lib/MC/MCWasmStreamer.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/MC/MCAsmBackend.h"
1515
#include "llvm/MC/MCAssembler.h"
1616
#include "llvm/MC/MCCodeEmitter.h"
17+
#include "llvm/MC/MCContext.h"
1718
#include "llvm/MC/MCExpr.h"
1819
#include "llvm/MC/MCFixup.h"
1920
#include "llvm/MC/MCObjectStreamer.h"
@@ -131,7 +132,29 @@ bool MCWasmStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
131132

132133
void MCWasmStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
133134
Align ByteAlignment) {
134-
llvm_unreachable("Common symbols are not yet implemented for Wasm");
135+
auto *Symbol = cast<MCSymbolWasm>(S);
136+
137+
pushSection();
138+
139+
// Common symbols are very close to weak symbols, so manually build a weak
140+
// symbol.
141+
MCSectionWasm *SW = getContext().getWasmSection(".bss.common." + S->getName(),
142+
SectionKind::getData());
143+
SW->setAlignment(ByteAlignment);
144+
getAssembler().registerSection(*SW);
145+
146+
switchSection(SW);
147+
148+
MCDataFragment *DF = getOrCreateDataFragment();
149+
DF->setContents(std::vector<char>(Size, '\0'));
150+
Symbol->setFragment(DF);
151+
152+
Symbol->setSize(MCConstantExpr::create(Size, getContext(), false, 8));
153+
Symbol->setWeak(true);
154+
Symbol->setExternal(true);
155+
getAssembler().registerSymbol(*Symbol);
156+
157+
popSection();
135158
}
136159

137160
void MCWasmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {

llvm/test/MC/WebAssembly/common.ll

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; RUN; llc -mcpu=mvp -filetype=obj %s -o - | obj2yaml | FileCheck %s
2+
; RUN; llc -mcpu=mvp -filetype=asm %s -asm-verbose=false -o - | FileCheck --check-prefix=ASM %s
3+
; RUN: llc -mcpu=mvp -filetype=asm %s -o - | llvm-mc -triple=wasm32 -filetype=obj -o - | obj2yaml | FileCheck %s
4+
5+
target triple = "wasm32-unknown-unknown"
6+
;target triple = "x86_64-redhat-linux-gnu"
7+
@b = common dso_local global [10 x i32] zeroinitializer, align 4
8+
@c = common dso_local global [20 x i32] zeroinitializer, align 32
9+
10+
; CHECK-ASM: .file "common.ll"
11+
; CHECK-ASM: .type b,@object
12+
; CHECK-ASM: .comm b,40,2
13+
; CHECK-ASM: .type c,@object
14+
; CHECK-ASM: .comm c,80,5
15+
16+
17+
; CHECK: --- !WASM
18+
; CHECK-NEXT: FileHeader:
19+
; CHECK-NEXT: Version: 0x1
20+
; CHECK-NEXT: Sections:
21+
; CHECK-NEXT: - Type: IMPORT
22+
; CHECK-NEXT: Imports:
23+
; CHECK-NEXT: - Module: env
24+
; CHECK-NEXT: Field: __linear_memory
25+
; CHECK-NEXT: Kind: MEMORY
26+
; CHECK-NEXT: Memory:
27+
; CHECK-NEXT: Minimum: 0x1
28+
; CHECK-NEXT: - Type: DATACOUNT
29+
; CHECK-NEXT: Count: 2
30+
; CHECK-NEXT: - Type: DATA
31+
; CHECK-NEXT: Segments:
32+
; CHECK-NEXT: - SectionOffset: 6
33+
; CHECK-NEXT: InitFlags: 0
34+
; CHECK-NEXT: Offset:
35+
; CHECK-NEXT: Opcode: I32_CONST
36+
; CHECK-NEXT: Value: 0
37+
; CHECK-NEXT: Content: '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
38+
; CHECK-NEXT: - SectionOffset: 52
39+
; CHECK-NEXT: InitFlags: 0
40+
; CHECK-NEXT: Offset:
41+
; CHECK-NEXT: Opcode: I32_CONST
42+
; CHECK-NEXT: Value: 64
43+
; CHECK-NEXT: Content: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
44+
; CHECK-NEXT: - Type: CUSTOM
45+
; CHECK-NEXT: Name: linking
46+
; CHECK-NEXT: Version: 2
47+
; CHECK-NEXT: SymbolTable:
48+
; CHECK-NEXT: - Index: 0
49+
; CHECK-NEXT: Kind: DATA
50+
; CHECK-NEXT: Name: b
51+
; CHECK-NEXT: Flags: [ BINDING_WEAK ]
52+
; CHECK-NEXT: Segment: 0
53+
; CHECK-NEXT: Size: 40
54+
; CHECK-NEXT: - Index: 1
55+
; CHECK-NEXT: Kind: DATA
56+
; CHECK-NEXT: Name: c
57+
; CHECK-NEXT: Flags: [ BINDING_WEAK ]
58+
; CHECK-NEXT: Segment: 1
59+
; CHECK-NEXT: Size: 80
60+
; CHECK-NEXT: SegmentInfo:
61+
; CHECK-NEXT: - Index: 0
62+
; CHECK-NEXT: Name: .bss.common.b
63+
; CHECK-NEXT: Alignment: 2
64+
; CHECK-NEXT: Flags: [ ]
65+
; CHECK-NEXT: - Index: 1
66+
; CHECK-NEXT: Name: .bss.common.c
67+
; CHECK-NEXT: Alignment: 5
68+
; CHECK-NEXT: Flags: [ ]
69+
; CHECK-NEXT: ...

0 commit comments

Comments
 (0)