ssagen

Imports

Imports #

"fmt"
"internal/buildcfg"
"os"
"slices"
"sort"
"strings"
"sync"
"cmd/compile/internal/base"
"cmd/compile/internal/inline"
"cmd/compile/internal/ir"
"cmd/compile/internal/liveness"
"cmd/compile/internal/objw"
"cmd/compile/internal/pgoir"
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
"container/heap"
"fmt"
"cmd/compile/internal/ir"
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/src"
"bufio"
"bytes"
"fmt"
"go/constant"
"html"
"internal/buildcfg"
"os"
"path/filepath"
"slices"
"strings"
"cmd/compile/internal/abi"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/liveness"
"cmd/compile/internal/objw"
"cmd/compile/internal/reflectdata"
"cmd/compile/internal/rttype"
"cmd/compile/internal/ssa"
"cmd/compile/internal/staticdata"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
rtabi "internal/abi"
"fmt"
"internal/buildcfg"
"log"
"os"
"strings"
"cmd/compile/internal/abi"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/objw"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/obj/wasm"
rtabi "internal/abi"
"cmd/compile/internal/ir"
"cmd/compile/internal/objw"
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/obj"
"fmt"
"internal/abi"
"internal/buildcfg"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/sys"
"fmt"
"strings"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/src"

Constants & Variables

Arch var #

var Arch ArchInfo

BoundsCheckFunc var #

var BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym

ExtendCheckFunc var #

var ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym

callDefer const #

const callDefer

callDeferStack const #

const callDeferStack

callGo const #

const callGo

callNormal const #

const callNormal callKind = iota

callTail const #

const callTail

capVar var #

var capVar = *ast.CallExpr

debugPhi const #

const debugPhi = false

deferBitsVar var #

var deferBitsVar = *ast.CallExpr

deferStructFnField const #

deferStructFnField is the field index of _defer.fn.

const deferStructFnField = 4

deferType var #

var deferType *types.Type

f32_u32 var #

var f32_u32 = f2uCvtTab{...}

f32_u64 var #

var f32_u64 = f2uCvtTab{...}

f64_u32 var #

var f64_u32 = f2uCvtTab{...}

f64_u64 var #

var f64_u64 = f2uCvtTab{...}

fpConvOpToSSA var #

var fpConvOpToSSA = map[twoTypes]twoOpsAndType{...}

fpConvOpToSSA32 var #

this map is used only for 32-bit arch, and only includes the difference on 32-bit arch, don't use int64<->float conversion for uint32

var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{...}

globalMapInitLsyms var #

globalMapInitLsyms records the LSym of each map.init.NNN outlined map initializer function created by the compiler.

var globalMapInitLsyms map[*obj.LSym]struct{...}

hashVar var #

var hashVar = *ast.CallExpr

instrumentMove const #

const instrumentMove

instrumentRead const #

const instrumentRead = iota

instrumentWrite const #

const instrumentWrite

intrinsics var #

var intrinsics intrinsicBuilders

largeStackFrames var #

var largeStackFrames []largeStack

largeStackFramesMu var #

var largeStackFramesMu sync.Mutex

lenVar var #

var lenVar = *ast.CallExpr

maxStackSize const #

const maxStackSize = *ast.BinaryExpr

memVar var #

marker node for the memory variable

var memVar = *ast.CallExpr

nowritebarrierrecCheck var #

var nowritebarrierrecCheck *nowritebarrierrecChecker

okVar var #

var okVar = *ast.CallExpr

opToSSA var #

var opToSSA = map[opAndType]ssa.Op{...}

ptrVar var #

marker nodes for temporary variables

var ptrVar = *ast.CallExpr

shareDeferExits const #

If true, share as many open-coded defer exits as possible (with the downside of worse line-number information)

const shareDeferExits = false

shiftOpToSSA var #

var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{...}

skipCap const #

const skipCap

skipLen const #

const skipLen

skipPtr const #

const skipPtr skipMask = *ast.BinaryExpr

smallBlocks const #

const smallBlocks = 500

softFloatOps var #

var softFloatOps map[ssa.Op]sfRtCallDef

ssaCaches var #

var ssaCaches []ssa.Cache

ssaConfig var #

var ssaConfig *ssa.Config

ssaDir var #

var ssaDir string

ssaDump var #

var ssaDump string

ssaDumpCFG var #

var ssaDumpCFG string

ssaDumpFile const #

const ssaDumpFile = "ssa.html"

ssaDumpInlined var #

ssaDumpInlined holds all inlined functions when ssaDump contains a function name.

var ssaDumpInlined []*ir.Func

ssaDumpStdout var #

var ssaDumpStdout bool

typVar var #

var typVar = *ast.CallExpr

u32_f32 var #

var u32_f32 = u322fcvtTab{...}

u32_f64 var #

var u32_f64 = u322fcvtTab{...}

u64_f32 var #

var u64_f32 = u642fcvtTab{...}

u64_f64 var #

var u64_f64 = u642fcvtTab{...}

uint64fpConvOpToSSA var #

uint64<->float conversions, only on machines that have instructions for that

var uint64fpConvOpToSSA = map[twoTypes]twoOpsAndType{...}

Type Aliases

callKind type #

type callKind int8

instrumentKind type #

type instrumentKind uint8

intrinsicBuilder type #

An intrinsicBuilder converts a call node n into an ssa value that implements that call as an intrinsic. args is a list of arguments to the func.

type intrinsicBuilder func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value

intrinsicBuilders type #

type intrinsicBuilders map[intrinsicKey]intrinsicBuilder

skipMask type #

type skipMask uint8

Structs

ArchInfo struct #

type ArchInfo struct {
LinkArch *obj.LinkArch
REGSP int
MAXWIDTH int64
SoftFloat bool
PadFrame func(int64) int64
ZeroRange func(*objw.Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
Ginsnop func(*objw.Progs) *obj.Prog
SSAMarkMoves func(*State, *ssa.Block)
SSAGenValue func(*State, *ssa.Value)
SSAGenBlock func(s *State, b *ssa.Block, next *ssa.Block)
LoadRegResult func(s *State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
SpillArgReg func(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
}

Branch struct #

Branch is an unresolved branch.

type Branch struct {
P *obj.Prog
B *ssa.Block
}

IndexJump struct #

For generating consecutive jump instructions to model a specific branching

type IndexJump struct {
Jump obj.As
Index int
}

State struct #

State contains state needed during Prog generation.

type State struct {
ABI obj.ABI
pp *objw.Progs
Branches []Branch
JumpTables []*ssa.Block
bstart []*obj.Prog
maxarg int64
livenessMap liveness.Map
partLiveArgs map[*ir.Name]bool
lineRunStart *obj.Prog
OnWasmStackSkipped int
}

SymABIs struct #

SymABIs records information provided by the assembler about symbol definition ABIs and reference ABIs.

type SymABIs struct {
defs map[string]obj.ABI
refs map[string]obj.ABISet
}

blockHeap struct #

A block heap is used as a priority queue to implement the PiggyBank from Sreedhar and Gao. That paper uses an array which is better asymptotically but worse in the common case when the PiggyBank holds a sparse set of blocks.

type blockHeap struct {
a []*ssa.Block
level []int32
}

domBlock struct #

domBlock contains extra per-block information to record the dominator tree.

type domBlock struct {
firstChild *ssa.Block
sibling *ssa.Block
}

f2uCvtTab struct #

type f2uCvtTab struct {
ltf ssa.Op
cvt2U ssa.Op
subf ssa.Op
or ssa.Op
floatValue func(*state, *types.Type, float64) *ssa.Value
intValue func(*state, *types.Type, int64) *ssa.Value
cutoff uint64
}

funcLine struct #

type funcLine struct {
f *obj.LSym
base *src.PosBase
line uint
}

fwdRefAux struct #

fwdRefAux wraps an arbitrary ir.Node as an ssa.Aux for use with OpFwdref.

type fwdRefAux struct {
_ [0]func()
N ir.Node
}

intrinsicBuildConfig struct #

intrinsicBuildConfig specifies the config to use for intrinsic building.

type intrinsicBuildConfig struct {
instrumenting bool
go386 string
goamd64 int
goarm buildcfg.GoarmFeatures
goarm64 buildcfg.Goarm64Features
gomips string
gomips64 string
goppc64 int
goriscv64 int
}

intrinsicKey struct #

type intrinsicKey struct {
arch *sys.Arch
pkg string
fn string
}

largeStack struct #

largeStack is info about a function whose stack frame is too large (rare).

type largeStack struct {
locals int64
args int64
callee int64
pos src.XPos
}

nowritebarrierrecCall struct #

type nowritebarrierrecCall struct {
target *ir.Func
lineno src.XPos
}

nowritebarrierrecChecker struct #

type nowritebarrierrecChecker struct {
extraCalls map[*ir.Func][]nowritebarrierrecCall
curfn *ir.Func
}

opAndTwoTypes struct #

type opAndTwoTypes struct {
op ir.Op
etype1 types.Kind
etype2 types.Kind
}

opAndType struct #

type opAndType struct {
op ir.Op
etype types.Kind
}

openDeferInfo struct #

Information about each open-coded defer.

type openDeferInfo struct {
n *ir.CallExpr
closure *ssa.Value
closureNode *ir.Name
}

phiState struct #

type phiState struct {
s *state
f *ssa.Func
defvars []map[ir.Node]*ssa.Value
varnum map[ir.Node]int32
idom []*ssa.Block
tree []domBlock
level []int32
priq blockHeap
q []*ssa.Block
queued *sparseSet
hasPhi *sparseSet
hasDef *sparseSet
placeholder *ssa.Value
}

sfRtCallDef struct #

type sfRtCallDef struct {
rtfn *obj.LSym
rtype types.Kind
}

simplePhiState struct #

Variant to use for small functions.

type simplePhiState struct {
s *state
f *ssa.Func
fwdrefs []*ssa.Value
defvars []map[ir.Node]*ssa.Value
reachable []bool
}

sparseSet struct #

copy of ../ssa/sparseset.go TODO: move this file to ../ssa, then use sparseSet there.

type sparseSet struct {
dense []ssa.ID
sparse []int32
}

ssaLabel struct #

type ssaLabel struct {
target *ssa.Block
breakTarget *ssa.Block
continueTarget *ssa.Block
}

ssafn struct #

ssafn holds frontend information about a function that the backend is processing. It also exports a bunch of compiler services for the ssa backend.

type ssafn struct {
curfn *ir.Func
strings map[string]*obj.LSym
stksize int64
stkptrsize int64
stkalign int64
log bool
}

state struct #

type state struct {
config *ssa.Config
f *ssa.Func
curfn *ir.Func
labels map[string]*ssaLabel
breakTo *ssa.Block
continueTo *ssa.Block
curBlock *ssa.Block
vars map[ir.Node]*ssa.Value
fwdVars map[ir.Node]*ssa.Value
defvars []map[ir.Node]*ssa.Value
decladdrs map[*ir.Name]*ssa.Value
startmem *ssa.Value
sp *ssa.Value
sb *ssa.Value
deferBitsAddr *ssa.Value
deferBitsTemp *ir.Name
line []src.XPos
lastPos src.XPos
panics map[funcLine]*ssa.Block
cgoUnsafeArgs bool
hasdefer bool
softFloat bool
hasOpenDefers bool
checkPtrEnabled bool
instrumentEnterExit bool
instrumentMemory bool
openDefers []*openDeferInfo
lastDeferExit *ssa.Block
lastDeferFinalBlock *ssa.Block
lastDeferCount int
prevCall *ssa.Value
}

twoOpsAndType struct #

type twoOpsAndType struct {
op1 ssa.Op
op2 ssa.Op
intermediateType types.Kind
}

twoTypes struct #

type twoTypes struct {
etype1 types.Kind
etype2 types.Kind
}

u322fcvtTab struct #

type u322fcvtTab struct {
cvtI2F ssa.Op
cvtF2F ssa.Op
}

u642fcvtTab struct #

type u642fcvtTab struct {
leq ssa.Op
cvt2F ssa.Op
and ssa.Op
rsh ssa.Op
or ssa.Op
add ssa.Op
one func(*state, *types.Type, int64) *ssa.Value
}

Functions

AbiForBodylessFuncStackMap function #

AbiForBodylessFuncStackMap returns the ABI for a bodyless function's stack map. This is not necessarily the ABI used to call it. Currently (1.17 dev) such a stack map is always ABI0; any ABI wrapper that is present is nosplit, hence a precise stack map is not needed there (the parameters survive only long enough to call the wrapped assembly function). This always returns a freshly copied ABI.

func AbiForBodylessFuncStackMap(fn *ir.Func) *abi.ABIConfig

AddAux function #

AddAux adds the offset in the aux fields (AuxInt and Aux) of v to a.

func AddAux(a *obj.Addr, v *ssa.Value)

AddAux2 function #

func AddAux2(a *obj.Addr, v *ssa.Value, offset int64)

AddrAuto function #

func AddrAuto(a *obj.Addr, v *ssa.Value)

AllocFrame method #

func (s *ssafn) AllocFrame(f *ssa.Func)

Br method #

Br emits a single branch instruction and returns the instruction. Not all architectures need the returned instruction, but otherwise the boilerplate is common to all.

func (s *State) Br(op obj.As, target *ssa.Block) *obj.Prog

Call method #

Call returns a new CALL instruction for the SSA value v. It uses PrepareCall to prepare the call.

func (s *State) Call(v *ssa.Value) *obj.Prog

CanBeAnSSAAux method #

func (fwdRefAux) CanBeAnSSAAux()

CheckArgReg function #

CheckArgReg ensures that v is in the function's entry block.

func CheckArgReg(v *ssa.Value)

CheckLargeStacks function #

func CheckLargeStacks()

CheckLoweredGetClosurePtr function #

CheckLoweredGetClosurePtr checks that v is the first instruction in the function's entry block, except for incoming in-register arguments. The output of LoweredGetClosurePtr is generally hardwired to the correct register. That register contains the closure pointer on closure entry.

func CheckLoweredGetClosurePtr(v *ssa.Value)

CheckLoweredPhi function #

CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values. Called during ssaGenValue.

func CheckLoweredPhi(v *ssa.Value)

CombJump method #

CombJump generates combinational instructions (2 at present) for a block jump, thereby the behaviour of non-standard condition codes could be simulated

func (s *State) CombJump(b *ssa.Block, next *ssa.Block, jumps *[2][2]IndexJump)

Compile function #

Compile builds an SSA backend function, uses it to generate a plist, and flushes that plist to machine code. worker indicates which of the backend workers is doing the processing.

func Compile(fn *ir.Func, worker int, profile *pgoir.Profile)

CreateWasmImportWrapper function #

CreateWasmImportWrapper creates a wrapper for imported WASM functions to adapt them to the Go calling convention. The body for this function is generated in cmd/internal/obj/wasm/wasmobj.go

func CreateWasmImportWrapper(fn *ir.Func) bool

DebugFriendlySetPosFrom method #

DebugFriendlySetPosFrom adjusts Pos.IsStmt subject to heuristics that reduce "jumpy" line number churn when debugging. Spill/fill/copy instructions from the register allocator, phi functions, and instructions with a no-pos position are examples of instructions that can cause churn.

func (s *State) DebugFriendlySetPosFrom(v *ssa.Value)

Debug_checknil method #

func (s *state) Debug_checknil() bool

Debug_checknil method #

func (e *ssafn) Debug_checknil() bool

DumpInline function #

func DumpInline(fn *ir.Func)

EmitArgInfo function #

emit argument info (locations on stack) of f for traceback.

func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym

EnableNoWriteBarrierRecCheck function #

func EnableNoWriteBarrierRecCheck()

Fatalf method #

Fatalf reports a compiler error and exits.

func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{})

Fatalf method #

func (s *state) Fatalf(msg string, args ...interface{})

Func method #

func (e *ssafn) Func() *ir.Func

FuncInfo method #

func (s *State) FuncInfo() *obj.FuncInfo

GenABIWrappers method #

GenABIWrappers applies ABI information to Funcs and generates ABI wrapper functions where necessary.

func (s *SymABIs) GenABIWrappers()

GenWasmExportWrapper function #

func GenWasmExportWrapper(wrapped *ir.Func)

InitConfig function #

func InitConfig()

InitEnv function #

func InitEnv()

InitTables function #

func InitTables()

IsIntrinsicCall function #

func IsIntrinsicCall(n *ir.CallExpr) bool

Len method #

func (h *blockHeap) Len() int

Less method #

func (h *blockHeap) Less(i int, j int) bool

Log method #

func (s *state) Log() bool

Log method #

func (e *ssafn) Log() bool

Logf method #

Logf logs a message from the compiler.

func (e *ssafn) Logf(msg string, args ...interface{})

Logf method #

func (s *state) Logf(msg string, args ...interface{})

NewSymABIs function #

func NewSymABIs() *SymABIs

NoWriteBarrierRecCheck function #

func NoWriteBarrierRecCheck()

Pc method #

Pc returns the current Prog.

func (s *State) Pc() *obj.Prog

Pop method #

func (h *blockHeap) Pop() interface{}

PrepareCall method #

PrepareCall prepares to emit a CALL instruction for v and does call-related bookkeeping. It must be called immediately before emitting the actual CALL instruction, since it emits PCDATA for the stack map at the call (calls are safe points).

func (s *State) PrepareCall(v *ssa.Value)

Prog method #

Prog appends a new Prog.

func (s *State) Prog(as obj.As) *obj.Prog

Push method #

func (h *blockHeap) Push(x interface{})

ReadSymABIs method #

ReadSymABIs reads a symabis file that specifies definitions and references of text symbols by ABI. The symabis format is a set of lines, where each line is a sequence of whitespace-separated fields. The first field is a verb and is either "def" for defining a symbol ABI or "ref" for referencing a symbol using an ABI. For both "def" and "ref", the second field is the symbol name and the third field is the ABI name, as one of the named cmd/internal/obj.ABI constants.

func (s *SymABIs) ReadSymABIs(file string)

RegisterMapInitLsym function #

RegisterMapInitLsym records "s" in the set of outlined map initializer functions.

func RegisterMapInitLsym(s *obj.LSym)

SetPos method #

SetPos sets the current source position.

func (s *State) SetPos(pos src.XPos)

SpillSlotAddr function #

SpillSlotAddr uses LocalSlot information to initialize an obj.Addr The resulting addr is used in a non-standard context -- in the prologue of a function, before the frame has been constructed, so the standard addressing for the parameters will be wrong.

func SpillSlotAddr(spill ssa.Spill, baseReg int16, extraOffset int64) obj.Addr

SplitSlot method #

SplitSlot returns a slot representing the data of parent starting at offset.

func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot

StackOffset function #

StackOffset returns the stack location of a LocalSlot relative to the stack pointer, suitable for use in a DWARF location entry. This has nothing to do with its offset in the user variable.

func StackOffset(slot ssa.LocalSlot) int32

StringData method #

StringData returns a symbol which is the data component of a global string constant containing s.

func (e *ssafn) StringData(s string) *obj.LSym

Swap method #

func (h *blockHeap) Swap(i int, j int)

Syslook method #

func (e *ssafn) Syslook(name string) *obj.LSym

TailCall method #

TailCall returns a new tail call instruction for the SSA value v. It is like Call, but for a tail call.

func (s *State) TailCall(v *ssa.Value) *obj.Prog

UseArgs method #

UseArgs records the fact that an instruction needs a certain amount of callee args space for its use.

func (s *State) UseArgs(n int64)

UseWriteBarrier method #

func (e *ssafn) UseWriteBarrier() bool

Warnl method #

func (s *state) Warnl(pos src.XPos, msg string, args ...interface{})

Warnl method #

Warnl reports a "warning", which is usually flag-triggered logging output for the benefit of tests.

func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{})

abiForFunc function #

abiForFunc implements ABI policy for a function, but does not return a copy of the ABI. Passing a nil function returns the default ABI based on experiment configuration.

func abiForFunc(fn *ir.Func, abi0 *abi.ABIConfig, abi1 *abi.ABIConfig) *abi.ABIConfig

add method #

func (s *sparseSet) add(x ssa.ID)

add method #

add adds the intrinsic builder b for pkg.fn for the given architecture.

func (ib intrinsicBuilders) add(arch *sys.Arch, pkg string, fn string, b intrinsicBuilder)

addForArchs method #

addForArchs adds the intrinsic builder b for pkg.fn for the given architectures.

func (ib intrinsicBuilders) addForArchs(pkg string, fn string, b intrinsicBuilder, archs ...*sys.Arch)

addForFamilies method #

addForFamilies does the same as addForArchs but operates on architecture families.

func (ib intrinsicBuilders) addForFamilies(pkg string, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)

addNamedValue method #

func (s *state) addNamedValue(n *ir.Name, v *ssa.Value)

addr method #

addr converts the address of the expression n to SSA, adds it to s and returns the SSA result. The value that the returned Value represents is guaranteed to be non-nil.

func (s *state) addr(n ir.Node) *ssa.Value

alias method #

alias aliases pkg.fn to targetPkg.targetFn for all architectures in archs for which targetPkg.targetFn already exists.

func (ib intrinsicBuilders) alias(pkg string, fn string, targetPkg string, targetFn string, archs ...*sys.Arch)

append method #

append converts an OAPPEND node to SSA. If inplace is false, it converts the OAPPEND expression n to an ssa.Value, adds it to s, and returns the Value. If inplace is true, it writes the result of the OAPPEND expression n back to the slice being appended to, and returns nil. inplace MUST be set to false if the slice can be SSA'd. Note: this code only handles fixed-count appends. Dotdotdot appends have already been rewritten at this point (by walk).

func (s *state) append(n *ir.CallExpr, inplace bool) *ssa.Value

assign method #

assign does left = right. Right has already been evaluated to ssa, left has not. If deref is true, then we do left = *right instead (and right has already been nil-checked). If deref is true and right == nil, just do left = 0. skip indicates assignments (at the top level) that can be avoided. mayOverlap indicates whether left&right might partially overlap in memory. Default is false.

func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask)

assignWhichMayOverlap method #

func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool, skip skipMask, mayOverlap bool)

boundsCheck method #

boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not. Starts a new block on return. On input, len must be converted to full int width and be nonnegative. Returns idx converted to full int width. If bounded is true then caller guarantees the index is not out of bounds (but boundsCheck will still extend the index to full int width).

func (s *state) boundsCheck(idx *ssa.Value, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value

buildssa function #

buildssa builds an SSA function for fn. worker indicates which of the backend workers is doing the processing.

func buildssa(fn *ir.Func, worker int, isPgoHot bool) *ssa.Func

call method #

Calls the function n using the specified call type. Returns the address of the return value (or nil if none).

func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool, deferExtra ir.Expr) *ssa.Value

callAddr method #

func (s *state) callAddr(n *ir.CallExpr, k callKind) *ssa.Value

callResult method #

func (s *state) callResult(n *ir.CallExpr, k callKind) *ssa.Value

callTargetLSym function #

callTargetLSym returns the correct LSym to call 'callee' using its ABI.

func callTargetLSym(callee *ir.Name) *obj.LSym

canSSA method #

canSSA reports whether n is SSA-able. n must be an ONAME (or an ODOT sequence with an ONAME base).

func (s *state) canSSA(n ir.Node) bool

canSSAName method #

func (s *state) canSSAName(name *ir.Name) bool

canonicalize method #

canonicalize returns the canonical name used for a linker symbol in s's maps. Symbols in this package may be written either as "".X or with the package's import path already in the symbol. This rewrites both to use the full path, which matches compiler-generated linker symbol names.

func (s *SymABIs) canonicalize(linksym string) string

check method #

If cmp (a bool) is false, panic using the given function.

func (s *state) check(cmp *ssa.Value, fn *obj.LSym)

check method #

func (c *nowritebarrierrecChecker) check()

checkPtrAlignment method #

func (s *state) checkPtrAlignment(n *ir.ConvExpr, v *ssa.Value, count *ssa.Value)

clear method #

func (s *sparseSet) clear()

clobberBase function #

func clobberBase(n ir.Node) ir.Node

cmpstackvarlt function #

cmpstackvarlt reports whether the stack variable a sorts before b.

func cmpstackvarlt(a *ir.Name, b *ir.Name, mls *liveness.MergeLocalsState) bool

concreteEtype method #

func (s *state) concreteEtype(t *types.Type) types.Kind

condBranch method #

condBranch evaluates the boolean expression cond and branches to yes if cond is true and no if cond is false. This function is intended to handle && and || better than just calling s.expr(cond) and branching on the result.

func (s *state) condBranch(cond ir.Node, yes *ssa.Block, no *ssa.Block, likely int8)

constBool method #

func (s *state) constBool(c bool) *ssa.Value

constEmptyString method #

func (s *state) constEmptyString(t *types.Type) *ssa.Value

constFloat32 method #

func (s *state) constFloat32(t *types.Type, c float64) *ssa.Value

constFloat64 method #

func (s *state) constFloat64(t *types.Type, c float64) *ssa.Value

constInt method #

func (s *state) constInt(t *types.Type, c int64) *ssa.Value

constInt16 method #

func (s *state) constInt16(t *types.Type, c int16) *ssa.Value

constInt32 method #

func (s *state) constInt32(t *types.Type, c int32) *ssa.Value

constInt64 method #

func (s *state) constInt64(t *types.Type, c int64) *ssa.Value

constInt8 method #

func (s *state) constInt8(t *types.Type, c int8) *ssa.Value

constInterface method #

func (s *state) constInterface(t *types.Type) *ssa.Value

constNil method #

func (s *state) constNil(t *types.Type) *ssa.Value

constOffPtrSP method #

func (s *state) constOffPtrSP(t *types.Type, c int64) *ssa.Value

constSlice method #

const* routines add a new const value to the entry block.

func (s *state) constSlice(t *types.Type) *ssa.Value

contains method #

func (s *sparseSet) contains(x ssa.ID) bool

conv method #

func (s *state) conv(n ir.Node, v *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

deferstruct function #

deferstruct returns a type interchangeable with runtime._defer. Make sure this stays in sync with runtime/runtime2.go:_defer.

func deferstruct() *types.Type

defframe function #

func defframe(s *State, e *ssafn, f *ssa.Func)

dottype method #

dottype generates SSA for a type assertion node. commaok indicates whether to panic or return a bool. If commaok is false, resok will be nil.

func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res *ssa.Value, resok *ssa.Value)

dottype1 method #

dottype1 implements a x.(T) operation. iface is the argument (x), dst is the type we're asserting to (T) and src is the type we're asserting from. source is the *runtime._type of src target is the *runtime._type of dst. If src is a nonempty interface and dst is not an interface, targetItab is an itab representing (dst, src). Otherwise it is nil. commaok is true if the caller wants a boolean success value. Otherwise, the generated code panics if the conversion fails. descriptor is a compiler-allocated internal/abi.TypeAssert whose address is passed to runtime.typeAssert when the target type is a compile-time-known non-empty interface. It may be nil.

func (s *state) dottype1(pos src.XPos, src *types.Type, dst *types.Type, iface *ssa.Value, source *ssa.Value, target *ssa.Value, targetItab *ssa.Value, commaok bool, descriptor *obj.LSym) (res *ssa.Value, resok *ssa.Value)

dumpSourcesColumn function #

func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Func)

dynamicDottype method #

func (s *state) dynamicDottype(n *ir.DynamicTypeAssertExpr, commaok bool) (res *ssa.Value, resok *ssa.Value)

emitArgInfo function #

emit argument info (locations on stack) for traceback.

func emitArgInfo(e *ssafn, f *ssa.Func, pp *objw.Progs)

emitOpenDeferInfo method #

emitOpenDeferInfo emits FUNCDATA information about the defers in a function that is using open-coded defers. This funcdata is used to determine the active defers in a function and execute those defers during panic processing. The funcdata is all encoded in varints (since values will almost always be less than 128, but stack offsets could potentially be up to 2Gbyte). All "locations" (offsets) for stack variables are specified as the number of bytes below varp (pointer to the top of the local variables) for their starting address. The format is: - Offset of the deferBits variable - Offset of the first closure slot (the rest are laid out consecutively).

func (s *state) emitOpenDeferInfo()

emitWrappedFuncInfo function #

for wrapper, emit info of wrapped function.

func emitWrappedFuncInfo(e *ssafn, pp *objw.Progs)

endBlock method #

endBlock marks the end of generating code for the current block. Returns the (former) current block. Returns nil if there is no current block, i.e. if no code flows to the current execution point.

func (s *state) endBlock() *ssa.Block

entryBlock method #

func (s *state) entryBlock() *ssa.Block

entryNewValue0 method #

entryNewValue0 adds a new value with no arguments to the entry block.

func (s *state) entryNewValue0(op ssa.Op, t *types.Type) *ssa.Value

entryNewValue0A method #

entryNewValue0A adds a new value with no arguments and an aux value to the entry block.

func (s *state) entryNewValue0A(op ssa.Op, t *types.Type, aux ssa.Aux) *ssa.Value

entryNewValue1 method #

entryNewValue1 adds a new value with one argument to the entry block.

func (s *state) entryNewValue1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value

entryNewValue1A method #

entryNewValue1A adds a new value with one argument and an aux value to the entry block.

func (s *state) entryNewValue1A(op ssa.Op, t *types.Type, aux ssa.Aux, arg *ssa.Value) *ssa.Value

entryNewValue1I method #

entryNewValue1I adds a new value with one argument and an auxint value to the entry block.

func (s *state) entryNewValue1I(op ssa.Op, t *types.Type, auxint int64, arg *ssa.Value) *ssa.Value

entryNewValue2 method #

entryNewValue2 adds a new value with two arguments to the entry block.

func (s *state) entryNewValue2(op ssa.Op, t *types.Type, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

entryNewValue2A method #

entryNewValue2A adds a new value with two arguments and an aux value to the entry block.

func (s *state) entryNewValue2A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

etypesign function #

etypesign returns the signed-ness of e, for integer/pointer etypes. -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer.

func etypesign(e types.Kind) int8

exit method #

exit processes any code that needs to be generated just before returning. It returns a BlockRet block that ends the control flow. Its control value will be set to the final memory state.

func (s *state) exit() *ssa.Block

expr method #

expr converts the expression n to ssa, adds it to s and returns the ssa result.

func (s *state) expr(n ir.Node) *ssa.Value

exprCheckPtr method #

func (s *state) exprCheckPtr(n ir.Node, checkPtrOK bool) *ssa.Value

exprPtr method #

exprPtr evaluates n to a pointer and nil-checks it.

func (s *state) exprPtr(n ir.Node, bounded bool, lineno src.XPos) *ssa.Value

extendIndex method #

extendIndex extends v to a full int width. panic with the given kind if v does not fit in an int (only on 32-bit archs).

func (s *state) extendIndex(idx *ssa.Value, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value

fieldIdx function #

fieldIdx finds the index of the field referred to by the ODOT node n.

func fieldIdx(n *ir.SelectorExpr) int

fieldtrack function #

fieldtrack adds R_USEFIELD relocations to fnsym to record any struct fields that it used.

func fieldtrack(fnsym *obj.LSym, tracked map[*obj.LSym]struct{...})

findExtraCalls method #

func (c *nowritebarrierrecChecker) findExtraCalls(nn ir.Node)

findIntrinsic function #

findIntrinsic returns a function which builds the SSA equivalent of the function identified by the symbol sym. If sym is not an intrinsic call, returns nil.

func findIntrinsic(sym *types.Sym) intrinsicBuilder

float32ToUint32 method #

func (s *state) float32ToUint32(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

float32ToUint64 method #

func (s *state) float32ToUint64(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

float64ToUint32 method #

func (s *state) float64ToUint32(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

float64ToUint64 method #

func (s *state) float64ToUint64(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

floatToUint method #

func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

forEachWrapperABI function #

func forEachWrapperABI(fn *ir.Func, cb func(fn *ir.Func, wrapperABI obj.ABI))

genssa function #

genssa appends entries to pp for each instruction in f.

func genssa(f *ssa.Func, pp *objw.Progs)

getClosureAndRcvr method #

getClosureAndRcvr returns values for the appropriate closure and receiver of an interface call

func (s *state) getClosureAndRcvr(fn *ir.SelectorExpr) (*ssa.Value, *ssa.Value)

initIntrinsics function #

func initIntrinsics(cfg *intrinsicBuildConfig)

insertPhis method #

func (s *phiState) insertPhis()

insertPhis method #

func (s *simplePhiState) insertPhis()

insertPhis method #

insertPhis finds all the places in the function where a phi is necessary and inserts them. Uses FwdRef ops to find all uses of variables, and s.defvars to find all definitions. Phi values are inserted, and all FwdRefs are changed to a Copy of the appropriate phi or definition. TODO: make this part of cmd/compile/internal/ssa somehow?

func (s *state) insertPhis()

insertVarPhis method #

func (s *phiState) insertVarPhis(n int, var_ ir.Node, defs []*ssa.Block, typ *types.Type)

instrument method #

func (s *state) instrument(t *types.Type, addr *ssa.Value, kind instrumentKind)

instrument2 method #

func (s *state) instrument2(t *types.Type, addr *ssa.Value, addr2 *ssa.Value, kind instrumentKind)

instrumentFields method #

instrumentFields instruments a read/write operation on addr. If it is instrumenting for MSAN or ASAN and t is a struct type, it instruments operation for each field, instead of for the whole struct.

func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrumentKind)

instrumentMove method #

func (s *state) instrumentMove(t *types.Type, dst *ssa.Value, src *ssa.Value)

intDivide method #

func (s *state) intDivide(n ir.Node, a *ssa.Value, b *ssa.Value) *ssa.Value

intrinsicArgs method #

intrinsicArgs extracts args from n, evaluates them to SSA values, and returns them.

func (s *state) intrinsicArgs(n *ir.CallExpr) []*ssa.Value

intrinsicCall method #

intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation.

func (s *state) intrinsicCall(n *ir.CallExpr) *ssa.Value

label method #

label returns the label associated with sym, creating it if necessary.

func (s *state) label(sym *types.Sym) *ssaLabel

load method #

func (s *state) load(t *types.Type, src *ssa.Value) *ssa.Value

lookup method #

lookup looks up the intrinsic for a pkg.fn on the specified architecture.

func (ib intrinsicBuilders) lookup(arch *sys.Arch, pkg string, fn string) intrinsicBuilder

lookupVarOutgoing method #

lookupVarOutgoing finds the variable's value at the end of block b.

func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ ir.Node, line src.XPos) *ssa.Value

makeABIWrapper function #

makeABIWrapper creates a new function that will be called with wrapperABI and calls "f" using f.ABI.

func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI)

maybeNilCheckClosure method #

maybeNilCheckClosure checks if a nil check of a closure is needed in some architecture-dependent situations and, if so, emits the nil check.

func (s *state) maybeNilCheckClosure(closure *ssa.Value, k callKind)

mem method #

func (s *state) mem() *ssa.Value

minMax method #

minMax converts an OMIN/OMAX builtin call into SSA.

func (s *state) minMax(n *ir.CallExpr) *ssa.Value

move method #

func (s *state) move(t *types.Type, dst *ssa.Value, src *ssa.Value)

moveWhichMayOverlap method #

func (s *state) moveWhichMayOverlap(t *types.Type, dst *ssa.Value, src *ssa.Value, mayOverlap bool)

needAlloc function #

needAlloc reports whether n is within the current frame, for which we need to allocate space. In particular, it excludes arguments and results, which are in the callers frame.

func needAlloc(n *ir.Name) bool

newHeapaddr method #

newHeapaddr allocates heap memory for n and sets its heap address.

func (s *state) newHeapaddr(n *ir.Name)

newNowritebarrierrecChecker function #

newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It must be called before walk.

func newNowritebarrierrecChecker() *nowritebarrierrecChecker

newObject method #

newObject returns an SSA value denoting new(typ).

func (s *state) newObject(typ *types.Type, rtype *ssa.Value) *ssa.Value

newSparseSet function #

newSparseSet returns a sparseSet that can represent integers between 0 and n-1.

func newSparseSet(n int) *sparseSet

newValue0 method #

newValue0 adds a new value with no arguments to the current block.

func (s *state) newValue0(op ssa.Op, t *types.Type) *ssa.Value

newValue0A method #

newValue0A adds a new value with no arguments and an aux value to the current block.

func (s *state) newValue0A(op ssa.Op, t *types.Type, aux ssa.Aux) *ssa.Value

newValue0I method #

newValue0I adds a new value with no arguments and an auxint value to the current block.

func (s *state) newValue0I(op ssa.Op, t *types.Type, auxint int64) *ssa.Value

newValue1 method #

newValue1 adds a new value with one argument to the current block.

func (s *state) newValue1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value

newValue1A method #

newValue1A adds a new value with one argument and an aux value to the current block.

func (s *state) newValue1A(op ssa.Op, t *types.Type, aux ssa.Aux, arg *ssa.Value) *ssa.Value

newValue1Apos method #

newValue1Apos adds a new value with one argument and an aux value to the current block. isStmt determines whether the created values may be a statement or not (i.e., false means never, yes means maybe).

func (s *state) newValue1Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg *ssa.Value, isStmt bool) *ssa.Value

newValue1I method #

newValue1I adds a new value with one argument and an auxint value to the current block.

func (s *state) newValue1I(op ssa.Op, t *types.Type, aux int64, arg *ssa.Value) *ssa.Value

newValue2 method #

newValue2 adds a new value with two arguments to the current block.

func (s *state) newValue2(op ssa.Op, t *types.Type, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

newValue2A method #

newValue2A adds a new value with two arguments and an aux value to the current block.

func (s *state) newValue2A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

newValue2Apos method #

newValue2Apos adds a new value with two arguments and an aux value to the current block. isStmt determines whether the created values may be a statement or not (i.e., false means never, yes means maybe).

func (s *state) newValue2Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg0 *ssa.Value, arg1 *ssa.Value, isStmt bool) *ssa.Value

newValue2I method #

newValue2I adds a new value with two arguments and an auxint value to the current block.

func (s *state) newValue2I(op ssa.Op, t *types.Type, aux int64, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

newValue3 method #

newValue3 adds a new value with three arguments to the current block.

func (s *state) newValue3(op ssa.Op, t *types.Type, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value) *ssa.Value

newValue3A method #

newValue3A adds a new value with three arguments and an aux value to the current block.

func (s *state) newValue3A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value) *ssa.Value

newValue3Apos method #

newValue3Apos adds a new value with three arguments and an aux value to the current block. isStmt determines whether the created values may be a statement or not (i.e., false means never, yes means maybe).

func (s *state) newValue3Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value, isStmt bool) *ssa.Value

newValue3I method #

newValue3I adds a new value with three arguments and an auxint value to the current block.

func (s *state) newValue3I(op ssa.Op, t *types.Type, aux int64, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value) *ssa.Value

newValue4 method #

newValue4 adds a new value with four arguments to the current block.

func (s *state) newValue4(op ssa.Op, t *types.Type, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value, arg3 *ssa.Value) *ssa.Value

newValue4I method #

newValue4I adds a new value with four arguments and an auxint value to the current block.

func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0 *ssa.Value, arg1 *ssa.Value, arg2 *ssa.Value, arg3 *ssa.Value) *ssa.Value

