From: Keith Randall Date: Fri, 11 Dec 2015 22:59:01 +0000 (-0800) Subject: [dev.ssa] cmd/compile: allow control values to be CSEd X-Git-Tag: go1.7beta1~1623^2^2~103 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=498933719287fbba1015c97d177a9bd4cfb9aada;p=gostls13.git [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 Run-TryBot: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index 25f424fbee..58c52f23e6 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -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 + } + } } } diff --git a/src/cmd/compile/internal/ssa/flagalloc.go b/src/cmd/compile/internal/ssa/flagalloc.go index c088158057..714ac016a2 100644 --- a/src/cmd/compile/internal/ssa/flagalloc.go +++ b/src/cmd/compile/internal/ssa/flagalloc.go @@ -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. diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 7d0aa4b2d3..0edbfdaa1a 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -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) diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index ba53e81ddd..461026bd7b 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -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 }, }, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 132ca83f95..bbedf2fb64 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -3177,7 +3177,7 @@ var opcodeTable = [...]opInfo{ {0, 128}, // .DI {1, 64}, // .SI }, - clobbers: 65728, // .SI .DI .X0 + clobbers: 8590000320, // .SI .DI .X0 .FLAGS }, }, { diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 3be94e37e7..5c2f3db4b2 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -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: