...

Package liveness

import "cmd/compile/internal/liveness"
Overview
Index

Overview ▾

Index ▾

func ArgLiveness(fn *ir.Func, f *ssa.Func, pp *objw.Progs) (blockIdx, valueIdx map[ssa.ID]int)
func IsUnsafe(f *ssa.Func) bool
func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo)
type Interval
    func (i1 *Interval) MergeInto(i2 Interval) error
    func (i Interval) Overlaps(i2 Interval) bool
    func (i Interval) String() string
type Intervals
    func (is Intervals) Merge(is2 Intervals) Intervals
    func (is Intervals) Overlaps(is2 Intervals) bool
    func (is *Intervals) String() string
type IntervalsBuilder
    func (c *IntervalsBuilder) Finish() (Intervals, error)
    func (c *IntervalsBuilder) Kill(pos int) error
    func (c *IntervalsBuilder) Live(pos int) error
type Map
    func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) (Map, map[*ir.Name]bool)
    func (m Map) Get(v *ssa.Value) objw.StackMapIndex
    func (m Map) GetUnsafe(v *ssa.Value) bool
    func (m Map) GetUnsafeBlock(b *ssa.Block) bool
type MergeLocalsState
    func MakeMergeLocalsState(partition map[*ir.Name][]int, vars []*ir.Name) (*MergeLocalsState, error)
    func MergeLocals(fn *ir.Func, f *ssa.Func) *MergeLocalsState
    func (mls *MergeLocalsState) EstSavings() (int, int)
    func (mls *MergeLocalsState) Followers(n *ir.Name, tmp []*ir.Name) []*ir.Name
    func (mls *MergeLocalsState) IsLeader(n *ir.Name) bool
    func (mls *MergeLocalsState) Leader(n *ir.Name) *ir.Name
    func (mls *MergeLocalsState) String() string
    func (mls *MergeLocalsState) Subsumed(n *ir.Name) bool

Package files

arg.go bvset.go intervals.go mergelocals.go plive.go

func ArgLiveness

func ArgLiveness(fn *ir.Func, f *ssa.Func, pp *objw.Progs) (blockIdx, valueIdx map[ssa.ID]int)

ArgLiveness computes the liveness information of register argument spill slots. An argument's spill slot is "live" if we know it contains a meaningful value, that is, we have stored the register value to it. Returns the liveness map indices at each Block entry and at each Value (where it changes).

func IsUnsafe

func IsUnsafe(f *ssa.Func) bool

IsUnsafe indicates that all points in this function are unsafe-points.

func WriteFuncMap

func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo)

WriteFuncMap writes the pointer bitmaps for bodyless function fn's inputs and outputs as the value of symbol <fn>.args_stackmap. If fn has outputs, two bitmaps are written, otherwise just one.

type Interval

Interval hols the range [st,en).

type Interval struct {
    // contains filtered or unexported fields
}

func (*Interval) MergeInto

func (i1 *Interval) MergeInto(i2 Interval) error

MergeInto merges interval i2 into i1. This version happens to require that the two intervals either overlap or are adjacent.

func (Interval) Overlaps

func (i Interval) Overlaps(i2 Interval) bool

Overlaps returns true if here is any overlap between i and i2.

func (Interval) String

func (i Interval) String() string

type Intervals

Intervals is a sequence of sorted, disjoint intervals.

type Intervals []Interval

func (Intervals) Merge

func (is Intervals) Merge(is2 Intervals) Intervals

Merge combines the intervals from "is" and "is2" and returns a new Intervals object containing all combined ranges from the two inputs.

func (Intervals) Overlaps

func (is Intervals) Overlaps(is2 Intervals) bool

Overlaps returns whether any of the component ranges in is overlaps with some range in is2.

func (*Intervals) String

func (is *Intervals) String() string

type IntervalsBuilder

IntervalsBuilder is a helper for constructing intervals based on live dataflow sets for a series of BBs where we're making a backwards pass over each BB looking for uses and kills. The expected use case is:

See the Live method comment for an IR example.

type IntervalsBuilder struct {
    // contains filtered or unexported fields
}

func (*IntervalsBuilder) Finish

func (c *IntervalsBuilder) Finish() (Intervals, error)

func (*IntervalsBuilder) Kill

func (c *IntervalsBuilder) Kill(pos int) error

