ci: add support for LLVM 15
This commit switches to LLVM 15 everywhere by default, while still keeping LLVM 14 support.
Этот коммит содержится в:
родитель
08a51535d4
коммит
2b7f562202
40 изменённых файлов: 895 добавлений и 881 удалений
6
.github/workflows/build-macos.yml
предоставленный
6
.github/workflows/build-macos.yml
предоставленный
|
@ -40,7 +40,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-macos-v1
|
||||
key: llvm-source-15-macos-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -54,7 +54,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-macos-v1
|
||||
key: llvm-build-15-macos-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
@ -108,7 +108,7 @@ jobs:
|
|||
- name: Install LLVM
|
||||
shell: bash
|
||||
run: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@14
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@15
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Go
|
||||
|
|
16
.github/workflows/linux.yml
предоставленный
16
.github/workflows/linux.yml
предоставленный
|
@ -43,7 +43,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-linux-alpine-v1
|
||||
key: llvm-source-15-linux-alpine-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -57,7 +57,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-linux-alpine-v1
|
||||
key: llvm-build-15-linux-alpine-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
@ -185,7 +185,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-linux-asserts-v2
|
||||
key: llvm-source-15-linux-asserts-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -199,7 +199,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-linux-asserts-v1
|
||||
key: llvm-build-15-linux-asserts-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
@ -277,7 +277,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-linux-v2
|
||||
key: llvm-source-15-linux-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -291,7 +291,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-linux-arm-v1
|
||||
key: llvm-build-15-linux-arm-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
@ -377,7 +377,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-linux-v1
|
||||
key: llvm-source-15-linux-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -391,7 +391,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-linux-arm64-v1
|
||||
key: llvm-build-15-linux-arm64-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
|
4
.github/workflows/windows.yml
предоставленный
4
.github/workflows/windows.yml
предоставленный
|
@ -35,7 +35,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-14-windows-v2
|
||||
key: llvm-source-15-windows-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
|
@ -49,7 +49,7 @@ jobs:
|
|||
uses: actions/cache@v3
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-14-windows-v2
|
||||
key: llvm-build-15-windows-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
|
6
Makefile
6
Makefile
|
@ -113,7 +113,7 @@ endif
|
|||
|
||||
.PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-nxp gen-device-avr gen-device-rp
|
||||
|
||||
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsmanifest
|
||||
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE = .exe
|
||||
|
@ -148,7 +148,7 @@ else
|
|||
endif
|
||||
|
||||
# Libraries that should be linked in for the statically linked Clang.
|
||||
CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
|
||||
CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
|
||||
CLANG_LIBS = $(START_GROUP) $(addprefix -l,$(CLANG_LIB_NAMES)) $(END_GROUP) -lstdc++
|
||||
|
||||
# Libraries that should be linked in for the statically linked LLD.
|
||||
|
@ -236,7 +236,7 @@ gen-device-rp: build/gen-device-svd
|
|||
|
||||
# Get LLVM sources.
|
||||
$(LLVM_PROJECTDIR)/llvm:
|
||||
git clone -b xtensa_release_14.0.0-patched --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
|
||||
git clone -b xtensa_release_15.x --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
|
||||
llvm-source: $(LLVM_PROJECTDIR)/llvm
|
||||
|
||||
# Configure LLVM.
|
||||
|
|
|
@ -101,6 +101,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||
|
||||
// Target Options
|
||||
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
|
||||
if (Arg *A = Args.getLastArg(options::OPT_darwin_target_variant_triple))
|
||||
Opts.DarwinTargetVariantTriple = llvm::Triple(A->getValue());
|
||||
|
||||
Opts.CPU = std::string(Args.getLastArgValue(OPT_target_cpu));
|
||||
Opts.Features = Args.getAllArgValues(OPT_target_feature);
|
||||
|
||||
|
@ -203,6 +206,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||
.Default(0);
|
||||
}
|
||||
|
||||
if (auto *A = Args.getLastArg(OPT_femit_dwarf_unwind_EQ)) {
|
||||
Opts.EmitDwarfUnwind =
|
||||
llvm::StringSwitch<EmitDwarfUnwindType>(A->getValue())
|
||||
.Case("always", EmitDwarfUnwindType::Always)
|
||||
.Case("no-compact-unwind", EmitDwarfUnwindType::NoCompactUnwind)
|
||||
.Case("default", EmitDwarfUnwindType::Default);
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
@ -253,6 +264,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||
assert(MRI && "Unable to create target register info!");
|
||||
|
||||
MCTargetOptions MCOptions;
|
||||
MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
|
||||
|
||||
std::unique_ptr<MCAsmInfo> MAI(
|
||||
TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions));
|
||||
assert(MAI && "Unable to create target asm info!");
|
||||
|
@ -299,6 +312,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
|
||||
std::unique_ptr<MCObjectFileInfo> MOFI(
|
||||
TheTarget->createMCObjectFileInfo(Ctx, PIC));
|
||||
if (Opts.DarwinTargetVariantTriple)
|
||||
MOFI->setDarwinTargetVariantTriple(*Opts.DarwinTargetVariantTriple);
|
||||
Ctx.setObjectFileInfo(MOFI.get());
|
||||
|
||||
if (Opts.SaveTemporaryLabels)
|
||||
|
@ -347,7 +362,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||
|
||||
std::unique_ptr<MCCodeEmitter> CE;
|
||||
if (Opts.ShowEncoding)
|
||||
CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
|
||||
CE.reset(TheTarget->createMCCodeEmitter(*MCII, Ctx));
|
||||
std::unique_ptr<MCAsmBackend> MAB(
|
||||
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
|
||||
|
||||
|
@ -367,7 +382,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||
}
|
||||
|
||||
std::unique_ptr<MCCodeEmitter> CE(
|
||||
TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
|
||||
TheTarget->createMCCodeEmitter(*MCII, Ctx));
|
||||
std::unique_ptr<MCAsmBackend> MAB(
|
||||
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
|
||||
assert(MAB && "Unable to create asm backend!");
|
||||
|
@ -389,7 +404,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||
if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) {
|
||||
MCSection *AsmLabel = Ctx.getMachOSection(
|
||||
"__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly());
|
||||
Str.get()->SwitchSection(AsmLabel);
|
||||
Str.get()->switchSection(AsmLabel);
|
||||
Str.get()->emitZeros(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@ struct AssemblerInvocation {
|
|||
unsigned IncrementalLinkerCompatible : 1;
|
||||
unsigned EmbedBitcode : 1;
|
||||
|
||||
/// Whether to emit DWARF unwind info.
|
||||
EmitDwarfUnwindType EmitDwarfUnwind;
|
||||
|
||||
/// The name of the relocation model to use.
|
||||
std::string RelocationModel;
|
||||
|
||||
|
@ -92,6 +95,9 @@ struct AssemblerInvocation {
|
|||
/// otherwise.
|
||||
std::string TargetABI;
|
||||
|
||||
/// Darwin target variant triple, the variant of the deployment target
|
||||
/// for which the code is being compiled.
|
||||
llvm::Optional<llvm::Triple> DarwinTargetVariantTriple;
|
||||
/// @}
|
||||
|
||||
public:
|
||||
|
@ -112,6 +118,7 @@ public:
|
|||
Dwarf64 = 0;
|
||||
DwarfVersion = 0;
|
||||
EmbedBitcode = 0;
|
||||
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
|
||||
}
|
||||
|
||||
static bool CreateFromArgs(AssemblerInvocation &Res,
|
||||
|
|
|
@ -6,10 +6,12 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
var Musl = Library{
|
||||
|
@ -77,7 +79,7 @@ var Musl = Library{
|
|||
cflags: func(target, headerPath string) []string {
|
||||
arch := compileopts.MuslArchitecture(target)
|
||||
muslDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl")
|
||||
return []string{
|
||||
cflags := []string{
|
||||
"-std=c99", // same as in musl
|
||||
"-D_XOPEN_SOURCE=700", // same as in musl
|
||||
// Musl triggers some warnings and we don't want to show any
|
||||
|
@ -104,6 +106,12 @@ var Musl = Library{
|
|||
"-I" + muslDir + "/include",
|
||||
"-fno-stack-protector",
|
||||
}
|
||||
llvmMajor, _ := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0])
|
||||
if llvmMajor >= 15 {
|
||||
// This flag was added in Clang 15. It is not present in LLVM 14.
|
||||
cflags = append(cflags, "-Wno-deprecated-non-prototype")
|
||||
}
|
||||
return cflags
|
||||
},
|
||||
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl/src") },
|
||||
librarySources: func(target string) ([]string, error) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:build !byollvm
|
||||
// +build !byollvm
|
||||
//go:build !byollvm && llvm14
|
||||
// +build !byollvm,llvm14
|
||||
|
||||
package cgo
|
||||
|
||||
|
|
16
cgo/libclang_config_llvm15.go
Обычный файл
16
cgo/libclang_config_llvm15.go
Обычный файл
|
@ -0,0 +1,16 @@
|
|||
//go:build !byollvm && !llvm14
|
||||
// +build !byollvm,!llvm14
|
||||
|
||||
package cgo
|
||||
|
||||
/*
|
||||
#cgo linux CFLAGS: -I/usr/lib/llvm-15/include
|
||||
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@15/include
|
||||
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@15/include
|
||||
#cgo freebsd CFLAGS: -I/usr/local/llvm15/include
|
||||
#cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lclang
|
||||
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -lclang -lffi
|
||||
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -lclang -lffi
|
||||
#cgo freebsd LDFLAGS: -L/usr/local/llvm15/lib -lclang
|
||||
*/
|
||||
import "C"
|
|
@ -57,14 +57,15 @@ func (b *builder) extractFuncContext(funcValue llvm.Value) llvm.Value {
|
|||
// value. This may be an expensive operation.
|
||||
func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcType llvm.Type, funcPtr, context llvm.Value) {
|
||||
context = b.CreateExtractValue(funcValue, 0, "")
|
||||
bitcast := b.CreateExtractValue(funcValue, 1, "")
|
||||
if !bitcast.IsAConstantExpr().IsNil() && bitcast.Opcode() == llvm.BitCast {
|
||||
funcPtr = bitcast.Operand(0)
|
||||
return
|
||||
funcPtr = b.CreateExtractValue(funcValue, 1, "")
|
||||
if !funcPtr.IsAConstantExpr().IsNil() && funcPtr.Opcode() == llvm.BitCast {
|
||||
funcPtr = funcPtr.Operand(0) // needed for LLVM 14 (no opaque pointers)
|
||||
}
|
||||
if sig != nil {
|
||||
funcType = b.getRawFuncType(sig)
|
||||
llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace)
|
||||
funcPtr = b.CreateBitCast(funcPtr, llvmSig, "")
|
||||
}
|
||||
funcType = b.getRawFuncType(sig)
|
||||
llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace)
|
||||
funcPtr = b.CreateBitCast(bitcast, llvmSig, "")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
|
@ -44,7 +45,10 @@ func (b *builder) defineIntrinsicFunction() {
|
|||
// and will otherwise be lowered to regular libc memcpy/memmove calls.
|
||||
func (b *builder) createMemoryCopyImpl() {
|
||||
b.createFunctionStart(true)
|
||||
fnName := "llvm." + b.fn.Name() + ".p0i8.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
fnName := "llvm." + b.fn.Name() + ".p0.p0.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
if llvmutil.Major() < 15 { // compatibility with LLVM 14
|
||||
fnName = "llvm." + b.fn.Name() + ".p0i8.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
}
|
||||
llvmFn := b.mod.NamedFunction(fnName)
|
||||
if llvmFn.IsNil() {
|
||||
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.i8ptrType, b.i8ptrType, b.uintptrType, b.ctx.Int1Type()}, false)
|
||||
|
@ -64,7 +68,10 @@ func (b *builder) createMemoryCopyImpl() {
|
|||
// regular libc memset calls if they aren't optimized out in a different way.
|
||||
func (b *builder) createMemoryZeroImpl() {
|
||||
b.createFunctionStart(true)
|
||||
fnName := "llvm.memset.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
fnName := "llvm.memset.p0.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
if llvmutil.Major() < 15 { // compatibility with LLVM 14
|
||||
fnName = "llvm.memset.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
|
||||
}
|
||||
llvmFn := b.mod.NamedFunction(fnName)
|
||||
if llvmFn.IsNil() {
|
||||
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.i8ptrType, b.ctx.Int8Type(), b.uintptrType, b.ctx.Int1Type()}, false)
|
||||
|
|
|
@ -7,7 +7,22 @@
|
|||
// places would be a big risk if only one of them is updated.
|
||||
package llvmutil
|
||||
|
||||
import "tinygo.org/x/go-llvm"
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
// Major returns the LLVM major version.
|
||||
func Major() int {
|
||||
llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0])
|
||||
if err != nil {
|
||||
// sanity check, should be unreachable
|
||||
panic("could not parse LLVM version: " + err.Error())
|
||||
}
|
||||
return llvmMajor
|
||||
}
|
||||
|
||||
// CreateEntryBlockAlloca creates a new alloca in the entry block, even though
|
||||
// the IR builder is located elsewhere. It assumes that the insert point is
|
||||
|
@ -78,12 +93,16 @@ func EmitLifetimeEnd(builder llvm.Builder, mod llvm.Module, ptr, size llvm.Value
|
|||
// getLifetimeStartFunc returns the llvm.lifetime.start intrinsic and creates it
|
||||
// first if it doesn't exist yet.
|
||||
func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) {
|
||||
fn := mod.NamedFunction("llvm.lifetime.start.p0i8")
|
||||
fnName := "llvm.lifetime.start.p0"
|
||||
if Major() < 15 { // compatibility with LLVM 14
|
||||
fnName = "llvm.lifetime.start.p0i8"
|
||||
}
|
||||
fn := mod.NamedFunction(fnName)
|
||||
ctx := mod.Context()
|
||||
i8ptrType := llvm.PointerType(ctx.Int8Type(), 0)
|
||||
fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
|
||||
if fn.IsNil() {
|
||||
fn = llvm.AddFunction(mod, "llvm.lifetime.start.p0i8", fnType)
|
||||
fn = llvm.AddFunction(mod, fnName, fnType)
|
||||
}
|
||||
return fnType, fn
|
||||
}
|
||||
|
@ -91,12 +110,16 @@ func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) {
|
|||
// getLifetimeEndFunc returns the llvm.lifetime.end intrinsic and creates it
|
||||
// first if it doesn't exist yet.
|
||||
func getLifetimeEndFunc(mod llvm.Module) (llvm.Type, llvm.Value) {
|
||||
fn := mod.NamedFunction("llvm.lifetime.end.p0i8")
|
||||
fnName := "llvm.lifetime.end.p0"
|
||||
if Major() < 15 {
|
||||
fnName = "llvm.lifetime.end.p0i8"
|
||||
}
|
||||
fn := mod.NamedFunction(fnName)
|
||||
ctx := mod.Context()
|
||||
i8ptrType := llvm.PointerType(ctx.Int8Type(), 0)
|
||||
fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
|
||||
if fn.IsNil() {
|
||||
fn = llvm.AddFunction(mod, "llvm.lifetime.end.p0i8", fnType)
|
||||
fn = llvm.AddFunction(mod, fnName, fnType)
|
||||
}
|
||||
return fnType, fn
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"github.com/tinygo-org/tinygo/loader"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"tinygo.org/x/go-llvm"
|
||||
|
@ -353,7 +354,15 @@ func (c *compilerContext) addStandardDefinedAttributes(llvmFn llvm.Value) {
|
|||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nounwind"), 0))
|
||||
if strings.Split(c.Triple, "-")[0] == "x86_64" {
|
||||
// Required by the ABI.
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 0))
|
||||
if llvmutil.Major() < 15 {
|
||||
// Needed for LLVM 14 support.
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 0))
|
||||
} else {
|
||||
// The uwtable has two possible values: sync (1) or async (2). We
|
||||
// use sync because we currently don't use async unwind tables.
|
||||
// For details, see: https://llvm.org/docs/LangRef.html#function-attributes
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
compiler/testdata/basic.go
предоставленный
12
compiler/testdata/basic.go
предоставленный
|
@ -75,14 +75,18 @@ func complexMul(x, y complex64) complex64 {
|
|||
// A type 'kv' also exists in function foo. Test that these two types don't
|
||||
// conflict with each other.
|
||||
type kv struct {
|
||||
v float32
|
||||
v float32
|
||||
x, y, z int
|
||||
}
|
||||
|
||||
func foo(a *kv) {
|
||||
var kvGlobal kv
|
||||
|
||||
func foo() {
|
||||
// Define a new 'kv' type.
|
||||
type kv struct {
|
||||
v byte
|
||||
v byte
|
||||
x, y, z int
|
||||
}
|
||||
// Use this type.
|
||||
func(b *kv) {}(nil)
|
||||
func(b kv) {}(kv{})
|
||||
}
|
||||
|
|
69
compiler/testdata/basic.ll
предоставленный
69
compiler/testdata/basic.ll
предоставленный
|
@ -3,35 +3,37 @@ source_filename = "basic.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%main.kv = type { float }
|
||||
%main.kv.0 = type { i8 }
|
||||
%main.kv = type { float, i32, i32, i32 }
|
||||
%main.kv.0 = type { i8, i32, i32, i32 }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
@main.kvGlobal = hidden global %main.kv zeroinitializer, align 4
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.addInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = add i32 %x, %y
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.equalInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.divInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
|
@ -45,14 +47,14 @@ divbyzero.next: ; preds = %entry
|
|||
ret i32 %5
|
||||
|
||||
divbyzero.throw: ; preds = %entry
|
||||
call void @runtime.divideByZeroPanic(i8* undef) #2
|
||||
call void @runtime.divideByZeroPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.divideByZeroPanic(i8*) #0
|
||||
declare void @runtime.divideByZeroPanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.divUint(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
|
@ -62,12 +64,12 @@ divbyzero.next: ; preds = %entry
|
|||
ret i32 %1
|
||||
|
||||
divbyzero.throw: ; preds = %entry
|
||||
call void @runtime.divideByZeroPanic(i8* undef) #2
|
||||
call void @runtime.divideByZeroPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.remInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
|
@ -81,12 +83,12 @@ divbyzero.next: ; preds = %entry
|
|||
ret i32 %5
|
||||
|
||||
divbyzero.throw: ; preds = %entry
|
||||
call void @runtime.divideByZeroPanic(i8* undef) #2
|
||||
call void @runtime.divideByZeroPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.remUint(i32 %x, i32 %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
|
@ -96,66 +98,66 @@ divbyzero.next: ; preds = %entry
|
|||
ret i32 %1
|
||||
|
||||
divbyzero.throw: ; preds = %entry
|
||||
call void @runtime.divideByZeroPanic(i8* undef) #2
|
||||
call void @runtime.divideByZeroPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatEQ(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp oeq float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatNE(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp une float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatLower(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp olt float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatLowerEqual(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp ole float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatGreater(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp ogt float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatGreaterEqual(float %x, float %y, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp oge float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.complexReal(float %x.r, float %x.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float %x.r
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.complexImag(float %x.r, float %x.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float %x.i
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fadd float %x.r, %y.r
|
||||
%1 = fadd float %x.i, %y.i
|
||||
|
@ -165,7 +167,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fsub float %x.r, %y.r
|
||||
%1 = fsub float %x.i, %y.i
|
||||
|
@ -175,7 +177,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fmul float %x.r, %y.r
|
||||
%1 = fmul float %x.i, %y.i
|
||||
|
@ -189,15 +191,22 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.foo(%main.kv* dereferenceable_or_null(4) %a, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.foo(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"main.foo$1"(%main.kv.0* null, i8* undef)
|
||||
%complit = alloca %main.kv.0, align 8
|
||||
store %main.kv.0 zeroinitializer, ptr %complit, align 8
|
||||
call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #2
|
||||
call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%b1 = alloca %main.kv.0, align 8
|
||||
store %main.kv.0 zeroinitializer, ptr %b1, align 8
|
||||
call void @runtime.trackPointer(ptr nonnull %b1, ptr undef) #2
|
||||
store %main.kv.0 %b, ptr %b1, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
110
compiler/testdata/channel.ll
предоставленный
110
compiler/testdata/channel.ll
предоставленный
|
@ -3,110 +3,94 @@ source_filename = "channel.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type { i8* }
|
||||
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
|
||||
%"internal/task.stackState" = type { i32, i32 }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
%runtime.channelBlockedList = type { ptr, ptr, ptr, { ptr, i32, i32 } }
|
||||
%runtime.chanSelectState = type { ptr, ptr }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanIntSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.chanIntSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
%chan.value.bitcast = bitcast i32* %chan.value to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %chan.value.bitcast)
|
||||
store i32 3, i32* %chan.value, align 4
|
||||
%chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @runtime.chanSend(%runtime.channel* %ch, i8* nonnull %chan.value.bitcast, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3
|
||||
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %chan.value.bitcast)
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
|
||||
store i32 3, ptr %chan.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.blockedList, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2
|
||||
; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2
|
||||
|
||||
declare void @runtime.chanSend(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*) #0
|
||||
declare void @runtime.chanSend(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #0
|
||||
|
||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2
|
||||
; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanIntRecv(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
%chan.value.bitcast = bitcast i32* %chan.value to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %chan.value.bitcast)
|
||||
%chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
%0 = call i1 @runtime.chanRecv(%runtime.channel* %ch, i8* nonnull %chan.value.bitcast, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3
|
||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %chan.value.bitcast)
|
||||
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.blockedList, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i1 @runtime.chanRecv(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*) #0
|
||||
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanZeroSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%complit = alloca {}, align 8
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%0 = bitcast {}* %complit to i8*
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #3
|
||||
%chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @runtime.chanSend(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3
|
||||
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #3
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanZeroRecv(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
%0 = call i1 @runtime.chanRecv(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3
|
||||
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast)
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.selectZeroRecv(%runtime.channel* dereferenceable_or_null(32) %ch1, %runtime.channel* dereferenceable_or_null(32) %ch2, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(32) %ch1, ptr dereferenceable_or_null(32) %ch2, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8
|
||||
%select.send.value = alloca i32, align 4
|
||||
store i32 1, i32* %select.send.value, align 4
|
||||
%select.states.alloca.bitcast = bitcast [2 x %runtime.chanSelectState]* %select.states.alloca to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %select.states.alloca.bitcast)
|
||||
%.repack = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0, i32 0
|
||||
store %runtime.channel* %ch1, %runtime.channel** %.repack, align 8
|
||||
%.repack1 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0, i32 1
|
||||
%0 = bitcast i8** %.repack1 to i32**
|
||||
store i32* %select.send.value, i32** %0, align 4
|
||||
%.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 1, i32 0
|
||||
store %runtime.channel* %ch2, %runtime.channel** %.repack3, align 8
|
||||
%.repack4 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 1, i32 1
|
||||
store i8* null, i8** %.repack4, align 4
|
||||
%select.states = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0
|
||||
%select.result = call { i32, i1 } @runtime.tryChanSelect(i8* undef, %runtime.chanSelectState* nonnull %select.states, i32 2, i32 2, i8* undef) #3
|
||||
call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %select.states.alloca.bitcast)
|
||||
store i32 1, ptr %select.send.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||
store ptr %ch1, ptr %select.states.alloca, align 8
|
||||
%select.states.alloca.repack1 = getelementptr inbounds %runtime.chanSelectState, ptr %select.states.alloca, i32 0, i32 1
|
||||
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
||||
%0 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1
|
||||
store ptr %ch2, ptr %0, align 8
|
||||
%.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1, i32 1
|
||||
store ptr null, ptr %.repack3, align 4
|
||||
%select.result = call { i32, i1 } @runtime.tryChanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||
%1 = extractvalue { i32, i1 } %select.result, 0
|
||||
%2 = icmp eq i32 %1, 0
|
||||
br i1 %2, label %select.done, label %select.next
|
||||
|
@ -122,9 +106,9 @@ select.body: ; preds = %select.next
|
|||
br label %select.done
|
||||
}
|
||||
|
||||
declare { i32, i1 } @runtime.tryChanSelect(i8*, %runtime.chanSelectState*, i32, i32, i8*) #0
|
||||
declare { i32, i1 } @runtime.tryChanSelect(ptr, ptr, i32, i32, ptr) #0
|
||||
|
||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { argmemonly nofree nosync nounwind willreturn }
|
||||
attributes #2 = { argmemonly nocallback nofree nosync nounwind willreturn }
|
||||
attributes #3 = { nounwind }
|
||||
|
|
265
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
265
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
|
@ -3,103 +3,99 @@ source_filename = "defer.go"
|
|||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
target triple = "thumbv7m-unknown-unknown-eabi"
|
||||
|
||||
%runtime._defer = type { i32, %runtime._defer* }
|
||||
%runtime.deferFrame = type { i8*, i8*, [0 x i8*], %runtime.deferFrame*, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, ptr }
|
||||
%runtime._defer = type { i32, ptr }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.external(i8*) #0
|
||||
declare void @main.external(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.deferSimple(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.deferSimple(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
|
||||
%deferPtr = alloca %runtime._defer*, align 4
|
||||
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
|
||||
%defer.alloca = alloca { i32, ptr }, align 4
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call i8* @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
|
||||
store i32 0, i32* %defer.alloca.repack, align 4
|
||||
%defer.alloca.repack16 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
|
||||
store %runtime._defer* null, %runtime._defer** %defer.alloca.repack16, align 4
|
||||
%1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4
|
||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%0 = call ptr @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack15, align 4
|
||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result = icmp eq i32 %setjmp, 0
|
||||
br i1 %setjmp.result, label %2, label %lpad
|
||||
br i1 %setjmp.result, label %1, label %lpad
|
||||
|
||||
2: ; preds = %entry
|
||||
call void @main.external(i8* undef) #3
|
||||
1: ; preds = %entry
|
||||
call void @main.external(ptr undef) #3
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.loophead: ; preds = %4, %2
|
||||
%3 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4
|
||||
%stackIsNil = icmp eq %runtime._defer* %3, null
|
||||
rundefers.loophead: ; preds = %3, %1
|
||||
%2 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil = icmp eq ptr %2, null
|
||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||
|
||||
rundefers.loop: ; preds = %rundefers.loophead
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 1
|
||||
%stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4
|
||||
store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4
|
||||
%callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 0
|
||||
%callback = load i32, i32* %callback.gep, align 4
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1
|
||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||
store ptr %stack.next, ptr %deferPtr, align 4
|
||||
%callback = load i32, ptr %2, align 4
|
||||
switch i32 %callback, label %rundefers.default [
|
||||
i32 0, label %rundefers.callback0
|
||||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
%setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result2 = icmp eq i32 %setjmp1, 0
|
||||
br i1 %setjmp.result2, label %4, label %lpad
|
||||
br i1 %setjmp.result2, label %3, label %lpad
|
||||
|
||||
4: ; preds = %rundefers.callback0
|
||||
call void @"main.deferSimple$1"(i8* undef)
|
||||
3: ; preds = %rundefers.callback0
|
||||
call void @"main.deferSimple$1"(ptr undef)
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.default: ; preds = %rundefers.loop
|
||||
unreachable
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3
|
||||
ret void
|
||||
|
||||
recover: ; preds = %rundefers.end3
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry
|
||||
br label %rundefers.loophead6
|
||||
|
||||
rundefers.loophead6: ; preds = %6, %lpad
|
||||
%5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4
|
||||
%stackIsNil7 = icmp eq %runtime._defer* %5, null
|
||||
rundefers.loophead6: ; preds = %5, %lpad
|
||||
%4 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil7 = icmp eq ptr %4, null
|
||||
br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5
|
||||
|
||||
rundefers.loop5: ; preds = %rundefers.loophead6
|
||||
%stack.next.gep8 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1
|
||||
%stack.next9 = load %runtime._defer*, %runtime._defer** %stack.next.gep8, align 4
|
||||
store %runtime._defer* %stack.next9, %runtime._defer** %deferPtr, align 4
|
||||
%callback.gep10 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0
|
||||
%callback11 = load i32, i32* %callback.gep10, align 4
|
||||
%stack.next.gep8 = getelementptr inbounds %runtime._defer, ptr %4, i32 0, i32 1
|
||||
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
||||
store ptr %stack.next9, ptr %deferPtr, align 4
|
||||
%callback11 = load i32, ptr %4, align 4
|
||||
switch i32 %callback11, label %rundefers.default4 [
|
||||
i32 0, label %rundefers.callback012
|
||||
]
|
||||
|
||||
rundefers.callback012: ; preds = %rundefers.loop5
|
||||
%setjmp14 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%setjmp.result15 = icmp eq i32 %setjmp14, 0
|
||||
br i1 %setjmp.result15, label %6, label %lpad
|
||||
%setjmp13 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result14 = icmp eq i32 %setjmp13, 0
|
||||
br i1 %setjmp.result14, label %5, label %lpad
|
||||
|
||||
6: ; preds = %rundefers.callback012
|
||||
call void @"main.deferSimple$1"(i8* undef)
|
||||
5: ; preds = %rundefers.callback012
|
||||
call void @"main.deferSimple$1"(ptr undef)
|
||||
br label %rundefers.loophead6
|
||||
|
||||
rundefers.default4: ; preds = %rundefers.loop5
|
||||
|
@ -109,158 +105,151 @@ rundefers.end3: ; preds = %rundefers.loophead6
|
|||
br label %recover
|
||||
}
|
||||
|
||||
; Function Attrs: nofree nosync nounwind willreturn
|
||||
declare i8* @llvm.stacksave() #2
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn
|
||||
declare ptr @llvm.stacksave() #2
|
||||
|
||||
declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0
|
||||
declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, i8* undef) #3
|
||||
call void @runtime.printint32(i32 3, ptr undef) #3
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.destroyDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*) #0
|
||||
declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #0
|
||||
|
||||
declare void @runtime.printint32(i32, i8*) #0
|
||||
declare void @runtime.printint32(i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.deferMultiple(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%defer.alloca2 = alloca { i32, %runtime._defer* }, align 4
|
||||
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
|
||||
%deferPtr = alloca %runtime._defer*, align 4
|
||||
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
|
||||
%defer.alloca2 = alloca { i32, ptr }, align 4
|
||||
%defer.alloca = alloca { i32, ptr }, align 4
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call i8* @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
|
||||
store i32 0, i32* %defer.alloca.repack, align 4
|
||||
%defer.alloca.repack26 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
|
||||
store %runtime._defer* null, %runtime._defer** %defer.alloca.repack26, align 4
|
||||
%1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4
|
||||
%defer.alloca2.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 0
|
||||
store i32 1, i32* %defer.alloca2.repack, align 4
|
||||
%defer.alloca2.repack27 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 1
|
||||
%2 = bitcast %runtime._defer** %defer.alloca2.repack27 to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %2, align 4
|
||||
%3 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca2, { i32, %runtime._defer* }** %3, align 4
|
||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%0 = call ptr @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack22, align 4
|
||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||
store i32 1, ptr %defer.alloca2, align 4
|
||||
%defer.alloca2.repack23 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca2, i32 0, i32 1
|
||||
store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4
|
||||
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result = icmp eq i32 %setjmp, 0
|
||||
br i1 %setjmp.result, label %4, label %lpad
|
||||
br i1 %setjmp.result, label %1, label %lpad
|
||||
|
||||
4: ; preds = %entry
|
||||
call void @main.external(i8* undef) #3
|
||||
1: ; preds = %entry
|
||||
call void @main.external(ptr undef) #3
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.loophead: ; preds = %7, %6, %4
|
||||
%5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4
|
||||
%stackIsNil = icmp eq %runtime._defer* %5, null
|
||||
rundefers.loophead: ; preds = %4, %3, %1
|
||||
%2 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil = icmp eq ptr %2, null
|
||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||
|
||||
rundefers.loop: ; preds = %rundefers.loophead
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1
|
||||
%stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4
|
||||
store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4
|
||||
%callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0
|
||||
%callback = load i32, i32* %callback.gep, align 4
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1
|
||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||
store ptr %stack.next, ptr %deferPtr, align 4
|
||||
%callback = load i32, ptr %2, align 4
|
||||
switch i32 %callback, label %rundefers.default [
|
||||
i32 0, label %rundefers.callback0
|
||||
i32 1, label %rundefers.callback1
|
||||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
%setjmp4 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%setjmp.result5 = icmp eq i32 %setjmp4, 0
|
||||
br i1 %setjmp.result5, label %6, label %lpad
|
||||
%setjmp3 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result4 = icmp eq i32 %setjmp3, 0
|
||||
br i1 %setjmp.result4, label %3, label %lpad
|
||||
|
||||
6: ; preds = %rundefers.callback0
|
||||
call void @"main.deferMultiple$1"(i8* undef)
|
||||
3: ; preds = %rundefers.callback0
|
||||
call void @"main.deferMultiple$1"(ptr undef)
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.callback1: ; preds = %rundefers.loop
|
||||
%setjmp7 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%setjmp.result8 = icmp eq i32 %setjmp7, 0
|
||||
br i1 %setjmp.result8, label %7, label %lpad
|
||||
%setjmp5 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result6 = icmp eq i32 %setjmp5, 0
|
||||
br i1 %setjmp.result6, label %4, label %lpad
|
||||
|
||||
7: ; preds = %rundefers.callback1
|
||||
call void @"main.deferMultiple$2"(i8* undef)
|
||||
4: ; preds = %rundefers.callback1
|
||||
call void @"main.deferMultiple$2"(ptr undef)
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.default: ; preds = %rundefers.loop
|
||||
unreachable
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3
|
||||
ret void
|
||||
|
||||
recover: ; preds = %rundefers.end9
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
recover: ; preds = %rundefers.end7
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback122, %rundefers.callback018, %rundefers.callback1, %rundefers.callback0, %entry
|
||||
br label %rundefers.loophead12
|
||||
lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry
|
||||
br label %rundefers.loophead10
|
||||
|
||||
rundefers.loophead12: ; preds = %10, %9, %lpad
|
||||
%8 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4
|
||||
%stackIsNil13 = icmp eq %runtime._defer* %8, null
|
||||
br i1 %stackIsNil13, label %rundefers.end9, label %rundefers.loop11
|
||||
rundefers.loophead10: ; preds = %7, %6, %lpad
|
||||
%5 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil11 = icmp eq ptr %5, null
|
||||
br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9
|
||||
|
||||
rundefers.loop11: ; preds = %rundefers.loophead12
|
||||
%stack.next.gep14 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 1
|
||||
%stack.next15 = load %runtime._defer*, %runtime._defer** %stack.next.gep14, align 4
|
||||
store %runtime._defer* %stack.next15, %runtime._defer** %deferPtr, align 4
|
||||
%callback.gep16 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 0
|
||||
%callback17 = load i32, i32* %callback.gep16, align 4
|
||||
switch i32 %callback17, label %rundefers.default10 [
|
||||
i32 0, label %rundefers.callback018
|
||||
i32 1, label %rundefers.callback122
|
||||
rundefers.loop9: ; preds = %rundefers.loophead10
|
||||
%stack.next.gep12 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1
|
||||
%stack.next13 = load ptr, ptr %stack.next.gep12, align 4
|
||||
store ptr %stack.next13, ptr %deferPtr, align 4
|
||||
%callback15 = load i32, ptr %5, align 4
|
||||
switch i32 %callback15, label %rundefers.default8 [
|
||||
i32 0, label %rundefers.callback016
|
||||
i32 1, label %rundefers.callback119
|
||||
]
|
||||
|
||||
rundefers.callback018: ; preds = %rundefers.loop11
|
||||
%setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
rundefers.callback016: ; preds = %rundefers.loop9
|
||||
%setjmp17 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result18 = icmp eq i32 %setjmp17, 0
|
||||
br i1 %setjmp.result18, label %6, label %lpad
|
||||
|
||||
6: ; preds = %rundefers.callback016
|
||||
call void @"main.deferMultiple$1"(ptr undef)
|
||||
br label %rundefers.loophead10
|
||||
|
||||
rundefers.callback119: ; preds = %rundefers.loop9
|
||||
%setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4
|
||||
%setjmp.result21 = icmp eq i32 %setjmp20, 0
|
||||
br i1 %setjmp.result21, label %9, label %lpad
|
||||
br i1 %setjmp.result21, label %7, label %lpad
|
||||
|
||||
9: ; preds = %rundefers.callback018
|
||||
call void @"main.deferMultiple$1"(i8* undef)
|
||||
br label %rundefers.loophead12
|
||||
7: ; preds = %rundefers.callback119
|
||||
call void @"main.deferMultiple$2"(ptr undef)
|
||||
br label %rundefers.loophead10
|
||||
|
||||
rundefers.callback122: ; preds = %rundefers.loop11
|
||||
%setjmp24 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
|
||||
%setjmp.result25 = icmp eq i32 %setjmp24, 0
|
||||
br i1 %setjmp.result25, label %10, label %lpad
|
||||
|
||||
10: ; preds = %rundefers.callback122
|
||||
call void @"main.deferMultiple$2"(i8* undef)
|
||||
br label %rundefers.loophead12
|
||||
|
||||
rundefers.default10: ; preds = %rundefers.loop11
|
||||
rundefers.default8: ; preds = %rundefers.loop9
|
||||
unreachable
|
||||
|
||||
rundefers.end9: ; preds = %rundefers.loophead12
|
||||
rundefers.end7: ; preds = %rundefers.loophead10
|
||||
br label %recover
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, i8* undef) #3
|
||||
call void @runtime.printint32(i32 3, ptr undef) #3
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 5, i8* undef) #3
|
||||
call void @runtime.printint32(i32 5, ptr undef) #3
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
|
||||
attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
|
||||
attributes #2 = { nofree nosync nounwind willreturn }
|
||||
attributes #2 = { nocallback nofree nosync nounwind willreturn }
|
||||
attributes #3 = { nounwind }
|
||||
attributes #4 = { nounwind returns_twice }
|
||||
|
|
22
compiler/testdata/float.ll
предоставленный
22
compiler/testdata/float.ll
предоставленный
|
@ -3,18 +3,18 @@ source_filename = "float.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.f32tou32(float %v, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.f32tou32(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 0x41EFFFFFC0000000
|
||||
|
@ -26,25 +26,25 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.maxu32f(i8* %context) unnamed_addr #1 {
|
||||
define hidden float @main.maxu32f(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float 0x41F0000000000000
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.maxu32tof32(i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.maxu32tof32(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 -1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32, i32, i32, i32 } @main.inftoi32(i8* %context) unnamed_addr #1 {
|
||||
define hidden { i32, i32, i32, i32 } @main.inftoi32(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret { i32, i32, i32, i32 } { i32 -1, i32 0, i32 2147483647, i32 -2147483648 }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.u32tof32tou32(i32 %v, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.u32tof32tou32(i32 %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = uitofp i32 %v to float
|
||||
%withinmax = fcmp ole float %0, 0x41EFFFFFC0000000
|
||||
|
@ -54,7 +54,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.f32tou32tof32(float %v, i8* %context) unnamed_addr #1 {
|
||||
define hidden float @main.f32tou32tof32(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 0x41EFFFFFC0000000
|
||||
|
@ -67,7 +67,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.f32tou8(float %v, i8* %context) unnamed_addr #1 {
|
||||
define hidden i8 @main.f32tou8(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 2.550000e+02
|
||||
|
@ -79,7 +79,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.f32toi8(float %v, i8* %context) unnamed_addr #1 {
|
||||
define hidden i8 @main.f32toi8(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%abovemin = fcmp oge float %v, -1.280000e+02
|
||||
%belowmax = fcmp ole float %v, 1.270000e+02
|
||||
|
|
23
compiler/testdata/func.ll
предоставленный
23
compiler/testdata/func.ll
предоставленный
|
@ -3,43 +3,42 @@ source_filename = "func.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.foo(i8* %callback.context, void ()* %callback.funcptr, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq void ()* %callback.funcptr, null
|
||||
%0 = icmp eq ptr %callback.funcptr, null
|
||||
br i1 %0, label %fpcall.throw, label %fpcall.next
|
||||
|
||||
fpcall.next: ; preds = %entry
|
||||
%1 = bitcast void ()* %callback.funcptr to void (i32, i8*)*
|
||||
call void %1(i32 3, i8* %callback.context) #2
|
||||
call void %callback.funcptr(i32 3, ptr %callback.context) #2
|
||||
ret void
|
||||
|
||||
fpcall.throw: ; preds = %entry
|
||||
call void @runtime.nilPanic(i8* undef) #2
|
||||
call void @runtime.nilPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.nilPanic(i8*) #0
|
||||
declare void @runtime.nilPanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.bar(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.bar(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @main.foo(i8* undef, void ()* bitcast (void (i32, i8*)* @main.someFunc to void ()*), i8* undef)
|
||||
call void @main.foo(ptr undef, ptr nonnull @main.someFunc, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.someFunc(i32 %arg0, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
|
176
compiler/testdata/gc.ll
предоставленный
176
compiler/testdata/gc.ll
предоставленный
|
@ -3,133 +3,129 @@ source_filename = "gc.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 }
|
||||
%runtime.interfaceMethodInfo = type { i8*, i32 }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime.typecodeID = type { ptr, i32, ptr, ptr, i32 }
|
||||
%runtime._interface = type { i32, ptr }
|
||||
|
||||
@main.scalar1 = hidden global i8* null, align 4
|
||||
@main.scalar2 = hidden global i32* null, align 4
|
||||
@main.scalar3 = hidden global i64* null, align 4
|
||||
@main.scalar4 = hidden global float* null, align 4
|
||||
@main.array1 = hidden global [3 x i8]* null, align 4
|
||||
@main.array2 = hidden global [71 x i8]* null, align 4
|
||||
@main.array3 = hidden global [3 x i8*]* null, align 4
|
||||
@main.struct1 = hidden global {}* null, align 4
|
||||
@main.struct2 = hidden global { i32, i32 }* null, align 4
|
||||
@main.struct3 = hidden global { i8*, [60 x i32], i8* }* null, align 4
|
||||
@main.struct4 = hidden global { i8*, [61 x i32] }* null, align 4
|
||||
@main.slice1 = hidden global { i8*, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice2 = hidden global { i32**, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice3 = hidden global { { i8*, i32, i32 }*, i32, i32 } zeroinitializer, align 8
|
||||
@main.scalar1 = hidden global ptr null, align 4
|
||||
@main.scalar2 = hidden global ptr null, align 4
|
||||
@main.scalar3 = hidden global ptr null, align 4
|
||||
@main.scalar4 = hidden global ptr null, align 4
|
||||
@main.array1 = hidden global ptr null, align 4
|
||||
@main.array2 = hidden global ptr null, align 4
|
||||
@main.array3 = hidden global ptr null, align 4
|
||||
@main.struct1 = hidden global ptr null, align 4
|
||||
@main.struct2 = hidden global ptr null, align 4
|
||||
@main.struct3 = hidden global ptr null, align 4
|
||||
@main.struct4 = hidden global ptr null, align 4
|
||||
@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c" \00\00\00\00\00\00\01" }
|
||||
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\00\00\00\00\00\00\00\01" }
|
||||
@"reflect/types.type:basic:complex128" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* null, i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:basic:complex128", i32 0 }
|
||||
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:complex128", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 }
|
||||
@"reflect/types.type:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:complex128", i32 0 }
|
||||
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:complex128", i32 0, ptr null, ptr null, i32 0 }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newScalar(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.newScalar(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%new = call i8* @runtime.alloc(i32 1, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2
|
||||
store i8* %new, i8** @main.scalar1, align 4
|
||||
%new1 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2
|
||||
store i8* %new1, i8** bitcast (i32** @main.scalar2 to i8**), align 4
|
||||
%new2 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2
|
||||
store i8* %new2, i8** bitcast (i64** @main.scalar3 to i8**), align 4
|
||||
%new3 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new3, i8* undef) #2
|
||||
store i8* %new3, i8** bitcast (float** @main.scalar4 to i8**), align 4
|
||||
%new = call ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
||||
store ptr %new, ptr @main.scalar1, align 4
|
||||
%new1 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
||||
store ptr %new1, ptr @main.scalar2, align 4
|
||||
%new2 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
||||
store ptr %new2, ptr @main.scalar3, align 4
|
||||
%new3 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2
|
||||
store ptr %new3, ptr @main.scalar4, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newArray(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.newArray(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%new = call i8* @runtime.alloc(i32 3, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2
|
||||
store i8* %new, i8** bitcast ([3 x i8]** @main.array1 to i8**), align 4
|
||||
%new1 = call i8* @runtime.alloc(i32 71, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2
|
||||
store i8* %new1, i8** bitcast ([71 x i8]** @main.array2 to i8**), align 4
|
||||
%new2 = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 67 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2
|
||||
store i8* %new2, i8** bitcast ([3 x i8*]** @main.array3 to i8**), align 4
|
||||
%new = call ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
||||
store ptr %new, ptr @main.array1, align 4
|
||||
%new1 = call ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
||||
store ptr %new1, ptr @main.array2, align 4
|
||||
%new2 = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
||||
store ptr %new2, ptr @main.array3, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newStruct(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.newStruct(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%new = call i8* @runtime.alloc(i32 0, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2
|
||||
store i8* %new, i8** bitcast ({}** @main.struct1 to i8**), align 4
|
||||
%new1 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2
|
||||
store i8* %new1, i8** bitcast ({ i32, i32 }** @main.struct2 to i8**), align 4
|
||||
%new2 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-2000000000000001" to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2
|
||||
store i8* %new2, i8** bitcast ({ i8*, [60 x i32], i8* }** @main.struct3 to i8**), align 4
|
||||
%new3 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-0001" to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %new3, i8* undef) #2
|
||||
store i8* %new3, i8** bitcast ({ i8*, [61 x i32] }** @main.struct4 to i8**), align 4
|
||||
%new = call ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
||||
store ptr %new, ptr @main.struct1, align 4
|
||||
%new1 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
||||
store ptr %new1, ptr @main.struct2, align 4
|
||||
%new2 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
||||
store ptr %new2, ptr @main.struct3, align 4
|
||||
%new3 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2
|
||||
store ptr %new3, ptr @main.struct4, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i8*, void ()* }* @main.newFuncValue(i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%new = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 197 to i8*), i8* undef) #2
|
||||
%0 = bitcast i8* %new to { i8*, void ()* }*
|
||||
call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2
|
||||
ret { i8*, void ()* }* %0
|
||||
%new = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
||||
ret ptr %new
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.makeSlice(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%makeslice = call i8* @runtime.alloc(i32 5, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2
|
||||
store i8* %makeslice, i8** getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 0), align 8
|
||||
store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 1), align 4
|
||||
store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 2), align 8
|
||||
%makeslice1 = call i8* @runtime.alloc(i32 20, i8* nonnull inttoptr (i32 67 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice1, i8* undef) #2
|
||||
store i8* %makeslice1, i8** bitcast ({ i32**, i32, i32 }* @main.slice2 to i8**), align 8
|
||||
store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 1), align 4
|
||||
store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 2), align 8
|
||||
%makeslice3 = call i8* @runtime.alloc(i32 60, i8* nonnull inttoptr (i32 71 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice3, i8* undef) #2
|
||||
store i8* %makeslice3, i8** bitcast ({ { i8*, i32, i32 }*, i32, i32 }* @main.slice3 to i8**), align 8
|
||||
store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 1), align 4
|
||||
store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 2), align 8
|
||||
%makeslice = call ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2
|
||||
store ptr %makeslice, ptr @main.slice1, align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
|
||||
%makeslice1 = call ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr undef) #2
|
||||
store ptr %makeslice1, ptr @main.slice2, align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
|
||||
%makeslice3 = call ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr undef) #2
|
||||
store ptr %makeslice3, ptr @main.slice3, align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
|
||||
%.repack = bitcast i8* %0 to double*
|
||||
store double %v.r, double* %.repack, align 8
|
||||
%.repack1 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%1 = bitcast i8* %.repack1 to double*
|
||||
store double %v.i, double* %1, align 8
|
||||
%2 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:complex128" to i32), i8* undef }, i8* %0, 1
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
|
||||
ret %runtime._interface %2
|
||||
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
||||
store double %v.r, ptr %0, align 8
|
||||
%.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1
|
||||
store double %v.i, ptr %.repack1, align 8
|
||||
%1 = insertvalue %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:complex128" to i32), ptr undef }, ptr %0, 1
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
||||
ret %runtime._interface %1
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
|
|
189
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
189
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
|
@ -3,201 +3,176 @@ source_filename = "goroutine.go"
|
|||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
target triple = "thumbv7m-unknown-unknown-eabi"
|
||||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type {}
|
||||
%"internal/task.state" = type { i32, i32* }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
%runtime._string = type { ptr, i32 }
|
||||
|
||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.regularFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 %stacksize, i8* undef) #8
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 %stacksize, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.regularFunction(i32, i8*) #0
|
||||
declare void @main.regularFunction(i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.regularFunction$gowrapper"(i8* %0) unnamed_addr #2 {
|
||||
define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 {
|
||||
entry:
|
||||
%unpack.int = ptrtoint i8* %0 to i32
|
||||
call void @main.regularFunction(i32 %unpack.int, i8* undef) #8
|
||||
%unpack.int = ptrtoint ptr %0 to i32
|
||||
call void @main.regularFunction(i32 %unpack.int, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @"internal/task.getGoroutineStackSize"(i32, i8*) #0
|
||||
declare i32 @"internal/task.getGoroutineStackSize"(i32, ptr) #0
|
||||
|
||||
declare void @"internal/task.start"(i32, i8*, i32, i8*) #0
|
||||
declare void @"internal/task.start"(i32, ptr, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.inlineFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 %stacksize, i8* undef) #8
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 %stacksize, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #3 {
|
||||
define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 {
|
||||
entry:
|
||||
%unpack.int = ptrtoint i8* %0 to i32
|
||||
call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, i8* undef)
|
||||
%unpack.int = ptrtoint ptr %0 to i32
|
||||
call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closureFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #8
|
||||
%0 = bitcast i8* %n to i32*
|
||||
store i32 3, i32* %0, align 4
|
||||
%1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef) #8
|
||||
%2 = bitcast i8* %1 to i32*
|
||||
store i32 5, i32* %2, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %1, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
store i8* %n, i8** %4, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* nonnull %1, i32 %stacksize, i8* undef) #8
|
||||
%5 = load i32, i32* %0, align 4
|
||||
call void @runtime.printint32(i32 %5, i8* undef) #8
|
||||
%n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8
|
||||
store i32 3, ptr %n, align 4
|
||||
%0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %n, ptr %1, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8
|
||||
%2 = load i32, ptr %n, align 4
|
||||
call void @runtime.printint32(i32 %2, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%unpack.ptr = bitcast i8* %context to i32*
|
||||
store i32 7, i32* %unpack.ptr, align 4
|
||||
store i32 7, ptr %context, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #4 {
|
||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
%2 = load i32, i32* %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
call void @"main.closureFunctionGoroutine$1"(i32 %2, i8* %5)
|
||||
%1 = load i32, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.printint32(i32, i8*) #0
|
||||
declare void @runtime.printint32(i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef) #8
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
store i32 5, i32* %1, align 4
|
||||
%2 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%3 = bitcast i8* %2 to i8**
|
||||
store i8* %fn.context, i8** %3, align 4
|
||||
%4 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%5 = bitcast i8* %4 to void ()**
|
||||
store void ()* %fn.funcptr, void ()** %5, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* nonnull %0, i32 %stacksize, i8* undef) #8
|
||||
%0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %fn.context, ptr %1, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2
|
||||
store ptr %fn.funcptr, ptr %2, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @main.funcGoroutine.gowrapper(i8* %0) unnamed_addr #5 {
|
||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #5 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
%2 = load i32, i32* %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
%6 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%7 = bitcast i8* %6 to void (i32, i8*)**
|
||||
%8 = load void (i32, i8*)*, void (i32, i8*)** %7, align 4
|
||||
call void %8(i32 %2, i8* %5) #8
|
||||
%1 = load i32, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
%4 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2
|
||||
%5 = load ptr, ptr %4, align 4
|
||||
call void %5(i32 %1, ptr %3) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.recoverBuiltinGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.copyBuiltinGoroutine(i8* %dst.data, i32 %dst.len, i32 %dst.cap, i8* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%copy.n = call i32 @runtime.sliceCopy(i8* %dst.data, i8* %src.data, i32 %dst.len, i32 %src.len, i32 1, i8* undef) #8
|
||||
%copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closeBuiltinGoroutine(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.chanClose(%runtime.channel* %ch, i8* undef) #8
|
||||
call void @runtime.chanClose(ptr %ch, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i8*) #0
|
||||
declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #8
|
||||
%1 = bitcast i8* %0 to i8**
|
||||
store i8* %itf.value, i8** %1, align 4
|
||||
%2 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%.repack = bitcast i8* %2 to i8**
|
||||
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4
|
||||
%.repack1 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%3 = bitcast i8* %.repack1 to i32*
|
||||
store i32 4, i32* %3, align 4
|
||||
%4 = getelementptr inbounds i8, i8* %0, i32 12
|
||||
%5 = bitcast i8* %4 to i32*
|
||||
store i32 %itf.typecode, i32* %5, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* nonnull %0, i32 %stacksize, i8* undef) #8
|
||||
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8
|
||||
store ptr %itf.value, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1
|
||||
store ptr @"main$string", ptr %1, align 4
|
||||
%.repack1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1, i32 1
|
||||
store i32 4, ptr %.repack1, align 4
|
||||
%2 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 2
|
||||
store i32 %itf.typecode, ptr %2, align 4
|
||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8*, i8*, i32, i32, i8*) #6
|
||||
declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i32, i32, ptr) #6
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(i8* %0) unnamed_addr #7 {
|
||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #7 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i8**
|
||||
%2 = load i8*, i8** %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
%6 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%7 = bitcast i8* %6 to i32*
|
||||
%8 = load i32, i32* %7, align 4
|
||||
%9 = getelementptr inbounds i8, i8* %0, i32 12
|
||||
%10 = bitcast i8* %9 to i32*
|
||||
%11 = load i32, i32* %10, align 4
|
||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8* %2, i8* %5, i32 %8, i32 %11, i8* undef) #8
|
||||
%1 = load ptr, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
%4 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 2
|
||||
%5 = load i32, ptr %4, align 4
|
||||
%6 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 3
|
||||
%7 = load i32, ptr %6, align 4
|
||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, i32 %7, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
204
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
204
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
|
@ -3,210 +3,184 @@ source_filename = "goroutine.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type { i8* }
|
||||
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
|
||||
%"internal/task.stackState" = type { i32, i32 }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
%runtime._string = type { ptr, i32 }
|
||||
|
||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.regularFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.regularFunction(i32, i8*) #0
|
||||
declare void @main.regularFunction(i32, ptr) #0
|
||||
|
||||
declare void @runtime.deadlock(i8*) #0
|
||||
declare void @runtime.deadlock(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.regularFunction$gowrapper"(i8* %0) unnamed_addr #2 {
|
||||
define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 {
|
||||
entry:
|
||||
%unpack.int = ptrtoint i8* %0 to i32
|
||||
call void @main.regularFunction(i32 %unpack.int, i8* undef) #8
|
||||
call void @runtime.deadlock(i8* undef) #8
|
||||
%unpack.int = ptrtoint ptr %0 to i32
|
||||
call void @main.regularFunction(i32 %unpack.int, ptr undef) #8
|
||||
call void @runtime.deadlock(ptr undef) #8
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @"internal/task.start"(i32, i8*, i32, i8*) #0
|
||||
declare void @"internal/task.start"(i32, ptr, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.inlineFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #3 {
|
||||
define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 {
|
||||
entry:
|
||||
%unpack.int = ptrtoint i8* %0 to i32
|
||||
call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, i8* undef)
|
||||
call void @runtime.deadlock(i8* undef) #8
|
||||
%unpack.int = ptrtoint ptr %0 to i32
|
||||
call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef)
|
||||
call void @runtime.deadlock(ptr undef) #8
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closureFunctionGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #8
|
||||
%0 = bitcast i8* %n to i32*
|
||||
call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8
|
||||
store i32 3, i32* %0, align 4
|
||||
call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8
|
||||
call void @runtime.trackPointer(i8* bitcast (void (i32, i8*)* @"main.closureFunctionGoroutine$1" to i8*), i8* undef) #8
|
||||
%1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef) #8
|
||||
call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #8
|
||||
%2 = bitcast i8* %1 to i32*
|
||||
store i32 5, i32* %2, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %1, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
store i8* %n, i8** %4, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* nonnull %1, i32 16384, i8* undef) #8
|
||||
%5 = load i32, i32* %0, align 4
|
||||
call void @runtime.printint32(i32 %5, i8* undef) #8
|
||||
%n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8
|
||||
store i32 3, ptr %n, align 4
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8
|
||||
call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr undef) #8
|
||||
%0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %n, ptr %1, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8
|
||||
%2 = load i32, ptr %n, align 4
|
||||
call void @runtime.printint32(i32 %2, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%unpack.ptr = bitcast i8* %context to i32*
|
||||
store i32 7, i32* %unpack.ptr, align 4
|
||||
store i32 7, ptr %context, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #4 {
|
||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
%2 = load i32, i32* %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
call void @"main.closureFunctionGoroutine$1"(i32 %2, i8* %5)
|
||||
call void @runtime.deadlock(i8* undef) #8
|
||||
%1 = load i32, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||
call void @runtime.deadlock(ptr undef) #8
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.printint32(i32, i8*) #0
|
||||
declare void @runtime.printint32(i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef) #8
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
store i32 5, i32* %1, align 4
|
||||
%2 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%3 = bitcast i8* %2 to i8**
|
||||
store i8* %fn.context, i8** %3, align 4
|
||||
%4 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%5 = bitcast i8* %4 to void ()**
|
||||
store void ()* %fn.funcptr, void ()** %5, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* nonnull %0, i32 16384, i8* undef) #8
|
||||
%0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %fn.context, ptr %1, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2
|
||||
store ptr %fn.funcptr, ptr %2, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 16384, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @main.funcGoroutine.gowrapper(i8* %0) unnamed_addr #5 {
|
||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #5 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i32*
|
||||
%2 = load i32, i32* %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
%6 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%7 = bitcast i8* %6 to void (i32, i8*)**
|
||||
%8 = load void (i32, i8*)*, void (i32, i8*)** %7, align 4
|
||||
call void %8(i32 %2, i8* %5) #8
|
||||
call void @runtime.deadlock(i8* undef) #8
|
||||
%1 = load i32, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
%4 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2
|
||||
%5 = load ptr, ptr %4, align 4
|
||||
call void %5(i32 %1, ptr %3) #8
|
||||
call void @runtime.deadlock(ptr undef) #8
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.recoverBuiltinGoroutine(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.copyBuiltinGoroutine(i8* %dst.data, i32 %dst.len, i32 %dst.cap, i8* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%copy.n = call i32 @runtime.sliceCopy(i8* %dst.data, i8* %src.data, i32 %dst.len, i32 %src.len, i32 1, i8* undef) #8
|
||||
%copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closeBuiltinGoroutine(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.chanClose(%runtime.channel* %ch, i8* undef) #8
|
||||
call void @runtime.chanClose(ptr %ch, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i8*) #0
|
||||
declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #8
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8
|
||||
%1 = bitcast i8* %0 to i8**
|
||||
store i8* %itf.value, i8** %1, align 4
|
||||
%2 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%.repack = bitcast i8* %2 to i8**
|
||||
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4
|
||||
%.repack1 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%3 = bitcast i8* %.repack1 to i32*
|
||||
store i32 4, i32* %3, align 4
|
||||
%4 = getelementptr inbounds i8, i8* %0, i32 12
|
||||
%5 = bitcast i8* %4 to i32*
|
||||
store i32 %itf.typecode, i32* %5, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* nonnull %0, i32 16384, i8* undef) #8
|
||||
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
||||
store ptr %itf.value, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1
|
||||
store ptr @"main$string", ptr %1, align 4
|
||||
%.repack1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1, i32 1
|
||||
store i32 4, ptr %.repack1, align 4
|
||||
%2 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 2
|
||||
store i32 %itf.typecode, ptr %2, align 4
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8*, i8*, i32, i32, i8*) #6
|
||||
declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i32, i32, ptr) #6
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(i8* %0) unnamed_addr #7 {
|
||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #7 {
|
||||
entry:
|
||||
%1 = bitcast i8* %0 to i8**
|
||||
%2 = load i8*, i8** %1, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %0, i32 4
|
||||
%4 = bitcast i8* %3 to i8**
|
||||
%5 = load i8*, i8** %4, align 4
|
||||
%6 = getelementptr inbounds i8, i8* %0, i32 8
|
||||
%7 = bitcast i8* %6 to i32*
|
||||
%8 = load i32, i32* %7, align 4
|
||||
%9 = getelementptr inbounds i8, i8* %0, i32 12
|
||||
%10 = bitcast i8* %9 to i32*
|
||||
%11 = load i32, i32* %10, align 4
|
||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8* %2, i8* %5, i32 %8, i32 %11, i8* undef) #8
|
||||
call void @runtime.deadlock(i8* undef) #8
|
||||
%1 = load ptr, ptr %0, align 4
|
||||
%2 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 1
|
||||
%3 = load ptr, ptr %2, align 4
|
||||
%4 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 2
|
||||
%5 = load i32, ptr %4, align 4
|
||||
%6 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 3
|
||||
%7 = load i32, ptr %6, align 4
|
||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, i32 %7, ptr undef) #8
|
||||
call void @runtime.deadlock(ptr undef) #8
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
|
81
compiler/testdata/interface.ll
предоставленный
81
compiler/testdata/interface.ll
предоставленный
|
@ -3,71 +3,70 @@ source_filename = "interface.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 }
|
||||
%runtime.interfaceMethodInfo = type { i8*, i32 }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime._string = type { i8*, i32 }
|
||||
%runtime.typecodeID = type { ptr, i32, ptr, ptr, i32 }
|
||||
%runtime._interface = type { i32, ptr }
|
||||
%runtime._string = type { ptr, i32 }
|
||||
|
||||
@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* null, i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:basic:int", i32 0 }
|
||||
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:int", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 }
|
||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:named:error", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 }
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:named:error", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{Error() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:int", i32 0 }
|
||||
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:int", i32 0, ptr null, ptr null, i32 0 }
|
||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:named:error", i32 0, ptr null, ptr null, i32 0 }
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr @"reflect/types.type:pointer:named:error", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{Error() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/methods.Error() string" = linkonce_odr constant i8 0, align 1
|
||||
@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.Error() string"]
|
||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 }
|
||||
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 }
|
||||
@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{String() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.Error() string"]
|
||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 }
|
||||
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 }
|
||||
@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{String() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) }
|
||||
@"reflect/methods.String() string" = linkonce_odr constant i8 0, align 1
|
||||
@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.String() string"]
|
||||
@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.String() string"]
|
||||
@"reflect/types.typeid:basic:int" = external constant i8
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.simpleType(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* null, i8* undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:int" to i32), i8* null }
|
||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.pointerType(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* null, i8* undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:basic:int" to i32), i8* null }
|
||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.interfaceType(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* null, i8* undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:named:error" to i32), i8* null }
|
||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null }
|
||||
}
|
||||
|
||||
declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.anonymousInterfaceType(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* null, i8* undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), i8* null }
|
||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null }
|
||||
}
|
||||
|
||||
declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32) #3
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isInt(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.isInt(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, i8* nonnull @"reflect/types.typeid:basic:int", i8* undef) #6
|
||||
%typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, ptr nonnull @"reflect/types.typeid:basic:int", ptr undef) #6
|
||||
br i1 %typecode, label %typeassert.ok, label %typeassert.next
|
||||
|
||||
typeassert.next: ; preds = %typeassert.ok, %entry
|
||||
|
@ -77,10 +76,10 @@ typeassert.ok: ; preds = %entry
|
|||
br label %typeassert.next
|
||||
}
|
||||
|
||||
declare i1 @runtime.typeAssert(i32, i8* dereferenceable_or_null(1), i8*) #0
|
||||
declare i1 @runtime.typeAssert(i32, ptr dereferenceable_or_null(1), ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isError(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.isError(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6
|
||||
br i1 %0, label %typeassert.ok, label %typeassert.next
|
||||
|
@ -93,7 +92,7 @@ typeassert.ok: ; preds = %entry
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isStringer(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.isStringer(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6
|
||||
br i1 %0, label %typeassert.ok, label %typeassert.next
|
||||
|
@ -106,24 +105,24 @@ typeassert.ok: ; preds = %entry
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.callFooMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden i8 @main.callFooMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8* %itf.value, i32 3, i32 %itf.typecode, i8* undef) #6
|
||||
%0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr %itf.value, i32 3, i32 %itf.typecode, ptr undef) #6
|
||||
ret i8 %0
|
||||
}
|
||||
|
||||
declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8*, i32, i32, i8*) #4
|
||||
declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, i32, ptr) #4
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8* %itf.value, i32 %itf.typecode, i8* undef) #6
|
||||
%0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6
|
||||
%1 = extractvalue %runtime._string %0, 0
|
||||
call void @runtime.trackPointer(i8* %1, i8* undef) #6
|
||||
call void @runtime.trackPointer(ptr %1, ptr undef) #6
|
||||
ret %runtime._string %0
|
||||
}
|
||||
|
||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8*, i32, i8*) #5
|
||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, i32, ptr) #5
|
||||
|
||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
|
|
68
compiler/testdata/pointer.ll
предоставленный
68
compiler/testdata/pointer.ll
предоставленный
|
@ -3,76 +3,72 @@ source_filename = "pointer.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden [0 x i32] @main.pointerDerefZero([0 x i32]* %x, i8* %context) unnamed_addr #1 {
|
||||
define hidden [0 x i32] @main.pointerDerefZero(ptr %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret [0 x i32] zeroinitializer
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32* @main.pointerCastFromUnsafe(i8* %x, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = bitcast i8* %x to i32*
|
||||
call void @runtime.trackPointer(i8* %x, i8* undef) #2
|
||||
ret i32* %0
|
||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.pointerCastToUnsafe(i32* dereferenceable_or_null(4) %x, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = bitcast i32* %x to i8*
|
||||
call void @runtime.trackPointer(i8* %0, i8* undef) #2
|
||||
ret i8* %0
|
||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.pointerCastToUnsafeNoop(i8* dereferenceable_or_null(1) %x, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* %x, i8* undef) #2
|
||||
ret i8* %x
|
||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.pointerUnsafeGEPFixedOffset(i8* dereferenceable_or_null(1) %ptr, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerUnsafeGEPFixedOffset(ptr dereferenceable_or_null(1) %ptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2
|
||||
%0 = getelementptr inbounds i8, i8* %ptr, i32 10
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
|
||||
ret i8* %0
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
%0 = getelementptr inbounds i8, ptr %ptr, i32 10
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
||||
ret ptr %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.pointerUnsafeGEPByteOffset(i8* dereferenceable_or_null(1) %ptr, i32 %offset, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerUnsafeGEPByteOffset(ptr dereferenceable_or_null(1) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2
|
||||
%0 = getelementptr inbounds i8, i8* %ptr, i32 %offset
|
||||
call void @runtime.trackPointer(i8* %0, i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* %0, i8* undef) #2
|
||||
ret i8* %0
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
%0 = getelementptr inbounds i8, ptr %ptr, i32 %offset
|
||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
||||
ret ptr %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32* @main.pointerUnsafeGEPIntOffset(i32* dereferenceable_or_null(4) %ptr, i32 %offset, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.pointerUnsafeGEPIntOffset(ptr dereferenceable_or_null(4) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = bitcast i32* %ptr to i8*
|
||||
call void @runtime.trackPointer(i8* %0, i8* undef) #2
|
||||
%1 = getelementptr i32, i32* %ptr, i32 %offset
|
||||
%2 = bitcast i32* %1 to i8*
|
||||
call void @runtime.trackPointer(i8* %2, i8* undef) #2
|
||||
%3 = bitcast i32* %1 to i8*
|
||||
call void @runtime.trackPointer(i8* %3, i8* undef) #2
|
||||
ret i32* %1
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
%0 = shl i32 %offset, 2
|
||||
%1 = getelementptr inbounds i8, ptr %ptr, i32 %0
|
||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
||||
ret ptr %1
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
|
|
18
compiler/testdata/pragma.ll
предоставленный
18
compiler/testdata/pragma.ll
предоставленный
|
@ -10,12 +10,12 @@ target triple = "wasm32-unknown-wasi"
|
|||
@undefinedGlobalNotInSection = external global i32, align 4
|
||||
@main.multipleGlobalPragmas = hidden global i32 0, section ".global_section", align 1024
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
@ -27,27 +27,27 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @somepkg.someFunction1(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @somepkg.someFunction2(i8*) #0
|
||||
declare void @somepkg.someFunction2(ptr) #0
|
||||
|
||||
; Function Attrs: inlinehint nounwind
|
||||
define hidden void @main.inlineFunc(i8* %context) unnamed_addr #3 {
|
||||
define hidden void @main.inlineFunc(ptr %context) unnamed_addr #3 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden void @main.noinlineFunc(i8* %context) unnamed_addr #4 {
|
||||
define hidden void @main.noinlineFunc(ptr %context) unnamed_addr #4 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.functionInSection(i8* %context) unnamed_addr #1 section ".special_function_section" {
|
||||
define hidden void @main.functionInSection(ptr %context) unnamed_addr #1 section ".special_function_section" {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
declare void @main.undefinedFunctionNotInSection(i8*) #0
|
||||
declare void @main.undefinedFunctionNotInSection(ptr) #0
|
||||
|
||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||
|
|
264
compiler/testdata/slice.ll
предоставленный
264
compiler/testdata/slice.ll
предоставленный
|
@ -3,286 +3,270 @@ source_filename = "slice.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceLen(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.sliceLen(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %ints.len
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceCap(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.sliceCap(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %ints.cap
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceElement(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.sliceElement(ptr %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%.not = icmp ult i32 %index, %ints.len
|
||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||
|
||||
lookup.next: ; preds = %entry
|
||||
%0 = getelementptr inbounds i32, i32* %ints.data, i32 %index
|
||||
%1 = load i32, i32* %0, align 4
|
||||
%0 = getelementptr inbounds i32, ptr %ints.data, i32 %index
|
||||
%1 = load i32, ptr %0, align 4
|
||||
ret i32 %1
|
||||
|
||||
lookup.throw: ; preds = %entry
|
||||
call void @runtime.lookupPanic(i8* undef) #2
|
||||
call void @runtime.lookupPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.lookupPanic(i8*) #0
|
||||
declare void @runtime.lookupPanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.sliceAppendValues(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%varargs = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %varargs, i8* undef) #2
|
||||
%0 = bitcast i8* %varargs to i32*
|
||||
store i32 1, i32* %0, align 4
|
||||
%1 = getelementptr inbounds i8, i8* %varargs, i32 4
|
||||
%2 = bitcast i8* %1 to i32*
|
||||
store i32 2, i32* %2, align 4
|
||||
%3 = getelementptr inbounds i8, i8* %varargs, i32 8
|
||||
%4 = bitcast i8* %3 to i32*
|
||||
store i32 3, i32* %4, align 4
|
||||
%append.srcPtr = bitcast i32* %ints.data to i8*
|
||||
%append.new = call { i8*, i32, i32 } @runtime.sliceAppend(i8* %append.srcPtr, i8* nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, i8* undef) #2
|
||||
%append.newPtr = extractvalue { i8*, i32, i32 } %append.new, 0
|
||||
%append.newBuf = bitcast i8* %append.newPtr to i32*
|
||||
%append.newLen = extractvalue { i8*, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { i8*, i32, i32 } %append.new, 2
|
||||
%5 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0
|
||||
%6 = insertvalue { i32*, i32, i32 } %5, i32 %append.newLen, 1
|
||||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(i8* %append.newPtr, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %7
|
||||
%varargs = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr undef) #2
|
||||
store i32 1, ptr %varargs, align 4
|
||||
%0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1
|
||||
store i32 2, ptr %0, align 4
|
||||
%1 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 2
|
||||
store i32 3, ptr %1, align 4
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #2
|
||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2
|
||||
%2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||
%3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1
|
||||
%4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %4
|
||||
}
|
||||
|
||||
declare { i8*, i32, i32 } @runtime.sliceAppend(i8*, i8* nocapture readonly, i32, i32, i32, i32, i8*) #0
|
||||
declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.sliceAppendSlice(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32* %added.data, i32 %added.len, i32 %added.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%append.srcPtr = bitcast i32* %ints.data to i8*
|
||||
%append.srcPtr1 = bitcast i32* %added.data to i8*
|
||||
%append.new = call { i8*, i32, i32 } @runtime.sliceAppend(i8* %append.srcPtr, i8* %append.srcPtr1, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, i8* undef) #2
|
||||
%append.newPtr = extractvalue { i8*, i32, i32 } %append.new, 0
|
||||
%append.newBuf = bitcast i8* %append.newPtr to i32*
|
||||
%append.newLen = extractvalue { i8*, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { i8*, i32, i32 } %append.new, 2
|
||||
%0 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0
|
||||
%1 = insertvalue { i32*, i32, i32 } %0, i32 %append.newLen, 1
|
||||
%2 = insertvalue { i32*, i32, i32 } %1, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(i8* %append.newPtr, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %2
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #2
|
||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceCopy(i32* %dst.data, i32 %dst.len, i32 %dst.cap, i32* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.sliceCopy(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%copy.dstPtr = bitcast i32* %dst.data to i8*
|
||||
%copy.srcPtr = bitcast i32* %src.data to i8*
|
||||
%copy.n = call i32 @runtime.sliceCopy(i8* %copy.dstPtr, i8* %copy.srcPtr, i32 %dst.len, i32 %src.len, i32 4, i8* undef) #2
|
||||
%copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 4, ptr undef) #2
|
||||
ret i32 %copy.n
|
||||
}
|
||||
|
||||
declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i8*, i32, i32 } @main.makeByteSlice(i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%slice.maxcap = icmp slt i32 %len, 0
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.buf = call i8* @runtime.alloc(i32 %len, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
%0 = insertvalue { i8*, i32, i32 } undef, i8* %makeslice.buf, 0
|
||||
%1 = insertvalue { i8*, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { i8*, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2
|
||||
ret { i8*, i32, i32 } %2
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %len, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
call void @runtime.slicePanic(i8* undef) #2
|
||||
call void @runtime.slicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.slicePanic(i8*) #0
|
||||
declare void @runtime.slicePanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i16*, i32, i32 } @main.makeInt16Slice(i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%slice.maxcap = icmp slt i32 %len, 0
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.cap = shl i32 %len, 1
|
||||
%makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
%makeslice.array = bitcast i8* %makeslice.buf to i16*
|
||||
%0 = insertvalue { i16*, i32, i32 } undef, i16* %makeslice.array, 0
|
||||
%1 = insertvalue { i16*, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { i16*, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2
|
||||
ret { i16*, i32, i32 } %2
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
call void @runtime.slicePanic(i8* undef) #2
|
||||
call void @runtime.slicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { [3 x i8]*, i32, i32 } @main.makeArraySlice(i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%slice.maxcap = icmp ugt i32 %len, 1431655765
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.cap = mul i32 %len, 3
|
||||
%makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
%makeslice.array = bitcast i8* %makeslice.buf to [3 x i8]*
|
||||
%0 = insertvalue { [3 x i8]*, i32, i32 } undef, [3 x i8]* %makeslice.array, 0
|
||||
%1 = insertvalue { [3 x i8]*, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { [3 x i8]*, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2
|
||||
ret { [3 x i8]*, i32, i32 } %2
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
call void @runtime.slicePanic(i8* undef) #2
|
||||
call void @runtime.slicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.makeInt32Slice(i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%slice.maxcap = icmp ugt i32 %len, 1073741823
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.cap = shl i32 %len, 2
|
||||
%makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
%makeslice.array = bitcast i8* %makeslice.buf to i32*
|
||||
%0 = insertvalue { i32*, i32, i32 } undef, i32* %makeslice.array, 0
|
||||
%1 = insertvalue { i32*, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { i32*, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %2
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
call void @runtime.slicePanic(i8* undef) #2
|
||||
call void @runtime.slicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = getelementptr i8, i8* %p, i32 %len
|
||||
call void @runtime.trackPointer(i8* %0, i8* undef) #2
|
||||
ret i8* %0
|
||||
%0 = getelementptr i8, ptr %p, i32 %len
|
||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
||||
ret ptr %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = trunc i64 %len to i32
|
||||
%1 = getelementptr i8, i8* %p, i32 %0
|
||||
call void @runtime.trackPointer(i8* %1, i8* undef) #2
|
||||
ret i8* %1
|
||||
%1 = getelementptr i8, ptr %p, i32 %0
|
||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
||||
ret ptr %1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.SliceToArray(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp ult i32 %s.len, 4
|
||||
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next
|
||||
|
||||
slicetoarray.next: ; preds = %entry
|
||||
%1 = bitcast i32* %s.data to [4 x i32]*
|
||||
ret [4 x i32]* %1
|
||||
ret ptr %s.data
|
||||
|
||||
slicetoarray.throw: ; preds = %entry
|
||||
call void @runtime.sliceToArrayPointerPanic(i8* undef) #2
|
||||
call void @runtime.sliceToArrayPointerPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.sliceToArrayPointerPanic(i8*) #0
|
||||
declare void @runtime.sliceToArrayPointerPanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context) unnamed_addr #1 {
|
||||
define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
|
||||
call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2
|
||||
%makeslice = call ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2
|
||||
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
|
||||
|
||||
slicetoarray.next: ; preds = %entry
|
||||
%0 = bitcast i8* %makeslice to [4 x i32]*
|
||||
ret [4 x i32]* %0
|
||||
ret ptr %makeslice
|
||||
|
||||
slicetoarray.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp ugt i32 %len, 1073741823
|
||||
%1 = icmp eq i32* %ptr, null
|
||||
%1 = icmp eq ptr %ptr, null
|
||||
%2 = icmp ne i32 %len, 0
|
||||
%3 = and i1 %1, %2
|
||||
%4 = or i1 %3, %0
|
||||
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
|
||||
|
||||
unsafe.Slice.next: ; preds = %entry
|
||||
%5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
|
||||
%6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1
|
||||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2
|
||||
%8 = bitcast i32* %ptr to i8*
|
||||
call void @runtime.trackPointer(i8* %8, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %7
|
||||
%5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %7
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
call void @runtime.unsafeSlicePanic(i8* undef) #2
|
||||
call void @runtime.unsafeSlicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.unsafeSlicePanic(i8*) #0
|
||||
declare void @runtime.unsafeSlicePanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i8* %ptr, null
|
||||
%0 = icmp eq ptr %ptr, null
|
||||
%1 = icmp ne i16 %len, 0
|
||||
%2 = and i1 %0, %1
|
||||
br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next
|
||||
|
||||
unsafe.Slice.next: ; preds = %entry
|
||||
%3 = zext i16 %len to i32
|
||||
%4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0
|
||||
%5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1
|
||||
%6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2
|
||||
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2
|
||||
ret { i8*, i32, i32 } %6
|
||||
%4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1
|
||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %6
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
call void @runtime.unsafeSlicePanic(i8* undef) #2
|
||||
call void @runtime.unsafeSlicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp ugt i64 %len, 1073741823
|
||||
%1 = icmp eq i32* %ptr, null
|
||||
%1 = icmp eq ptr %ptr, null
|
||||
%2 = icmp ne i64 %len, 0
|
||||
%3 = and i1 %1, %2
|
||||
%4 = or i1 %3, %0
|
||||
|
@ -290,23 +274,22 @@ entry:
|
|||
|
||||
unsafe.Slice.next: ; preds = %entry
|
||||
%5 = trunc i64 %len to i32
|
||||
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
|
||||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
|
||||
%9 = bitcast i32* %ptr to i8*
|
||||
call void @runtime.trackPointer(i8* %9, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %8
|
||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %8
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
call void @runtime.unsafeSlicePanic(i8* undef) #2
|
||||
call void @runtime.unsafeSlicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp ugt i64 %len, 1073741823
|
||||
%1 = icmp eq i32* %ptr, null
|
||||
%1 = icmp eq ptr %ptr, null
|
||||
%2 = icmp ne i64 %len, 0
|
||||
%3 = and i1 %1, %2
|
||||
%4 = or i1 %3, %0
|
||||
|
@ -314,15 +297,14 @@ entry:
|
|||
|
||||
unsafe.Slice.next: ; preds = %entry
|
||||
%5 = trunc i64 %len to i32
|
||||
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
|
||||
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
|
||||
%9 = bitcast i32* %ptr to i8*
|
||||
call void @runtime.trackPointer(i8* %9, i8* undef) #2
|
||||
ret { i32*, i32, i32 } %8
|
||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
||||
ret { ptr, i32, i32 } %8
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
call void @runtime.unsafeSlicePanic(i8* undef) #2
|
||||
call void @runtime.unsafeSlicePanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
|
50
compiler/testdata/string.ll
предоставленный
50
compiler/testdata/string.ll
предоставленный
|
@ -3,96 +3,96 @@ source_filename = "string.go"
|
|||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime._string = type { i8*, i32 }
|
||||
%runtime._string = type { ptr, i32 }
|
||||
|
||||
@"main$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(i8* %context) unnamed_addr #1 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.someString(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret %runtime._string { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"main$string", i32 0, i32 0), i32 3 }
|
||||
ret %runtime._string { ptr @"main$string", i32 3 }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.zeroLengthString(i8* %context) unnamed_addr #1 {
|
||||
define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret %runtime._string zeroinitializer
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.stringLen(i8* %s.data, i32 %s.len, i8* %context) unnamed_addr #1 {
|
||||
define hidden i32 @main.stringLen(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %s.len
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.stringIndex(i8* %s.data, i32 %s.len, i32 %index, i8* %context) unnamed_addr #1 {
|
||||
define hidden i8 @main.stringIndex(ptr %s.data, i32 %s.len, i32 %index, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%.not = icmp ult i32 %index, %s.len
|
||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||
|
||||
lookup.next: ; preds = %entry
|
||||
%0 = getelementptr inbounds i8, i8* %s.data, i32 %index
|
||||
%1 = load i8, i8* %0, align 1
|
||||
%0 = getelementptr inbounds i8, ptr %s.data, i32 %index
|
||||
%1 = load i8, ptr %0, align 1
|
||||
ret i8 %1
|
||||
|
||||
lookup.throw: ; preds = %entry
|
||||
call void @runtime.lookupPanic(i8* undef) #2
|
||||
call void @runtime.lookupPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.lookupPanic(i8*) #0
|
||||
declare void @runtime.lookupPanic(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.stringCompareEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* undef) #2
|
||||
%0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #2
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
declare i1 @runtime.stringEqual(i8*, i32, i8*, i32, i8*) #0
|
||||
declare i1 @runtime.stringEqual(ptr, i32, ptr, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareUnequal(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.stringCompareUnequal(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* undef) #2
|
||||
%0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #2
|
||||
%1 = xor i1 %0, true
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareLarger(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 {
|
||||
define hidden i1 @main.stringCompareLarger(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringLess(i8* %s2.data, i32 %s2.len, i8* %s1.data, i32 %s1.len, i8* undef) #2
|
||||
%0 = call i1 @runtime.stringLess(ptr %s2.data, i32 %s2.len, ptr %s1.data, i32 %s1.len, ptr undef) #2
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
declare i1 @runtime.stringLess(i8*, i32, i8*, i32, i8*) #0
|
||||
declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.stringLookup(i8* %s.data, i32 %s.len, i8 %x, i8* %context) unnamed_addr #1 {
|
||||
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = zext i8 %x to i32
|
||||
%.not = icmp ult i32 %0, %s.len
|
||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||
|
||||
lookup.next: ; preds = %entry
|
||||
%1 = getelementptr inbounds i8, i8* %s.data, i32 %0
|
||||
%2 = load i8, i8* %1, align 1
|
||||
%1 = getelementptr inbounds i8, ptr %s.data, i32 %0
|
||||
%2 = load i8, ptr %1, align 1
|
||||
ret i8 %2
|
||||
|
||||
lookup.throw: ; preds = %entry
|
||||
call void @runtime.lookupPanic(i8* undef) #2
|
||||
call void @runtime.lookupPanic(ptr undef) #2
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -17,7 +17,7 @@ require (
|
|||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
||||
golang.org/x/tools v0.1.11
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
4
go.sum
4
go.sum
|
@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec h1:FYtAFrw/YQPc644uNN65dW50FrEuVNaPBf70x23ApY4=
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266 h1:vg4sYKEM+w6epr5S1nXqP/7UhMYcc8nRt7Ohkq28rok=
|
||||
tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
|
|
@ -356,7 +356,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||
default:
|
||||
panic("unknown integer type width")
|
||||
}
|
||||
case strings.HasPrefix(callFn.name, "llvm.memcpy.p0i8.p0i8.") || strings.HasPrefix(callFn.name, "llvm.memmove.p0i8.p0i8."):
|
||||
case strings.HasPrefix(callFn.name, "llvm.memcpy.p0") || strings.HasPrefix(callFn.name, "llvm.memmove.p0"):
|
||||
// Copy a block of memory from one pointer to another.
|
||||
dst, err := operands[1].asPointer(r)
|
||||
if err != nil {
|
||||
|
@ -496,7 +496,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||
typecodeID := typecodeIDBitCast.Operand(0).Initializer()
|
||||
|
||||
// Load the method set, which is part of the typecodeID object.
|
||||
methodSet := r.builder.CreateExtractValue(typecodeID, 2, "").Operand(0).Initializer()
|
||||
methodSet := stripPointerCasts(r.builder.CreateExtractValue(typecodeID, 2, "")).Initializer()
|
||||
|
||||
// We don't need to load the interface method set.
|
||||
|
||||
|
@ -1095,3 +1095,15 @@ func intPredicateString(predicate llvm.IntPredicate) string {
|
|||
return "cmp?"
|
||||
}
|
||||
}
|
||||
|
||||
// Strip some pointer casts. This is probably unnecessary once support for
|
||||
// LLVM 14 (non-opaque pointers) is dropped.
|
||||
func stripPointerCasts(value llvm.Value) llvm.Value {
|
||||
if !value.IsAConstantExpr().IsNil() {
|
||||
switch value.Opcode() {
|
||||
case llvm.GetElementPtr, llvm.BitCast:
|
||||
return stripPointerCasts(value.Operand(0))
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
|
|
@ -27,18 +27,18 @@ func GOROOT() string {
|
|||
|
||||
// Copy size bytes from src to dst. The memory areas must not overlap.
|
||||
// This function is implemented by the compiler as a call to a LLVM intrinsic
|
||||
// like llvm.memcpy.p0i8.p0i8.i32(dst, src, size, false).
|
||||
// like llvm.memcpy.p0.p0.i32(dst, src, size, false).
|
||||
func memcpy(dst, src unsafe.Pointer, size uintptr)
|
||||
|
||||
// Copy size bytes from src to dst. The memory areas may overlap and will do the
|
||||
// correct thing.
|
||||
// This function is implemented by the compiler as a call to a LLVM intrinsic
|
||||
// like llvm.memmove.p0i8.p0i8.i32(dst, src, size, false).
|
||||
// like llvm.memmove.p0.p0.i32(dst, src, size, false).
|
||||
func memmove(dst, src unsafe.Pointer, size uintptr)
|
||||
|
||||
// Set the given number of bytes to zero.
|
||||
// This function is implemented by the compiler as a call to a LLVM intrinsic
|
||||
// like llvm.memset.p0i8.i32(ptr, 0, size, false).
|
||||
// like llvm.memset.p0.i32(ptr, 0, size, false).
|
||||
func memzero(ptr unsafe.Pointer, size uintptr)
|
||||
|
||||
// This intrinsic returns the current stack pointer.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"inherits": ["riscv32"],
|
||||
"features": "+c,+m",
|
||||
"features": "+c,+m,-relax,-save-restore",
|
||||
"build-tags": ["esp32c3", "esp"],
|
||||
"serial": "uart",
|
||||
"rtlib": "compiler-rt",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"inherits": ["riscv32"],
|
||||
"cpu": "sifive-e31",
|
||||
"features": "+a,+c,+m",
|
||||
"features": "+a,+c,+m,-64bit,-relax,-save-restore",
|
||||
"build-tags": ["fe310", "sifive"]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"inherits": ["riscv64"],
|
||||
"features": "+64bit,+a,+c,+d,+f,+m",
|
||||
"features": "+64bit,+a,+c,+d,+f,+m,-relax,-save-restore",
|
||||
"build-tags": ["k210", "kendryte"],
|
||||
"code-model": "medium"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"inherits": ["riscv32"],
|
||||
"features": "+a,+c,+m",
|
||||
"features": "+a,+c,+m,-relax,-save-restore",
|
||||
"build-tags": ["virt", "qemu"],
|
||||
"default-stack-size": 4096,
|
||||
"linkerscript": "targets/riscv-qemu.ld",
|
||||
|
|
|
@ -305,7 +305,9 @@ func (p *lowerInterfacesPass) addTypeMethods(t *typeInfo, methodSet llvm.Value)
|
|||
// no methods or methods already read
|
||||
return
|
||||
}
|
||||
methodSet = methodSet.Operand(0) // get global from GEP
|
||||
if !methodSet.IsAConstantExpr().IsNil() && methodSet.Opcode() == llvm.GetElementPtr {
|
||||
methodSet = methodSet.Operand(0) // get global from GEP, for LLVM 14 (non-opaque pointers)
|
||||
}
|
||||
|
||||
// This type has methods, collect all methods of this type.
|
||||
t.methodSet = methodSet
|
||||
|
|
|
@ -36,9 +36,8 @@ func LowerInterrupts(mod llvm.Module) []error {
|
|||
handleMap := map[int64][]llvm.Value{}
|
||||
handleType := mod.GetTypeByName("runtime/interrupt.handle")
|
||||
if !handleType.IsNil() {
|
||||
handlePtrType := llvm.PointerType(handleType, 0)
|
||||
for global := mod.FirstGlobal(); !global.IsNil(); global = llvm.NextGlobal(global) {
|
||||
if global.Type() != handlePtrType {
|
||||
if global.GlobalValueType() != handleType {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,12 @@ func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) ll
|
|||
// stripPointerCasts strips instruction pointer casts (getelementptr and
|
||||
// bitcast) and returns the original value without the casts.
|
||||
func stripPointerCasts(value llvm.Value) llvm.Value {
|
||||
if !value.IsAConstantExpr().IsNil() {
|
||||
switch value.Opcode() {
|
||||
case llvm.GetElementPtr, llvm.BitCast:
|
||||
return stripPointerCasts(value.Operand(0))
|
||||
}
|
||||
}
|
||||
if !value.IsAInstruction().IsNil() {
|
||||
switch value.InstructionOpcode() {
|
||||
case llvm.GetElementPtr, llvm.BitCast:
|
||||
|
|
|
@ -251,7 +251,10 @@ func LowerReflect(mod llvm.Module) {
|
|||
// a pointer to a runtime.structField array and therefore a
|
||||
// bitcast. This global should be erased separately, otherwise
|
||||
// typecode objects cannot be erased.
|
||||
structFields := references.Operand(0)
|
||||
structFields := references
|
||||
if !structFields.IsAConstantExpr().IsNil() && structFields.Opcode() == llvm.BitCast {
|
||||
structFields = structFields.Operand(0) // get global from bitcast, for LLVM 14 compatibility (non-opaque pointers)
|
||||
}
|
||||
structFields.EraseFromParentAsGlobal()
|
||||
}
|
||||
}
|
||||
|
@ -460,7 +463,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
|
|||
|
||||
// Get the fields this struct type contains.
|
||||
// The struct number will be the start index of
|
||||
structTypeGlobal := state.builder.CreateExtractValue(typecode.Initializer(), 0, "").Operand(0).Initializer()
|
||||
structTypeGlobal := stripPointerCasts(state.builder.CreateExtractValue(typecode.Initializer(), 0, "")).Initializer()
|
||||
numFields := structTypeGlobal.Type().ArrayLength()
|
||||
|
||||
// The first data that is stored in the struct sidetable is the number of
|
||||
|
@ -483,7 +486,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
|
|||
if nameGlobal == llvm.ConstPointerNull(nameGlobal.Type()) {
|
||||
panic("compiler: no name for this struct field")
|
||||
}
|
||||
fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0), state.builder)
|
||||
fieldNameBytes := getGlobalBytes(stripPointerCasts(nameGlobal), state.builder)
|
||||
fieldNameNumber := state.getStructNameNumber(fieldNameBytes)
|
||||
|
||||
// See whether this struct field has an associated tag, and if so,
|
||||
|
@ -493,7 +496,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
|
|||
tagNumber := 0
|
||||
if tagGlobal != llvm.ConstPointerNull(tagGlobal.Type()) {
|
||||
hasTag = true
|
||||
tagBytes := getGlobalBytes(tagGlobal.Operand(0), state.builder)
|
||||
tagBytes := getGlobalBytes(stripPointerCasts(tagGlobal), state.builder)
|
||||
tagNumber = state.getStructNameNumber(tagBytes)
|
||||
}
|
||||
|
||||
|
|
|
@ -139,14 +139,13 @@ func OptimizeReflectImplements(mod llvm.Module) {
|
|||
if call.IsACallInst().IsNil() {
|
||||
continue
|
||||
}
|
||||
interfaceTypeBitCast := call.Operand(2)
|
||||
if interfaceTypeBitCast.IsAConstantExpr().IsNil() || interfaceTypeBitCast.Opcode() != llvm.BitCast {
|
||||
interfaceType := stripPointerCasts(call.Operand(2))
|
||||
if interfaceType.IsAGlobalVariable().IsNil() {
|
||||
// The asserted interface is not constant, so can't optimize this
|
||||
// code.
|
||||
continue
|
||||
}
|
||||
|
||||
interfaceType := interfaceTypeBitCast.Operand(0)
|
||||
if strings.HasPrefix(interfaceType.Name(), "reflect/types.type:named:") {
|
||||
// Get the underlying type.
|
||||
interfaceType = builder.CreateExtractValue(interfaceType.Initializer(), 0, "")
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче