github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/inline-over-budget/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"regexp"
     9  	"sort"
    10  	"strconv"
    11  )
    12  
    13  func main() {
    14  	threshold := flag.Int("threshold", 15, "inlining budget to test for")
    15  	flag.Parse()
    16  
    17  	args := []string{"build", "-a", "-gcflags=all=-m -m"}
    18  	args = append(args, flag.Args()...)
    19  
    20  	out, err := exec.Command("go", args...).CombinedOutput()
    21  	if err != nil {
    22  		fmt.Fprintln(os.Stderr, string(out))
    23  		fmt.Fprintln(os.Stderr, err)
    24  		os.Exit(1)
    25  	}
    26  
    27  	type Match struct {
    28  		File   string
    29  		Line   int
    30  		Func   string
    31  		Cost   int
    32  		Budget int
    33  	}
    34  
    35  	var all []Match
    36  
    37  	rx := regexp.MustCompile(`(?m)^(.*):(\d+):\d+: cannot inline (.*): function too complex: cost (\d+) exceeds budget (\d+)$`)
    38  	for _, matches := range rx.FindAllStringSubmatch(string(out), -1) {
    39  		var fn Match
    40  		var err error
    41  
    42  		fn.File = matches[1]
    43  		if fn.Line, err = strconv.Atoi(matches[2]); err != nil {
    44  			continue
    45  		}
    46  		fn.Func = matches[3]
    47  		if fn.Cost, err = strconv.Atoi(matches[4]); err != nil {
    48  			continue
    49  		}
    50  
    51  		if fn.Budget, err = strconv.Atoi(matches[5]); err != nil {
    52  			continue
    53  		}
    54  
    55  		if fn.Cost-fn.Budget > *threshold {
    56  			continue
    57  		}
    58  
    59  		all = append(all, fn)
    60  	}
    61  
    62  	sort.Slice(all, func(i, k int) bool {
    63  		return all[i].Cost < all[k].Cost
    64  	})
    65  
    66  	for _, fn := range all {
    67  		fmt.Printf("%s:%d: func %s cost +%d\n", fn.File, fn.Line, fn.Func, fn.Cost-fn.Budget)
    68  	}
    69  }