diff --git a/internal/engine/wazevo/ssa/basic_block.go b/internal/engine/wazevo/ssa/basic_block.go index 39627b98..0e1bab02 100644 --- a/internal/engine/wazevo/ssa/basic_block.go +++ b/internal/engine/wazevo/ssa/basic_block.go @@ -81,7 +81,7 @@ type ( rootInstr, currentInstr *Instruction // params are Values that represent parameters to a basicBlock. // Each parameter can be considered as an output of PHI instruction in traditional SSA. - params []Value + params Values preds []basicBlockPredecessorInfo success []*basicBlock // singlePred is the alias to preds[0] for fast lookup, and only set after Seal is called. @@ -179,23 +179,23 @@ func (bb *basicBlock) ReturnBlock() bool { // AddParam implements BasicBlock.AddParam. func (bb *basicBlock) AddParam(b Builder, typ Type) Value { paramValue := b.allocateValue(typ) - bb.params = append(bb.params, paramValue) + bb.params = bb.params.Append(&b.(*builder).varLengthPool, paramValue) return paramValue } // addParamOn adds a parameter to this block whose value is already allocated. -func (bb *basicBlock) addParamOn(value Value) { - bb.params = append(bb.params, value) +func (bb *basicBlock) addParamOn(b *builder, value Value) { + bb.params = bb.params.Append(&b.varLengthPool, value) } // Params implements BasicBlock.Params. func (bb *basicBlock) Params() int { - return len(bb.params) + return len(bb.params.View()) } // Param implements BasicBlock.Param. func (bb *basicBlock) Param(i int) Value { - return bb.params[i] + return bb.params.View()[i] } // Valid implements BasicBlock.Valid. @@ -268,7 +268,7 @@ func (bb *basicBlock) Tail() *Instruction { // reset resets the basicBlock to its initial state so that it can be reused for another function. func resetBasicBlock(bb *basicBlock) { - bb.params = bb.params[:0] + bb.params = ValuesNil bb.rootInstr, bb.currentInstr = nil, nil bb.preds = bb.preds[:0] bb.success = bb.success[:0] @@ -310,8 +310,8 @@ func (bb *basicBlock) addPred(blk BasicBlock, branch *Instruction) { // formatHeader returns the string representation of the header of the basicBlock. func (bb *basicBlock) formatHeader(b Builder) string { - ps := make([]string, len(bb.params)) - for i, p := range bb.params { + ps := make([]string, len(bb.params.View())) + for i, p := range bb.params.View() { ps[i] = p.formatWithType(b) } @@ -349,14 +349,14 @@ func (bb *basicBlock) validate(b *builder) { if bb.ReturnBlock() { exp = len(b.currentSignature.Results) } else { - exp = len(bb.params) + exp = len(bb.params.View()) } if len(pred.branch.vs.View()) != exp { panic(fmt.Sprintf( "BUG: len(argument at %s) != len(params at %s): %d != %d: %s", pred.blk.Name(), bb.Name(), - len(pred.branch.vs.View()), len(bb.params), pred.branch.Format(b), + len(pred.branch.vs.View()), len(bb.params.View()), pred.branch.Format(b), )) } diff --git a/internal/engine/wazevo/ssa/builder.go b/internal/engine/wazevo/ssa/builder.go index 0b700c4b..4fe456d1 100644 --- a/internal/engine/wazevo/ssa/builder.go +++ b/internal/engine/wazevo/ssa/builder.go @@ -543,7 +543,7 @@ func (b *builder) findValue(typ Type, variable Variable, blk *basicBlock) Value // Otherwise, add the tmpValue to this block as a parameter which may or may not be redundant, but // later we eliminate trivial params in an optimization pass. This must be done before finding the // definitions in the predecessors so that we can break the cycle. - blk.addParamOn(tmpValue) + blk.addParamOn(b, tmpValue) // After the new param is added, we have to manipulate the original branching instructions // in predecessors so that they would pass the definition of `variable` as the argument to // the newly added PHI. @@ -567,7 +567,7 @@ func (b *builder) Seal(raw BasicBlock) { for _, v := range blk.unknownValues { variable, phiValue := v.variable, v.value typ := b.definedVariableType(variable) - blk.addParamOn(phiValue) + blk.addParamOn(b, phiValue) for i := range blk.preds { pred := &blk.preds[i] predValue := b.findValue(typ, variable, pred.blk) diff --git a/internal/engine/wazevo/ssa/pass.go b/internal/engine/wazevo/ssa/pass.go index 89ec34b7..50e6f464 100644 --- a/internal/engine/wazevo/ssa/pass.go +++ b/internal/engine/wazevo/ssa/pass.go @@ -128,10 +128,11 @@ func passRedundantPhiEliminationOpt(b *builder) { _ = b.blockIteratorReversePostOrderBegin() // skip entry block! // Below, we intentionally use the named iteration variable name, as this comes with inevitable nested for loops! for blk := b.blockIteratorReversePostOrderNext(); blk != nil; blk = b.blockIteratorReversePostOrderNext() { - paramNum := len(blk.params) + params := blk.params.View() + paramNum := len(params) for paramIndex := 0; paramIndex < paramNum; paramIndex++ { - phiValue := blk.params[paramIndex] + phiValue := params[paramIndex] redundant := true nonSelfReferencingValue := ValueInvalid @@ -189,7 +190,7 @@ func passRedundantPhiEliminationOpt(b *builder) { // Still need to have the definition of the value of the PHI (previously as the parameter). for _, redundantParamIndex := range redundantParameterIndexes { - phiValue := blk.params[redundantParamIndex] + phiValue := params[redundantParamIndex] onlyValue := b.redundantParameterIndexToValue[redundantParamIndex] // Create an alias in this block from the only phi argument to the phi value. b.alias(phiValue, onlyValue) @@ -198,13 +199,13 @@ func passRedundantPhiEliminationOpt(b *builder) { // Finally, Remove the param from the blk. var cur int for paramIndex := 0; paramIndex < paramNum; paramIndex++ { - param := blk.params[paramIndex] + param := params[paramIndex] if _, ok := b.redundantParameterIndexToValue[paramIndex]; !ok { - blk.params[cur] = param + params[cur] = param cur++ } } - blk.params = blk.params[:cur] + blk.params.Cut(cur) // Clears the map for the next iteration. for _, paramIndex := range redundantParameterIndexes { diff --git a/internal/engine/wazevo/ssa/pass_blk_layouts.go b/internal/engine/wazevo/ssa/pass_blk_layouts.go index 584b5ead..c7e14fb4 100644 --- a/internal/engine/wazevo/ssa/pass_blk_layouts.go +++ b/internal/engine/wazevo/ssa/pass_blk_layouts.go @@ -303,7 +303,7 @@ func (b *builder) splitCriticalEdge(pred, succ *basicBlock, predInfo *basicBlock trampoline.validate(b) } - if len(trampoline.params) > 0 { + if len(trampoline.params.View()) > 0 { panic("trampoline should not have params") }