Skip to content

Commit

Permalink
Refactor to abstract User to support block parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
rj45 committed Dec 24, 2021
1 parent c94e2d3 commit c5bb564
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 192 deletions.
9 changes: 8 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@
- [x] Add A32 to test suite to make sure it doesn't break

- [ ] Rework IR (ir2)

- [x] Split globals into Literals (strings) and Globals (bss data)
- [x] Split values into Values and Instructions
- [x] Instructions can return multiple values
Expand All @@ -183,6 +182,14 @@
- [x] Handle translating tuples to multiple return values
- [x] Can emit IR code in a way that simplifies text, assembly and html generation
- [x] Emits to ssa.html
- [ ] Block parameters instead of phis
- [x] Values can be used by both Blocks and Instrs
- [x] Blocks and Instrs are Users of Values
- [ ] Block parameters are emitted
- [ ] Block parameter defs are parsed
- [ ] Terminal instructions specify dest block arguments
- [ ] Frontend builds blocks with parameters
- [ ] Phis are eliminated
- [ ] Implement a simplified type system
- [ ] integer types i/u 8,16,32,64
- [ ] bool type
Expand Down
5 changes: 2 additions & 3 deletions ir2/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import (
"log"
)

func (blk *Block) init(fn *Func, id ID) {
blk.fn = fn
blk.ID = id
func (blk *Block) init(fn *Func, id ident) {
blk.User.init(fn, id)
blk.instrs = blk.instrstorage[:0]
blk.preds = blk.predstorage[:0]
blk.succs = blk.succstorage[:0]
Expand Down
18 changes: 7 additions & 11 deletions ir2/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (fn *Func) LongString() string {
}

func (blk *Block) String() string {
return fmt.Sprintf("b%d", blk.ID)
return blk.IDString()
}

func (blk *Block) Emit(out io.Writer, dec Decorator) {
Expand Down Expand Up @@ -277,29 +277,25 @@ func (in *Instr) LongString() string {
}

func (val *Value) String() string {
if val.ID == Placeholder {
if val.ident == Placeholder {
return "<" + val.Const().String() + ">"
}
if val.IsConst() {
return val.Const().String()
}
if val.InReg() {
return fmt.Sprintf("v%d_%s", val.ID, val.Reg())
return fmt.Sprintf("%s_%s", val.IDString(), val.Reg())
}
if val.InArgSlot() {
return fmt.Sprintf("v%d_sa%d", val.ID, val.ArgSlot())
return fmt.Sprintf("%s_sa%d", val.IDString(), val.ArgSlot())
}
if val.InParamSlot() {
return fmt.Sprintf("v%d_sp%d", val.ID, val.ParamSlot())
return fmt.Sprintf("%s_sp%d", val.IDString(), val.ParamSlot())
}
if val.InSpillSlot() {
return fmt.Sprintf("v%d_ss%d", val.ID, val.SpillSlot())
return fmt.Sprintf("%s_ss%d", val.IDString(), val.SpillSlot())
}
return fmt.Sprintf("v%d", val.ID)
}

func (val *Value) IDString() string {
return fmt.Sprintf("v%d", val.ID)
return val.IDString()
}

// SSAString emits a plain string in SSA form
Expand Down
22 changes: 11 additions & 11 deletions ir2/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func (fn *Func) Package() *Package {
}

// ValueForID returns the Value for the ID
func (fn *Func) ValueForID(v ID) *Value {
return fn.idValues[v]
func (fn *Func) ValueForID(v ident) *Value {
return fn.idValues[v&idMask]
}

// NewValue creates a new Value of type typ
Expand All @@ -32,7 +32,7 @@ func (fn *Func) NewValue(typ types.Type) *Value {
fn.valueslab = append(fn.valueslab, Value{})
val := &fn.valueslab[len(fn.valueslab)-1]

val.init(ID(len(fn.idValues)), typ)
val.init(idFor(ValueObject, len(fn.idValues)), typ)

fn.idValues = append(fn.idValues, val)

Expand Down Expand Up @@ -84,7 +84,7 @@ func (fn *Func) PlaceholderFor(label string) *Value {
}

ph = &Value{
ID: Placeholder,
ident: Placeholder,
}
ph.SetConst(ConstFor(label))

Expand Down Expand Up @@ -135,8 +135,8 @@ func (fn *Func) PlaceholderLabels() []string {
// Instrs

// InstrForID returns the Instr for the ID
func (fn *Func) InstrForID(i ID) *Instr {
return fn.idInstrs[i]
func (fn *Func) InstrForID(i ident) *Instr {
return fn.idInstrs[i&idMask]
}

// NewInstr creates an unbound Instr
Expand All @@ -149,11 +149,11 @@ func (fn *Func) NewInstr(op Op, typ types.Type, args ...interface{}) *Instr {
fn.instrslab = append(fn.instrslab, Instr{})
instr := &fn.instrslab[len(fn.instrslab)-1]

instr.init(ID(len(fn.idInstrs)))
instr.init(fn, idFor(InstrObject, len(fn.idInstrs)))

fn.idInstrs = append(fn.idInstrs, instr)

instr.update(fn, op, typ, args)
instr.update(op, typ, args)

return instr
}
Expand All @@ -171,8 +171,8 @@ func (fn *Func) Block(i int) *Block {
}

// BlockForID returns a Block by ID
func (fn *Func) BlockForID(b ID) *Block {
return fn.idBlocks[b]
func (fn *Func) BlockForID(b ident) *Block {
return fn.idBlocks[b&idMask]
}

// NewBlock adds a new block
Expand All @@ -185,7 +185,7 @@ func (fn *Func) NewBlock() *Block {
fn.blockslab = append(fn.blockslab, Block{})
blk := &fn.blockslab[len(fn.blockslab)-1]

blk.init(fn, ID(len(fn.idBlocks)))
blk.init(fn, idFor(BlockObject, len(fn.idBlocks)))

fn.idBlocks = append(fn.idBlocks, blk)

Expand Down
80 changes: 80 additions & 0 deletions ir2/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package ir2

import "fmt"

const kindShift = 24
const idMask = (1 << kindShift) - 1

// ObjectKind returns the kind of object the ID is for
func (id ident) ObjectKind() ObjectKind {
return ObjectKind(id >> kindShift)
}

// IDNum returns the ID number for the ID
func (id ident) IDNum() int {
return int(id & idMask)
}

// IDString returns the ID string
func (id ident) IDString() string {
prefix := ""
switch id.ObjectKind() {
case BlockObject:
prefix = "b"
case InstrObject:
prefix = "i"
case ValueObject:
prefix = "v"
}
return fmt.Sprintf("%s%d", prefix, id.IDNum())
}

// idFor returns a new ID for a given object kind
func idFor(kind ObjectKind, idNum int) ident {
return ident(kind)<<kindShift | (ident(idNum) & idMask)
}

// IsBlock returns if ID points to a Block
func (id ident) IsBlock() bool {
return id.ObjectKind() == BlockObject
}

// BlockIn returns the Block in the Func or nil
// if this ID is not for a Block
func (id ident) BlockIn(fn *Func) *Block {
if id.ObjectKind() != BlockObject {
return nil
}

return fn.idBlocks[id&idMask]
}

// IsInstr returns if ID points to a Instr
func (id ident) IsInstr() bool {
return id.ObjectKind() == InstrObject
}

// InstrIn returns the Instr in the Func or nil
// if this ID is not for a Instr
func (id ident) InstrIn(fn *Func) *Instr {
if id.ObjectKind() != InstrObject {
return nil
}

return fn.idInstrs[id&idMask]
}

// IsValue returns if ID points to a Value
func (id ident) IsValue() bool {
return id.ObjectKind() == ValueObject
}

// ValueIn returns the Value in the Func or nil
// if this ID is not for a Value
func (id ident) ValueIn(fn *Func) *Value {
if id.ObjectKind() != ValueObject {
return nil
}

return fn.idValues[id&idMask]
}
Loading

0 comments on commit c5bb564

Please sign in to comment.