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

     1  // Copyright 2015 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 ssa
     6  
     7  import (
     8  	"github.com/shogo82148/std/cmd/compile/internal/abi"
     9  	"github.com/shogo82148/std/cmd/compile/internal/ir"
    10  	"github.com/shogo82148/std/cmd/compile/internal/types"
    11  	"github.com/shogo82148/std/cmd/internal/obj"
    12  	"github.com/shogo82148/std/cmd/internal/src"
    13  )
    14  
    15  // A Func represents a Go func declaration (or function literal) and its body.
    16  // This package compiles each Func independently.
    17  // Funcs are single-use; a new Func must be created for every compiled function.
    18  type Func struct {
    19  	Config *Config
    20  	Cache  *Cache
    21  	fe     Frontend
    22  	pass   *pass
    23  	Name   string
    24  	Type   *types.Type
    25  	Blocks []*Block
    26  	Entry  *Block
    27  
    28  	bid idAlloc
    29  	vid idAlloc
    30  
    31  	HTMLWriter     *HTMLWriter
    32  	PrintOrHtmlSSA bool
    33  	ruleMatches    map[string]int
    34  	ABI0           *abi.ABIConfig
    35  	ABI1           *abi.ABIConfig
    36  	ABISelf        *abi.ABIConfig
    37  	ABIDefault     *abi.ABIConfig
    38  
    39  	scheduled   bool
    40  	laidout     bool
    41  	NoSplit     bool
    42  	dumpFileSeq uint8
    43  
    44  	// when register allocation is done, maps value ids to locations
    45  	RegAlloc []Location
    46  
    47  	// temporary registers allocated to rare instructions
    48  	tempRegs map[ID]*Register
    49  
    50  	// map from LocalSlot to set of Values that we want to store in that slot.
    51  	NamedValues map[LocalSlot][]*Value
    52  	// Names is a copy of NamedValues.Keys. We keep a separate list
    53  	// of keys to make iteration order deterministic.
    54  	Names []*LocalSlot
    55  	// Canonicalize root/top-level local slots, and canonicalize their pieces.
    56  	// Because LocalSlot pieces refer to their parents with a pointer, this ensures that equivalent slots really are equal.
    57  	CanonicalLocalSlots  map[LocalSlot]*LocalSlot
    58  	CanonicalLocalSplits map[LocalSlotSplitKey]*LocalSlot
    59  
    60  	// RegArgs is a slice of register-memory pairs that must be spilled and unspilled in the uncommon path of function entry.
    61  	RegArgs []Spill
    62  	// OwnAux describes parameters and results for this function.
    63  	OwnAux *AuxCall
    64  
    65  	freeValues *Value
    66  	freeBlocks *Block
    67  
    68  	cachedPostorder  []*Block
    69  	cachedIdom       []*Block
    70  	cachedSdom       SparseTree
    71  	cachedLoopnest   *loopnest
    72  	cachedLineStarts *xposmap
    73  
    74  	auxmap    auxmap
    75  	constants map[int64][]*Value
    76  }
    77  
    78  type LocalSlotSplitKey struct {
    79  	parent *LocalSlot
    80  	Off    int64
    81  	Type   *types.Type
    82  }
    83  
    84  // NewFunc returns a new, empty function object.
    85  // Caller must reset cache before calling NewFunc.
    86  func (c *Config) NewFunc(fe Frontend, cache *Cache) *Func
    87  
    88  // NumBlocks returns an integer larger than the id of any Block in the Func.
    89  func (f *Func) NumBlocks() int
    90  
    91  // NumValues returns an integer larger than the id of any Value in the Func.
    92  func (f *Func) NumValues() int
    93  
    94  // NameABI returns the function name followed by comma and the ABI number.
    95  // This is intended for use with GOSSAFUNC and HTML dumps, and differs from
    96  // the linker's "<1>" convention because "<" and ">" require shell quoting
    97  // and are not legal file names (for use with GOSSADIR) on Windows.
    98  func (f *Func) NameABI() string
    99  
   100  // FuncNameABI returns n followed by a comma and the value of a.
   101  // This is a separate function to allow a single point encoding
   102  // of the format, which is used in places where there's not a Func yet.
   103  func FuncNameABI(n string, a obj.ABI) string
   104  
   105  func (f *Func) SplitString(name *LocalSlot) (*LocalSlot, *LocalSlot)
   106  
   107  func (f *Func) SplitInterface(name *LocalSlot) (*LocalSlot, *LocalSlot)
   108  
   109  func (f *Func) SplitSlice(name *LocalSlot) (*LocalSlot, *LocalSlot, *LocalSlot)
   110  
   111  func (f *Func) SplitComplex(name *LocalSlot) (*LocalSlot, *LocalSlot)
   112  
   113  func (f *Func) SplitInt64(name *LocalSlot) (*LocalSlot, *LocalSlot)
   114  
   115  func (f *Func) SplitStruct(name *LocalSlot, i int) *LocalSlot
   116  
   117  func (f *Func) SplitArray(name *LocalSlot) *LocalSlot
   118  
   119  func (f *Func) SplitSlot(name *LocalSlot, sfx string, offset int64, t *types.Type) *LocalSlot
   120  
   121  // LogStat writes a string key and int value as a warning in a
   122  // tab-separated format easily handled by spreadsheets or awk.
   123  // file names, lines, and function names are included to provide enough (?)
   124  // context to allow item-by-item comparisons across runs.
   125  // For example:
   126  // awk 'BEGIN {FS="\t"} $3~/TIME/{sum+=$4} END{print "t(ns)=",sum}' t.log
   127  func (f *Func) LogStat(key string, args ...interface{})
   128  
   129  // NewBlock allocates a new Block of the given kind and places it at the end of f.Blocks.
   130  func (f *Func) NewBlock(kind BlockKind) *Block
   131  
   132  // NewValue0 returns a new value in the block with no arguments and zero aux values.
   133  func (b *Block) NewValue0(pos src.XPos, op Op, t *types.Type) *Value
   134  
   135  // NewValue0I returns a new value in the block with no arguments and an auxint value.
   136  func (b *Block) NewValue0I(pos src.XPos, op Op, t *types.Type, auxint int64) *Value
   137  
   138  // NewValue0A returns a new value in the block with no arguments and an aux value.
   139  func (b *Block) NewValue0A(pos src.XPos, op Op, t *types.Type, aux Aux) *Value
   140  
   141  // NewValue0IA returns a new value in the block with no arguments and both an auxint and aux values.
   142  func (b *Block) NewValue0IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux) *Value
   143  
   144  // NewValue1 returns a new value in the block with one argument and zero aux values.
   145  func (b *Block) NewValue1(pos src.XPos, op Op, t *types.Type, arg *Value) *Value
   146  
   147  // NewValue1I returns a new value in the block with one argument and an auxint value.
   148  func (b *Block) NewValue1I(pos src.XPos, op Op, t *types.Type, auxint int64, arg *Value) *Value
   149  
   150  // NewValue1A returns a new value in the block with one argument and an aux value.
   151  func (b *Block) NewValue1A(pos src.XPos, op Op, t *types.Type, aux Aux, arg *Value) *Value
   152  
   153  // NewValue1IA returns a new value in the block with one argument and both an auxint and aux values.
   154  func (b *Block) NewValue1IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux, arg *Value) *Value
   155  
   156  // NewValue2 returns a new value in the block with two arguments and zero aux values.
   157  func (b *Block) NewValue2(pos src.XPos, op Op, t *types.Type, arg0, arg1 *Value) *Value
   158  
   159  // NewValue2A returns a new value in the block with two arguments and one aux values.
   160  func (b *Block) NewValue2A(pos src.XPos, op Op, t *types.Type, aux Aux, arg0, arg1 *Value) *Value
   161  
   162  // NewValue2I returns a new value in the block with two arguments and an auxint value.
   163  func (b *Block) NewValue2I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1 *Value) *Value
   164  
   165  // NewValue2IA returns a new value in the block with two arguments and both an auxint and aux values.
   166  func (b *Block) NewValue2IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux, arg0, arg1 *Value) *Value
   167  
   168  // NewValue3 returns a new value in the block with three arguments and zero aux values.
   169  func (b *Block) NewValue3(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2 *Value) *Value
   170  
   171  // NewValue3I returns a new value in the block with three arguments and an auxint value.
   172  func (b *Block) NewValue3I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2 *Value) *Value
   173  
   174  // NewValue3A returns a new value in the block with three argument and an aux value.
   175  func (b *Block) NewValue3A(pos src.XPos, op Op, t *types.Type, aux Aux, arg0, arg1, arg2 *Value) *Value
   176  
   177  // NewValue4 returns a new value in the block with four arguments and zero aux values.
   178  func (b *Block) NewValue4(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2, arg3 *Value) *Value
   179  
   180  // NewValue4I returns a new value in the block with four arguments and auxint value.
   181  func (b *Block) NewValue4I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2, arg3 *Value) *Value
   182  
   183  // ConstBool returns an int constant representing its argument.
   184  func (f *Func) ConstBool(t *types.Type, c bool) *Value
   185  
   186  func (f *Func) ConstInt8(t *types.Type, c int8) *Value
   187  
   188  func (f *Func) ConstInt16(t *types.Type, c int16) *Value
   189  
   190  func (f *Func) ConstInt32(t *types.Type, c int32) *Value
   191  
   192  func (f *Func) ConstInt64(t *types.Type, c int64) *Value
   193  
   194  func (f *Func) ConstFloat32(t *types.Type, c float64) *Value
   195  
   196  func (f *Func) ConstFloat64(t *types.Type, c float64) *Value
   197  
   198  func (f *Func) ConstSlice(t *types.Type) *Value
   199  
   200  func (f *Func) ConstInterface(t *types.Type) *Value
   201  
   202  func (f *Func) ConstNil(t *types.Type) *Value
   203  
   204  func (f *Func) ConstEmptyString(t *types.Type) *Value
   205  
   206  func (f *Func) ConstOffPtrSP(t *types.Type, c int64, sp *Value) *Value
   207  
   208  func (f *Func) Frontend() Frontend
   209  func (f *Func) Warnl(pos src.XPos, msg string, args ...interface{})
   210  func (f *Func) Logf(msg string, args ...interface{})
   211  func (f *Func) Log() bool
   212  
   213  func (f *Func) Fatalf(msg string, args ...interface{})
   214  
   215  func (f *Func) Postorder() []*Block
   216  
   217  // Idom returns a map from block ID to the immediate dominator of that block.
   218  // f.Entry.ID maps to nil. Unreachable blocks map to nil as well.
   219  func (f *Func) Idom() []*Block
   220  
   221  // Sdom returns a sparse tree representing the dominator relationships
   222  // among the blocks of f.
   223  func (f *Func) Sdom() SparseTree
   224  
   225  // DebugHashMatch returns
   226  //
   227  //	base.DebugHashMatch(this function's package.name)
   228  //
   229  // for use in bug isolation.  The return value is true unless
   230  // environment variable GOSSAHASH is set, in which case "it depends".
   231  // See [base.DebugHashMatch] for more information.
   232  func (f *Func) DebugHashMatch() bool
   233  
   234  // NewLocal returns a new anonymous local variable of the given type.
   235  func (f *Func) NewLocal(pos src.XPos, typ *types.Type) *ir.Name