Kill method should be invoked on instruction at position p if instr should be treated as as having a kill (lifetime end) for the resource. See the example in the comment at the beginning of this file for an example. Note that if we see a kill at position K for a resource currently live since J, this will result in a lifetime segment of [K+1,J+1), the assumption being that the first live instruction will be the one after the kill position, not the kill position itself.

func (*IntervalsBuilder) Live

func (c *IntervalsBuilder) Live(pos int) error

Live method should be invoked on instruction at position p if instr contains an upwards-exposed use of a resource. See the example in the comment at the beginning of this file for an example.

type Map

Map maps from *ssa.Value to StackMapIndex. Also keeps track of unsafe ssa.Values and ssa.Blocks. (unsafe = can't be interrupted during GC.)

type Map struct {
    Vals         map[ssa.ID]objw.StackMapIndex
    UnsafeVals   map[ssa.ID]bool
    UnsafeBlocks map[ssa.ID]bool
    // The set of live, pointer-containing variables at the DeferReturn
    // call (only set when open-coded defers are used).
    DeferReturn objw.StackMapIndex
}

func Compute

func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) (Map, map[*ir.Name]bool)

Entry pointer for Compute analysis. Solves for the Compute of pointer variables in the function and emits a runtime data structure read by the garbage collector. Returns a map from GC safe points to their corresponding stack map index, and a map that contains all input parameters that may be partially live.

func (Map) Get

func (m Map) Get(v *ssa.Value) objw.StackMapIndex

func (Map) GetUnsafe

func (m Map) GetUnsafe(v *ssa.Value) bool

func (Map) GetUnsafeBlock

func (m Map) GetUnsafeBlock(b *ssa.Block) bool

type MergeLocalsState

MergeLocalsState encapsulates information about which AUTO (stack-allocated) variables within a function can be safely merged/overlapped, e.g. share a stack slot with some other auto). An instance of MergeLocalsState is produced by MergeLocals() below and then consumed in ssagen.AllocFrame. The map 'partition' contains entries of the form <N,SL> where N is an *ir.Name and SL is a slice holding the indices (within 'vars') of other variables that share the same slot, specifically the slot of the first element in the partition, which we'll call the "leader". For example, if a function contains five variables where v1/v2/v3 are safe to overlap and v4/v5 are safe to overlap, the MergeLocalsState content might look like

vars: [v1, v2, v3, v4, v5]
partition: v1 -> [1, 0, 2], v2 -> [1, 0, 2], v3 -> [1, 0, 2]
           v4 -> [3, 4], v5 -> [3, 4]

A nil MergeLocalsState indicates that no local variables meet the necessary criteria for overlap.

type MergeLocalsState struct {
    // contains filtered or unexported fields
}

func MakeMergeLocalsState

func MakeMergeLocalsState(partition map[*ir.Name][]int, vars []*ir.Name) (*MergeLocalsState, error)

for unit testing only.

func MergeLocals

func MergeLocals(fn *ir.Func, f *ssa.Func) *MergeLocalsState

MergeLocals analyzes the specified ssa function f to determine which of its auto variables can safely share the same stack slot, returning a state object that describes how the overlap should be done.

func (*MergeLocalsState) EstSavings

func (mls *MergeLocalsState) EstSavings() (int, int)

EstSavings returns the estimated reduction in stack size (number of bytes) for the given merge locals state via a pair of ints, the first for non-pointer types and the second for pointer types.

func (*MergeLocalsState) Followers

func (mls *MergeLocalsState) Followers(n *ir.Name, tmp []*ir.Name) []*ir.Name

Followers writes a list of the followers for leader n into the slice tmp.

func (*MergeLocalsState) IsLeader

func (mls *MergeLocalsState) IsLeader(n *ir.Name) bool

IsLeader returns whether a variable n is the leader (first element) in a sharing partition.

func (*MergeLocalsState) Leader

func (mls *MergeLocalsState) Leader(n *ir.Name) *ir.Name

Leader returns the leader variable for subsumed var n.

func (*MergeLocalsState) String

func (mls *MergeLocalsState) String() string

func (*MergeLocalsState) Subsumed

func (mls *MergeLocalsState) Subsumed(n *ir.Name) bool

Subsumed returns whether variable n is subsumed, e.g. appears in an overlap position but is not the leader in that partition.