github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/ssa/sparsetree.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  type SparseTreeNode struct {
     8  	child   *Block
     9  	sibling *Block
    10  	parent  *Block
    11  
    12  	// Every block has 6 numbers associated with it:
    13  	// entry-1, entry, entry+1, exit-1, and exit, exit+1.
    14  	// entry and exit are conceptually the top of the block (phi functions)
    15  	// entry+1 and exit-1 are conceptually the bottom of the block (ordinary defs)
    16  	// entry-1 and exit+1 are conceptually "just before" the block (conditions flowing in)
    17  	//
    18  	// This simplifies life if we wish to query information about x
    19  	// when x is both an input to and output of a block.
    20  	entry, exit int32
    21  }
    22  
    23  func (s *SparseTreeNode) String() string
    24  
    25  func (s *SparseTreeNode) Entry() int32
    26  
    27  func (s *SparseTreeNode) Exit() int32
    28  
    29  const (
    30  	// When used to lookup up definitions in a sparse tree,
    31  	// these adjustments to a block's entry (+adjust) and
    32  	// exit (-adjust) numbers allow a distinction to be made
    33  	// between assignments (typically branch-dependent
    34  	// conditionals) occurring "before" the block (e.g., as inputs
    35  	// to the block and its phi functions), "within" the block,
    36  	// and "after" the block.
    37  	AdjustBefore = -1
    38  	AdjustWithin = 0
    39  	AdjustAfter  = 1
    40  )
    41  
    42  // A SparseTree is a tree of Blocks.
    43  // It allows rapid ancestor queries,
    44  // such as whether one block dominates another.
    45  type SparseTree []SparseTreeNode
    46  
    47  // Sibling returns a sibling of x in the dominator tree (i.e.,
    48  // a node with the same immediate dominator) or nil if there
    49  // are no remaining siblings in the arbitrary but repeatable
    50  // order chosen. Because the Child-Sibling order is used
    51  // to assign entry and exit numbers in the treewalk, those
    52  // numbers are also consistent with this order (i.e.,
    53  // Sibling(x) has entry number larger than x's exit number).
    54  func (t SparseTree) Sibling(x *Block) *Block
    55  
    56  // Child returns a child of x in the dominator tree, or
    57  // nil if there are none. The choice of first child is
    58  // arbitrary but repeatable.
    59  func (t SparseTree) Child(x *Block) *Block
    60  
    61  // Parent returns the parent of x in the dominator tree, or
    62  // nil if x is the function's entry.
    63  func (t SparseTree) Parent(x *Block) *Block
    64  
    65  // IsAncestorEq reports whether x is an ancestor of or equal to y.
    66  func (t SparseTree) IsAncestorEq(x, y *Block) bool