]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6g: peephole fixes/additions
authorRuss Cox <rsc@golang.org>
Thu, 24 May 2012 16:11:32 +0000 (12:11 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 24 May 2012 16:11:32 +0000 (12:11 -0400)
* Shift/rotate by constant doesn't have to stop subprop. (also in 8g)
* Remove redundant MOVLQZX instructions.
* An attempt at issuing loads early.
  Good for 0.5% on a good day, might not be worth keeping.
  Need to understand more about whether the x86
  looks ahead to what loads might be coming up.

R=ken2, ken
CC=golang-dev
https://golang.org/cl/6203091

src/cmd/6g/peep.c
src/cmd/8g/peep.c

index a4d9b8edab4c1c7dba3512e7eeac578509d961c1..f55dfc8868fc1e7262e5c49b492c22245a31271c 100644 (file)
@@ -34,6 +34,9 @@
 #include "opt.h"
 
 static void    conprop(Reg *r);
+static int prevl(Reg *r, int reg);
+static void pushback(Reg *r);
+static int regconsttyp(Adr*);
 
 // do we need the carry bit
 static int
@@ -125,7 +128,7 @@ peep(void)
                        p = p->link;
                }
        }
-
+       
        // constant propagation
        // find MOV $con,R followed by
        // another MOV $con,R without
@@ -273,6 +276,104 @@ loop1:
        }
        if(t)
                goto loop1;
+
+       // MOVLQZX removal.
+       // The MOVLQZX exists to avoid being confused for a
+       // MOVL that is just copying 32-bit data around during
+       // copyprop.  Now that copyprop is done, remov MOVLQZX R1, R2
+       // if it is dominated by an earlier ADDL/MOVL/etc into R1 that
+       // will have already cleared the high bits.
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               if(p->as == AMOVLQZX)
+               if(regtyp(&p->from))
+               if(p->from.type == p->to.type)
+               if(prevl(r, p->from.type))
+                       excise(r);
+       }
+
+       // load pipelining
+       // push any load from memory as early as possible
+       // to give it time to complete before use.
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               switch(p->as) {
+               case AMOVB:
+               case AMOVW:
+               case AMOVL:
+               case AMOVQ:
+               case AMOVLQZX:
+                       if(regtyp(&p->to) && !regconsttyp(&p->from))
+                               pushback(r);
+               }
+       }
+}
+
+static void
+pushback(Reg *r0)
+{
+       Reg *r, *b;
+       Prog *p0, *p, t;
+       
+       b = R;
+       p0 = r0->prog;
+       for(r=uniqp(r0); r!=R && uniqs(r)!=R; r=uniqp(r)) {
+               p = r->prog;
+               if(p->as != ANOP) {
+                       if(!regconsttyp(&p->from) || !regtyp(&p->to))
+                               break;
+                       if(copyu(p, &p0->to, A) || copyu(p0, &p->to, A))
+                               break;
+               }
+               if(p->as == ACALL)
+                       break;
+               b = r;
+       }
+       
+       if(b == R) {
+               if(debug['v']) {
+                       print("no pushback: %P\n", r0->prog);
+                       if(r)
+                               print("\t%P [%d]\n", r->prog, uniqs(r)!=R);
+               }
+               return;
+       }
+
+       if(debug['v']) {
+               print("pushback\n");
+               for(r=b;; r=r->link) {
+                       print("\t%P\n", r->prog);
+                       if(r == r0)
+                               break;
+               }
+       }
+
+       t = *r0->prog;
+       for(r=uniqp(r0);; r=uniqp(r)) {
+               p0 = r->link->prog;
+               p = r->prog;
+               p0->as = p->as;
+               p0->lineno = p->lineno;
+               p0->from = p->from;
+               p0->to = p->to;
+
+               if(r == b)
+                       break;
+       }
+       p0 = r->prog;
+       p0->as = t.as;
+       p0->lineno = t.lineno;
+       p0->from = t.from;
+       p0->to = t.to;
+
+       if(debug['v']) {
+               print("\tafter\n");
+               for(r=b;; r=r->link) {
+                       print("\t%P\n", r->prog);
+                       if(r == r0)
+                               break;
+               }
+       }
 }
 
 void
@@ -336,6 +437,60 @@ regtyp(Adr *a)
        return 0;
 }
 
+int
+regconsttyp(Adr *a)
+{
+       if(regtyp(a))
+               return 1;
+       switch(a->type) {
+       case D_CONST:
+       case D_FCONST:
+       case D_SCONST:
+       case D_ADDR:
+               return 1;
+       }
+       return 0;
+}
+
+// is reg guaranteed to be truncated by a previous L instruction?
+static int
+prevl(Reg *r0, int reg)
+{
+       Prog *p;
+       Reg *r;
+
+       for(r=uniqp(r0); r!=R; r=uniqp(r)) {
+               p = r->prog;
+               if(p->to.type == reg) {
+                       switch(p->as) {
+                       case AADDL:
+                       case AANDL:
+                       case ADECL:
+                       case ADIVL:
+                       case AIDIVL:
+                       case AIMULL:
+                       case AINCL:
+                       case AMOVL:
+                       case AMULL:
+                       case AORL:
+                       case ARCLL:
+                       case ARCRL:
+                       case AROLL:
+                       case ARORL:
+                       case ASALL:
+                       case ASARL:
+                       case ASHLL:
+                       case ASHRL:
+                       case ASUBL:
+                       case AXORL:
+                               return 1;
+                       }
+                       return 0;
+               }
+       }
+       return 0;
+}
+
 /*
  * the idea is to substitute
  * one register for another
@@ -379,20 +534,6 @@ subprop(Reg *r0)
                        if(p->to.type != D_NONE)
                                break;
 
-               case ADIVB:
-               case ADIVL:
-               case ADIVQ:
-               case ADIVW:
-               case AIDIVB:
-               case AIDIVL:
-               case AIDIVQ:
-               case AIDIVW:
-               case AIMULB:
-               case AMULB:
-               case AMULL:
-               case AMULQ:
-               case AMULW:
-
                case ARCLB:
                case ARCLL:
                case ARCLQ:
@@ -425,6 +566,22 @@ subprop(Reg *r0)
                case ASHRL:
                case ASHRQ:
                case ASHRW:
+                       if(p->from.type == D_CONST)
+                               break;
+
+               case ADIVB:
+               case ADIVL:
+               case ADIVQ:
+               case ADIVW:
+               case AIDIVB:
+               case AIDIVL:
+               case AIDIVQ:
+               case AIDIVW:
+               case AIMULB:
+               case AMULB:
+               case AMULL:
+               case AMULQ:
+               case AMULW:
 
                case AREP:
                case AREPN:
index b8a2825e5a8fc7a82c05e6cfc9bc11da725efb20..38674d02a140ec867b33d45a17f8e46560b48807 100644 (file)
@@ -357,17 +357,6 @@ subprop(Reg *r0)
                        if(p->to.type != D_NONE)
                                break;
 
-               case ADIVB:
-               case ADIVL:
-               case ADIVW:
-               case AIDIVB:
-               case AIDIVL:
-               case AIDIVW:
-               case AIMULB:
-               case AMULB:
-               case AMULL:
-               case AMULW:
-
                case ARCLB:
                case ARCLL:
                case ARCLW:
@@ -392,6 +381,19 @@ subprop(Reg *r0)
                case ASHRB:
                case ASHRL:
                case ASHRW:
+                       if(p->from.type == D_CONST)
+                               break;
+
+               case ADIVB:
+               case ADIVL:
+               case ADIVW:
+               case AIDIVB:
+               case AIDIVL:
+               case AIDIVW:
+               case AIMULB:
+               case AMULB:
+               case AMULL:
+               case AMULW:
 
                case AREP:
                case AREPN: