[dev.ssa] cmd/compile: copy values during rewrites
Rather than require an explicit Copy on the RHS of rewrite rules,
use rulegen magic to add it.
The advantages to handling this in rulegen are:
* simpler rules
* harder to accidentally miss a Copy
Change-Id: I46853bade83bdf517eee9495bf5a553175277b53
Reviewed-on: https://go-review.googlesource.com/13242
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 2a54bb0..1e9f615 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -71,12 +71,12 @@
(ZeroExt32to64 x) -> (MOVLQZX x)
// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 x) -> (Copy x)
-(Trunc32to8 x) -> (Copy x)
-(Trunc32to16 x) -> (Copy x)
-(Trunc64to8 x) -> (Copy x)
-(Trunc64to16 x) -> (Copy x)
-(Trunc64to32 x) -> (Copy x)
+(Trunc16to8 x) -> x
+(Trunc32to8 x) -> x
+(Trunc32to16 x) -> x
+(Trunc64to8 x) -> x
+(Trunc64to16 x) -> x
+(Trunc64to32 x) -> x
// Lowering shifts
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
@@ -338,7 +338,7 @@
// strength reduction
(MULQconst [-1] x) -> (NEGQ x)
(MULQconst [0] _) -> (MOVQconst [0])
-(MULQconst [1] x) -> (Copy x)
+(MULQconst [1] x) -> x
(MULQconst [3] x) -> (LEAQ2 x x)
(MULQconst [5] x) -> (LEAQ4 x x)
(MULQconst [9] x) -> (LEAQ8 x x)
@@ -393,10 +393,10 @@
(MOVQloadidx8 [off1] (ADDQconst [off2] ptr) idx mem) -> (MOVQloadidx8 [addOff(off1, off2)] ptr idx mem)
(MOVQstoreidx8 [off1] (ADDQconst [off2] ptr) idx val mem) -> (MOVQstoreidx8 [addOff(off1, off2)] ptr idx val mem)
-(ADDQconst [0] x) -> (Copy x)
+(ADDQconst [0] x) -> x
// lower Zero instructions with word sizes
-(Zero [0] _ mem) -> (Copy mem)
+(Zero [0] _ mem) -> mem
(Zero [1] destptr mem) -> (MOVBstore destptr (MOVBconst <config.Frontend().TypeInt8()> [0]) mem)
(Zero [2] destptr mem) -> (MOVWstore destptr (MOVWconst <config.Frontend().TypeInt16()> [0]) mem)
(Zero [4] destptr mem) -> (MOVLstore destptr (MOVLconst <config.Frontend().TypeInt32()> [0]) mem)
@@ -440,14 +440,14 @@
(ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0])
(ANDWconst [c] _) && int16(c)==0 -> (MOVWconst [0])
(ANDBconst [c] _) && int8(c)==0 -> (MOVBconst [0])
-(ANDQconst [-1] x) -> (Copy x)
-(ANDLconst [c] x) && int32(c)==-1 -> (Copy x)
-(ANDWconst [c] x) && int16(c)==-1 -> (Copy x)
-(ANDBconst [c] x) && int8(c)==-1 -> (Copy x)
-(ORQconst [0] x) -> (Copy x)
-(ORLconst [c] x) && int32(c)==0 -> (Copy x)
-(ORWconst [c] x) && int16(c)==0 -> (Copy x)
-(ORBconst [c] x) && int8(c)==0 -> (Copy x)
+(ANDQconst [-1] x) -> x
+(ANDLconst [c] x) && int32(c)==-1 -> x
+(ANDWconst [c] x) && int16(c)==-1 -> x
+(ANDBconst [c] x) && int8(c)==-1 -> x
+(ORQconst [0] x) -> x
+(ORLconst [c] x) && int32(c)==0 -> x
+(ORWconst [c] x) && int16(c)==0 -> x
+(ORBconst [c] x) && int8(c)==0 -> x
(ORQconst [-1] _) -> (MOVQconst [-1])
(ORLconst [c] _) && int32(c)==-1 -> (MOVLconst [-1])
(ORWconst [c] _) && int16(c)==-1 -> (MOVWconst [-1])
@@ -505,14 +505,14 @@
(SUBL x x) -> (MOVLconst [0])
(SUBW x x) -> (MOVWconst [0])
(SUBB x x) -> (MOVBconst [0])
-(ANDQ x x) -> (Copy x)
-(ANDL x x) -> (Copy x)
-(ANDW x x) -> (Copy x)
-(ANDB x x) -> (Copy x)
-(ORQ x x) -> (Copy x)
-(ORL x x) -> (Copy x)
-(ORW x x) -> (Copy x)
-(ORB x x) -> (Copy x)
+(ANDQ x x) -> x
+(ANDL x x) -> x
+(ANDW x x) -> x
+(ANDB x x) -> x
+(ORQ x x) -> x
+(ORL x x) -> x
+(ORW x x) -> x
+(ORB x x) -> x
(XORQ x x) -> (MOVQconst [0])
(XORL x x) -> (MOVLconst [0])
(XORW x x) -> (MOVWconst [0])
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index cb6a200..8656b7c 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -34,10 +34,10 @@
(Neq16 x x) -> (ConstBool {false})
(Neq8 x x) -> (ConstBool {false})
-(Com8 (Com8 x)) -> (Copy x)
-(Com16 (Com16 x)) -> (Copy x)
-(Com32 (Com32 x)) -> (Copy x)
-(Com64 (Com64 x)) -> (Copy x)
+(Com8 (Com8 x)) -> x
+(Com16 (Com16 x)) -> x
+(Com32 (Com32 x)) -> x
+(Com64 (Com64 x)) -> x
// tear apart slices
// TODO: anything that generates a slice needs to go in here.
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index 9edef83..6ee22c1 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -376,11 +376,15 @@
if result[0] != '(' {
// variable
if top {
- fmt.Fprintf(w, "v.Op = %s.Op\n", result)
- fmt.Fprintf(w, "v.AuxInt = %s.AuxInt\n", result)
- fmt.Fprintf(w, "v.Aux = %s.Aux\n", result)
+ // It in not safe in general to move a variable between blocks
+ // (and particularly not a phi node).
+ // Introduce a copy.
+ fmt.Fprintf(w, "v.Op = OpCopy\n")
+ fmt.Fprintf(w, "v.AuxInt = 0\n")
+ fmt.Fprintf(w, "v.Aux = nil\n")
fmt.Fprintf(w, "v.resetArgs()\n")
- fmt.Fprintf(w, "v.AddArgs(%s.Args...)\n", result)
+ fmt.Fprintf(w, "v.Type = %s.Type\n", result)
+ fmt.Fprintf(w, "v.AddArg(%s)\n", result)
}
return result
}