newValueOrSfCall1 method #

newValueOrSfCall* are wrappers around newValue*, which may create a call to a soft-float runtime function instead (when emitting soft-float code).

func (s *state) newValueOrSfCall1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value

newValueOrSfCall2 method #

func (s *state) newValueOrSfCall2(op ssa.Op, t *types.Type, arg0 *ssa.Value, arg1 *ssa.Value) *ssa.Value

nilCheck method #

nilCheck generates nil pointer checking code. Used only for automatically inserted nil checks, not for user code like 'x != nil'. Returns a "definitely not nil" copy of x to ensure proper ordering of the uses of the post-nilcheck pointer.

func (s *state) nilCheck(ptr *ssa.Value) *ssa.Value

oneJump method #

func (s *State) oneJump(b *ssa.Block, jump *IndexJump)

openDeferExit method #

openDeferExit generates SSA for processing all the open coded defers at exit. The code involves loading deferBits, and checking each of the bits to see if the corresponding defer statement was executed. For each bit that is turned on, the associated defer call is made.

func (s *state) openDeferExit()

openDeferRecord method #

openDeferRecord adds code to evaluate and store the function for an open-code defer call, and records info about the defer, so we can generate proper code on the exit paths. n is the sub-node of the defer node that is the actual function call. We will also record funcdata information on where the function is stored (as well as the deferBits variable), and this will enable us to run the proper defer calls during panics.

func (s *state) openDeferRecord(n *ir.CallExpr)

openDeferSave method #

openDeferSave generates SSA nodes to store a value (with type t) for an open-coded defer at an explicit autotmp location on the stack, so it can be reloaded and used for the appropriate call on exit. Type t must be a function type (therefore SSAable). val is the value to be stored. The function returns an SSA value representing a pointer to the autotmp location.

func (s *state) openDeferSave(t *types.Type, val *ssa.Value) *ssa.Value

paramsToHeap method #

paramsToHeap produces code to allocate memory for heap-escaped parameters and to copy non-result parameters' values from the stack.

func (s *state) paramsToHeap()

paramsToWasmFields function #

func paramsToWasmFields(f *ir.Func, pragma string, result *abi.ABIParamResultInfo, abiParams []abi.ABIParamAssignment) []obj.WasmField

peekPos method #

peekPos peeks the top of the line number stack.

func (s *state) peekPos() src.XPos

popLine method #

popLine pops the top of the line number stack.

func (s *state) popLine()

pushLine method #

pushLine pushes a line number on the line number stack.

func (s *state) pushLine(line src.XPos)

putArg method #

putArg evaluates n for the purpose of passing it as an argument to a function and returns the value for the call.

func (s *state) putArg(n ir.Node, t *types.Type) *ssa.Value

rawLoad method #

func (s *state) rawLoad(t *types.Type, src *ssa.Value) *ssa.Value

readFuncLines function #

func readFuncLines(file string, start uint, end uint) (*ssa.FuncLines, error)

recordCall method #

recordCall records a call from ODCLFUNC node "from", to function symbol "to" at position pos. This should be done as late as possible during compilation to capture precise call graphs. The target of the call is an LSym because that's all we know after we start SSA. This can be called concurrently for different from Nodes.

func (c *nowritebarrierrecChecker) recordCall(fn *ir.Func, to *obj.LSym, pos src.XPos)

referenceTypeBuiltin method #

referenceTypeBuiltin generates code for the len/cap builtins for maps and channels.

func (s *state) referenceTypeBuiltin(n *ir.UnaryExpr, x *ssa.Value) *ssa.Value

reflectType method #

reflectType returns an SSA value representing a pointer to typ's reflection type descriptor.

