* Enable basic constant propagation for floats.
The constant propagation is still not as aggressive as it could be.
* Implement MOVSS $(0), Xx and MOVSD $(0), Xx as XORPS Xx, Xx.
Sample code:
func f32() float32 {
var f float32
return f
}
func f64() float64 {
var f float64
return f
}
Before:
"".f32 t=1 size=32 value=0 args=0x8 locals=0x0
0x0000 00000 (demo.go:3) TEXT "".f32+0(SB),4,$0-8
0x0000 00000 (demo.go:3) FUNCDATA $0,gclocals·
a7a3692b8e27e823add69ec4239ba55f+0(SB)
0x0000 00000 (demo.go:3) FUNCDATA $1,gclocals·
3280bececceccd33cb74587feedb1f9f+0(SB)
0x0000 00000 (demo.go:3) MOVSS $f32.
00000000+0(SB),X0
0x0008 00008 (demo.go:4) MOVSS $f32.
00000000+0(SB),X0
0x0010 00016 (demo.go:5) MOVSS X0,"".~r0+8(FP)
0x0016 00022 (demo.go:5) RET ,
"".f64 t=1 size=32 value=0 args=0x8 locals=0x0
0x0000 00000 (demo.go:8) TEXT "".f64+0(SB),4,$0-8
0x0000 00000 (demo.go:8) FUNCDATA $0,gclocals·
a7a3692b8e27e823add69ec4239ba55f+0(SB)
0x0000 00000 (demo.go:8) FUNCDATA $1,gclocals·
3280bececceccd33cb74587feedb1f9f+0(SB)
0x0000 00000 (demo.go:8) MOVSD $f64.
0000000000000000+0(SB),X0
0x0008 00008 (demo.go:9) MOVSD $f64.
0000000000000000+0(SB),X0
0x0010 00016 (demo.go:10) MOVSD X0,"".~r0+8(FP)
0x0016 00022 (demo.go:10) RET ,
After:
"".f32 t=1 size=16 value=0 args=0x8 locals=0x0
0x0000 00000 (demo.go:3) TEXT "".f32+0(SB),4,$0-8
0x0000 00000 (demo.go:3) FUNCDATA $0,gclocals·
a7a3692b8e27e823add69ec4239ba55f+0(SB)
0x0000 00000 (demo.go:3) FUNCDATA $1,gclocals·
3280bececceccd33cb74587feedb1f9f+0(SB)
0x0000 00000 (demo.go:3) XORPS X0,X0
0x0003 00003 (demo.go:5) MOVSS X0,"".~r0+8(FP)
0x0009 00009 (demo.go:5) RET ,
"".f64 t=1 size=16 value=0 args=0x8 locals=0x0
0x0000 00000 (demo.go:8) TEXT "".f64+0(SB),4,$0-8
0x0000 00000 (demo.go:8) FUNCDATA $0,gclocals·
a7a3692b8e27e823add69ec4239ba55f+0(SB)
0x0000 00000 (demo.go:8) FUNCDATA $1,gclocals·
3280bececceccd33cb74587feedb1f9f+0(SB)
0x0000 00000 (demo.go:8) XORPS X0,X0
0x0003 00003 (demo.go:10) MOVSD X0,"".~r0+8(FP)
0x0009 00009 (demo.go:10) RET ,
Change-Id: Ie9eb65e324af4f664153d0a7cd22bb16b0fba16d
Reviewed-on: https://go-review.googlesource.com/2053
Reviewed-by: Russ Cox <rsc@golang.org>
* t = f
* hard part is conversions.
*/
-// TODO: lost special constants for floating point. XORPD for 0.0?
void
gmove(Node *f, Node *t)
{
case AMOVSS:
case AMOVSD:
if(regtyp(&p->to))
- if(p->from.type == D_CONST)
+ if(p->from.type == D_CONST || p->from.type == D_FCONST)
conprop(r);
break;
}
t = a->type;
if(t >= D_AX && t <= D_R15)
return 1;
- if(t >= D_X0 && t <= D_X0+15)
+ if(t >= D_X0 && t <= D_X15)
return 1;
return 0;
}
case AMOVSS:
case AMOVSD:
if(regtyp(&p->to))
- if(p->from.type == D_CONST)
+ if(p->from.type == D_CONST || p->from.type == D_FCONST)
conprop(r);
break;
}
// Rewrite float constants to values stored in memory.
switch(p->as) {
+ case AMOVSS:
+ // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
+ if(p->from.type == D_FCONST)
+ if(p->from.u.dval == 0)
+ if(p->to.type >= D_X0)
+ if(p->to.type <= D_X15) {
+ p->as = AXORPS;
+ p->from.type = p->to.type;
+ p->from.index = p->to.index;
+ break;
+ }
+ // fallthrough
+
case AFMOVF:
case AFADDF:
case AFSUBF:
case AFDIVRF:
case AFCOMF:
case AFCOMFP:
- case AMOVSS:
case AADDSS:
case ASUBSS:
case AMULSS:
p->from.offset = 0;
}
break;
+
+ case AMOVSD:
+ // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
+ if(p->from.type == D_FCONST)
+ if(p->from.u.dval == 0)
+ if(p->to.type >= D_X0)
+ if(p->to.type <= D_X15) {
+ p->as = AXORPS;
+ p->from.type = p->to.type;
+ p->from.index = p->to.index;
+ break;
+ }
+ // fallthrough
case AFMOVD:
case AFADDD:
case AFDIVRD:
case AFCOMD:
case AFCOMDP:
- case AMOVSD:
case AADDSD:
case ASUBSD:
case AMULSD:
// Rewrite float constants to values stored in memory.
switch(p->as) {
+ case AMOVSS:
+ // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
+ if(p->from.type == D_FCONST)
+ if(p->from.u.dval == 0)
+ if(p->to.type >= D_X0)
+ if(p->to.type <= D_X7) {
+ p->as = AXORPS;
+ p->from.type = p->to.type;
+ p->from.index = p->to.index;
+ break;
+ }
+ // fallthrough
+
case AFMOVF:
case AFADDF:
case AFSUBF:
case AFDIVRF:
case AFCOMF:
case AFCOMFP:
- case AMOVSS:
case AADDSS:
case ASUBSS:
case AMULSS:
}
break;
+ case AMOVSD:
+ // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
+ if(p->from.type == D_FCONST)
+ if(p->from.u.dval == 0)
+ if(p->to.type >= D_X0)
+ if(p->to.type <= D_X7) {
+ p->as = AXORPS;
+ p->from.type = p->to.type;
+ p->from.index = p->to.index;
+ break;
+ }
+ // fallthrough
+
case AFMOVD:
case AFADDD:
case AFSUBD:
case AFDIVRD:
case AFCOMD:
case AFCOMDP:
- case AMOVSD:
case AADDSD:
case ASUBSD:
case AMULSD: