Skip to content

ssa: optimizes findValue function #2245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions internal/engine/wazevo/frontend/frontend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,14 +1058,14 @@ blk1: () <-- (blk0)
Call f1:sig1, exec_ctx, module_ctx
v5:i64 = Load module_ctx, 0x8
v6:i64 = Uload32 module_ctx, 0x10
Jump blk3, v2
Jump blk3

blk2: () <-- (blk0)
Jump blk3, v2
Jump blk3

blk3: (v7:i32) <-- (blk1,blk2)
blk3: () <-- (blk1,blk2)
v8:i64 = Iconst_64 0x4
v9:i64 = UExtend v7, 32->64
v9:i64 = UExtend v2, 32->64
v10:i64 = Uload32 module_ctx, 0x10
v11:i64 = Iadd v9, v8
v12:i32 = Icmp lt_u, v10, v11
Expand Down Expand Up @@ -2869,7 +2869,7 @@ blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)

blk1: () <-- (blk0)
v11:i32 = Load v9, 0x10
Jump blk3, v2
Jump blk3

blk2: () <-- (blk0)
v12:i32 = Load v9, 0x10
Expand All @@ -2880,18 +2880,13 @@ blk2: () <-- (blk0)
ExitIfTrue v16, exec_ctx, memory_out_of_bounds
v17:i32 = Load v9, 0x30
v18:i32 = Load v9, 0x25
Jump blk3, v2
Jump blk3

blk3: (v19:i32) <-- (blk1,blk2)
v20:i64 = Iconst_64 0x19
v21:i64 = UExtend v19, 32->64
v22:i64 = Uload32 module_ctx, 0x10
v23:i64 = Iadd v21, v20
v24:i32 = Icmp lt_u, v22, v23
ExitIfTrue v24, exec_ctx, memory_out_of_bounds
v25:i64 = Load module_ctx, 0x8
v26:i64 = Iadd v25, v21
v27:i32 = Load v26, 0x15
blk3: () <-- (blk1,blk2)
v20:i64 = Load module_ctx, 0x8
v21:i64 = UExtend v2, 32->64
v22:i64 = Iadd v20, v21
v23:i32 = Load v22, 0x15
Jump blk_ret
`,
},
Expand Down
47 changes: 34 additions & 13 deletions internal/engine/wazevo/ssa/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,21 +518,42 @@ func (b *builder) findValue(typ Type, variable Variable, blk *basicBlock) Value
// If this block has multiple predecessors, we have to gather the definitions,
// and treat them as an argument to this block.
//
// The first thing is to define a new parameter to this block 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.
paramValue := blk.AddParam(b, typ)
b.DefineVariable(variable, paramValue, blk)

// 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.
// But before that, we have to check if the possible definitions are the same Value.
tmpValue := b.allocateValue(typ)
// Break the cycle by defining the variable with the tmpValue.
b.DefineVariable(variable, tmpValue, blk)
// Check all the predecessors if they have the same definition.
uniqueValue := ValueInvalid
for i := range blk.preds {
pred := &blk.preds[i]
value := b.findValue(typ, variable, pred.blk)
pred.branch.addArgumentBranchInst(b, value)
predValue := b.findValue(typ, variable, blk.preds[i].blk)
if uniqueValue == ValueInvalid {
uniqueValue = predValue
} else if uniqueValue != predValue {
uniqueValue = ValueInvalid
break
}
}

if uniqueValue != ValueInvalid {
// If all the predecessors have the same definition, we can use that value.
b.DefineVariable(variable, uniqueValue, blk)
b.alias(tmpValue, uniqueValue)
return uniqueValue
} else {
// 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)
// 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.
for i := range blk.preds {
pred := &blk.preds[i]
value := b.findValue(typ, variable, pred.blk)
pred.branch.addArgumentBranchInst(b, value)
}
return tmpValue
}
return paramValue
}

// Seal implements Builder.Seal.
Expand Down
Loading