Skip to content

Commit

Permalink
inline in bottom-up complexity order (#240)
Browse files Browse the repository at this point in the history
The inliner must perform inlining in a deterministic
order in order for the generated code to be
deterministic.

This patch uses a "bottom-up" inlining heuristic:
the least complex types are inlined first, followed
by more complex types (if the fixed inlining "budget"
still allows it.)

Fixes #239
  • Loading branch information
philhofer authored Nov 28, 2018
1 parent f69a9cf commit af6442a
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion parse/inline.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package parse

import (
"sort"

"github.com/tinylib/msgp/gen"
)

Expand Down Expand Up @@ -78,9 +80,30 @@ func (f *FileSet) nextShim(ref *gen.Elem, id string, be *gen.BaseElem) {

// propInline identifies and inlines candidates
func (f *FileSet) propInline() {
type gelem struct {
name string
el gen.Elem
}

all := make([]gelem, 0, len(f.Identities))

for name, el := range f.Identities {
all = append(all, gelem{name: name, el: el})
}

// make sure we process inlining determinstically:
// start with the least-complex elems;
// use identifier names as a tie-breaker
sort.Slice(all, func(i, j int) bool {
ig, jg := &all[i], &all[j]
ic, jc := ig.el.Complexity(), jg.el.Complexity()
return ic < jc || (ic == jc && ig.name < jg.name)
})

for i := range all {
name := all[i].name
pushstate(name)
switch el := el.(type) {
switch el := all[i].el.(type) {
case *gen.Struct:
for i := range el.Fields {
f.nextInline(&el.Fields[i].FieldElem, name)
Expand Down

0 comments on commit af6442a

Please sign in to comment.