Documentation ¶
Index ¶
- Constants
- Variables
- func AddAux(a *obj.Addr, v *ssa.Value)
- func AddAux2(a *obj.Addr, v *ssa.Value, offset int64)
- func AddrAuto(a *obj.Addr, v *ssa.Value)
- func Addrconst(a *obj.Addr, v int64)
- func AuxOffset(v *ssa.Value) (offset int64)
- func CheckLoweredGetClosurePtr(v *ssa.Value)
- func CheckLoweredPhi(v *ssa.Value)
- func Dump(s string, n *Node)
- func Exit(code int)
- func Fatalf(fmt_ string, args ...interface{})
- func IncomparableField(t *types.Type) *types.Field
- func IsAlias(sym *types.Sym) bool
- func IsComparable(t *types.Type) bool
- func IsRegularMemory(t *types.Type) bool
- func Isconst(n *Node, ct Ctype) bool
- func Main(archInit func(*Arch))
- func Patch(p *obj.Prog, to *obj.Prog)
- func Rnd(o int64, r int64) int64
- func Warn(fmt_ string, args ...interface{})
- func Warnl(line src.XPos, fmt_ string, args ...interface{})
- type AlgKind
- type Arch
- type BlockEffects
- type Branch
- type Class
- type Ctype
- type Dlist
- type Error
- type EscState
- type EscStep
- type FloatingEQNEJump
- type FmtFlag
- type Func
- func (f *Func) Dupok() bool
- func (f *Func) ExportInline() bool
- func (f *Func) HasDefer() bool
- func (f *Func) InlinabilityChecked() bool
- func (f *Func) InstrumentBody() bool
- func (f *Func) IsHiddenClosure() bool
- func (f *Func) Needctxt() bool
- func (f *Func) NilCheckDisabled() bool
- func (f *Func) ReflectMethod() bool
- func (f *Func) SetDupok(b bool)
- func (f *Func) SetExportInline(b bool)
- func (f *Func) SetHasDefer(b bool)
- func (f *Func) SetInlinabilityChecked(b bool)
- func (f *Func) SetInstrumentBody(b bool)
- func (f *Func) SetIsHiddenClosure(b bool)
- func (f *Func) SetNeedctxt(b bool)
- func (f *Func) SetNilCheckDisabled(b bool)
- func (f *Func) SetReflectMethod(b bool)
- func (f *Func) SetWrapper(b bool)
- func (f *Func) Wrapper() bool
- type GCProg
- type InitEntry
- type InitPlan
- type Inline
- type Level
- type Liveness
- type LivenessIndex
- type LivenessMap
- type Mark
- type Mpcplx
- type Mpflt
- func (a *Mpflt) Add(b *Mpflt)
- func (a *Mpflt) AddFloat64(c float64)
- func (a *Mpflt) Cmp(b *Mpflt) int
- func (a *Mpflt) CmpFloat64(c float64) int
- func (a *Mpflt) Float32() float64
- func (a *Mpflt) Float64() float64
- func (fvp *Mpflt) GoString() string
- func (a *Mpflt) Mul(b *Mpflt)
- func (a *Mpflt) MulFloat64(c float64)
- func (a *Mpflt) Neg()
- func (a *Mpflt) Quo(b *Mpflt)
- func (a *Mpflt) Set(b *Mpflt)
- func (a *Mpflt) SetFloat64(c float64)
- func (a *Mpflt) SetInt(b *Mpint)
- func (a *Mpflt) SetString(as string)
- func (f *Mpflt) String() string
- func (a *Mpflt) Sub(b *Mpflt)
- type Mpint
- func (a *Mpint) Add(b *Mpint)
- func (a *Mpint) And(b *Mpint)
- func (a *Mpint) AndNot(b *Mpint)
- func (a *Mpint) Cmp(b *Mpint) int
- func (a *Mpint) CmpInt64(c int64) int
- func (a *Mpint) GoString() string
- func (a *Mpint) Int64() int64
- func (a *Mpint) Lsh(b *Mpint)
- func (a *Mpint) Mul(b *Mpint)
- func (a *Mpint) Neg()
- func (a *Mpint) Or(b *Mpint)
- func (a *Mpint) Quo(b *Mpint)
- func (a *Mpint) Rem(b *Mpint)
- func (a *Mpint) Rsh(b *Mpint)
- func (a *Mpint) Set(b *Mpint)
- func (a *Mpint) SetFloat(b *Mpflt) bool
- func (a *Mpint) SetInt64(c int64)
- func (a *Mpint) SetOverflow()
- func (a *Mpint) SetString(as string)
- func (a *Mpint) String() string
- func (a *Mpint) Sub(b *Mpint)
- func (a *Mpint) Xor(b *Mpint)
- type Name
- func (n *Name) AutoTemp() bool
- func (n *Name) Byval() bool
- func (n *Name) Captured() bool
- func (n *Name) Keepalive() bool
- func (n *Name) Needzero() bool
- func (n *Name) Readonly() bool
- func (n *Name) SetAutoTemp(b bool)
- func (n *Name) SetByval(b bool)
- func (n *Name) SetCaptured(b bool)
- func (n *Name) SetKeepalive(b bool)
- func (n *Name) SetNeedzero(b bool)
- func (n *Name) SetReadonly(b bool)
- func (n *Name) SetUsed(b bool)
- func (n *Name) Used() bool
- type NilVal
- type Node
- func (n *Node) Addable() bool
- func (n *Node) Addrtaken() bool
- func (n *Node) Assigned() bool
- func (n *Node) Bool() bool
- func (n *Node) Bounded() bool
- func (n *Node) CanInt64() bool
- func (n *Node) Class() Class
- func (n *Node) Colas() bool
- func (n *Node) Diag() bool
- func (n *Node) Embedded() bool
- func (n *Node) Format(s fmt.State, verb rune)
- func (n *Node) HasBreak() bool
- func (n *Node) HasCall() bool
- func (n *Node) HasOpt() bool
- func (n *Node) HasVal() bool
- func (n *Node) Implicit() bool
- func (n *Node) IndexMapLValue() bool
- func (n *Node) Initorder() uint8
- func (n *Node) InlFormal() bool
- func (n *Node) InlLocal() bool
- func (n *Node) Int64() int64
- func (n *Node) Iota() int64
- func (n *Node) IsAutoTmp() bool
- func (n *Node) IsClosureVar() bool
- func (n *Node) IsDDD() bool
- func (n *Node) IsMethod() bool
- func (n *Node) IsOutputParamHeapAddr() bool
- func (n *Node) IsSynthetic() bool
- func (n *Node) Likely() bool
- func (n *Node) Line() string
- func (n *Node) NoInline() bool
- func (n *Node) Noescape() bool
- func (n *Node) NonNil() bool
- func (n *Node) Opt() interface{}
- func (n *Node) ResetAux()
- func (n *Node) SetAddable(b bool)
- func (n *Node) SetAddrtaken(b bool)
- func (n *Node) SetAssigned(b bool)
- func (n *Node) SetBounded(b bool)
- func (n *Node) SetClass(b Class)
- func (n *Node) SetColas(b bool)
- func (n *Node) SetDiag(b bool)
- func (n *Node) SetEmbedded(b bool)
- func (n *Node) SetHasBreak(b bool)
- func (n *Node) SetHasCall(b bool)
- func (n *Node) SetHasOpt(b bool)
- func (n *Node) SetHasVal(b bool)
- func (n *Node) SetImplicit(b bool)
- func (n *Node) SetIndexMapLValue(b bool)
- func (n *Node) SetInitorder(b uint8)
- func (n *Node) SetInlFormal(b bool)
- func (n *Node) SetInlLocal(b bool)
- func (n *Node) SetIota(x int64)
- func (n *Node) SetIsClosureVar(b bool)
- func (n *Node) SetIsDDD(b bool)
- func (n *Node) SetIsOutputParamHeapAddr(b bool)
- func (n *Node) SetLikely(b bool)
- func (n *Node) SetNoInline(b bool)
- func (n *Node) SetNoescape(b bool)
- func (n *Node) SetNonNil(b bool)
- func (n *Node) SetOpt(x interface{})
- func (n *Node) SetSliceBounds(low, high, max *Node)
- func (n *Node) SetSubOp(op Op)
- func (n *Node) SetTChanDir(dir types.ChanDir)
- func (n *Node) SetTypecheck(b uint8)
- func (n *Node) SetVal(v Val)
- func (n *Node) SetWalkdef(b uint8)
- func (n *Node) SliceBounds() (low, high, max *Node)
- func (n *Node) StorageClass() ssa.StorageClass
- func (n *Node) String() string
- func (n *Node) SubOp() Op
- func (n *Node) TChanDir() types.ChanDir
- func (n *Node) Typ() *types.Type
- func (n *Node) Typecheck() uint8
- func (n *Node) Val() Val
- func (n *Node) Walkdef() uint8
- type NodeEscState
- type Nodes
- func (n Nodes) Addr(i int) **Node
- func (n *Nodes) Append(a ...*Node)
- func (n *Nodes) AppendNodes(n2 *Nodes)
- func (n Nodes) First() *Node
- func (n Nodes) Format(s fmt.State, verb rune)
- func (n Nodes) Index(i int) *Node
- func (n Nodes) Len() int
- func (n *Nodes) MoveNodes(n2 *Nodes)
- func (n *Nodes) Prepend(a ...*Node)
- func (n Nodes) Second() *Node
- func (n *Nodes) Set(s []*Node)
- func (n *Nodes) Set1(n1 *Node)
- func (n *Nodes) Set2(n1, n2 *Node)
- func (n *Nodes) Set3(n1, n2, n3 *Node)
- func (n Nodes) SetFirst(node *Node)
- func (n Nodes) SetIndex(i int, node *Node)
- func (n Nodes) SetSecond(node *Node)
- func (n Nodes) Slice() []*Node
- func (n Nodes) String() string
- type Op
- type Order
- type Param
- type Progs
- type SSAGenState
- func (s *SSAGenState) AddrScratch(a *obj.Addr)
- func (s *SSAGenState) Br(op obj.As, target *ssa.Block) *obj.Prog
- func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog
- func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value)
- func (s *SSAGenState) FPJump(b, next *ssa.Block, jumps *[2][2]FloatingEQNEJump)
- func (s *SSAGenState) Pc() *obj.Prog
- func (s *SSAGenState) PrepareCall(v *ssa.Value)
- func (s *SSAGenState) Prog(as obj.As) *obj.Prog
- func (s *SSAGenState) SetPos(pos src.XPos)
- type ScopeID
- type Sig
- type Symlink
- type Timings
- type Val
Constants ¶
const ( H0 = 2166136261 Hp = 16777619 )
FNV-1 hash function constants.
const ( EscFuncUnknown = 0 + iota EscFuncPlanned EscFuncStarted EscFuncTagged )
const ( EscUnknown = iota EscNone // Does not escape to heap, result, or parameters. EscReturn // Is returned or reachable from returned. EscHeap // Reachable from the heap EscNever // By construction will not escape. EscBits = 3 EscMask = (1 << EscBits) - 1 EscContentEscapes = 1 << EscBits // value obtained by indirect of parameter escapes to heap EscReturnBits = EscBits + 1 )
Escape constants are numbered in order of increasing "escapiness" to help make inferences be monotonic. With the exception of EscNever which is sticky, eX < eY means that eY is more exposed than eX, and hence replaces it in a conservative analysis.
const ( FErr = iota FDbg FTypeId FTypeIdName // same as FTypeId, but use package name instead of prefix )
*types.Sym, *types.Type, and *Node types use the flags below to set the format mode
const ( // Func pragmas. Nointerface syntax.Pragma = 1 << iota Noescape // func parameters don't escape Norace // func must not have race detector annotations Nosplit // func should not execute on separate stack Noinline // func should not be inlined CgoUnsafeArgs // treat a pointer to one arg as a pointer to them all UintptrEscapes // pointers converted to uintptr escape // Runtime-only func pragmas. // See ../../../../runtime/README.md for detailed descriptions. Systemstack // func must run on system stack Nowritebarrier // emit compiler error instead of write barrier Nowritebarrierrec // error on write barrier in this or recursive callees Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees // Runtime-only type pragmas NotInHeap // values of this type must not be heap allocated )
const ( // Maximum size in bits for Mpints before signalling // overflow and also mantissa precision for Mpflts. Mpprec = 512 // Turn on for constant arithmetic debugging output. Mpdebug = false )
const ( BUCKETSIZE = 8 MAXKEYSIZE = 128 MAXVALSIZE = 128 )
Builds a type representing a Bucket structure for the given map type. This type is not visible to users - we include only enough information to generate a correct GC program for it. Make sure this stays in sync with runtime/map.go.
const ( InitNotStarted = iota InitDone InitPending )
Static initialization ordering state. These values are stored in two bits in Node.flags.
const ( Txxx = types.Txxx TINT8 = types.TINT8 TUINT8 = types.TUINT8 TINT16 = types.TINT16 TUINT16 = types.TUINT16 TINT32 = types.TINT32 TUINT32 = types.TUINT32 TINT64 = types.TINT64 TUINT64 = types.TUINT64 TINT = types.TINT TUINT = types.TUINT TUINTPTR = types.TUINTPTR TCOMPLEX64 = types.TCOMPLEX64 TCOMPLEX128 = types.TCOMPLEX128 TFLOAT32 = types.TFLOAT32 TFLOAT64 = types.TFLOAT64 TBOOL = types.TBOOL TPTR = types.TPTR TFUNC = types.TFUNC TSLICE = types.TSLICE TARRAY = types.TARRAY TSTRUCT = types.TSTRUCT TCHAN = types.TCHAN TMAP = types.TMAP TINTER = types.TINTER TFORW = types.TFORW TANY = types.TANY TSTRING = types.TSTRING TUNSAFEPTR = types.TUNSAFEPTR // pseudo-types for literals TIDEAL = types.TIDEAL TNIL = types.TNIL TBLANK = types.TBLANK // pseudo-types for frame layout TFUNCARGS = types.TFUNCARGS TCHANARGS = types.TCHANARGS // pseudo-types for import/export TDDDFIELD = types.TDDDFIELD // wrapper: contained type is a ... field NTYPE = types.NTYPE )
convenience constants
const ArhdrSize = 60
architecture-independent object file output
const (
BADWIDTH = types.BADWIDTH
)
const (
Etype // evaluated in type context
)
const MinLevel = -2
There are loops in the escape graph, causing arbitrary recursion into deeper and deeper levels. Cut this off safely by making minLevel sticky: once you get that deep, you cannot go down any further but you also cannot go up any further. This is a conservative fix. Making minLevel smaller (more negative) would handle more complex chains of indirections followed by address-of operations, at the cost of repeating the traversal once for each additional allowed level when a loop is encountered. Using -2 suffices to pass all the tests we have written so far, which we assume matches the level of complexity we want the escape analysis code to handle.
const NOTALOOPDEPTH = -1
Variables ¶
var ( Deferreturn, Duffcopy, Duffzero, Udiv *obj.LSym // GO386=387 ControlWord64trunc, ControlWord32 *obj.LSym // Wasm WasmMove, WasmZero, WasmDiv, WasmTruncS, WasmTruncU, SigPanic *obj.LSym )
var ( Debug_append int Debug_closure int Debug_compilelater int Debug_panic int Debug_slice int Debug_vlog bool Debug_wb int Debug_pctab string Debug_locationlist int Debug_typecheckinl int Debug_gendwarfinl int Debug_softfloat int )
var Ctxt *obj.Link
var Debug [256]int
var Debug_checknil int
var (
Debug_export int // if set, print debugging information about export data
)
var Debug_gcprog int // set by -d gcprog
var Debug_typeassert int
var LivenessInvalid = LivenessIndex{-2, -2}
LivenessInvalid indicates an unsafe point.
We use index -2 because PCDATA tables conventionally start at -1, so -1 is used to mean the entry liveness map (which is actually at index 0; sigh). TODO(austin): Maybe we should use PCDATA+1 as the index into the liveness map so -1 uniquely refers to the entry liveness map.
var Nacl bool
var Runtimepkg *types.Pkg // fake package runtime
var Widthptr int
var Widthreg int
Functions ¶
func CheckLoweredGetClosurePtr ¶
CheckLoweredGetClosurePtr checks that v is the first instruction in the function's entry block. The output of LoweredGetClosurePtr is generally hardwired to the correct register. That register contains the closure pointer on closure entry.
func CheckLoweredPhi ¶
CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values. Called during ssaGenValue.
func IncomparableField ¶
IncomparableField returns an incomparable Field of struct Type t, if any.
func IsComparable ¶
IsComparable reports whether t is a comparable type.
func IsRegularMemory ¶
IsRegularMemory reports whether t can be compared/hashed as regular memory.
Types ¶
type AlgKind ¶
type AlgKind int
AlgKind describes the kind of algorithms used for comparing and hashing a Type.
const ( // These values are known by runtime. ANOEQ AlgKind = iota AMEM0 AMEM8 AMEM16 AMEM32 AMEM64 AMEM128 ASTRING AINTER ANILINTER AFLOAT32 AFLOAT64 ACPLX64 ACPLX128 // Type can be compared/hashed as regular memory. AMEM AlgKind = 100 // Type needs special comparison/hashing functions. ASPECIAL AlgKind = -1 )
type Arch ¶
type Arch struct { LinkArch *obj.LinkArch REGSP int MAXWIDTH int64 Use387 bool // should 386 backend use 387 FP instructions instead of sse2. SoftFloat bool PadFrame func(int64) int64 ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog Ginsnop func(*Progs) *obj.Prog // SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags. SSAMarkMoves func(*SSAGenState, *ssa.Block) // SSAGenValue emits Prog(s) for the Value. SSAGenValue func(*SSAGenState, *ssa.Value) // SSAGenBlock emits end-of-block Progs. SSAGenValue should be called // for all values in the block before SSAGenBlock. SSAGenBlock func(s *SSAGenState, b, next *ssa.Block) // ZeroAuto emits code to zero the given auto stack variable. // ZeroAuto must not use any non-temporary registers. // ZeroAuto will only be called for variables which contain a pointer. ZeroAuto func(*Progs, *Node) }
type BlockEffects ¶
type BlockEffects struct {
// contains filtered or unexported fields
}
BlockEffects summarizes the liveness effects on an SSA block.
type Class ¶
type Class uint8
The Class of a variable/function describes the "storage class" of a variable or function. During parsing, storage classes are called declaration contexts.
const ( Pxxx Class = iota // no class; used during ssa conversion to indicate pseudo-variables PEXTERN // global variable PAUTO // local variables PAUTOHEAP // local variable or parameter moved to heap PPARAM // input arguments PPARAMOUT // output results PFUNC // global function PDISCARD // discard during parse of duplicate import )
type Dlist ¶
type Dlist struct {
// contains filtered or unexported fields
}
A Dlist stores a pointer to a TFIELD Type embedded within a TSTRUCT or TINTER Type.
type EscStep ¶
type EscStep struct {
// contains filtered or unexported fields
}
An EscStep documents one step in the path from memory that is heap allocated to the (alleged) reason for the heap allocation.
type FloatingEQNEJump ¶
type FmtFlag ¶
type FmtFlag int
A FmtFlag value is a set of flags (or 0). They control how the Xconv functions format their values. See the respective function's documentation for details.
type Func ¶
type Func struct { Shortname *types.Sym Enter Nodes // for example, allocate and initialize memory for escaping parameters Exit Nodes Cvars Nodes // closure params Dcl []*Node // autodcl for this func/closure // Parents records the parent scope of each scope within a // function. The root scope (0) has no parent, so the i'th // scope's parent is stored at Parents[i-1]. Parents []ScopeID // Marks records scope boundary changes. Marks []Mark // Closgen tracks how many closures have been generated within // this function. Used by closurename for creating unique // function names. Closgen int FieldTrack map[*types.Sym]struct{} DebugInfo *ssa.FuncDebug Ntype *Node // signature Top int // top context (ctxCallee, etc) Closure *Node // OCLOSURE <-> ODCLFUNC Nname *Node Inl *Inline Label int32 // largest auto-generated label in this function Endlineno src.XPos WBPos src.XPos // position of first write barrier; see SetWBPos Pragma syntax.Pragma // go:xxx function annotations // contains filtered or unexported fields }
Func holds Node fields used only with function-like nodes.
func (*Func) ExportInline ¶
func (*Func) InlinabilityChecked ¶
func (*Func) InstrumentBody ¶
func (*Func) IsHiddenClosure ¶
func (*Func) NilCheckDisabled ¶
func (*Func) ReflectMethod ¶
func (*Func) SetExportInline ¶
func (*Func) SetHasDefer ¶
func (*Func) SetInlinabilityChecked ¶
func (*Func) SetInstrumentBody ¶
func (*Func) SetIsHiddenClosure ¶
func (*Func) SetNeedctxt ¶
func (*Func) SetNilCheckDisabled ¶
func (*Func) SetReflectMethod ¶
func (*Func) SetWrapper ¶
type Inline ¶
type Inline struct { Cost int32 // heuristic cost of inlining this function // Copies of Func.Dcl and Nbody for use during inlining. Dcl []*Node Body []*Node }
An Inline holds fields used for function bodies that can be inlined.
type Level ¶
type Level struct {
// contains filtered or unexported fields
}
There's one of these for each Node, and the integer values rarely exceed even what can be stored in 4 bits, never mind 8.
type Liveness ¶
type Liveness struct {
// contains filtered or unexported fields
}
A collection of global state used by liveness analysis.
type LivenessIndex ¶
type LivenessIndex struct {
// contains filtered or unexported fields
}
LivenessIndex stores the liveness map index for a safe-point.
func (LivenessIndex) Valid ¶
func (idx LivenessIndex) Valid() bool
type LivenessMap ¶
type LivenessMap struct {
// contains filtered or unexported fields
}
LivenessMap maps from *ssa.Value to LivenessIndex.
func (LivenessMap) Get ¶
func (m LivenessMap) Get(v *ssa.Value) LivenessIndex
type Mark ¶
type Mark struct { // Pos is the position of the token that marks the scope // change. Pos src.XPos // Scope identifies the innermost scope to the right of Pos. Scope ScopeID }
A Mark represents a scope boundary.
type Mpcplx ¶
Mpcplx represents a complex constant.
func (*Mpcplx) Div ¶
complex divide v /= rv
(a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d)
type Mpflt ¶
Mpflt represents a floating-point constant.
func (*Mpflt) AddFloat64 ¶
func (*Mpflt) CmpFloat64 ¶
func (*Mpflt) MulFloat64 ¶
func (*Mpflt) SetFloat64 ¶
type Mpint ¶
type Mpint struct { Val big.Int Ovf bool // set if Val overflowed compiler limit (sticky) Rune bool // set if syntax indicates default type rune }
Mpint represents an integer constant.
func (*Mpint) SetOverflow ¶
func (a *Mpint) SetOverflow()
type Name ¶
type Name struct { Pack *Node // real package for import . names Pkg *types.Pkg // pkg for OPACK nodes Defn *Node // initializing assignment Curfn *Node // function for local variables Param *Param // additional fields for ONAME, OTYPE Decldepth int32 // declaration loop depth, increased for every loop or label Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. // contains filtered or unexported fields }
Name holds Node fields used only by named nodes (ONAME, OTYPE, OPACK, OLABEL, some OLITERAL).
func (*Name) SetAutoTemp ¶
func (*Name) SetCaptured ¶
func (*Name) SetKeepalive ¶
func (*Name) SetNeedzero ¶
func (*Name) SetReadonly ¶
type Node ¶
type Node struct { // Tree structure. // Generic recursive walks should follow these fields. Left *Node Right *Node Ninit Nodes Nbody Nodes List Nodes Rlist Nodes // most nodes Type *types.Type Orig *Node // original form, for printing, and tracking copies of ONAMEs // func Func *Func // ONAME, OTYPE, OPACK, OLABEL, some OLITERAL Name *Name Sym *types.Sym // various E interface{} // Opt or Val, see methods below // Various. Usually an offset into a struct. For example: // - ONAME nodes that refer to local variables use it to identify their stack frame position. // - ODOT, ODOTPTR, and OINDREGSP use it to indicate offset relative to their base address. // - OSTRUCTKEY uses it to store the named field's offset. // - Named OLITERALs use it to store their ambient iota value. // - OINLMARK stores an index into the inlTree data structure. // Possibly still more uses. If you find any, document them. Xoffset int64 Pos src.XPos Esc uint16 // EscXXX Op Op // contains filtered or unexported fields }
A Node is a single node in the syntax tree. Actually the syntax tree is a syntax DAG, because there is only one node with Op=ONAME for a given instance of a variable x. The same is true for Op=OTYPE and Op=OLITERAL. See Node.mayBeShared.
var Curfn *Node
func AutoVar ¶
AutoVar returns a *Node and int64 representing the auto variable and offset within it where v should be spilled.
func (*Node) IndexMapLValue ¶
func (*Node) IsAutoTmp ¶
IsAutoTmp indicates if n was created by the compiler as a temporary, based on the setting of the .AutoTemp flag in n's Name.
func (*Node) IsClosureVar ¶
func (*Node) IsOutputParamHeapAddr ¶
func (*Node) IsSynthetic ¶
func (*Node) Line ¶
Line returns n's position as a string. If n has been inlined, it uses the outermost position where n has been inlined.
func (*Node) SetAddable ¶
func (*Node) SetAddrtaken ¶
func (*Node) SetAssigned ¶
func (*Node) SetBounded ¶
func (*Node) SetEmbedded ¶
func (*Node) SetHasBreak ¶
func (*Node) SetHasCall ¶
func (*Node) SetImplicit ¶
func (*Node) SetIndexMapLValue ¶
func (*Node) SetInitorder ¶
func (*Node) SetInlFormal ¶
func (*Node) SetInlLocal ¶
func (*Node) SetIsClosureVar ¶
func (*Node) SetIsOutputParamHeapAddr ¶
func (*Node) SetNoInline ¶
func (*Node) SetNoescape ¶
func (*Node) SetOpt ¶
func (n *Node) SetOpt(x interface{})
SetOpt sets the optimizer data for the node, which must not have been used with SetVal. SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
func (*Node) SetSliceBounds ¶
SetSliceBounds sets n's slice bounds, where n is a slice expression. n must be a slice expression. If max is non-nil, n must be a full slice expression.
func (*Node) SetTChanDir ¶
func (*Node) SetTypecheck ¶
func (*Node) SetWalkdef ¶
func (*Node) SliceBounds ¶
SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max]. n must be a slice expression. max is nil if n is a simple slice expression.
func (*Node) StorageClass ¶
func (n *Node) StorageClass() ssa.StorageClass
type NodeEscState ¶
type NodeEscState struct { Curfn *Node Flowsrc []EscStep // flow(this, src) Retval Nodes // on OCALLxxx, list of dummy return values Loopdepth int32 // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes Level Level Walkgen uint32 Maxextraloopdepth int32 }
type Nodes ¶
type Nodes struct {
// contains filtered or unexported fields
}
Nodes is a pointer to a slice of *Node. For fields that are not used in most nodes, this is used instead of a slice to save space.
func (Nodes) Addr ¶
Addr returns the address of the i'th element of Nodes. It panics if n does not have at least i+1 elements.
func (*Nodes) AppendNodes ¶
AppendNodes appends the contents of *n2 to n, then clears n2.
func (Nodes) First ¶
First returns the first element of Nodes (same as n.Index(0)). It panics if n has no elements.
func (Nodes) Index ¶
Index returns the i'th element of Nodes. It panics if n does not have at least i+1 elements.
func (*Nodes) Prepend ¶
Prepend prepends entries to Nodes. If a slice is passed in, this will take ownership of it.
func (Nodes) Second ¶
Second returns the second element of Nodes (same as n.Index(1)). It panics if n has fewer than two elements.
func (Nodes) SetFirst ¶
SetFirst sets the first element of Nodes to node. It panics if n does not have at least one elements.
func (Nodes) SetIndex ¶
SetIndex sets the i'th element of Nodes to node. It panics if n does not have at least i+1 elements.
func (Nodes) SetSecond ¶
SetSecond sets the second element of Nodes to node. It panics if n does not have at least two elements.
type Op ¶
type Op uint8
const ( OXXX Op = iota // names ONAME // var or func name ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc } OTYPE // type name OPACK // import OLITERAL // literal // expressions OADD // Left + Right OSUB // Left - Right OOR // Left | Right OXOR // Left ^ Right OADDSTR // +{List} (string addition, list elements are strings) OADDR // &Left OANDAND // Left && Right OAPPEND // append(List); after walk, Left may contain elem type descriptor OBYTES2STR // Type(Left) (Type is string, Left is a []byte) OBYTES2STRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral) ORUNES2STR // Type(Left) (Type is string, Left is a []rune) OSTR2BYTES // Type(Left) (Type is []byte, Left is a string) OSTR2BYTESTMP // Type(Left) (Type is []byte, Left is a string, ephemeral) OSTR2RUNES // Type(Left) (Type is []rune, Left is a string) OAS // Left = Right or (if Colas=true) Left := Right OAS2 // List = Rlist (x, y, z = a, b, c) OAS2FUNC // List = Rlist (x, y = f()) OAS2RECV // List = Rlist (x, ok = <-c) OAS2MAPR // List = Rlist (x, ok = m["foo"]) OAS2DOTTYPE // List = Rlist (x, ok = I.(int)) OASOP // Left Etype= Right (x += y) OCALL // Left(List) (function call, method call or type conversion) // OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure. // Prior to walk, they are: Left(List), where List is all regular arguments. // If present, Right is an ODDDARG that holds the // generated slice used in a call to a variadic function. // After walk, List is a series of assignments to temporaries, // and Rlist is an updated set of arguments, including any ODDDARG slice. // TODO(josharian/khr): Use Ninit instead of List for the assignments to temporaries. See CL 114797. OCALLFUNC // Left(List/Rlist) (function call f(args)) OCALLMETH // Left(List/Rlist) (direct method call x.Method(args)) OCALLINTER // Left(List/Rlist) (interface method call x.Method(args)) OCALLPART // Left.Right (method expression x.Method, not called) OCAP // cap(Left) OCLOSE // close(Left) OCLOSURE // func Type { Body } (func literal) OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) OMAPLIT // Type{List} (composite literal, Type is map) OSTRUCTLIT // Type{List} (composite literal, Type is struct) OARRAYLIT // Type{List} (composite literal, Type is array) OSLICELIT // Type{List} (composite literal, Type is slice) Right.Int64() = slice length. OPTRLIT // &Left (left is composite literal) OCONV // Type(Left) (type conversion) OCONVIFACE // Type(Left) (type conversion, to interface) OCONVNOP // Type(Left) (type conversion, no effect) OCOPY // copy(Left, Right) ODCL // var Left (declares Left of type Left.Type) // Used during parsing but don't last. ODCLFUNC // func f() or func (r) f() ODCLFIELD // struct field, interface field, or func/method argument/return value. ODCLCONST // const pi = 3.14 ODCLTYPE // type Int int or type Int = int ODELETE // delete(Left, Right) ODOT // Left.Sym (Left is of struct type) ODOTPTR // Left.Sym (Left is of pointer to struct type) ODOTMETH // Left.Sym (Left is non-interface, Right is method name) ODOTINTER // Left.Sym (Left is interface, Right is method name) OXDOT // Left.Sym (before rewrite to one of the preceding) ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor OEQ // Left == Right ONE // Left != Right OLT // Left < Right OLE // Left <= Right OGE // Left >= Right OGT // Left > Right ODEREF // *Left OINDEX // Left[Right] (index of array or slice) OINDEXMAP // Left[Right] (index of map) OKEY // Left:Right (key:value in struct/array/map literal) OSTRUCTKEY // Sym:Left (key:value in struct literal, after type checking) OLEN // len(Left) OMAKE // make(List) (before type checking converts to one of the following) OMAKECHAN // make(Type, Left) (type is chan) OMAKEMAP // make(Type, Left) (type is map) OMAKESLICE // make(Type, Left, Right) (type is slice) OMUL // Left * Right ODIV // Left / Right OMOD // Left % Right OLSH // Left << Right ORSH // Left >> Right OAND // Left & Right OANDNOT // Left &^ Right ONEW // new(Left) ONOT // !Left OBITNOT // ^Left OPLUS // +Left ONEG // -Left OOROR // Left || Right OPANIC // panic(Left) OPRINT // print(List) OPRINTN // println(List) OPAREN // (Left) OSEND // Left <- Right OSLICE // Left[List[0] : List[1]] (Left is untypechecked or slice) OSLICEARR // Left[List[0] : List[1]] (Left is array) OSLICESTR // Left[List[0] : List[1]] (Left is string) OSLICE3 // Left[List[0] : List[1] : List[2]] (Left is untypedchecked or slice) OSLICE3ARR // Left[List[0] : List[1] : List[2]] (Left is array) OSLICEHEADER // sliceheader{Left, List[0], List[1]} (Left is unsafe.Pointer, List[0] is length, List[1] is capacity) ORECOVER // recover() ORECV // <-Left ORUNESTR // Type(Left) (Type is string, Left is rune) OSELRECV // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV) OSELRECV2 // List = <-Right.Left: (apperas as .Left of OCASE; count(List) == 2, Right.Op == ORECV) OIOTA // iota OREAL // real(Left) OIMAG // imag(Left) OCOMPLEX // complex(Left, Right) or complex(List[0]) where List[0] is a 2-result function call OALIGNOF // unsafe.Alignof(Left) OOFFSETOF // unsafe.Offsetof(Left) OSIZEOF // unsafe.Sizeof(Left) // statements OBLOCK // { List } (block of code) OBREAK // break [Sym] OCASE // case Left or List[0]..List[1]: Nbody (select case after processing; Left==nil and List==nil means default) OXCASE // case List: Nbody (select case before processing; List==nil means default) OCONTINUE // continue [Sym] ODEFER // defer Left (Left must be call) OEMPTY // no-op (empty statement) OFALL // fallthrough OFOR // for Ninit; Left; Right { Nbody } // OFORUNTIL is like OFOR, but the test (Left) is applied after the body: // Ninit // top: { Nbody } // Execute the body at least once // cont: Right // if Left { // And then test the loop condition // List // Before looping to top, execute List // goto top // } // OFORUNTIL is created by walk. There's no way to write this in Go code. OFORUNTIL OGOTO // goto Sym OIF // if Ninit; Left { Nbody } else { Rlist } OLABEL // Sym: OGO // go Left (Left must be call) ORANGE // for List = range Right { Nbody } ORETURN // return List OSELECT // select { List } (List is list of OXCASE or OCASE) OSWITCH // switch Ninit; Left { List } (List is a list of OXCASE or OCASE) OTYPESW // Left = Right.(type) (appears as .Left of OSWITCH) // types OTCHAN // chan int OTMAP // map[string]int OTSTRUCT // struct{} OTINTER // interface{} OTFUNC // func() OTARRAY // []int, [8]int, [N]int or [...]int // misc ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. ODDDARG // func f(args ...int), introduced by escape analysis. OINLCALL // intermediary representation of an inlined call. OEFACE // itable and data words of an empty-interface value. OITAB // itable word of an interface value. OIDATA // data word of an interface value in Left OSPTR // base pointer of a slice or string. OCLOSUREVAR // variable reference at beginning of closure function OCFUNC // reference to c function pointer (not go func value) OCHECKNIL // emit code to ensure pointer/interface not nil OVARDEF // variable is about to be fully initialized OVARKILL // variable is dead OVARLIVE // variable is alive OINDREGSP // offset plus indirect of REGSP, such as 8(SP). OINLMARK // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree. // arch-specific opcodes ORETJMP // return to other function OGETG // runtime.getg() (read g pointer) OEND )
Node ops.
type Order ¶
type Order struct {
// contains filtered or unexported fields
}
Order holds state during the ordering process.
type Param ¶
type Param struct { Ntype *Node Heapaddr *Node // temp holding heap address of param // ONAME PAUTOHEAP Stackcopy *Node // the PPARAM/PPARAMOUT on-stack slot (moved func params only) // ONAME closure linkage // Consider: // // func f() { // x := 1 // x1 // func() { // use(x) // x2 // func() { // use(x) // x3 // --- parser is here --- // }() // }() // } // // There is an original declaration of x and then a chain of mentions of x // leading into the current function. Each time x is mentioned in a new closure, // we create a variable representing x for use in that specific closure, // since the way you get to x is different in each closure. // // Let's number the specific variables as shown in the code: // x1 is the original x, x2 is when mentioned in the closure, // and x3 is when mentioned in the closure in the closure. // // We keep these linked (assume N > 1): // // - x1.Defn = original declaration statement for x (like most variables) // - x1.Innermost = current innermost closure x (in this case x3), or nil for none // - x1.IsClosureVar() = false // // - xN.Defn = x1, N > 1 // - xN.IsClosureVar() = true, N > 1 // - x2.Outer = nil // - xN.Outer = x(N-1), N > 2 // // // When we look up x in the symbol table, we always get x1. // Then we can use x1.Innermost (if not nil) to get the x // for the innermost known closure function, // but the first reference in a closure will find either no x1.Innermost // or an x1.Innermost with .Funcdepth < Funcdepth. // In that case, a new xN must be created, linked in with: // // xN.Defn = x1 // xN.Outer = x1.Innermost // x1.Innermost = xN // // When we finish the function, we'll process its closure variables // and find xN and pop it off the list using: // // x1 := xN.Defn // x1.Innermost = xN.Outer // // We leave xN.Innermost set so that we can still get to the original // variable quickly. Not shown here, but once we're // done parsing a function and no longer need xN.Outer for the // lexical x reference links as described above, closurebody // recomputes xN.Outer as the semantic x reference link tree, // even filling in x in intermediate closures that might not // have mentioned it along the way to inner closures that did. // See closurebody for details. // // During the eventual compilation, then, for closure variables we have: // // xN.Defn = original variable // xN.Outer = variable captured in next outward scope // to make closure where xN appears // // Because of the sharding of pieces of the node, x.Defn means x.Name.Defn // and x.Innermost/Outer means x.Name.Param.Innermost/Outer. Innermost *Node Outer *Node // OTYPE // // TODO: Should Func pragmas also be stored on the Name? Pragma syntax.Pragma Alias bool // node is alias for Ntype (only used when type-checking ODCLTYPE) }
type Progs ¶
type Progs struct { Text *obj.Prog // ATEXT Prog for this function // contains filtered or unexported fields }
Progs accumulates Progs for a function and converts them into machine code.
type SSAGenState ¶
type SSAGenState struct { // Branches remembers all the branch instructions we've seen // and where they would like to go. Branches []Branch // 387 port: maps from SSE registers (REG_X?) to 387 registers (REG_F?) SSEto387 map[int16]int16 // Some architectures require a 64-bit temporary for FP-related register shuffling. Examples include x86-387, PPC, and Sparc V8. ScratchFpMem *Node // wasm: The number of values on the WebAssembly stack. This is only used as a safeguard. OnWasmStackSkipped int // contains filtered or unexported fields }
SSAGenState contains state needed during Prog generation.
func (*SSAGenState) AddrScratch ¶
func (s *SSAGenState) AddrScratch(a *obj.Addr)
func (*SSAGenState) Br ¶
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 (*SSAGenState) Call ¶
func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog
Call returns a new CALL instruction for the SSA value v. It uses PrepareCall to prepare the call.
func (*SSAGenState) DebugFriendlySetPosFrom ¶
func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value)
DebugFriendlySetPos 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 (*SSAGenState) FPJump ¶
func (s *SSAGenState) FPJump(b, next *ssa.Block, jumps *[2][2]FloatingEQNEJump)
func (*SSAGenState) PrepareCall ¶
func (s *SSAGenState) PrepareCall(v *ssa.Value)
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 (*SSAGenState) SetPos ¶
func (s *SSAGenState) SetPos(pos src.XPos)
SetPos sets the current source position.
type Timings ¶
type Timings struct {
// contains filtered or unexported fields
}
Timings collects the execution times of labeled phases which are added trough a sequence of Start/Stop calls. Events may be associated with each phase via AddEvent.
func (*Timings) AddEvent ¶
AddEvent associates an event, i.e., a count, or an amount of data, with the most recently started or stopped phase; or the very first phase if Start or Stop hasn't been called yet. The unit specifies the unit of measurement (e.g., MB, lines, no. of funcs, etc.).
func (*Timings) Start ¶
Start marks the beginning of a new phase and implicitly stops the previous phase. The phase name is the colon-separated concatenation of the labels.
type Val ¶
type Val struct { // U contains one of: // bool bool when n.ValCtype() == CTBOOL // *Mpint int when n.ValCtype() == CTINT, rune when n.ValCtype() == CTRUNE // *Mpflt float when n.ValCtype() == CTFLT // *Mpcplx pair of floats when n.ValCtype() == CTCPLX // string string when n.ValCtype() == CTSTR // *Nilval when n.ValCtype() == CTNIL U interface{} }
Source Files ¶
- alg.go
- align.go
- bexport.go
- bimport.go
- bitset.go
- builtin.go
- bv.go
- class_string.go
- closure.go
- const.go
- dcl.go
- dump.go
- dwinl.go
- esc.go
- export.go
- fmt.go
- gen.go
- go.go
- gsubr.go
- iexport.go
- iimport.go
- init.go
- inl.go
- lex.go
- main.go
- mapfile_mmap.go
- mpfloat.go
- mpint.go
- noder.go
- norace.go
- obj.go
- op_string.go
- order.go
- pgen.go
- phi.go
- plive.go
- pprof.go
- racewalk.go
- range.go
- reflect.go
- scope.go
- select.go
- sinit.go
- ssa.go
- subr.go
- swt.go
- syntax.go
- timings.go
- trace.go
- typecheck.go
- types.go
- types_acc.go
- universe.go
- unsafe.go
- util.go
- walk.go