rua.fn.Sym().Name, rname)
}
if cs := rua.returnHasProp(rname, ResultIsConcreteTypeConvertedToInterface); cs != nil {
- // FIXME: add cond level support here
- adj := passConcreteToItfCallAdj
- cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
- adj = callResultRescoreAdj
+
+ adj := returnFeedsConcreteToInterfaceCallAdj
cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
}
case ir.OCALLFUNC:
}
}
if cs := rua.returnHasProp(rname, ResultAlwaysSameInlinableFunc); cs != nil {
- // FIXME: add cond level support here
- adj := passInlinableFuncToIndCallAdj
- cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
- adj = callResultRescoreAdj
+ adj := returnFeedsInlinableFuncToIndCallAdj
cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
} else if cs := rua.returnHasProp(rname, ResultAlwaysSameFunc); cs != nil {
- // FIXME: add cond level support here
- adj := passFuncToIndCallAdj
- cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
- adj = callResultRescoreAdj
+ adj := returnFeedsFuncToIndCallAdj
cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
+
}
}
}
if !ShouldFoldIfNameConstant(cond, namesUsed) {
return
}
- // FIXME: add cond level support here
- adj := passConstToIfAdj
- cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
- adj = callResultRescoreAdj
+ adj := returnFeedsConstToIfAdj
cs.Score, cs.ScoreMask = adjustScore(adj, cs.Score, cs.ScoreMask)
}
_ = x[passFuncToNestedIndCallAdj-256]
_ = x[passInlinableFuncToIndCallAdj-512]
_ = x[passInlinableFuncToNestedIndCallAdj-1024]
- _ = x[callResultRescoreAdj-2048]
- _ = x[lastAdj-2048]
+ _ = x[returnFeedsConstToIfAdj-2048]
+ _ = x[returnFeedsFuncToIndCallAdj-4096]
+ _ = x[returnFeedsInlinableFuncToIndCallAdj-8192]
+ _ = x[returnFeedsConcreteToInterfaceCallAdj-16384]
}
var _scoreAdjustTyp_value = [...]uint64{
- 0x1, /* panicPathAdj */
- 0x2, /* initFuncAdj */
- 0x4, /* inLoopAdj */
- 0x8, /* passConstToIfAdj */
- 0x10, /* passConstToNestedIfAdj */
- 0x20, /* passConcreteToItfCallAdj */
- 0x40, /* passConcreteToNestedItfCallAdj */
- 0x80, /* passFuncToIndCallAdj */
- 0x100, /* passFuncToNestedIndCallAdj */
- 0x200, /* passInlinableFuncToIndCallAdj */
- 0x400, /* passInlinableFuncToNestedIndCallAdj */
- 0x800, /* callResultRescoreAdj */
- 0x800, /* lastAdj */
+ 0x1, /* panicPathAdj */
+ 0x2, /* initFuncAdj */
+ 0x4, /* inLoopAdj */
+ 0x8, /* passConstToIfAdj */
+ 0x10, /* passConstToNestedIfAdj */
+ 0x20, /* passConcreteToItfCallAdj */
+ 0x40, /* passConcreteToNestedItfCallAdj */
+ 0x80, /* passFuncToIndCallAdj */
+ 0x100, /* passFuncToNestedIndCallAdj */
+ 0x200, /* passInlinableFuncToIndCallAdj */
+ 0x400, /* passInlinableFuncToNestedIndCallAdj */
+ 0x800, /* returnFeedsConstToIfAdj */
+ 0x1000, /* returnFeedsFuncToIndCallAdj */
+ 0x2000, /* returnFeedsInlinableFuncToIndCallAdj */
+ 0x4000, /* returnFeedsConcreteToInterfaceCallAdj */
}
-const _scoreAdjustTyp_name = "panicPathAdjinitFuncAdjinLoopAdjpassConstToIfAdjpassConstToNestedIfAdjpassConcreteToItfCallAdjpassConcreteToNestedItfCallAdjpassFuncToIndCallAdjpassFuncToNestedIndCallAdjpassInlinableFuncToIndCallAdjpassInlinableFuncToNestedIndCallAdjcallResultRescoreAdjlastAdj"
+const _scoreAdjustTyp_name = "panicPathAdjinitFuncAdjinLoopAdjpassConstToIfAdjpassConstToNestedIfAdjpassConcreteToItfCallAdjpassConcreteToNestedItfCallAdjpassFuncToIndCallAdjpassFuncToNestedIndCallAdjpassInlinableFuncToIndCallAdjpassInlinableFuncToNestedIndCallAdjreturnFeedsConstToIfAdjreturnFeedsFuncToIndCallAdjreturnFeedsInlinableFuncToIndCallAdjreturnFeedsConcreteToInterfaceCallAdj"
-var _scoreAdjustTyp_index = [...]uint16{0, 12, 23, 32, 48, 70, 94, 124, 144, 170, 199, 234, 254, 261}
+var _scoreAdjustTyp_index = [...]uint16{0, 12, 23, 32, 48, 70, 94, 124, 144, 170, 199, 234, 257, 284, 320, 357}
func (i scoreAdjustTyp) String() string {
var b bytes.Buffer
// in which we'll adjust the score of a given callsite.
type scoreAdjustTyp uint
+// These constants capture the various ways in which the inliner's
+// scoring phase can adjust a callsite score based on heuristics. They
+// fall broadly into three categories:
+//
+// 1) adjustments based solely on the callsite context (ex: call
+// appears on panic path)
+//
+// 2) adjustments that take into account specific interesting values
+// passed at a call site (ex: passing a constant that could result in
+// cprop/deadcode in the caller)
+//
+// 3) adjustments that take into account values returned from the call
+// at a callsite (ex: call always returns the same inlinable function,
+// and return value flows unmodified into an indirect call)
+//
+// For categories 2 and 3 above, each adjustment can have either a
+// "must" version and a "may" version (but not both). Here the idea is
+// that in the "must" version the value flow is unconditional: if the
+// callsite executes, then the condition we're interested in (ex:
+// param feeding call) is guaranteed to happen. For the "may" version,
+// there may be control flow that could cause the benefit to be
+// bypassed.
const (
+ // Catgegory 1 adjustments (see above)
panicPathAdj scoreAdjustTyp = (1 << iota)
initFuncAdj
inLoopAdj
+
+ // Category 2 adjustments (see above).
passConstToIfAdj
passConstToNestedIfAdj
passConcreteToItfCallAdj
passFuncToNestedIndCallAdj
passInlinableFuncToIndCallAdj
passInlinableFuncToNestedIndCallAdj
- callResultRescoreAdj
- lastAdj scoreAdjustTyp = callResultRescoreAdj
+
+ // Category 3 adjustments.
+ returnFeedsConstToIfAdj
+ returnFeedsFuncToIndCallAdj
+ returnFeedsInlinableFuncToIndCallAdj
+ returnFeedsConcreteToInterfaceCallAdj
)
// This table records the specific values we use to adjust call
// what value for each one produces the best performance.
var adjValues = map[scoreAdjustTyp]int{
- panicPathAdj: 40,
- initFuncAdj: 20,
- inLoopAdj: -5,
- passConstToIfAdj: -20,
- passConstToNestedIfAdj: -15,
- passConcreteToItfCallAdj: -30,
- passConcreteToNestedItfCallAdj: -25,
- passFuncToIndCallAdj: -25,
- passFuncToNestedIndCallAdj: -20,
- passInlinableFuncToIndCallAdj: -45,
- passInlinableFuncToNestedIndCallAdj: -40,
- callResultRescoreAdj: 0,
+ panicPathAdj: 40,
+ initFuncAdj: 20,
+ inLoopAdj: -5,
+ passConstToIfAdj: -20,
+ passConstToNestedIfAdj: -15,
+ passConcreteToItfCallAdj: -30,
+ passConcreteToNestedItfCallAdj: -25,
+ passFuncToIndCallAdj: -25,
+ passFuncToNestedIndCallAdj: -20,
+ passInlinableFuncToIndCallAdj: -45,
+ passInlinableFuncToNestedIndCallAdj: -40,
+ returnFeedsConstToIfAdj: -15,
+ returnFeedsFuncToIndCallAdj: -25,
+ returnFeedsInlinableFuncToIndCallAdj: -40,
+ returnFeedsConcreteToInterfaceCallAdj: -25,
}
func adjValue(x scoreAdjustTyp) int {
// returns2.go T_return_feeds_iface_call 18 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[],"ResultFlags":[]}
-// callsite: returns2.go:19:13|0 flagstr "" flagval 0 score -4 mask 2080 maskstr "passConcreteToItfCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:19:13|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_return_feeds_iface_call() {
// returns2.go T_multi_return_feeds_iface_call 29 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[],"ResultFlags":[]}
-// callsite: returns2.go:30:20|0 flagstr "" flagval 0 score -2 mask 2080 maskstr "passConcreteToItfCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:30:20|0 flagstr "" flagval 0 score 3 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_iface_call() {
// returns2.go T_returned_inlinable_func_feeds_indirect_call 41 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[]}
-// callsite: returns2.go:42:18|0 flagstr "" flagval 0 score -43 mask 2560 maskstr "passInlinableFuncToIndCallAdj|callResultRescoreAdj"
-// callsite: returns2.go:44:20|1 flagstr "" flagval 0 score -28 mask 2560 maskstr "passInlinableFuncToIndCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:42:18|0 flagstr "" flagval 0 score -51 mask 8200 maskstr "passConstToIfAdj|returnFeedsInlinableFuncToIndCallAdj"
+// callsite: returns2.go:44:20|1 flagstr "" flagval 0 score -23 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_returned_inlinable_func_feeds_indirect_call(q int) {
- f := returnsFunc()
+ f := returnsFunc(10)
f(q)
f2 := returnsFunc2()
f2(q)
// returns2.go T_returned_noninlineable_func_feeds_indirect_call 54 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[]}
-// callsite: returns2.go:55:30|0 flagstr "" flagval 0 score -23 mask 2176 maskstr "passFuncToIndCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:55:30|0 flagstr "" flagval 0 score -23 mask 4096 maskstr "returnFeedsFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_returned_noninlineable_func_feeds_indirect_call(q int) {
// returns2.go T_multi_return_feeds_indirect_call 65 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[]}
-// callsite: returns2.go:66:29|0 flagstr "" flagval 0 score -26 mask 2560 maskstr "passInlinableFuncToIndCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:66:29|0 flagstr "" flagval 0 score -21 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_indirect_call(q int) {
// returns2.go T_return_feeds_ifswitch 76 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
-// callsite: returns2.go:77:14|0 flagstr "" flagval 0 score 5 mask 2056 maskstr "passConstToIfAdj|callResultRescoreAdj"
+// callsite: returns2.go:77:14|0 flagstr "" flagval 0 score 10 mask 2048 maskstr "returnFeedsConstToIfAdj"
// <endcallsites>
// <endfuncpreamble>
func T_return_feeds_ifswitch(q int) int {
// returns2.go T_multi_return_feeds_ifswitch 93 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
-// callsite: returns2.go:94:21|0 flagstr "" flagval 0 score 4 mask 2056 maskstr "passConstToIfAdj|callResultRescoreAdj"
+// callsite: returns2.go:94:21|0 flagstr "" flagval 0 score 9 mask 2048 maskstr "returnFeedsConstToIfAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_ifswitch(q int) int {
// returns2.go T_chained_indirect_call 132 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[]}
-// callsite: returns2.go:135:18|0 flagstr "" flagval 0 score -43 mask 2560 maskstr "passInlinableFuncToIndCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:135:18|0 flagstr "" flagval 0 score -31 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_chained_indirect_call(x, y int) {
// Here 'returnsFunc' returns an inlinable func that feeds
// directly into a call (no named intermediate).
- G += returnsFunc()(x + y)
+ G += returnsFunc(x - y)(x + y)
}
// returns2.go T_chained_conc_iface_call 144 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[]}
-// callsite: returns2.go:148:8|0 flagstr "" flagval 0 score -4 mask 2080 maskstr "passConcreteToItfCallAdj|callResultRescoreAdj"
+// callsite: returns2.go:148:8|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_chained_conc_iface_call(x, y int) {
newBar(10).Plark().Plark()
}
-func returnsFunc() func(int) int {
+func returnsFunc(x int) func(int) int {
+ if x < 0 {
+ G++
+ }
return adder
}