github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/inline/inlheur/eclassify.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package inlheur
     6  
     7  import (
     8  	"github.com/shogo82148/std/cmd/compile/internal/ir"
     9  )
    10  
    11  // ShouldFoldIfNameConstant analyzes expression tree 'e' to see
    12  // whether it contains only combinations of simple references to all
    13  // of the names in 'names' with selected constants + operators. The
    14  // intent is to identify expression that could be folded away to a
    15  // constant if the value of 'n' were available. Return value is TRUE
    16  // if 'e' does look foldable given the value of 'n', and given that
    17  // 'e' actually makes reference to 'n'. Some examples where the type
    18  // of "n" is int64, type of "s" is string, and type of "p" is *byte:
    19  //
    20  //	Simple?		Expr
    21  //	yes			n<10
    22  //	yes			n*n-100
    23  //	yes			(n < 10 || n > 100) && (n >= 12 || n <= 99 || n != 101)
    24  //	yes			s == "foo"
    25  //	yes			p == nil
    26  //	no			n<foo()
    27  //	no			n<1 || n>m
    28  //	no			float32(n)<1.0
    29  //	no			*p == 1
    30  //	no			1 + 100
    31  //	no			1 / n
    32  //	no			1 + unsafe.Sizeof(n)
    33  //
    34  // To avoid complexities (e.g. nan, inf) we stay way from folding and
    35  // floating point or complex operations (integers, bools, and strings
    36  // only). We also try to be conservative about avoiding any operation
    37  // that might result in a panic at runtime, e.g. for "n" with type
    38  // int64:
    39  //
    40  //	1<<(n-9) < 100/(n<<9999)
    41  //
    42  // we would return FALSE due to the negative shift count and/or
    43  // potential divide by zero.
    44  func ShouldFoldIfNameConstant(n ir.Node, names []*ir.Name) bool