Functions
CalleeEffects
function
#
CalleeEffects appends any side effects from evaluating callee to init.
func CalleeEffects(init *ir.Nodes, callee ir.Node)
CanInline
function
#
CanInline determines whether fn is inlineable.
If so, CanInline saves copies of fn.Body and fn.Dcl in fn.Inl.
fn and fn.Body will already have been typechecked.
func CanInline(fn *ir.Func, profile *pgoir.Profile)
CanInlineFuncs
function
#
CanInlineFuncs computes whether a batch of functions are inlinable.
func CanInlineFuncs(funcs []*ir.Func, profile *pgoir.Profile)
HasPgoHotInline
function
#
func HasPgoHotInline(fn *ir.Func) bool
InlineCallTarget
function
#
InlineCallTarget returns the resolved-for-inlining target of a call.
It does not necessarily guarantee that the target can be inlined, though
obvious exclusions are applied.
func InlineCallTarget(callerfn *ir.Func, call *ir.CallExpr, profile *pgoir.Profile) *ir.Func
InlineImpossible
function
#
InlineImpossible returns a non-empty reason string if fn is impossible to
inline regardless of cost or contents.
func InlineImpossible(fn *ir.Func) string
IsBigFunc
function
#
IsBigFunc reports whether fn is a "big" function.
Note: The criteria for "big" is heuristic and subject to change.
func IsBigFunc(fn *ir.Func) bool
IsPgoHotFunc
function
#
func IsPgoHotFunc(fn *ir.Func, profile *pgoir.Profile) bool
PGOInlinePrologue
function
#
PGOInlinePrologue records the hot callsites from ir-graph.
func PGOInlinePrologue(p *pgoir.Profile)
PostProcessCallSites
function
#
func PostProcessCallSites(profile *pgoir.Profile)
TryInlineCall
function
#
TryInlineCall returns an inlined call expression for call, or nil
if inlining is not possible.
func TryInlineCall(callerfn *ir.Func, call *ir.CallExpr, bigCaller bool, profile *pgoir.Profile, closureCalledOnce bool) *ir.InlinedCallExpr
analyzeFuncProps
function
#
func analyzeFuncProps(fn *ir.Func, p *pgoir.Profile)
canDelayResults
function
#
canDelayResults reports whether inlined calls to fn can delay
declaring the result parameter until the "return" statement.
func canDelayResults(fn *ir.Func) bool
canInlineCallExpr
function
#
canInlineCallExpr returns true if the call n from caller to callee
can be inlined, plus the score computed for the call expr in question,
and whether the callee is hot according to PGO.
bigCaller indicates that caller is a big function. log
indicates that the 'cannot inline' reason should be logged.
Preconditions: CanInline(callee) has already been called.
func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCaller bool, closureCalledOnce bool, log bool) (bool, int32, bool)
doList
function
#
func doList(list []ir.Node, do func(ir.Node) bool) bool
doNode
method
#
doNode visits n and its children, updates the state in v, and returns true if
n makes the current function too hairy for inlining.
func (v *hairyVisitor) doNode(n ir.Node) bool
hotNodesFromCDF
function
#
hotNodesFromCDF computes an edge weight threshold and the list of hot
nodes that make up the given percentage of the CDF. The threshold, as
a percent, is the lower bound of weight for nodes to be considered hot
(currently only used in debug prints) (in case of equal weights,
comparing with the threshold may not accurately reflect which nodes are
considered hot).
func hotNodesFromCDF(p *pgoir.Profile) (float64, []pgo.NamedCallEdge)
inlCallee
function
#
inlCallee takes a function-typed expression and returns the underlying function ONAME
that it refers to if statically known. Otherwise, it returns nil.
resolveOnly skips cost-based inlineability checks for closures; the result may not actually be inlineable.
func inlCallee(caller *ir.Func, fn ir.Node, profile *pgoir.Profile, resolveOnly bool) (res *ir.Func)
inlineBudget
function
#
inlineBudget determines the max budget for function 'fn' prior to
analyzing the hairiness of the body of 'fn'. We pass in the pgo
profile if available (which can change the budget), also a
'relaxed' flag, which expands the budget slightly to allow for the
possibility that a call to the function might have its score
adjusted downwards. If 'verbose' is set, then print a remark where
we boost the budget due to PGO.
func inlineBudget(fn *ir.Func, profile *pgoir.Profile, relaxed bool, verbose bool) int32
inlineCallCheck
function
#
inlineCallCheck returns whether a call will never be inlineable
for basic reasons, and whether the call is an intrinisic call.
The intrinsic result singles out intrinsic calls for debug logging.
func inlineCallCheck(callerfn *ir.Func, call *ir.CallExpr) (bool, bool)
inlineCostOK
function
#
inlineCostOK returns true if call n from caller to callee is cheap enough to
inline. bigCaller indicates that caller is a big function.
In addition to the "cost OK" boolean, it also returns
- the "max cost" limit used to make the decision (which may differ depending on func size)
- the score assigned to this specific callsite
- whether the inlined function is "hot" according to PGO.
func inlineCostOK(n *ir.CallExpr, caller *ir.Func, callee *ir.Func, bigCaller bool, closureCalledOnce bool) (bool, int32, int32, bool)
isAtomicCoverageCounterUpdate
function
#
isAtomicCoverageCounterUpdate examines the specified node to
determine whether it represents a call to sync/atomic.AddUint32 to
increment a coverage counter.
func isAtomicCoverageCounterUpdate(cn *ir.CallExpr) bool
isIndexingCoverageCounter
function
#
isIndexingCoverageCounter returns true if the specified node 'n' is indexing
into a coverage counter array.
func isIndexingCoverageCounter(n ir.Node) bool
mkinlcall
function
#
mkinlcall returns an OINLCALL node that can replace OCALLFUNC n, or
nil if it cannot be inlined. callerfn is the function that contains
n, and fn is the function being called.
The result of mkinlcall MUST be assigned back to n, e.g.
n.Left = mkinlcall(n.Left, fn, isddd)
func mkinlcall(callerfn *ir.Func, n *ir.CallExpr, fn *ir.Func, bigCaller bool, closureCalledOnce bool) *ir.InlinedCallExpr
noteInlinableFunc
function
#
noteInlinableFunc issues a message to the user that the specified
function is inlinable.
func noteInlinableFunc(n *ir.Name, fn *ir.Func, cost int32)
numNonClosures
function
#
numNonClosures returns the number of functions in list which are not closures.
func numNonClosures(list []*ir.Func) int
parsePos
function
#
parsePos returns all the inlining positions and the innermost position.
func parsePos(pos src.XPos, posTmp []src.Pos) ([]src.Pos, src.Pos)
pruneUnusedAutos
function
#
func pruneUnusedAutos(ll []*ir.Name, vis *hairyVisitor) []*ir.Name
tooHairy
method
#
func (v *hairyVisitor) tooHairy(fn *ir.Func) bool