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
Этот коммит содержится в:
родитель
4d79d473c4
коммит
519adf3aef
2 изменённых файлов: 10 добавлений и 4 удалений
4
transform/testdata/wasm-abi.out.ll
предоставленный
4
transform/testdata/wasm-abi.out.ll
предоставленный
|
@ -14,11 +14,11 @@ define internal i64 @testCall(i8* %ptr, i32 %len, i64 %foo) {
|
||||||
|
|
||||||
define internal i64 @testCallNonEntry(i8* %ptr, i32 %len) {
|
define internal i64 @testCallNonEntry(i8* %ptr, i32 %len) {
|
||||||
entry:
|
entry:
|
||||||
|
%i64asptr = alloca i64
|
||||||
|
%i64asptr1 = alloca i64
|
||||||
br label %bb1
|
br label %bb1
|
||||||
|
|
||||||
bb1: ; preds = %entry
|
bb1: ; preds = %entry
|
||||||
%i64asptr = alloca i64
|
|
||||||
%i64asptr1 = alloca i64
|
|
||||||
store i64 3, i64* %i64asptr1
|
store i64 3, i64* %i64asptr1
|
||||||
call void @externalCall(i64* %i64asptr, i8* %ptr, i32 %len, i64* %i64asptr1)
|
call void @externalCall(i64* %i64asptr, i8* %ptr, i32 %len, i64* %i64asptr1)
|
||||||
%retval = load i64, i64* %i64asptr
|
%retval = load i64, i64* %i64asptr
|
||||||
|
|
|
@ -22,6 +22,11 @@ func ExternalInt64AsPtr(mod llvm.Module) error {
|
||||||
int64Type := ctx.Int64Type()
|
int64Type := ctx.Int64Type()
|
||||||
int64PtrType := llvm.PointerType(int64Type, 0)
|
int64PtrType := llvm.PointerType(int64Type, 0)
|
||||||
|
|
||||||
|
// This builder is only used for creating new allocas in the entry block of
|
||||||
|
// a function, avoiding many SetInsertPoint* calls.
|
||||||
|
entryBlockBuilder := ctx.NewBuilder()
|
||||||
|
defer entryBlockBuilder.Dispose()
|
||||||
|
|
||||||
for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
|
for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
|
||||||
if fn.Linkage() != llvm.ExternalLinkage {
|
if fn.Linkage() != llvm.ExternalLinkage {
|
||||||
// Only change externally visible functions (exports and imports).
|
// Only change externally visible functions (exports and imports).
|
||||||
|
@ -77,11 +82,12 @@ func ExternalInt64AsPtr(mod llvm.Module) error {
|
||||||
// be left in place.
|
// be left in place.
|
||||||
for use := fn.FirstUse(); !use.IsNil(); use = use.NextUse() {
|
for use := fn.FirstUse(); !use.IsNil(); use = use.NextUse() {
|
||||||
call := use.User()
|
call := use.User()
|
||||||
|
entryBlockBuilder.SetInsertPointBefore(call.InstructionParent().Parent().EntryBasicBlock().FirstInstruction())
|
||||||
builder.SetInsertPointBefore(call)
|
builder.SetInsertPointBefore(call)
|
||||||
callParams := []llvm.Value{}
|
callParams := []llvm.Value{}
|
||||||
var retvalAlloca llvm.Value
|
var retvalAlloca llvm.Value
|
||||||
if fnType.ReturnType() == int64Type {
|
if fnType.ReturnType() == int64Type {
|
||||||
retvalAlloca = builder.CreateAlloca(int64Type, "i64asptr")
|
retvalAlloca = entryBlockBuilder.CreateAlloca(int64Type, "i64asptr")
|
||||||
callParams = append(callParams, retvalAlloca)
|
callParams = append(callParams, retvalAlloca)
|
||||||
}
|
}
|
||||||
for i := 0; i < call.OperandsCount()-1; i++ {
|
for i := 0; i < call.OperandsCount()-1; i++ {
|
||||||
|
@ -89,7 +95,7 @@ func ExternalInt64AsPtr(mod llvm.Module) error {
|
||||||
if operand.Type() == int64Type {
|
if operand.Type() == int64Type {
|
||||||
// Pass a stack-allocated pointer instead of the value
|
// Pass a stack-allocated pointer instead of the value
|
||||||
// itself.
|
// itself.
|
||||||
alloca := builder.CreateAlloca(int64Type, "i64asptr")
|
alloca := entryBlockBuilder.CreateAlloca(int64Type, "i64asptr")
|
||||||
builder.CreateStore(operand, alloca)
|
builder.CreateStore(operand, alloca)
|
||||||
callParams = append(callParams, alloca)
|
callParams = append(callParams, alloca)
|
||||||
} else {
|
} else {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче