Skip to content

Commit

Permalink
ssa: stores types in higher 4-bits of Variable (#2284)
Browse files Browse the repository at this point in the history
Signed-off-by: Takeshi Yoneda <[email protected]>
  • Loading branch information
mathetake authored Jul 9, 2024
1 parent 6d8e131 commit 0194765
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 37 deletions.
40 changes: 5 additions & 35 deletions internal/engine/wazevo/ssa/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ type builder struct {
currentBB *basicBlock
returnBlk *basicBlock

// variables track the types for Variable with the index regarded Variable.
variables []Type
// nextValueID is used by builder.AllocateValue.
nextValueID ValueID
// nextVariable is used by builder.AllocateVariable.
Expand Down Expand Up @@ -411,13 +409,6 @@ func (b *builder) InsertInstruction(instr *Instruction) {

// DefineVariable implements Builder.DefineVariable.
func (b *builder) DefineVariable(variable Variable, value Value, block BasicBlock) {
if b.variables[variable].invalid() {
panic("BUG: trying to define variable " + variable.String() + " but is not declared yet")
}

if b.variables[variable] != value.Type() {
panic(fmt.Sprintf("BUG: inconsistent type for variable %d: expected %s but got %s", variable, b.variables[variable], value.Type()))
}
bb := block.(*basicBlock)
bb.lastDefinitions[variable] = value
}
Expand All @@ -444,20 +435,9 @@ func (b *builder) EntryBlock() BasicBlock {

// DeclareVariable implements Builder.DeclareVariable.
func (b *builder) DeclareVariable(typ Type) Variable {
v := b.allocateVariable()
iv := int(v)
if l := len(b.variables); l <= iv {
b.variables = append(b.variables, make([]Type, 2*(l+1))...)
}
b.variables[v] = typ
return v
}

// allocateVariable allocates a new variable.
func (b *builder) allocateVariable() (ret Variable) {
ret = b.nextVariable
v := b.nextVariable
b.nextVariable++
return
return v.setType(typ)
}

// allocateValue implements Builder.AllocateValue.
Expand Down Expand Up @@ -493,8 +473,7 @@ func (b *builder) findValueInLinearPath(variable Variable, blk *basicBlock) Valu

// MustFindValue implements Builder.MustFindValue.
func (b *builder) MustFindValue(variable Variable) Value {
typ := b.definedVariableType(variable)
return b.findValue(typ, variable, b.currentBB)
return b.findValue(variable.getType(), variable, b.currentBB)
}

// findValue recursively tries to find the latest definition of a `variable`. The algorithm is described in
Expand Down Expand Up @@ -522,7 +501,7 @@ func (b *builder) findValue(typ Type, variable Variable, blk *basicBlock) Value
return value
} else if blk.EntryBlock() {
// If this is the entry block, we reach the uninitialized variable which has zero value.
return b.zeros[b.definedVariableType(variable)]
return b.zeros[variable.getType()]
}

if pred := blk.singlePred; pred != nil {
Expand Down Expand Up @@ -583,7 +562,7 @@ func (b *builder) Seal(raw BasicBlock) {

for _, v := range blk.unknownValues {
variable, phiValue := v.variable, v.value
typ := b.definedVariableType(variable)
typ := variable.getType()
blk.addParamOn(b, phiValue)
for i := range blk.preds {
pred := &blk.preds[i]
Expand All @@ -596,15 +575,6 @@ func (b *builder) Seal(raw BasicBlock) {
}
}

// definedVariableType returns the type of the given variable. If the variable is not defined yet, it panics.
func (b *builder) definedVariableType(variable Variable) Type {
typ := b.variables[variable]
if typ.invalid() {
panic(fmt.Sprintf("%s is not defined yet", variable))
}
return typ
}

// Format implements Builder.Format.
func (b *builder) Format() string {
str := strings.Builder{}
Expand Down
17 changes: 15 additions & 2 deletions internal/engine/wazevo/ssa/vs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,24 @@ import (
//
// Variable is useful to track the SSA Values of a variable in the source program, and
// can be used to find the corresponding latest SSA Value via Builder.FindValue.
//
// Higher 4-bit is used to store Type for this variable.
type Variable uint32

// String implements fmt.Stringer.
func (v Variable) String() string {
return fmt.Sprintf("var%d", v)
return fmt.Sprintf("var%d", v&0x0fffffff)
}

func (v Variable) setType(typ Type) Variable {
if v >= 1<<28 {
panic(fmt.Sprintf("Too large variable: %d", v))
}
return Variable(typ)<<28 | v
}

func (v Variable) getType() Type {
return Type(v >> 28)
}

// Value represents an SSA value with a type information. The relationship with Variable is 1: N (including 0),
Expand All @@ -33,7 +46,7 @@ type ValueID uint32

const (
valueIDInvalid ValueID = math.MaxUint32
ValueInvalid Value = Value(valueIDInvalid)
ValueInvalid = Value(valueIDInvalid)
)

// Format creates a debug string for this Value using the data stored in Builder.
Expand Down

0 comments on commit 0194765

Please sign in to comment.