func (s *state) reflectType(typ *types.Type) *ssa.Value

resolveFwdRefs method #

resolveFwdRefs links all FwdRef uses up to their nearest dominating definition.

func (s *phiState) resolveFwdRefs()

resultAddrOfCall method #

func (s *state) resultAddrOfCall(c *ssa.Value, which int64, t *types.Type) *ssa.Value

resultOfCall method #

func (s *state) resultOfCall(c *ssa.Value, which int64, t *types.Type) *ssa.Value

resultsToWasmFields function #

func resultsToWasmFields(f *ir.Func, pragma string, result *abi.ABIParamResultInfo, abiParams []abi.ABIParamAssignment) []obj.WasmField

rtcall method #

rtcall issues a call to the given runtime function fn with the listed args. Returns a slice of results of the given result types. The call is added to the end of the current block. If returns is false, the block is marked as an exit block.

func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value

setHeapaddr method #

setHeapaddr allocates a new PAUTO variable to store ptr (which must be non-nil) and then sets it as n's heap address.

func (s *state) setHeapaddr(pos src.XPos, n *ir.Name, ptr *ssa.Value)

setupWasmExport function #

setupWasmExport calculates the params and results in terms of WebAssembly values for the given function, and sets up the wasmexport metadata.

func setupWasmExport(f *ir.Func, wrapped *ir.Func)

setupWasmImport function #

setupWasmImport calculates the params and results in terms of WebAssembly values for the given function, and sets up the wasmimport metadata.

func setupWasmImport(f *ir.Func)

sfcall method #

TODO: do not emit sfcall if operation can be optimized to constant in later opt phase

func (s *state) sfcall(op ssa.Op, args ...*ssa.Value) (*ssa.Value, bool)

slice method #

slice computes the slice v[i:j:k] and returns ptr, len, and cap of result. i,j,k may be nil, in which case they are set to their default value. v may be a slice, string or pointer to an array.

func (s *state) slice(v *ssa.Value, i *ssa.Value, j *ssa.Value, k *ssa.Value, bounded bool) (p *ssa.Value, l *ssa.Value, c *ssa.Value)

softfloatInit function #

func softfloatInit()

split method #

split breaks up a tuple-typed value into its 2 parts.

func (s *state) split(v *ssa.Value) (*ssa.Value, *ssa.Value)

ssaMarker function #

func ssaMarker(name string) *ir.Name

ssaOp method #

func (s *state) ssaOp(op ir.Op, t *types.Type) ssa.Op

ssaShiftOp method #

func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op

startBlock method #

startBlock sets the current block we're generating code in to b.

func (s *state) startBlock(b *ssa.Block)

stmt method #

stmt converts the statement n to SSA and adds it to s.

func (s *state) stmt(n ir.Node)

stmtList method #

stmtList converts the statement list n to SSA and adds it to s.

func (s *state) stmtList(l ir.Nodes)

store method #

func (s *state) store(t *types.Type, dst *ssa.Value, val *ssa.Value)

storeArgWithBase method #

func (s *state) storeArgWithBase(n ir.Node, t *types.Type, base *ssa.Value, off int64)

storeParameterRegsToStack method #

func (s *state) storeParameterRegsToStack(abi *abi.ABIConfig, paramAssignment *abi.ABIParamAssignment, n *ir.Name, addr *ssa.Value, pointersOnly bool)

storeType method #

do *left = right for type t.

func (s *state) storeType(t *types.Type, left *ssa.Value, right *ssa.Value, skip skipMask, leftIsStmt bool)

storeTypePtrs method #

do *left = right for all pointer parts of t.

func (s *state) storeTypePtrs(t *types.Type, left *ssa.Value, right *ssa.Value)

storeTypeScalars method #

do *left = right for all scalar (non-pointer) parts of t.

func (s *state) storeTypeScalars(t *types.Type, left *ssa.Value, right *ssa.Value, skip skipMask)

temp method #

temp allocates a temp of type t at position pos

func (s *state) temp(pos src.XPos, t *types.Type) (*ir.Name, *ssa.Value)

ternary method #

ternary emits code to evaluate cond ? x : y.

func (s *state) ternary(cond *ssa.Value, x *ssa.Value, y *ssa.Value) *ssa.Value

uint32Tofloat method #

func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uint32Tofloat32 method #

func (s *state) uint32Tofloat32(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uint32Tofloat64 method #

func (s *state) uint32Tofloat64(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uint64Tofloat method #

func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uint64Tofloat32 method #

func (s *state) uint64Tofloat32(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uint64Tofloat64 method #

func (s *state) uint64Tofloat64(n ir.Node, x *ssa.Value, ft *types.Type, tt *types.Type) *ssa.Value

uintptrConstant method #

func (s *state) uintptrConstant(v uint64) *ssa.Value

updateUnsetPredPos method #

updateUnsetPredPos propagates the earliest-value position information for b towards all of b's predecessors that need a position, and recurs on that predecessor if its position is updated. B should have a non-empty position.

func (s *state) updateUnsetPredPos(b *ssa.Block)

variable method #

variable returns the value of a variable at the current location.

func (s *state) variable(n ir.Node, t *types.Type) *ssa.Value

wasmElemTypeAllowed function #

wasmElemTypeAllowed reports whether t is allowed to be passed in memory (as a pointer's element type, a field of it, etc.) between the Go wasm module and the host.

func wasmElemTypeAllowed(t *types.Type) bool

weakenGlobalMapInitRelocs function #

weakenGlobalMapInitRelocs walks through all of the relocations on a given a package init function "fn" and looks for relocs that target outlined global map initializer functions; if it finds any such relocs, it flags them as R_WEAK.

func weakenGlobalMapInitRelocs(fn *ir.Func)

zero method #

func (s *state) zero(t *types.Type, dst *ssa.Value)

zeroResults method #

zeroResults zeros the return values at the start of the function. We need to do this very early in the function. Defer might stop a panic and show the return values as they exist at the time of panic. For precise stacks, the garbage collector assumes results are always live, so we need to zero them before any allocations, even allocations to move params/results to the heap.

func (s *state) zeroResults()

zeroVal method #

zeroVal returns the zero value for type t.

func (s *state) zeroVal(t *types.Type) *ssa.Value

Generated with Arrow