Commit 49893371 authored by Keith Randall's avatar Keith Randall

[dev.ssa] cmd/compile: allow control values to be CSEd

With the separate flagalloc pass, it should be fine to
allow CSE of control values.  The worst that can happen
is that the comparison gets un-CSEd by flagalloc.

Fix bug in flagalloc where flag restores were getting
clobbered by rematerialization during register allocation.

Change-Id: If476cf98b69973e8f1a8eb29441136dd12fab8ad
Reviewed-on: https://go-review.googlesource.com/17760Reviewed-by: 's avatarDavid Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
parent c140df03
......@@ -153,7 +153,6 @@ func cse(f *Func) {
i++
}
}
// TODO(khr): if value is a control value, do we need to keep it block-local?
}
}
......@@ -166,6 +165,16 @@ func cse(f *Func) {
}
}
}
if v := b.Control; v != nil {
if x := rewrite[v.ID]; x != nil {
if v.Op == OpNilCheck {
// nilcheck pass will remove the nil checks and log
// them appropriately, so don't mess with them here.
continue
}
b.Control = x
}
}
}
}
......
......@@ -21,6 +21,15 @@ func flagalloc(f *Func) {
// Walk blocks backwards. Poor-man's postorder traversal.
for i := len(f.Blocks) - 1; i >= 0; i-- {
b := f.Blocks[i]
if len(b.Preds) > 1 {
// Don't use any flags register at the start
// of a merge block. This causes problems
// in regalloc because some of the rematerialization
// instructions used on incoming merge edges clobber
// the flags register.
// TODO: only for architectures where this matters?
continue
}
// Walk values backwards to figure out what flag
// value we want in the flag register at the start
// of the block.
......
......@@ -370,7 +370,7 @@
(If (SETGF cmp) yes no) -> (UGT cmp yes no)
(If (SETGEF cmp) yes no) -> (UGE cmp yes no)
(If (SETEQF cmp) yes no) -> (EQF cmp yes no)
(If (SETNEF cmp) yes no) -> (EQF cmp yes no)
(If (SETNEF cmp) yes no) -> (NEF cmp yes no)
(If cond yes no) -> (NE (TESTB cond cond) yes no)
......
......@@ -433,7 +433,7 @@ func init() {
name: "DUFFCOPY",
reg: regInfo{
inputs: []regMask{buildReg("DI"), buildReg("SI")},
clobbers: buildReg("DI SI X0"), // uses X0 as a temporary
clobbers: buildReg("DI SI X0 FLAGS"), // uses X0 as a temporary
},
},
......
......@@ -3177,7 +3177,7 @@ var opcodeTable = [...]opInfo{
{0, 128}, // .DI
{1, 64}, // .SI
},
clobbers: 65728, // .SI .DI .X0
clobbers: 8590000320, // .SI .DI .X0 .FLAGS
},
},
{
......
......@@ -14213,23 +14213,23 @@ func rewriteBlockAMD64(b *Block) bool {
;
// match: (If (SETNEF cmp) yes no)
// cond:
// result: (EQF cmp yes no)
// result: (NEF cmp yes no)
{
v := b.Control
if v.Op != OpAMD64SETNEF {
goto endfe25939ca97349543bc2d2ce4f97ba41
goto endaa989df10b5bbc5fdf8f7f0b81767e86
}
cmp := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockAMD64EQF
b.Kind = BlockAMD64NEF
b.Control = cmp
b.Succs[0] = yes
b.Succs[1] = no
return true
}
goto endfe25939ca97349543bc2d2ce4f97ba41
endfe25939ca97349543bc2d2ce4f97ba41:
goto endaa989df10b5bbc5fdf8f7f0b81767e86
endaa989df10b5bbc5fdf8f7f0b81767e86:
;
// match: (If cond yes no)
// cond:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment