Browse Source

wasm: support ThinLTO

Using ThinLTO manages to optimize binaries quite significantly. The
exact amount varies a lot by program but it's about 10-15% usually.

Don't remove non-ThinLTO support yet. It would not surprise me if this
triggered some unintended side effect. Eventually, non-ThinLTO support
should be removed though.
pull/3412/head
Ayke van Laethem 2 years ago
committed by Ayke
parent
commit
da362b8a24
  1. 14
      compileopts/config.go
  2. 5
      compiler/compiler.go
  3. 1
      compiler/testdata/pragma.ll

14
compileopts/config.go

@ -190,17 +190,11 @@ func (c *Config) StackSize() uint64 {
return c.Target.DefaultStackSize
}
// UseThinLTO returns whether ThinLTO should be used for the given target. Some
// targets (such as wasm) are not yet supported.
// We should try and remove as many exceptions as possible in the future, so
// that this optimization can be applied in more places.
// UseThinLTO returns whether ThinLTO should be used for the given target.
func (c *Config) UseThinLTO() bool {
parts := strings.Split(c.Triple(), "-")
if parts[0] == "wasm32" {
// wasm-ld doesn't seem to support ThinLTO yet.
return false
}
// Other architectures support ThinLTO.
// All architectures support ThinLTO now. However, this code is kept for the
// time being in case there are regressions. The non-ThinLTO code support
// should be removed when it is proven to work reliably.
return true
}

5
compiler/compiler.go

@ -1099,6 +1099,11 @@ func (b *builder) createFunctionStart(intrinsic bool) {
// otherwise the function is not exported.
functionAttr := b.ctx.CreateStringAttribute("wasm-export-name", b.info.linkName)
b.llvmFn.AddFunctionAttr(functionAttr)
// Unlike most targets, exported functions are actually visible in
// WebAssembly (even if it's not called from within the WebAssembly
// module). But LTO generally optimizes such functions away. Therefore,
// exported functions must be explicitly marked as used.
llvmutil.AppendToGlobal(b.mod, "llvm.used", b.llvmFn)
}
// Some functions have a pragma controlling the inlining level.

1
compiler/testdata/pragma.ll

@ -6,6 +6,7 @@ target triple = "wasm32-unknown-wasi"
@extern_global = external global [0 x i8], align 1
@main.alignedGlobal = hidden global [4 x i32] zeroinitializer, align 32
@main.alignedGlobal16 = hidden global [4 x i32] zeroinitializer, align 16
@llvm.used = appending global [2 x ptr] [ptr @extern_func, ptr @exportedFunctionInSection]
@main.globalInSection = hidden global i32 0, section ".special_global_section", align 4
@undefinedGlobalNotInSection = external global i32, align 4
@main.multipleGlobalPragmas = hidden global i32 0, section ".global_section", align 1024

Loading…
Cancel
Save