GoPLS Viewer

Home|gopls/go/ssa/block.go
1// Copyright 2022 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
5package ssa
6
7import "fmt"
8
9// This file implements the BasicBlock type.
10
11// addEdge adds a control-flow graph edge from from to to.
12func addEdge(fromto *BasicBlock) {
13    from.Succs = append(from.Succsto)
14    to.Preds = append(to.Predsfrom)
15}
16
17// Parent returns the function that contains block b.
18func (b *BasicBlockParent() *Function { return b.parent }
19
20// String returns a human-readable label of this block.
21// It is not guaranteed unique within the function.
22func (b *BasicBlockString() string {
23    return fmt.Sprintf("%d"b.Index)
24}
25
26// emit appends an instruction to the current basic block.
27// If the instruction defines a Value, it is returned.
28func (b *BasicBlockemit(i InstructionValue {
29    i.setBlock(b)
30    b.Instrs = append(b.Instrsi)
31    v_ := i.(Value)
32    return v
33}
34
35// predIndex returns the i such that b.Preds[i] == c or panics if
36// there is none.
37func (b *BasicBlockpredIndex(c *BasicBlockint {
38    for ipred := range b.Preds {
39        if pred == c {
40            return i
41        }
42    }
43    panic(fmt.Sprintf("no edge %s -> %s"cb))
44}
45
46// hasPhi returns true if b.Instrs contains φ-nodes.
47func (b *BasicBlockhasPhi() bool {
48    _ok := b.Instrs[0].(*Phi)
49    return ok
50}
51
52// phis returns the prefix of b.Instrs containing all the block's φ-nodes.
53func (b *BasicBlockphis() []Instruction {
54    for iinstr := range b.Instrs {
55        if _ok := instr.(*Phi); !ok {
56            return b.Instrs[:i]
57        }
58    }
59    return nil // unreachable in well-formed blocks
60}
61
62// replacePred replaces all occurrences of p in b's predecessor list with q.
63// Ordinarily there should be at most one.
64func (b *BasicBlockreplacePred(pq *BasicBlock) {
65    for ipred := range b.Preds {
66        if pred == p {
67            b.Preds[i] = q
68        }
69    }
70}
71
72// replaceSucc replaces all occurrences of p in b's successor list with q.
73// Ordinarily there should be at most one.
74func (b *BasicBlockreplaceSucc(pq *BasicBlock) {
75    for isucc := range b.Succs {
76        if succ == p {
77            b.Succs[i] = q
78        }
79    }
80}
81
82// removePred removes all occurrences of p in b's
83// predecessor list and φ-nodes.
84// Ordinarily there should be at most one.
85func (b *BasicBlockremovePred(p *BasicBlock) {
86    phis := b.phis()
87
88    // We must preserve edge order for φ-nodes.
89    j := 0
90    for ipred := range b.Preds {
91        if pred != p {
92            b.Preds[j] = b.Preds[i]
93            // Strike out φ-edge too.
94            for _instr := range phis {
95                phi := instr.(*Phi)
96                phi.Edges[j] = phi.Edges[i]
97            }
98            j++
99        }
100    }
101    // Nil out b.Preds[j:] and φ-edges[j:] to aid GC.
102    for i := ji < len(b.Preds); i++ {
103        b.Preds[i] = nil
104        for _instr := range phis {
105            instr.(*Phi).Edges[i] = nil
106        }
107    }
108    b.Preds = b.Preds[:j]
109    for _instr := range phis {
110        phi := instr.(*Phi)
111        phi.Edges = phi.Edges[:j]
112    }
113}
114
MembersX
BasicBlock.emit.b
BasicBlock.predIndex.b
BasicBlock.removePred.BlockStmt.RangeStmt_2674.instr
addEdge.from
BasicBlock.String.b
BasicBlock.phis.RangeStmt_1455.instr
BasicBlock.replacePred.RangeStmt_1778.i
BasicBlock.replaceSucc
BasicBlock.replacePred.p
BasicBlock.replaceSucc.q
BasicBlock.replaceSucc.RangeStmt_2026.succ
addEdge.to
BasicBlock.emit.i
BasicBlock.predIndex.RangeStmt_1084.pred
BasicBlock.hasPhi
BasicBlock.phis.b
BasicBlock.removePred.RangeStmt_2352.BlockStmt.BlockStmt.RangeStmt_2460.instr
BasicBlock.removePred.i
BasicBlock.hasPhi.b
BasicBlock.replacePred
BasicBlock.replacePred.q
BasicBlock.removePred
BasicBlock.removePred.phis
BasicBlock.replaceSucc.b
BasicBlock.replaceSucc.RangeStmt_2026.i
fmt
BasicBlock.Parent
BasicBlock.predIndex.c
BasicBlock.phis.RangeStmt_1455.i
BasicBlock.replacePred.b
BasicBlock.removePred.p
BasicBlock.removePred.RangeStmt_2352.i
BasicBlock.removePred.RangeStmt_2765.instr
BasicBlock.String
BasicBlock.emit
BasicBlock.predIndex
BasicBlock.phis
BasicBlock.replaceSucc.p
addEdge
BasicBlock.predIndex.RangeStmt_1084.i
BasicBlock.removePred.j
BasicBlock.Parent.b
BasicBlock.replacePred.RangeStmt_1778.pred
BasicBlock.removePred.b
BasicBlock.removePred.RangeStmt_2352.pred
Members
X