[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/17760
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
This commit is contained in:
Keith Randall 2015-12-11 14:59:01 -08:00
parent c140df0326
commit 4989337192
6 changed files with 27 additions and 9 deletions

View File

@ -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
}
}
}
}

View File

@ -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.

View File

@ -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)

View File

@ -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
},
},

View File

@ -3177,7 +3177,7 @@ var opcodeTable = [...]opInfo{
{0, 128}, // .DI
{1, 64}, // .SI
},
clobbers: 65728, // .SI .DI .X0
clobbers: 8590000320, // .SI .DI .X0 .FLAGS
},
},
{

View File

@ -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: