Skip to content

Commit 519adf3

Browse files
aykevldeadprogram
authored andcommitted
transform: wasm-abi: create temporary allocas in the entry block
This avoids problems with goroutines in WebAssembly, and is generally a good thing. It fixes some cases of the following problem: LLVM ERROR: Coroutines cannot handle non static allocas yet
1 parent 4d79d47 commit 519adf3

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

transform/testdata/wasm-abi.out.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ define internal i64 @testCall(i8* %ptr, i32 %len, i64 %foo) {
1414

1515
define internal i64 @testCallNonEntry(i8* %ptr, i32 %len) {
1616
entry:
17+
%i64asptr = alloca i64
18+
%i64asptr1 = alloca i64
1719
br label %bb1
1820

1921
bb1: ; preds = %entry
20-
%i64asptr = alloca i64
21-
%i64asptr1 = alloca i64
2222
store i64 3, i64* %i64asptr1
2323
call void @externalCall(i64* %i64asptr, i8* %ptr, i32 %len, i64* %i64asptr1)
2424
%retval = load i64, i64* %i64asptr

transform/wasm-abi.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ func ExternalInt64AsPtr(mod llvm.Module) error {
2222
int64Type := ctx.Int64Type()
2323
int64PtrType := llvm.PointerType(int64Type, 0)
2424

25+
// This builder is only used for creating new allocas in the entry block of
26+
// a function, avoiding many SetInsertPoint* calls.
27+
entryBlockBuilder := ctx.NewBuilder()
28+
defer entryBlockBuilder.Dispose()
29+
2530
for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
2631
if fn.Linkage() != llvm.ExternalLinkage {
2732
// Only change externally visible functions (exports and imports).
@@ -77,19 +82,20 @@ func ExternalInt64AsPtr(mod llvm.Module) error {
7782
// be left in place.
7883
for use := fn.FirstUse(); !use.IsNil(); use = use.NextUse() {
7984
call := use.User()
85+
entryBlockBuilder.SetInsertPointBefore(call.InstructionParent().Parent().EntryBasicBlock().FirstInstruction())
8086
builder.SetInsertPointBefore(call)
8187
callParams := []llvm.Value{}
8288
var retvalAlloca llvm.Value
8389
if fnType.ReturnType() == int64Type {
84-
retvalAlloca = builder.CreateAlloca(int64Type, "i64asptr")
90+
retvalAlloca = entryBlockBuilder.CreateAlloca(int64Type, "i64asptr")
8591
callParams = append(callParams, retvalAlloca)
8692
}
8793
for i := 0; i < call.OperandsCount()-1; i++ {
8894
operand := call.Operand(i)
8995
if operand.Type() == int64Type {
9096
// Pass a stack-allocated pointer instead of the value
9197
// itself.
92-
alloca := builder.CreateAlloca(int64Type, "i64asptr")
98+
alloca := entryBlockBuilder.CreateAlloca(int64Type, "i64asptr")
9399
builder.CreateStore(operand, alloca)
94100
callParams = append(callParams, alloca)
95101
} else {

0 commit comments

Comments
 (0)