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 GosecurePhase(ttop []*Node)
- func Import(imp *types.Pkg, in *bufio.Reader)
- 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 PrintLast(path []*Pair)
- 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) IsHiddenClosure() bool
- func (f *Func) Needctxt() bool
- func (f *Func) NilCheckDisabled() bool
- func (f *Func) NoFramePointer() 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) SetIsHiddenClosure(b bool)
- func (f *Func) SetNeedctxt(b bool)
- func (f *Func) SetNilCheckDisabled(b bool)
- func (f *Func) SetNoFramePointer(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 Level
- type Liveness
- type Loc
- 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 (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) 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 (x *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) 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) IsMethod() bool
- func (n *Node) IsOutputParamHeapAddr() bool
- func (n *Node) Isddd() 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) 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) 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) SetIsOutputParamHeapAddr(b bool)
- func (n *Node) SetIsddd(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) 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) 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 Pair
- type Param
- type Progs
- type SSAGenState
- func (s *SSAGenState) AddrScratch(a *obj.Addr)
- 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) 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 ( 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 ( H0 = 2166136261 Hp = 16777619 )
FNV-1 hash function constants.
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/hashmap.go!
const ( InitNotStarted = iota InitDone InitPending )
Static initialization ordering state. These values are stored in two bits in Node.flags.
const ( Etop = 1 << iota // evaluated at statement level Erv // evaluated in value context Etype // evaluated in type context Ecall // call-only expressions are ok Efnstruct // multivalue function returns are ok Easgn // assigning to expression Ecomplit // type in composite literal )
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 TPTR32 = types.TPTR32 TPTR64 = types.TPTR64 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 MinLevel = -2
There appear to be some 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 ( Newproc, Deferproc, Gosecload, Deferreturn, Duffcopy, Duffzero, Udiv *obj.LSym // GO386=387 ControlWord64trunc, ControlWord32 *obj.LSym )
var ( Debug_append int Debug_asm bool Debug_closure int Debug_compilelater int Debug_panic int Debug_slice int Debug_vlog bool Debug_wb int Debug_eagerwb 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 Gosecpkg *types.Pkg // fake package for the gosecload function.
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 GosecurePhase ¶
func GosecurePhase(ttop []*Node)
findSecureNodes calls the walker on the ttop nodes.
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) // 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 Inldcl Nodes // copy of dcl for use in inlining // 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 int Outerfunc *Node // outer function (for closure) FieldTrack map[*types.Sym]struct{} DebugInfo *ssa.FuncDebug Ntype *Node // signature Top int // top context (Ecall, Eproc, etc) Closure *Node // OCLOSURE <-> ODCLFUNC Nname *Node Inl Nodes // copy of the body for use in inlining InlCost int32 Depth int32 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) IsHiddenClosure ¶
func (*Func) NilCheckDisabled ¶
func (*Func) NoFramePointer ¶
func (*Func) ReflectMethod ¶
func (*Func) SetExportInline ¶
func (*Func) SetHasDefer ¶
func (*Func) SetInlinabilityChecked ¶
func (*Func) SetIsHiddenClosure ¶
func (*Func) SetNeedctxt ¶
func (*Func) SetNilCheckDisabled ¶
func (*Func) SetNoFramePointer ¶
func (*Func) SetReflectMethod ¶
func (*Func) SetWrapper ¶
type Level ¶
type Level struct {
// contains filtered or unexported fields
}
A Level encodes the reference state and context applied to (stack, heap) allocated memory.
value is the overall sum of *(1) and &(-1) operations encountered along a path from a destination (sink, return value) to a source (allocation, parameter).
suffixValue is the maximum-copy-started-suffix-level applied to a sink. For example: sink = x.left.left --> level=2, x is dereferenced twice and does not escape to sink. sink = &Node{x} --> level=-1, x is accessible from sink via one "address of" sink = &Node{&Node{x}} --> level=-2, x is accessible from sink via two "address of" sink = &Node{&Node{x.left}} --> level=-1, but x is NOT accessible from sink because it was indirected and then copied. (The copy operations are sometimes implicit in the source code; in this case, value of x.left was copied into a field of a newly allocated Node)
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 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 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. Funcdepth int32 // 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 to store their ambient iota value. // Possibly still more uses. If you find any, document them. Xoffset int64 Pos src.XPos Esc uint16 // EscXXX Op Op Etype types.EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS // 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) 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) 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) 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) 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, const 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 OARRAYBYTESTR // Type(Left) (Type is string, Left is a []byte) OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral) OARRAYRUNESTR // Type(Left) (Type is string, Left is a []rune) OSTRARRAYBYTE // Type(Left) (Type is []byte, Left is a string) OSTRARRAYBYTETMP // Type(Left) (Type is []byte, Left is a string, ephemeral) OSTRARRAYRUNE // 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 // Left(List) (function call f(args)) OCALLMETH // Left(List) (direct method call x.Method(args)) OCALLINTER // Left(List) (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) OCMPIFACE // Left Etype Right (interface comparison, x == y or x != y) OCMPSTR // Left Etype Right (string comparison, x == y, x < y, etc) 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) 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 OIND // *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 OCOM // ^Left OPLUS // +Left OMINUS // -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) 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) OALIGNOF // unsafe.Alignof(Left) OOFFSETOF // unsafe.Offsetof(Left) OSIZEOF // unsafe.Sizeof(Left) // statements OBLOCK // { List } (block of code) OBREAK // break 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 ODEFER // defer Left (Left must be call) OEMPTY // no-op (empty statement) OFALL // fallthrough OFOR // for Ninit; Left; Right { Nbody } OFORUNTIL // for Ninit; Left; Right { Nbody } ; test applied after executing body, not before OGOTO // goto Left OIF // if Ninit; Left { Nbody } else { Rlist } OLABEL // Left: OPROC // go Left (Left must be call) OGOSECURE //gosecure 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 OVARKILL // variable is dead OVARLIVE // variable is alive OINDREGSP // offset plus indirect of REGSP, such as 8(SP). // 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 PPARAM Field *types.Field // TFIELD in arg struct // 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 // contains filtered or unexported fields }
SSAGenState contains state needed during Prog generation.
func (*SSAGenState) AddrScratch ¶
func (s *SSAGenState) AddrScratch(a *obj.Addr)
func (*SSAGenState) DebugFriendlySetPosFrom ¶
func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value)
DebugFriendlySetPos sets the position 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) SetPos ¶
func (s *SSAGenState) SetPos(pos src.XPos)
SetPos sets the current source position.
type Symlink ¶
type Symlink struct {
// contains filtered or unexported fields
}
code to help generate trampoline functions for methods on embedded subtypes. these are approx the same as the corresponding adddot routines except that they expect to be called with unique tasks and they return the actual methods.
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 ¶
- aghosn.go
- alg.go
- align.go
- bexport.go
- bimport.go
- bitset.go
- builtin.go
- bv.go
- class_string.go
- closure.go
- const.go
- dcl.go
- dwinl.go
- esc.go
- export.go
- fmt.go
- gen.go
- go.go
- gosecure.go
- gsubr.go
- init.go
- inl.go
- lex.go
- main.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