Skip to content

Commit 7b486e3

Browse files
committed
compiler: clean up pointer pack code
This means runtime.alloc isn't allocated every time but instead only when it is actually needed. It also just cleans up the compiler code a little bit, and makes the next commit a bit nicer.
1 parent da69f18 commit 7b486e3

19 files changed

Lines changed: 380 additions & 429 deletions

compiler/compiler.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
314314
// Load comments such as //go:extern on globals.
315315
c.loadASTComments(pkg)
316316

317-
// Predeclare the runtime.alloc function, which is used by the wordpack
318-
// functionality.
319-
c.getFunction(c.program.ImportedPackage("runtime").Members["alloc"].(*ssa.Function))
320317
if c.NeedsStackObjects {
321318
// Predeclare trackPointer, which is used everywhere we use runtime.alloc.
322319
c.getFunction(c.program.ImportedPackage("runtime").Members["trackPointer"].(*ssa.Function))

compiler/llvm.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,9 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value {
129129
// Packed data is bigger than a pointer, so allocate it on the heap.
130130
sizeValue := llvm.ConstInt(b.uintptrType, size, false)
131131
align := b.targetData.ABITypeAlignment(packedType)
132-
alloc := b.mod.NamedFunction("runtime.alloc")
133-
packedAlloc := b.CreateCall(alloc.GlobalValueType(), alloc, []llvm.Value{
132+
packedAlloc := b.createRuntimeCall("alloc", []llvm.Value{
134133
sizeValue,
135134
llvm.ConstNull(b.dataPtrType),
136-
llvm.Undef(b.dataPtrType), // unused context parameter
137135
}, "")
138136
packedAlloc.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align)))
139137
if b.NeedsStackObjects {

compiler/testdata/basic.ll

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,30 @@ target triple = "wasm32-unknown-wasi"
1010
@main.a = hidden global { ptr, i32, i32 } zeroinitializer, align 4
1111
@main.b = hidden global [2 x ptr] zeroinitializer, align 4
1212

13-
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
14-
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
15-
16-
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
13+
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
1714

1815
; Function Attrs: nounwind
19-
define hidden void @main.init(ptr %context) unnamed_addr #2 {
16+
define hidden void @main.init(ptr %context) unnamed_addr #1 {
2017
entry:
2118
ret void
2219
}
2320

2421
; Function Attrs: nounwind
25-
define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
22+
define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
2623
entry:
2724
%0 = add i32 %x, %y
2825
ret i32 %0
2926
}
3027

3128
; Function Attrs: nounwind
32-
define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
29+
define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
3330
entry:
3431
%0 = icmp eq i32 %x, %y
3532
ret i1 %0
3633
}
3734

3835
; Function Attrs: nounwind
39-
define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
36+
define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
4037
entry:
4138
%0 = icmp eq i32 %y, 0
4239
br i1 %0, label %divbyzero.throw, label %divbyzero.next
@@ -50,14 +47,14 @@ divbyzero.next: ; preds = %entry
5047
ret i32 %5
5148

5249
divbyzero.throw: ; preds = %entry
53-
call void @runtime.divideByZeroPanic(ptr undef) #3
50+
call void @runtime.divideByZeroPanic(ptr undef) #2
5451
unreachable
5552
}
5653

57-
declare void @runtime.divideByZeroPanic(ptr) #1
54+
declare void @runtime.divideByZeroPanic(ptr) #0
5855

5956
; Function Attrs: nounwind
60-
define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
57+
define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
6158
entry:
6259
%0 = icmp eq i32 %y, 0
6360
br i1 %0, label %divbyzero.throw, label %divbyzero.next
@@ -67,12 +64,12 @@ divbyzero.next: ; preds = %entry
6764
ret i32 %1
6865

6966
divbyzero.throw: ; preds = %entry
70-
call void @runtime.divideByZeroPanic(ptr undef) #3
67+
call void @runtime.divideByZeroPanic(ptr undef) #2
7168
unreachable
7269
}
7370

7471
; Function Attrs: nounwind
75-
define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
72+
define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
7673
entry:
7774
%0 = icmp eq i32 %y, 0
7875
br i1 %0, label %divbyzero.throw, label %divbyzero.next
@@ -86,12 +83,12 @@ divbyzero.next: ; preds = %entry
8683
ret i32 %5
8784

8885
divbyzero.throw: ; preds = %entry
89-
call void @runtime.divideByZeroPanic(ptr undef) #3
86+
call void @runtime.divideByZeroPanic(ptr undef) #2
9087
unreachable
9188
}
9289

9390
; Function Attrs: nounwind
94-
define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
91+
define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
9592
entry:
9693
%0 = icmp eq i32 %y, 0
9794
br i1 %0, label %divbyzero.throw, label %divbyzero.next
@@ -101,66 +98,66 @@ divbyzero.next: ; preds = %entry
10198
ret i32 %1
10299

103100
divbyzero.throw: ; preds = %entry
104-
call void @runtime.divideByZeroPanic(ptr undef) #3
101+
call void @runtime.divideByZeroPanic(ptr undef) #2
105102
unreachable
106103
}
107104

108105
; Function Attrs: nounwind
109-
define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #2 {
106+
define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #1 {
110107
entry:
111108
%0 = fcmp oeq float %x, %y
112109
ret i1 %0
113110
}
114111

115112
; Function Attrs: nounwind
116-
define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #2 {
113+
define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #1 {
117114
entry:
118115
%0 = fcmp une float %x, %y
119116
ret i1 %0
120117
}
121118

