]> Cypherpunks repositories - gostls13.git/commitdiff
arm optimizer bug fixes
authorKen Thompson <ken@golang.org>
Mon, 10 Jan 2011 21:15:52 +0000 (13:15 -0800)
committerKen Thompson <ken@golang.org>
Mon, 10 Jan 2011 21:15:52 +0000 (13:15 -0800)
R=rsc
CC=golang-dev
https://golang.org/cl/3913043

src/cmd/5g/peep.c
src/cmd/5g/reg.c

index 3e6bf3eb98ae7470191fd2cb959c5d247f94d269..32333e8a9fe04f65da2e8c6d0a571eeddff165c0 100644 (file)
@@ -37,6 +37,7 @@ int   shiftprop(Reg *r);
 void   constprop(Adr *c1, Adr *v1, Reg *r);
 void   predicate(void);
 int    copyau1(Prog *p, Adr *v);
+int    isdconst(Addr *a);
 
 void
 peep(void)
@@ -81,30 +82,42 @@ loop1:
        t = 0;
        for(r=firstr; r!=R; r=r->link) {
                p = r->prog;
-               if(p->as == ASLL || p->as == ASRL || p->as == ASRA) {
+               switch(p->as) {
+               case ASLL:
+               case ASRL:
+               case ASRA:
                        /*
                         * elide shift into D_SHIFT operand of subsequent instruction
                         */
                        if(shiftprop(r)) {
                                excise(r);
                                t++;
+                               break;
                        }
-               }
-               if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
-               if(regtyp(&p->to)) {
-                       if(p->from.type == D_CONST)
+                       break;
+
+               case AMOVW:
+               case AMOVF:
+               case AMOVD:
+                       if(!regtyp(&p->to))
+                               break;
+                       if(isdconst(&p->from)) {
                                constprop(&p->from, &p->to, r->s1);
-                       else
-                       if(regtyp(&p->from))
-                       if(p->from.type == p->to.type) {
-                               if(copyprop(r)) {
-                                       excise(r);
-                                       t++;
-                               } else
-                               if(subprop(r) && copyprop(r)) {
-                                       excise(r);
-                                       t++;
-                               }
+                               break;
+                       }
+                       if(!regtyp(&p->from))
+                               break;
+                       if(p->from.type != p->to.type)
+                               break;
+                       if(copyprop(r)) {
+                               excise(r);
+                               t++;
+                               break;
+                       }
+                       if(subprop(r) && copyprop(r)) {
+                               excise(r);
+                               t++;
+                               break;
                        }
                }
        }
@@ -122,7 +135,7 @@ loop1:
                        /*
                         * EOR -1,x,y => MVN x,y
                         */
-                       if(p->from.type == D_CONST && p->from.offset == -1) {
+                       if(isdconst(&p->from) && p->from.offset == -1) {
                                p->as = AMVN;
                                p->from.type = D_REG;
                                if(p->reg != NREG)
@@ -170,7 +183,7 @@ loop1:
                        /*
                         * elide CMP $0,x if calculation of x can set condition codes
                         */
-                       if(p->from.type != D_CONST || p->from.offset != 0)
+                       if(isdconst(&p->from) || p->from.offset != 0)
                                continue;
                        r2 = r->s1;
                        if(r2 == R)
@@ -668,12 +681,14 @@ shiftprop(Reg *r)
                }
                break;
        }
+
        /* make the substitution */
        p2->from.type = D_SHIFT;
        p2->from.reg = NREG;
        o = p->reg;
        if(o == NREG)
                o = p->to.reg;
+
        switch(p->from.type){
        case D_CONST:
                o |= (p->from.offset&0x1f)<<7;
@@ -735,7 +750,7 @@ findinc(Reg *r, Reg *r2, Adr *v)
                case 4: /* set and used */
                        p = r1->prog;
                        if(p->as == AADD)
-                       if(p->from.type == D_CONST)
+                       if(isdconst(&p->from))
                        if(p->from.offset > -4096 && p->from.offset < 4096)
                                return r1;
                default:
@@ -990,7 +1005,6 @@ copyu(Prog *p, Adr *v, Adr *s)
                        return 1;
                return 0;
 
-
        case AADD:      /* read, read, write */
        case ASUB:
        case ARSB:
@@ -1192,6 +1206,10 @@ copyau(Adr *a, Adr *v)
        if(copyas(a, v))
                return 1;
        if(v->type == D_REG) {
+               if(a->type == D_CONST && a->reg != NREG) {
+                       if(v->reg == a->reg)
+                               return 1;
+               } else
                if(a->type == D_OREG) {
                        if(v->reg == a->reg)
                                return 1;
@@ -1320,19 +1338,22 @@ isbranch(Prog *p)
 int
 predicable(Prog *p)
 {
-       if (isbranch(p)
-               || p->as == ANOP
-               || p->as == AXXX
-               || p->as == ADATA
-               || p->as == AGLOBL
-               || p->as == AGOK
-               || p->as == AHISTORY
-               || p->as == ANAME
-               || p->as == ASIGNAME
-               || p->as == ATEXT
-               || p->as == AWORD
-               || p->as == ABCASE
-               || p->as == ACASE)
+       switch(p->as) {
+       case ANOP:
+       case AXXX:
+       case ADATA:
+       case AGLOBL:
+       case AGOK:
+       case AHISTORY:
+       case ANAME:
+       case ASIGNAME:
+       case ATEXT:
+       case AWORD:
+       case ABCASE:
+       case ACASE:
+               return 0;
+       }
+       if(isbranch(p))
                return 0;
        return 1;
 }
@@ -1347,18 +1368,23 @@ predicable(Prog *p)
 int
 modifiescpsr(Prog *p)
 {
-       return (p->scond&C_SBIT)
-               || p->as == ATST
-               || p->as == ATEQ
-               || p->as == ACMN
-               || p->as == ACMP
-               || p->as == AMULU
-               || p->as == ADIVU
-               || p->as == AMUL
-               || p->as == ADIV
-               || p->as == AMOD
-               || p->as == AMODU
-               || p->as == ABL;
+       switch(p->as) {
+       case ATST:
+       case ATEQ:
+       case ACMN:
+       case ACMP:
+       case AMULU:
+       case ADIVU:
+       case AMUL:
+       case ADIV:
+       case AMOD:
+       case AMODU:
+       case ABL:
+               return 1;
+       }
+       if(p->scond & C_SBIT)
+               return 1;
+       return 0;
 }
 
 /*
@@ -1401,10 +1427,10 @@ joinsplit(Reg *r, Joininfo *j)
        return Toolong;
 }
 
-Reg *
+Reg*
 successor(Reg *r)
 {
-       if (r->s1)
+       if(r->s1)
                return r->s1;
        else
                return r->s2;
@@ -1418,23 +1444,24 @@ applypred(Reg *rstart, Joininfo *j, int cond, int branch)
 
        if(j->len == 0)
                return;
-       if (cond == Truecond)
+       if(cond == Truecond)
                pred = predinfo[rstart->prog->as - ABEQ].scond;
        else
                pred = predinfo[rstart->prog->as - ABEQ].notscond;
 
-       for (r = j->start; ; r = successor(r)) {
+       for(r = j->start;; r = successor(r)) {
                if (r->prog->as == AB) {
                        if (r != j->last || branch == Delbranch)
                                excise(r);
                        else {
-                         if (cond == Truecond)
-                               r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
-                         else
-                               r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
+                               if (cond == Truecond)
+                                       r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
+                               else
+                                       r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
                        }
                }
-               else if (predicable(r->prog))
+               else
+               if (predicable(r->prog))
                        r->prog->scond = (r->prog->scond&~C_SCOND)|pred;
                if (r->s1 != r->link) {
                        r->s1 = r->link;
@@ -1474,3 +1501,11 @@ predicate(void)
                }
        }
 }
+
+int
+isdconst(Addr *a)
+{
+       if(a->type == D_CONST && a->reg == NREG)
+               return 1;
+       return 0;
+}
index 46471a016ca7c8dab0e73aa44b7706407a58ce51..8f998b876418262e8f36e018b70eabef16dce5bd 100644 (file)
@@ -102,7 +102,7 @@ excise(Reg *r)
        p->scond = zprog.scond;
        p->from = zprog.from;
        p->to = zprog.to;
-       p->reg = zprog.reg; /**/
+       p->reg = zprog.reg;
 }
 
 static void
@@ -139,22 +139,16 @@ regopt(Prog *firstp)
 
        if(first == 0) {
                fmtinstall('Q', Qconv);
-//             exregoffset = D_R13;    // R14,R15 are external
        }
        first++;
 
-//if(!debug['K'])
-//     return;
-
-//if(first != 19) {
-//     return;
-//}
-
-//print("optimizing %S\n", curfn->nname->sym);
-
-//debug['R'] = 2;
-//debug['P'] = 2;
-
+       if(debug['K']) {
+               if(first != 20)
+                       return;
+//             debug['R'] = 2;
+//             debug['P'] = 2;
+               print("optimizing %S\n", curfn->nname->sym);
+       }
 
        // count instructions
        nr = 0;
@@ -189,7 +183,6 @@ regopt(Prog *firstp)
         * allocate pcs
         * find use and set of variables
         */
-if(0) print("pass 1\n");
        nr = 0;
        for(p=firstp; p != P; p = p->link) {
                switch(p->as) {
@@ -284,7 +277,6 @@ if(0) print("pass 1\n");
         * turn branch references to pointers
         * build back pointers
         */
-if(0) print("pass 2\n");
        for(r=firstr; r!=R; r=r->link) {
                p = r->prog;
                if(p->to.type == D_BRANCH) {
@@ -311,7 +303,6 @@ if(0) print("pass 2\n");
         * pass 2.5
         * find looping structure
         */
-if(0) print("pass 2.5\n");
        for(r = firstr; r != R; r = r->link)
                r->active = 0;
        change = 0;
@@ -323,7 +314,6 @@ if(0) print("pass 2.5\n");
         *      back until flow graph is complete
         */
 loop1:
-if(0) print("loop 1\n");
        change = 0;
        for(r = firstr; r != R; r = r->link)
                r->active = 0;
@@ -331,7 +321,6 @@ if(0) print("loop 1\n");
                if(r->prog->as == ARET)
                        prop(r, zbits, zbits);
 loop11:
-if(0) print("loop 11\n");
        /* pick up unreachable code */
        i = 0;
        for(r = firstr; r != R; r = r1) {
@@ -353,7 +342,6 @@ if(0) print("loop 11\n");
         *      forward until graph is complete
         */
 loop2:
-if(0) print("loop 2\n");
        change = 0;
        for(r = firstr; r != R; r = r->link)
                r->active = 0;
@@ -400,7 +388,6 @@ if(0) print("loop 2\n");
         * isolate regions
         * calculate costs (paint1)
         */
-if(0) print("pass 5\n");
        r = firstr;
        if(r) {
                for(z=0; z<BITS; z++)
@@ -490,7 +477,6 @@ brk:
         * pass 7
         * peep-hole on basic block
         */
-if(0) print("pass 7\n");
        if(!debug['R'] || debug['P']) {
                peep();
        }
@@ -652,8 +638,12 @@ mkvar(Reg *r, Adr *a, int docon)
                print("type %d %d %D\n", t, a->name, a);
                goto none;
 
-       case D_NONE:
        case D_CONST:
+               if(a->reg != NREG)
+                       r->regu |= RtoB(a->reg);
+               // fallthrough
+
+       case D_NONE:
        case D_FCONST:
        case D_BRANCH:
                goto none;
@@ -1028,9 +1018,6 @@ allreg(uint32 b, Rgn *r)
                }
                break;
 
-       case TINT64:
-       case TUINT64:
-       case TPTR64:
        case TFLOAT32:
        case TFLOAT64:
        case TFLOAT:
@@ -1040,6 +1027,14 @@ allreg(uint32 b, Rgn *r)
                        return FtoB(i);
                }
                break;
+
+       case TINT64:
+       case TUINT64:
+       case TPTR64:
+       case TINTER:
+       case TSTRUCT:
+       case TARRAY:
+               break;
        }
        return 0;
 }