github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/ssa/block.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/internal/src" 9 ) 10 11 // Block represents a basic block in the control flow graph of a function. 12 type Block struct { 13 // A unique identifier for the block. The system will attempt to allocate 14 // these IDs densely, but no guarantees. 15 ID ID 16 17 // Source position for block's control operation 18 Pos src.XPos 19 20 // The kind of block this is. 21 Kind BlockKind 22 23 // Likely direction for branches. 24 // If BranchLikely, Succs[0] is the most likely branch taken. 25 // If BranchUnlikely, Succs[1] is the most likely branch taken. 26 // Ignored if len(Succs) < 2. 27 // Fatal if not BranchUnknown and len(Succs) > 2. 28 Likely BranchPrediction 29 30 // After flagalloc, records whether flags are live at the end of the block. 31 FlagsLiveAtEnd bool 32 33 // Subsequent blocks, if any. The number and order depend on the block kind. 34 Succs []Edge 35 36 // Inverse of successors. 37 // The order is significant to Phi nodes in the block. 38 // TODO: predecessors is a pain to maintain. Can we somehow order phi 39 // arguments by block id and have this field computed explicitly when needed? 40 Preds []Edge 41 42 // A list of values that determine how the block is exited. The number 43 // and type of control values depends on the Kind of the block. For 44 // instance, a BlockIf has a single boolean control value and BlockExit 45 // has a single memory control value. 46 // 47 // The ControlValues() method may be used to get a slice with the non-nil 48 // control values that can be ranged over. 49 // 50 // Controls[1] must be nil if Controls[0] is nil. 51 Controls [2]*Value 52 53 // Auxiliary info for the block. Its value depends on the Kind. 54 Aux Aux 55 AuxInt int64 56 57 // The unordered set of Values that define the operation of this block. 58 // After the scheduling pass, this list is ordered. 59 Values []*Value 60 61 // The containing function 62 Func *Func 63 64 // Storage for Succs, Preds and Values. 65 succstorage [2]Edge 66 predstorage [4]Edge 67 valstorage [9]*Value 68 } 69 70 // Edge represents a CFG edge. 71 // Example edges for b branching to either c or d. 72 // (c and d have other predecessors.) 73 // 74 // b.Succs = [{c,3}, {d,1}] 75 // c.Preds = [?, ?, ?, {b,0}] 76 // d.Preds = [?, {b,1}, ?] 77 // 78 // These indexes allow us to edit the CFG in constant time. 79 // In addition, it informs phi ops in degenerate cases like: 80 // 81 // b: 82 // if k then c else c 83 // c: 84 // v = Phi(x, y) 85 // 86 // Then the indexes tell you whether x is chosen from 87 // the if or else branch from b. 88 // 89 // b.Succs = [{c,0},{c,1}] 90 // c.Preds = [{b,0},{b,1}] 91 // 92 // means x is chosen if k is true. 93 type Edge struct { 94 // block edge goes to (in a Succs list) or from (in a Preds list) 95 b *Block 96 // index of reverse edge. Invariant: 97 // e := x.Succs[idx] 98 // e.b.Preds[e.i] = Edge{x,idx} 99 // and similarly for predecessors. 100 i int 101 } 102 103 func (e Edge) Block() *Block 104 105 func (e Edge) Index() int 106 107 func (e Edge) String() string 108 109 // BlockKind is the kind of SSA block. 110 type BlockKind int16 111 112 // short form print 113 func (b *Block) String() string 114 115 // long form print 116 func (b *Block) LongString() string 117 118 // NumControls returns the number of non-nil control values the 119 // block has. 120 func (b *Block) NumControls() int 121 122 // ControlValues returns a slice containing the non-nil control 123 // values of the block. The index of each control value will be 124 // the same as it is in the Controls property and can be used 125 // in ReplaceControl calls. 126 func (b *Block) ControlValues() []*Value 127 128 // SetControl removes all existing control values and then adds 129 // the control value provided. The number of control values after 130 // a call to SetControl will always be 1. 131 func (b *Block) SetControl(v *Value) 132 133 // ResetControls sets the number of controls for the block to 0. 134 func (b *Block) ResetControls() 135 136 // AddControl appends a control value to the existing list of control values. 137 func (b *Block) AddControl(v *Value) 138 139 // ReplaceControl exchanges the existing control value at the index provided 140 // for the new value. The index must refer to a valid control value. 141 func (b *Block) ReplaceControl(i int, v *Value) 142 143 // CopyControls replaces the controls for this block with those from the 144 // provided block. The provided block is not modified. 145 func (b *Block) CopyControls(from *Block) 146 147 // Reset sets the block to the provided kind and clears all the blocks control 148 // and auxiliary values. Other properties of the block, such as its successors, 149 // predecessors and values are left unmodified. 150 func (b *Block) Reset(kind BlockKind) 151 152 // AddEdgeTo adds an edge from block b to block c. 153 func (b *Block) AddEdgeTo(c *Block) 154 155 // LackingPos indicates whether b is a block whose position should be inherited 156 // from its successors. This is true if all the values within it have unreliable positions 157 // and if it is "plain", meaning that there is no control flow that is also very likely 158 // to correspond to a well-understood source position. 159 func (b *Block) LackingPos() bool 160 161 func (b *Block) AuxIntString() string 162 163 func (b *Block) Logf(msg string, args ...interface{}) 164 func (b *Block) Log() bool 165 func (b *Block) Fatalf(msg string, args ...interface{}) 166 167 type BranchPrediction int8 168 169 const ( 170 BranchUnlikely = BranchPrediction(-1) 171 BranchUnknown = BranchPrediction(0) 172 BranchLikely = BranchPrediction(+1) 173 )