pass: remove redundant jumps and dangling labels (#81)
In jump-table-like constructs, the natural way of writing the code can sometimes produce redundant jumps or labels. Therefore some basic cleanup steps have been proposed. This diff adds two transforms: 1. Remove unconditional jumps to a label immediately following. 2. Remove labels with no references at all. Fixes #75
This commit is contained in:
committed by
GitHub
parent
57c23b967e
commit
2e7d06bc7a
@@ -42,3 +42,45 @@ func TestPruneSelfMoves(t *testing.T) {
|
||||
t.Fatal("unexpected result from self-move pruning")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPruneJumpToFollowingLabel(t *testing.T) {
|
||||
// Construct a function containing a jump to following.
|
||||
ctx := build.NewContext()
|
||||
ctx.Function("add")
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
ctx.JMP(operand.LabelRef("next"))
|
||||
ctx.Label("next")
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
|
||||
// Build the function with the PruneJumpToFollowingLabel pass.
|
||||
fn := BuildFunction(t, ctx, pass.PruneJumpToFollowingLabel)
|
||||
|
||||
// Confirm no JMP instruction remains.
|
||||
for _, i := range fn.Instructions() {
|
||||
if i.Opcode == "JMP" {
|
||||
t.Fatal("JMP instruction not removed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPruneDanglingLabels(t *testing.T) {
|
||||
// Construct a function containing an unreferenced label.
|
||||
ctx := build.NewContext()
|
||||
ctx.Function("add")
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
ctx.JMP(operand.LabelRef("referenced"))
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
ctx.Label("dangling")
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
ctx.Label("referenced")
|
||||
ctx.XORQ(reg.RAX, reg.RAX)
|
||||
|
||||
// Build the function with the PruneDanglingLabels pass.
|
||||
fn := BuildFunction(t, ctx, pass.PruneDanglingLabels)
|
||||
|
||||
// Confirm the only label remaining is "referenced".
|
||||
expect := []ir.Label{"referenced"}
|
||||
if !reflect.DeepEqual(expect, fn.Labels()) {
|
||||
t.Fatal("expected dangling label to be removed")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user