79 lines
No EOL
1.6 KiB
Go
79 lines
No EOL
1.6 KiB
Go
package ssa
|
|
|
|
// IR is a list of basic blocks.
|
|
type IR struct {
|
|
Blocks []*Block
|
|
}
|
|
|
|
// AddBlock adds a new block to the function.
|
|
func (f *IR) AddBlock() *Block {
|
|
block := &Block{
|
|
Instructions: make([]Value, 0, 8),
|
|
}
|
|
|
|
f.Blocks = append(f.Blocks, block)
|
|
return block
|
|
}
|
|
|
|
// Append adds a new value to the last block.
|
|
func (f *IR) Append(instr Value) Value {
|
|
if len(f.Blocks) == 0 {
|
|
f.AddBlock()
|
|
}
|
|
|
|
if instr.IsConst() {
|
|
for existing := range f.Values {
|
|
if existing.IsConst() && instr.Equals(existing) {
|
|
return existing
|
|
}
|
|
}
|
|
}
|
|
|
|
return f.Blocks[len(f.Blocks)-1].Append(instr)
|
|
}
|
|
|
|
// AppendInt adds a new integer value to the last block.
|
|
func (f *IR) AppendInt(x int) *Int {
|
|
v := &Int{Int: x}
|
|
f.Append(v)
|
|
return v
|
|
}
|
|
|
|
// AppendRegister adds a new register value to the last block.
|
|
func (f *IR) AppendRegister(index int) *Parameter {
|
|
v := &Parameter{Index: uint8(index)}
|
|
f.Append(v)
|
|
return v
|
|
}
|
|
|
|
// AppendFunction adds a new function value to the last block.
|
|
func (f *IR) AppendFunction(name string) *Function {
|
|
v := &Function{UniqueName: name}
|
|
f.Append(v)
|
|
return v
|
|
}
|
|
|
|
// AppendBytes adds a new byte slice value to the last block.
|
|
func (f *IR) AppendBytes(s []byte) *Bytes {
|
|
v := &Bytes{Bytes: s}
|
|
f.Append(v)
|
|
return v
|
|
}
|
|
|
|
// AppendString adds a new string value to the last block.
|
|
func (f *IR) AppendString(s string) *Bytes {
|
|
v := &Bytes{Bytes: []byte(s)}
|
|
f.Append(v)
|
|
return v
|
|
}
|
|
|
|
// Values yields on each value.
|
|
func (f *IR) Values(yield func(Value) bool) {
|
|
for _, block := range f.Blocks {
|
|
for _, instr := range block.Instructions {
|
|
if !yield(instr) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
} |