122119
; Function Attrs: nounwind
123-
define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #2 {
120+
define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #1 {
124121
entry:
125122
%0 = fcmp olt float %x, %y
126123
ret i1 %0
127124
}
128125

129126
; Function Attrs: nounwind
130-
define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #2 {
127+
define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
131128
entry:
132129
%0 = fcmp ole float %x, %y
133130
ret i1 %0
134131
}
135132

136133
; Function Attrs: nounwind
137-
define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #2 {
134+
define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #1 {
138135
entry:
139136
%0 = fcmp ogt float %x, %y
140137
ret i1 %0
141138
}
142139

143140
; Function Attrs: nounwind
144-
define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #2 {
141+
define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
145142
entry:
146143
%0 = fcmp oge float %x, %y
147144
ret i1 %0
148145
}
149146

150147
; Function Attrs: nounwind
151-
define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #2 {
148+
define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
152149
entry:
153150
ret float %x.r
154151
}
155152

156153
; Function Attrs: nounwind
157-
define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #2 {
154+
define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
158155
entry:
159156
ret float %x.i
160157
}
161158

162159
; Function Attrs: nounwind
163-
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
160+
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
164161
entry:
165162
%0 = fadd float %x.r, %y.r
166163
%1 = fadd float %x.i, %y.i
@@ -170,7 +167,7 @@ entry:
170167
}
171168

172169
; Function Attrs: nounwind
173-
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
170+
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
174171
entry:
175172
%0 = fsub float %x.r, %y.r
176173
%1 = fsub float %x.i, %y.i
@@ -180,7 +177,7 @@ entry:
180177
}
181178

182179
; Function Attrs: nounwind
183-
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
180+
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
184181
entry:
185182
%0 = fmul float %x.r, %y.r
186183
%1 = fmul float %x.i, %y.i
@@ -194,19 +191,18 @@ entry:
194191
}
195192

196193
; Function Attrs: nounwind
197-
define hidden void @main.foo(ptr %context) unnamed_addr #2 {
194+
define hidden void @main.foo(ptr %context) unnamed_addr #1 {
198195
entry:
199196
call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef)
200197
ret void
201198
}
202199

203200
; Function Attrs: nounwind
204-
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #2 {
201+
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 {
205202
entry:
206203
ret void
207204
}
208205

209-
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
210-
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
211-
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
212-
attributes #3 = { nounwind }
206+
attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
207+
attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
208+
attributes #2 = { nounwind }

compiler/testdata/channel.ll

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,76 +6,73 @@ target triple = "wasm32-unknown-wasi"
66
%runtime.channelOp = type { ptr, ptr, i32, ptr }
77
%runtime.chanSelectState = type { ptr, ptr }
88

9-
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
10-
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
11-
12-
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
9+
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
1310

1411
; Function Attrs: nounwind
15-
define hidden void @main.init(ptr %context) unnamed_addr #2 {
12+
define hidden void @main.init(ptr %context) unnamed_addr #1 {
1613
entry:
1714
ret void
1815
}
1916

2017
; Function Attrs: nounwind
21-
define hidden void @main.chanIntSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 {
18+
define hidden void @main.chanIntSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
2219
entry:
2320
%chan.op = alloca %runtime.channelOp, align 8
2421
%chan.value = alloca i32, align 4
2522
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
2623
store i32 3, ptr %chan.value, align 4
2724
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
28-
call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #4
25+
call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3
2926
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
3027
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
3128
ret void
3229
}
3330

3431
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
35-
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3
32+
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2
3633

37-
declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #1
34+
declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0
3835

3936
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
40-
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3
37+
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2
4138

4239
; Function Attrs: nounwind
43-
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 {
40+
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
4441
entry:
4542
%chan.op = alloca %runtime.channelOp, align 8
4643
%chan.value = alloca i32, align 4
4744
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
4845
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
49-
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #4
46+
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3
5047
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
5148
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
5249
ret void
5350
}
5451

55-
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #1
52+
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0
5653

5754
; Function Attrs: nounwind
58-
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 {
55+
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
5956
entry:
6057
%chan.op = alloca %runtime.channelOp, align 8
6158
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
62-
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #4
59+
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3
6360
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
6461
ret void
6562
}
6663

6764
; Function Attrs: nounwind
68-
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 {
65+
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
6966
entry:
7067
%chan.op = alloca %runtime.channelOp, align 8
7168
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
72-
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #4
69+
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3
7370
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
7471
ret void
7572
}
7673

7774
; Function Attrs: nounwind
78-
define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(36) %ch1, ptr dereferenceable_or_null(36) %ch2, ptr %context) unnamed_addr #2 {
75+
define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(36) %ch1, ptr dereferenceable_or_null(36) %ch2, ptr %context) unnamed_addr #1 {
7976
entry:
8077
%select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8
8178
%select.send.value = alloca i32, align 4
@@ -88,7 +85,7 @@ entry:
8885
store ptr %ch2, ptr %0, align 4
8986
%.repack3 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 12
9087
store ptr null, ptr %.repack3, align 4
91-
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4
88+
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #3
9289
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
9390
%1 = extractvalue { i32, i1 } %select.result, 0
9491
%2 = icmp eq i32 %1, 0
@@ -105,10 +102,9 @@ select.body: ; preds = %select.next
105102
br label %select.done
106103
}
107104

108-
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1
105+
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #0
109106

110-
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
111-
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
112-
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
113-
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
114-
attributes #4 = { nounwind }
107+
attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
108+
attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
109+
attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
110+
attributes #3 = { nounwind }

0 commit comments

Comments
 (0)