mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 18:47:47 +00:00
19f8874764
The x/tools/go/ssa package splits slice loads/stores into two
operations. So for code like this:
x = p[3]
It has two instructions:
x_ptr = &p[3]
x = *x_ptr
This makes the IR simpler, but also means we're accidentally inserting
more nil checks than necessary: the slice index operation has
effectively already checked for nil by performing a bounds check.
Therefore, omit nil pointer checks for pointers created by
*ssa.IndexAddr.
This change is necessary to make sure a future removal of runtime.isnil
will not cause the escape analysis pass to regress. Apart from that, it
reduces code size slightly in many smoke tests (with no increases in
code size).
31 lines
936 B
Go
31 lines
936 B
Go
package compiler
|
|
|
|
// This file implements volatile loads/stores in runtime/volatile.LoadT and
|
|
// runtime/volatile.StoreT as compiler builtins.
|
|
|
|
import (
|
|
"golang.org/x/tools/go/ssa"
|
|
"tinygo.org/x/go-llvm"
|
|
)
|
|
|
|
// createVolatileLoad is the implementation of the intrinsic function
|
|
// runtime/volatile.LoadT().
|
|
func (b *builder) createVolatileLoad(instr *ssa.CallCommon) (llvm.Value, error) {
|
|
addr := b.getValue(instr.Args[0])
|
|
b.createNilCheck(instr.Args[0], addr, "deref")
|
|
val := b.CreateLoad(addr, "")
|
|
val.SetVolatile(true)
|
|
return val, nil
|
|
}
|
|
|
|
// createVolatileStore is the implementation of the intrinsic function
|
|
// runtime/volatile.StoreT().
|
|
func (b *builder) createVolatileStore(instr *ssa.CallCommon) (llvm.Value, error) {
|
|
addr := b.getValue(instr.Args[0])
|
|
val := b.getValue(instr.Args[1])
|
|
b.createNilCheck(instr.Args[0], addr, "deref")
|
|
store := b.CreateStore(val, addr)
|
|
store.SetVolatile(true)
|
|
return llvm.Value{}, nil
|
|
}
|