wazevo: removes unused SSA insts, centralizes debug toggles (#1671)

Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
Takeshi Yoneda
2023-08-30 08:16:51 +09:00
committed by GitHub
parent b6ace485b6
commit c592c8e5c1
12 changed files with 110 additions and 214 deletions

View File

@@ -5,6 +5,7 @@ import (
"github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
// NewCompiler returns a new Compiler that can generate a machine code.
@@ -143,15 +144,15 @@ type compiler struct {
// Compile implements Compiler.Compile.
func (c *compiler) Compile() ([]byte, []RelocationInfo, int, error) {
c.Lower()
if false {
if wazevoapi.PrintSSAToBackendIRLowering {
fmt.Printf("[[[after lowering]]]%s\n", c.Format())
}
c.RegAlloc()
if false {
if wazevoapi.PrintRegisterAllocated {
fmt.Printf("[[[after regalloc]]]%s\n", c.Format())
}
c.Finalize()
if false {
if wazevoapi.PrintFinalizedMachineCode {
fmt.Printf("[[[after finalize]]]%s\n", c.Format())
}
goPreambleSize := c.Encode()

View File

@@ -1,8 +1,6 @@
package backend
import (
"fmt"
"github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
)
@@ -16,15 +14,10 @@ func (c *compiler) Lower() {
c.mach.EndLoweringFunction()
}
const debug = false
// lowerBlocks lowers each block in the ssa.Builder.
func (c *compiler) lowerBlocks() {
builder := c.ssaBuilder
for blk := builder.BlockIteratorReversePostOrderBegin(); blk != nil; blk = builder.BlockIteratorReversePostOrderNext() {
if debug {
fmt.Printf("lowering block %s\n", blk.Name())
}
c.lowerBlock(blk)
}
// After lowering all blocks, we need to link adjacent blocks to layout one single instruction list.
@@ -71,10 +64,6 @@ func (c *compiler) lowerBlock(blk ssa.BasicBlock) {
continue
}
if debug {
fmt.Printf("\tlowering instr %s\n", cur.Format(c.ssaBuilder))
}
switch cur.Opcode() {
case ssa.OpcodeReturn:
c.lowerFunctionReturns(cur.ReturnVals())

View File

@@ -3,6 +3,8 @@ package regalloc
import (
"fmt"
"sort"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
// assignRegisters assigns real registers to virtual registers on each instruction.
@@ -20,7 +22,7 @@ func (a *Allocator) assignRegisters(f Function) {
// assignRegistersPerBlock assigns real registers to virtual registers on each instruction in a block.
func (a *Allocator) assignRegistersPerBlock(f Function, blk Block, vRegIDToNode []*node, liveNodes []liveNodeInBlock) {
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Println("---------------------- assigning registers for block", blk.ID(), "----------------------")
}
@@ -59,7 +61,7 @@ func (a *Allocator) assignRegistersPerInstr(f Function, pc programCounter, instr
a.vs = append(a.vs, u)
continue
}
if false {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("%s uses %d\n", instr, u.ID())
}
n := vRegIDToNode[u.ID()]
@@ -90,7 +92,7 @@ func (a *Allocator) assignRegistersPerInstr(f Function, pc programCounter, instr
if d.IsRealReg() {
return
}
if false {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("%s defines %d\n", instr, d.ID())
}

View File

@@ -3,6 +3,8 @@ package regalloc
import (
"fmt"
"sort"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
// buildNeighbors builds the neighbors for each node in the interference graph.
@@ -87,7 +89,7 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
return currentDegrees[degreeSortedNodes[i]] < currentDegrees[degreeSortedNodes[j]]
})
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Println("-------------------------------")
fmt.Printf("coloringStack: ")
for _, c := range coloringStack {
@@ -122,7 +124,7 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
degreeSortedNodes[0], degreeSortedNodes[tail] = degreeSortedNodes[tail], degreeSortedNodes[0]
popNum++
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("Forcibly pop one node %s as a spill target\n", degreeSortedNodes[0].v)
}
}
@@ -139,7 +141,7 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
}
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
if len(coloringStack) == total {
fmt.Println("-------------------------------")
fmt.Printf("coloringStack: ")
@@ -159,10 +161,13 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
}
}
if debug {
if wazevoapi.RegAllocValidationEnabled {
if len(degreeSortedNodes) != 0 {
panic("BUG")
}
}
if wazevoapi.RegAllocLoggingEnabled {
fmt.Println("-------------------------------")
}
@@ -177,7 +182,7 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
continue
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("coloring %s\n", n)
}
@@ -189,13 +194,13 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
}
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("\tneighborColors: %v\n", neighborColors)
}
a.assignColor(n, neighborColorsSet, allocatable)
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("\tassigned color: %s\n", n.r)
}
@@ -206,7 +211,7 @@ func (a *Allocator) coloringFor(allocatable []RealReg) {
neighborColors = neighborColors[:0]
}
if debug {
if wazevoapi.RegAllocValidationEnabled {
for _, n := range coloringStack {
if n.r == RealRegInvalid {
continue

View File

@@ -17,8 +17,6 @@ import (
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
const debug = false
// NewAllocator returns a new Allocator.
func NewAllocator(allocatableRegs *RegisterInfo) Allocator {
a := Allocator{
@@ -204,7 +202,7 @@ func (a *Allocator) livenessAnalysis(f Function) {
pc += pcStride
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("constructed block info for block[%d]:\n%s\n\n", blkID, info)
}
}
@@ -241,7 +239,7 @@ func (a *Allocator) livenessAnalysis(f Function) {
}
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("\nfinalized info for block[%d]:\n%s\n", blk.ID(), info)
}
}
@@ -252,7 +250,7 @@ func (a *Allocator) livenessAnalysis(f Function) {
//
// We recursively call this, so passing `depth` for debugging.
func (a *Allocator) upAndMarkStack(b Block, v VReg, depth int) {
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("%supAndMarkStack for %v at %v\n", strings.Repeat("\t", depth), v, b.ID())
}
@@ -264,7 +262,7 @@ func (a *Allocator) upAndMarkStack(b Block, v VReg, depth int) {
if _, ok := info.liveIns[v]; ok {
return // But this case, it is already visited. (maybe by, for example, sibling blocks).
}
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("%sadding %v live-in at block[%d]\n", strings.Repeat("\t", depth), v, b.ID())
}
@@ -277,7 +275,7 @@ func (a *Allocator) upAndMarkStack(b Block, v VReg, depth int) {
// and climb up the CFG.
for _, pred := range preds {
if debug {
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("%sadding %v live-out at block[%d]\n", strings.Repeat("\t", depth+1), v, pred.ID())
}
a.blockInfoAt(pred.ID()).liveOuts[v] = struct{}{}
@@ -369,7 +367,7 @@ func (a *Allocator) buildLiveRangesForNonReals(blkID int, info *blockInfo) {
// Reuse for the next block.
a.vs = vs[:0]
if debug {
if wazevoapi.RegAllocValidationEnabled {
for u := range kills {
if !u.IsRealReg() {
_, defined := defs[u]

View File

@@ -5,7 +5,6 @@ import (
"encoding/hex"
"fmt"
"runtime"
"strings"
"sync"
"github.com/tetratelabs/wazero/api"
@@ -110,12 +109,6 @@ func (e *engine) CompileModule(_ context.Context, module *wasm.Module, _ []exper
fidx := wasm.Index(i + importedFns)
fref := frontend.FunctionIndexToFuncRef(fidx)
const debug = false
if debug {
name := exportedFnIndex[fidx]
fmt.Printf("%[1]s %d/%d %s %[1]s\n", strings.Repeat("-", 30), i, len(module.CodeSection)-1, name)
}
_, needGoEntryPreamble := exportedFnIndex[fidx]
if sf := module.StartSection; sf != nil && *sf == fidx {
needGoEntryPreamble = true
@@ -166,22 +159,22 @@ func (e *engine) CompileModule(_ context.Context, module *wasm.Module, _ []exper
return fmt.Errorf("wasm->ssa: %v", err)
}
if debug {
fmt.Printf("[[[SSA]]]%s\n", ssaBuilder.Format())
if wazevoapi.PrintSSA {
fmt.Printf("[[[SSA for %d/%d %s]]]%s\n", i, len(module.CodeSection)-1, exportedFnIndex[fidx], ssaBuilder.Format())
}
// Run SSA-level optimization passes.
ssaBuilder.RunPasses()
if debug {
fmt.Printf("[[[optimized SSA]]]%s\n", ssaBuilder.Format())
if wazevoapi.PrintOptimizedSSA {
fmt.Printf("[[[optimized SSA for %d/%d %s]]]%s\n", i, len(module.CodeSection)-1, exportedFnIndex[fidx], ssaBuilder.Format())
}
// Finalize the layout of SSA blocks which might use the optimization results.
ssaBuilder.LayoutBlocks()
if debug {
fmt.Printf("[[[laidout SSA]]]%s\n", ssaBuilder.Format())
if wazevoapi.PrintBlockLaidOutSSA {
fmt.Printf("[[[laidout SSA for %d/%d %s]]]%s\n", i, len(module.CodeSection)-1, exportedFnIndex[fidx], ssaBuilder.Format())
}
// Now our ssaBuilder contains the necessary information to further lower them to
@@ -210,7 +203,7 @@ func (e *engine) CompileModule(_ context.Context, module *wasm.Module, _ []exper
copy(copied, body)
bodies[i] = copied
totalSize += len(body)
if debug {
if wazevoapi.PrintMachineCodeHexPerFunction {
fmt.Println(hex.EncodeToString(body))
}
}

View File

@@ -126,8 +126,6 @@ func (l *loweringState) ctrlPeekAt(n int) (ret *controlFrame) {
return &l.controlFrames[tail-n]
}
const debug = false
// lowerBody lowers the body of the Wasm function to the SSA form.
func (c *Compiler) lowerBody(entryBlk ssa.BasicBlock) {
c.ssaBuilder.Seal(entryBlk)
@@ -142,7 +140,7 @@ func (c *Compiler) lowerBody(entryBlk ssa.BasicBlock) {
for c.loweringState.pc < len(c.wasmFunctionBody) {
op := c.wasmFunctionBody[c.loweringState.pc]
c.lowerOpcode(op)
if debug {
if wazevoapi.FrontEndLoggingEnabled {
fmt.Println("--------- Translated " + wasm.InstructionName(op) + " --------")
fmt.Println("state: " + c.loweringState.String())
fmt.Println(c.formatBuilder())
@@ -693,9 +691,6 @@ func (c *Compiler) lowerOpcode(op wasm.Opcode) {
}
variable := c.localVariable(index)
v := builder.MustFindValue(variable)
if false {
builder.AnnotateValue(v, fmt.Sprintf("v%d@local[%d]", v.ID(), index))
}
state.push(v)
case wasm.OpcodeLocalSet:
index := c.readI32u()

View File

@@ -418,7 +418,7 @@ func (b *builder) findValue(typ Type, variable Variable, blk *basicBlock) Value
// and record it as unknown.
// The unknown values are resolved when we call seal this block via BasicBlock.Seal().
value := b.allocateValue(typ)
if debug {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("adding unknown value placeholder for %s at %d\n", variable, blk.id)
}
blk.lastDefinitions[variable] = value
@@ -700,7 +700,7 @@ func (b *builder) LayoutBlocks() {
}
}
trampolines := []*basicBlock{}
var trampolines []*basicBlock
// Reset the order slice since we update on the fly by splitting critical edges.
b.reversePostOrderedBasicBlocks = b.reversePostOrderedBasicBlocks[:0]
@@ -754,7 +754,7 @@ func (b *builder) LayoutBlocks() {
panic("BUG: predecessor info not found while the successor exists in successors list")
}
if debug {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("trying to split edge from %d->%d at %s\n",
blk.ID(), succ.ID(), predInfo.branch.Format(b))
}
@@ -763,9 +763,11 @@ func (b *builder) LayoutBlocks() {
// Update the successors slice because the target is no longer the original `succ`.
blk.success[sidx] = trampoline
trampolines = append(trampolines, trampoline)
if wazevoapi.SSAValidationEnabled {
trampolines = append(trampolines, trampoline)
}
if debug {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("edge split from %d->%d at %s as %d->%d->%d \n",
blk.ID(), succ.ID(), predInfo.branch.Format(b),
blk.ID(), trampoline.ID(), succ.ID())
@@ -791,7 +793,7 @@ func (b *builder) LayoutBlocks() {
uninsertedTrampolines = uninsertedTrampolines[:0] // Reuse the stack for the next block.
}
if debug {
if wazevoapi.SSALoggingEnabled {
var bs []string
for _, blk := range b.reversePostOrderedBasicBlocks {
bs = append(bs, blk.Name())
@@ -803,6 +805,9 @@ func (b *builder) LayoutBlocks() {
}
sort.Slice(bs, func(i, j int) bool { return bs[i] < bs[j] })
fmt.Println("visited blocks: ", strings.Join(bs, ", "))
}
if wazevoapi.SSAValidationEnabled {
for _, trampoline := range trampolines {
if _, ok := b.blkVisited[trampoline]; !ok {
panic("BUG: trampoline block not inserted: " + trampoline.FormatHeader(b))
@@ -901,7 +906,7 @@ invert:
condBranch.InvertBrx()
condBranch.blk = fallthroughTarget
fallthroughBranch.blk = condTarget
if debug {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("inverting branches at %d->%d and %d->%d\n",
now.ID(), fallthroughTarget.ID(), now.ID(), condTarget.ID())
}
@@ -909,8 +914,6 @@ invert:
return true
}
const debug = false
// splitCriticalEdge splits the critical edge between the given predecessor (`pred`) and successor (owning `predInfo`).
//
// - `pred` is the source of the critical edge,
@@ -964,7 +967,7 @@ func (b *builder) splitCriticalEdge(pred, succ *basicBlock, predInfo *basicBlock
predInfo.blk = trampoline
predInfo.branch = originalBranch
if debug {
if wazevoapi.SSAValidationEnabled {
trampoline.validate(b)
}

View File

@@ -121,7 +121,6 @@ func (i *Instruction) IsBranching() bool {
}
// TODO: complete opcode comments.
// TODO: there should be unnecessary opcodes.
const (
OpcodeInvalid Opcode = iota
@@ -160,10 +159,6 @@ const (
// Note that this is different from call_indirect in Wasm, which also does type checking, etc.
OpcodeCallIndirect
// OpcodeFuncAddr ...
// `addr = func_addr FN`.
OpcodeFuncAddr
// OpcodeSplat ...
// `v = splat x`.
OpcodeSplat
@@ -273,34 +268,6 @@ const (
// `v = sload32x2 MemFlags, p, Offset`.
OpcodeSload32x2
// OpcodeGlobalValue ...
// `v = global_value GV`.
OpcodeGlobalValue
// OpcodeSymbolValue ...
// `v = symbol_value GV`.
OpcodeSymbolValue
// OpcodeHeapAddr ...
// `addr = heap_addr H, index, Offset, Size`.
OpcodeHeapAddr
// OpcodeHeapLoad ...
// `v = heap_load heap_imm, index`.
OpcodeHeapLoad
// OpcodeHeapStore ...
// `heap_store heap_imm, index, a`.
OpcodeHeapStore
// OpcodeGetReturnAddress ...
// `addr = get_return_address`.
OpcodeGetReturnAddress
// OpcodeTableAddr ...
// `addr = table_addr T, p, Offset`.
OpcodeTableAddr
// OpcodeIconst represents the integer const.
OpcodeIconst
@@ -320,14 +287,6 @@ const (
// `v = shuffle a, b, mask`.
OpcodeShuffle
// OpcodeNull ...
// `v = null`.
OpcodeNull
// OpcodeNop ...
// `nop`.
OpcodeNop
// OpcodeSelect chooses between two values based on a condition `c`: `v = Select c, x, y`.
OpcodeSelect
@@ -371,14 +330,6 @@ const (
// OpcodeIsub performs an integer subtraction: `v = Isub x, y`.
OpcodeIsub
// OpcodeIneg ...
// `v = ineg x`.
OpcodeIneg
// OpcodeIabs ...
// `v = iabs x`.
OpcodeIabs
// OpcodeImul performs an integer multiplication: `v = Imul x, y`.
OpcodeImul
@@ -568,106 +519,62 @@ const (
// `v = bitrev x`.
OpcodeBitrev
// OpcodeClz ...
// `v = clz x`.
// OpcodeClz counts the number of leading zeros: `v = clz x`.
OpcodeClz
// OpcodeCls ...
// `v = cls x`.
OpcodeCls
// OpcodeCtz ...
// `v = ctz x`.
// OpcodeCtz counts the number of trailing zeros: `v = ctz x`.
OpcodeCtz
// OpcodeBswap ...
// `v = bswap x`.
OpcodeBswap
// OpcodePopcnt ...
// `v = popcnt x`.
// OpcodePopcnt counts the number of 1-bits: `v = popcnt x`.
OpcodePopcnt
// OpcodeFcmp compares two floating point values: `v = fcmp Cond, x, y`.
OpcodeFcmp
// OpcodeFadd performs an floating point addition.
// `v = Fadd x, y`.
// OpcodeFadd performs a floating point addition: / `v = Fadd x, y`.
OpcodeFadd
// OpcodeFsub performs an floating point subtraction.
// `v = Fsub x, y`.
// OpcodeFsub performs a floating point subtraction: `v = Fsub x, y`.
OpcodeFsub
// OpcodeFmul ...
// `v = fmul x, y`.
// OpcodeFmul performs a floating point multiplication: `v = Fmul x, y`.
OpcodeFmul
// OpcodeFdiv ...
// `v = fdiv x, y`.
// OpcodeFdiv performs a floating point division: `v = Fdiv x, y`.
OpcodeFdiv
// OpcodeSqrt ...
// `v = sqrt x`.
// OpcodeSqrt takes the square root of the given floating point value: `v = sqrt x`.
OpcodeSqrt
// OpcodeFma ...
// `v = fma x, y, z`.
OpcodeFma
// OpcodeFneg negates the given floating point value: `v = Fneg x`.
OpcodeFneg
// OpcodeFabs ...
// `v = fabs x`.
// OpcodeFabs takes the absolute value of the given floating point value: `v = fabs x`.
OpcodeFabs
// OpcodeFcopysign ...
// `v = fcopysign x, y`.
OpcodeFcopysign
// OpcodeFmin ...
// `v = fmin x, y`.
// OpcodeFmin takes the minimum of two floating point values: `v = fmin x, y`.
OpcodeFmin
// OpcodeFminPseudo ...
// `v = fmin_pseudo x, y`.
OpcodeFminPseudo
// OpcodeFmax ...
// `v = fmax x, y`.
// OpcodeFmax takes the maximum of two floating point values: `v = fmax x, y`.
OpcodeFmax
// OpcodeFmaxPseudo ...
// `v = fmax_pseudo x, y`.
OpcodeFmaxPseudo
// OpcodeCeil ...
// `v = ceil x`.
// OpcodeCeil takes the ceiling of the given floating point value: `v = ceil x`.
OpcodeCeil
// OpcodeFloor ...
// `v = floor x`.
// OpcodeFloor takes the floor of the given floating point value: `v = floor x`.
OpcodeFloor
// OpcodeTrunc ...
// `v = trunc x`.
// OpcodeTrunc takes the truncation of the given floating point value: `v = trunc x`.
OpcodeTrunc
// OpcodeNearest ...
// `v = nearest x`.
// OpcodeNearest takes the nearest integer of the given floating point value: `v = nearest x`.
OpcodeNearest
// OpcodeIsNull ...
// `v = is_null x`.
OpcodeIsNull
// OpcodeIsInvalid ...
// `v = is_invalid x`.
OpcodeIsInvalid
// OpcodeBitcast ...
// `v = bitcast MemFlags, x`.
// OpcodeBitcast is a bitcast operation: `v = bitcast MemFlags, x`.
OpcodeBitcast
// OpcodeScalarToVector ...
@@ -1851,8 +1758,6 @@ func (o Opcode) String() (ret string) {
return "Call"
case OpcodeCallIndirect:
return "CallIndirect"
case OpcodeFuncAddr:
return "FuncAddr"
case OpcodeSplat:
return "Splat"
case OpcodeSwizzle:
@@ -1913,20 +1818,6 @@ func (o Opcode) String() (ret string) {
return "Uload32x2"
case OpcodeSload32x2:
return "Sload32x2"
case OpcodeGlobalValue:
return "GlobalValue"
case OpcodeSymbolValue:
return "SymbolValue"
case OpcodeHeapAddr:
return "HeapAddr"
case OpcodeHeapLoad:
return "HeapLoad"
case OpcodeHeapStore:
return "HeapStore"
case OpcodeGetReturnAddress:
return "GetReturnAddress"
case OpcodeTableAddr:
return "TableAddr"
case OpcodeIconst:
return "Iconst"
case OpcodeF32const:
@@ -1937,10 +1828,6 @@ func (o Opcode) String() (ret string) {
return "Vconst"
case OpcodeShuffle:
return "Shuffle"
case OpcodeNull:
return "Null"
case OpcodeNop:
return "Nop"
case OpcodeSelect:
return "Select"
case OpcodeBitselect:
@@ -1965,10 +1852,6 @@ func (o Opcode) String() (ret string) {
return "Iadd"
case OpcodeIsub:
return "Isub"
case OpcodeIneg:
return "Ineg"
case OpcodeIabs:
return "Iabs"
case OpcodeImul:
return "Imul"
case OpcodeUmulhi:
@@ -2069,12 +1952,8 @@ func (o Opcode) String() (ret string) {
return "Bitrev"
case OpcodeClz:
return "Clz"
case OpcodeCls:
return "Cls"
case OpcodeCtz:
return "Ctz"
case OpcodeBswap:
return "Bswap"
case OpcodePopcnt:
return "Popcnt"
case OpcodeFcmp:
@@ -2089,8 +1968,6 @@ func (o Opcode) String() (ret string) {
return "Fdiv"
case OpcodeSqrt:
return "Sqrt"
case OpcodeFma:
return "Fma"
case OpcodeFneg:
return "Fneg"
case OpcodeFabs:
@@ -2099,12 +1976,8 @@ func (o Opcode) String() (ret string) {
return "Fcopysign"
case OpcodeFmin:
return "Fmin"
case OpcodeFminPseudo:
return "FminPseudo"
case OpcodeFmax:
return "Fmax"
case OpcodeFmaxPseudo:
return "FmaxPseudo"
case OpcodeCeil:
return "Ceil"
case OpcodeFloor:
@@ -2113,10 +1986,6 @@ func (o Opcode) String() (ret string) {
return "Trunc"
case OpcodeNearest:
return "Nearest"
case OpcodeIsNull:
return "IsNull"
case OpcodeIsInvalid:
return "IsInvalid"
case OpcodeBitcast:
return "Bitcast"
case OpcodeScalarToVector:

View File

@@ -1,6 +1,10 @@
package ssa
import "fmt"
import (
"fmt"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
// RunPasses implements Builder.RunPasses.
//
@@ -45,7 +49,7 @@ func passDeadBlockEliminationOpt(b *builder) {
panic(fmt.Sprintf("%s is not sealed", reachableBlk))
}
if true {
if wazevoapi.SSAValidationEnabled {
reachableBlk.validate(b)
}
@@ -282,7 +286,7 @@ func passDeadCodeEliminationOpt(b *builder) {
}
func (b *builder) incRefCount(id ValueID, from *Instruction) {
if debug {
if wazevoapi.SSALoggingEnabled {
fmt.Printf("v%d referenced from %v\n", id, from.Format(b))
}
b.valueRefCounts[id]++

View File

@@ -3,6 +3,8 @@ package ssa
import (
"fmt"
"math"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
// Variable is a unique identifier for a source program's variable and will correspond to
@@ -49,7 +51,7 @@ func (v Value) formatWithType(b Builder) (ret string) {
ret = fmt.Sprintf("v%d:%s", v.ID(), v.Type())
}
if debug { // This is useful to check live value analysis bugs.
if wazevoapi.SSALoggingEnabled { // This is useful to check live value analysis bugs.
if bd := b.(*builder); bd.donePasses {
id := v.ID()
ret += fmt.Sprintf("(ref=%d)", bd.valueRefCounts[id])

View File

@@ -0,0 +1,35 @@
package wazevoapi
// These consts are used various places in the wazevo implementations.
// Instead of defining them in each file, we define them here so that we can quickly iterate on
// debugging without spending "where do we have debug logging?" time.
// ----- Debug logging -----
// These consts must be disabled by default. Enable them only when debugging.
const (
FrontEndLoggingEnabled = false
SSALoggingEnabled = false
RegAllocLoggingEnabled = false
)
// ----- Output prints -----
// These consts must be disabled by default. Enable them only when debugging.
const (
PrintSSA = false
PrintOptimizedSSA = false
PrintBlockLaidOutSSA = false
PrintSSAToBackendIRLowering = false
PrintRegisterAllocated = false
PrintFinalizedMachineCode = false
PrintMachineCodeHexPerFunction = false
)
// ----- Validations -----
// These consts must be enabled by default until we reach the point where we can disable them (e.g. multiple days of fuzzing passes).
const (
RegAllocValidationEnabled = true
SSAValidationEnabled = true
)