summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go105
1 files changed, 44 insertions, 61 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go
index 89ec34b7e..b9763791d 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/pass.go
@@ -112,7 +112,7 @@ func passDeadBlockEliminationOpt(b *builder) {
// This requires the reverse post-order traversal to be calculated before calling this function,
// hence passCalculateImmediateDominators must be called before this.
func passRedundantPhiEliminationOpt(b *builder) {
- redundantParameterIndexes := b.ints[:0] // reuse the slice from previous iterations.
+ redundantParams := b.redundantParams[:0] // reuse the slice from previous iterations.
// TODO: this might be costly for large programs, but at least, as far as I did the experiment, it's almost the
// same as the single iteration version in terms of the overall compilation time. That *might be* mostly thanks to the fact
@@ -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
@@ -162,55 +163,58 @@ func passRedundantPhiEliminationOpt(b *builder) {
}
if redundant {
- b.redundantParameterIndexToValue[paramIndex] = nonSelfReferencingValue
- redundantParameterIndexes = append(redundantParameterIndexes, paramIndex)
+ redundantParams = append(redundantParams, redundantParam{
+ index: paramIndex, uniqueValue: nonSelfReferencingValue,
+ })
}
}
- if len(b.redundantParameterIndexToValue) == 0 {
+ if len(redundantParams) == 0 {
continue
}
changed = true
// Remove the redundant PHIs from the argument list of branching instructions.
for predIndex := range blk.preds {
- var cur int
+ redundantParamsCur, predParamCur := 0, 0
predBlk := blk.preds[predIndex]
branchInst := predBlk.branch
view := branchInst.vs.View()
for argIndex, value := range view {
- if _, ok := b.redundantParameterIndexToValue[argIndex]; !ok {
- view[cur] = value
- cur++
+ if len(redundantParams) == redundantParamsCur ||
+ redundantParams[redundantParamsCur].index != argIndex {
+ view[predParamCur] = value
+ predParamCur++
+ } else {
+ redundantParamsCur++
}
}
- branchInst.vs.Cut(cur)
+ branchInst.vs.Cut(predParamCur)
}
// Still need to have the definition of the value of the PHI (previously as the parameter).
- for _, redundantParamIndex := range redundantParameterIndexes {
- phiValue := blk.params[redundantParamIndex]
- onlyValue := b.redundantParameterIndexToValue[redundantParamIndex]
+ for i := range redundantParams {
+ redundantValue := &redundantParams[i]
+ phiValue := params[redundantValue.index]
// Create an alias in this block from the only phi argument to the phi value.
- b.alias(phiValue, onlyValue)
+ b.alias(phiValue, redundantValue.uniqueValue)
}
// Finally, Remove the param from the blk.
- var cur int
+ paramsCur, redundantParamsCur := 0, 0
for paramIndex := 0; paramIndex < paramNum; paramIndex++ {
- param := blk.params[paramIndex]
- if _, ok := b.redundantParameterIndexToValue[paramIndex]; !ok {
- blk.params[cur] = param
- cur++
+ param := params[paramIndex]
+ if len(redundantParams) == redundantParamsCur || redundantParams[redundantParamsCur].index != paramIndex {
+ params[paramsCur] = param
+ paramsCur++
+ } else {
+ redundantParamsCur++
}
}
- blk.params = blk.params[:cur]
+ blk.params.Cut(paramsCur)
// Clears the map for the next iteration.
- for _, paramIndex := range redundantParameterIndexes {
- delete(b.redundantParameterIndexToValue, paramIndex)
- }
- redundantParameterIndexes = redundantParameterIndexes[:0]
+ redundantParams = redundantParams[:0]
}
if !changed {
@@ -219,7 +223,7 @@ func passRedundantPhiEliminationOpt(b *builder) {
}
// Reuse the slice for the future passes.
- b.ints = redundantParameterIndexes
+ b.redundantParams = redundantParams
}
// passDeadCodeEliminationOpt traverses all the instructions, and calculates the reference count of each Value, and
@@ -231,11 +235,13 @@ func passRedundantPhiEliminationOpt(b *builder) {
// TODO: the algorithm here might not be efficient. Get back to this later.
func passDeadCodeEliminationOpt(b *builder) {
nvid := int(b.nextValueID)
- if nvid >= len(b.valueRefCounts) {
- b.valueRefCounts = append(b.valueRefCounts, make([]int, nvid-len(b.valueRefCounts)+1)...)
- }
- if nvid >= len(b.valueIDToInstruction) {
- b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, nvid-len(b.valueIDToInstruction)+1)...)
+ if nvid >= len(b.valuesInfo) {
+ l := nvid - len(b.valuesInfo) + 1
+ b.valuesInfo = append(b.valuesInfo, make([]ValueInfo, l)...)
+ view := b.valuesInfo[len(b.valuesInfo)-l:]
+ for i := range view {
+ view[i].alias = ValueInvalid
+ }
}
// First, we gather all the instructions with side effects.
@@ -255,14 +261,6 @@ func passDeadCodeEliminationOpt(b *builder) {
// The strict side effect should create different instruction groups.
gid++
}
-
- r1, rs := cur.Returns()
- if r1.Valid() {
- b.valueIDToInstruction[r1.ID()] = cur
- }
- for _, r := range rs {
- b.valueIDToInstruction[r.ID()] = cur
- }
}
}
@@ -283,28 +281,28 @@ func passDeadCodeEliminationOpt(b *builder) {
v1, v2, v3, vs := live.Args()
if v1.Valid() {
- producingInst := b.valueIDToInstruction[v1.ID()]
+ producingInst := b.InstructionOfValue(v1)
if producingInst != nil {
liveInstructions = append(liveInstructions, producingInst)
}
}
if v2.Valid() {
- producingInst := b.valueIDToInstruction[v2.ID()]
+ producingInst := b.InstructionOfValue(v2)
if producingInst != nil {
liveInstructions = append(liveInstructions, producingInst)
}
}
if v3.Valid() {
- producingInst := b.valueIDToInstruction[v3.ID()]
+ producingInst := b.InstructionOfValue(v3)
if producingInst != nil {
liveInstructions = append(liveInstructions, producingInst)
}
}
for _, v := range vs {
- producingInst := b.valueIDToInstruction[v.ID()]
+ producingInst := b.InstructionOfValue(v)
if producingInst != nil {
liveInstructions = append(liveInstructions, producingInst)
}
@@ -352,34 +350,19 @@ func (b *builder) incRefCount(id ValueID, from *Instruction) {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("v%d referenced from %v\n", id, from.Format(b))
}
- b.valueRefCounts[id]++
+ info := &b.valuesInfo[id]
+ info.RefCount++
}
// passNopInstElimination eliminates the instructions which is essentially a no-op.
func passNopInstElimination(b *builder) {
- if int(b.nextValueID) >= len(b.valueIDToInstruction) {
- b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, int(b.nextValueID)-len(b.valueIDToInstruction)+1)...)
- }
-
- for blk := b.blockIteratorBegin(); blk != nil; blk = b.blockIteratorNext() {
- for cur := blk.rootInstr; cur != nil; cur = cur.next {
- r1, rs := cur.Returns()
- if r1.Valid() {
- b.valueIDToInstruction[r1.ID()] = cur
- }
- for _, r := range rs {
- b.valueIDToInstruction[r.ID()] = cur
- }
- }
- }
-
for blk := b.blockIteratorBegin(); blk != nil; blk = b.blockIteratorNext() {
for cur := blk.rootInstr; cur != nil; cur = cur.next {
switch cur.Opcode() {
// TODO: add more logics here.
case OpcodeIshl, OpcodeSshr, OpcodeUshr:
x, amount := cur.Arg2()
- definingInst := b.valueIDToInstruction[amount.ID()]
+ definingInst := b.InstructionOfValue(amount)
if definingInst == nil {
// If there's no defining instruction, that means the amount is coming from the parameter.
continue