Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.55
 
1.56
 
MAIN:plunky:20121022090641
 
optim.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 44  *
 55  * Redistribution and use in source and binary forms, with or without
 66  * modification, are permitted provided that the following conditions
 77  * are met:
 88  *
 99  * Redistributions of source code and documentation must retain the above
 1010  * copyright notice, this list of conditions and the following disclaimer.
 1111  * Redistributions in binary form must reproduce the above copyright
 1212  * notice, this list of conditionsand the following disclaimer in the
 1313  * documentation and/or other materials provided with the distribution.
 1414  * All advertising materials mentioning features or use of this software
 1515  * must display the following acknowledgement:
 1616  *      This product includes software developed or owned by Caldera
 1717  *      International, Inc.
 1818  * Neither the name of Caldera International, Inc. nor the names of other
 1919  * contributors may be used to endorse or promote products derived from
 2020  * this software without specific prior written permission.
 2121  *
 2222  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 2323  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 2424  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 2525  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 2626  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 2727  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 2828  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 2929  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 3030  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 3131  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 3232  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 3333  * POSSIBILITY OF SUCH DAMAGE.
 3434  */
 3535 
 3636 # include "pass1.h"
 3737 
 3838 # define SWAP(p,q) {sp=p; p=q; q=sp;}
 3939 # define RCON(p) (p->n_right->n_op==ICON)
 4040 # define RO(p) p->n_right->n_op
 4141 # define RV(p) p->n_right->n_lval
 4242 # define LCON(p) (p->n_left->n_op==ICON)
 4343 # define LO(p) p->n_left->n_op
 4444 # define LV(p) p->n_left->n_lval
 4545 
 4646 /* remove left node */
 4747 static NODE *
 4848 zapleft(NODE *p)
 4949 {
 5050         NODE *q;
 5151 
 5252         q = p->n_left;
 5353         nfree(p->n_right);
 5454         nfree(p);
 5555         return q;
 5656 }
 5757 
 5858 /*
 5959  * fortran function arguments
 6060  */
 6161 static NODE *
 6262 fortarg(NODE *p)
 6363 {
 6464         if( p->n_op == CM ){
 6565                 p->n_left = fortarg( p->n_left );
 6666                 p->n_right = fortarg( p->n_right );
 6767                 return(p);
 6868         }
 6969 
 7070         while( ISPTR(p->n_type) ){
 7171                 p = buildtree( UMUL, p, NIL );
 7272         }
 7373         return( optim(p) );
 7474 }
 7575 
 7676         /* mapping relationals when the sides are reversed */
 7777 short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
 7878 
 7979 /*
 8080  * local optimizations, most of which are probably
 8181  * machine independent
 8282  */
 8383 NODE *
 8484 optim(NODE *p)
 8585 {
 8686         int o, ty;
 8787         NODE *sp, *q;
 8888         OFFSZ sz;
 8989         int i;
 9090 
 9191         if (odebug) return(p);
 9292 
 9393         ty = coptype(p->n_op);
 9494         if( ty == LTYPE ) return(p);
 9595 
 9696         if( ty == BITYPE ) p->n_right = optim(p->n_right);
 9797         p->n_left = optim(p->n_left);
 9898 
 9999         /* collect constants */
 100100 again:  o = p->n_op;
 101101         switch(o){
 102102 
 103103         case SCONV:
 104104                 if (concast(p->n_left, p->n_type)) {
 105105                         q = p->n_left;
 106106                         nfree(p);
 107107                         p = q;
 108108                         break;
 109109                 }
 110110                 /* FALLTHROUGH */
 111111         case PCONV:
 112112                 if (p->n_type != VOID)
 113113                         p = clocal(p);
 114114                 break;
 115115 
 116116         case FORTCALL:
 117117                 p->n_right = fortarg( p->n_right );
 118118                 break;
 119119 
 120120         case ADDROF:
 121121                 if (LO(p) == TEMP)
 122122                         break;
 123123                 if( LO(p) != NAME ) cerror( "& error" );
 124124 
 125125                 if( !andable(p->n_left) && !statinit)
 126126                         break;
 127127 
 128128                 LO(p) = ICON;
 129129 
 130130                 setuleft:
 131131                 /* paint over the type of the left hand side with the type of the top */
 132132                 p->n_left->n_type = p->n_type;
 133133                 p->n_left->n_df = p->n_df;
 134134                 p->n_left->n_ap = p->n_ap;
 135135                 q = p->n_left;
 136136                 nfree(p);
 137137                 p = q;
 138138                 break;
 139139 
 140140         case NOT:
 141141         case UMINUS:
 142142         case COMPL:
 143143                 if (LCON(p) && conval(p->n_left, o, p->n_left))
 144144                         p = nfree(p);
 145145                 break;
 146146 
 147147         case UMUL:
 148148                 /* Do not discard ADDROF TEMP's */
 149149                 if (LO(p) == ADDROF && LO(p->n_left) != TEMP) {
 150150                         q = p->n_left->n_left;
 151151                         nfree(p->n_left);
 152152                         nfree(p);
 153153                         p = q;
 154154                         break;
 155155                 }
 156156                 if( LO(p) != ICON ) break;
 157157                 LO(p) = NAME;
 158158                 goto setuleft;
 159159 
 160160         case RS:
 161161                 if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
 162162                         goto zapright;
 163163 
 164164                 sz = tsize(p->n_type, p->n_df, p->n_ap);
 165165 
 166166                 if (LO(p) == RS && RCON(p->n_left) && RCON(p) &&
 167167                     (RV(p) + RV(p->n_left)) < sz) {
 168168                         /* two right-shift  by constants */
 169169                         RV(p) += RV(p->n_left);
 170170                         p->n_left = zapleft(p->n_left);
 171171                 }
 172172 #if 0
 173173                   else if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
 174174                         RV(p) -= RV(p->n_left);
 175175                         if (RV(p) < 0)
 176176                                 o = p->n_op = LS, RV(p) = -RV(p);
 177177                         p->n_left = zapleft(p->n_left);
 178178                 }
 179179 #endif
 180180                 if (RO(p) == ICON) {
 181181                         if (RV(p) < 0) {
 182182                                 RV(p) = -RV(p);
 183183                                 p->n_op = LS;
 184184                                 goto again;
 185185                         }
 186186 #ifdef notyet /* must check for side effects, --a >> 32; */
 187187                         if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue) &&
 188188                             ISUNSIGNED(p->n_type)) { /* ignore signed shifts */
 189189                                 /* too many shifts */
 190190                                 tfree(p->n_left);
 191191                                 nfree(p->n_right);
 192192                                 p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
 193193                         } else
 194194 #endif
 195195                         /* avoid larger shifts than type size */
 196196                         if (RV(p) >= sz)
 197197                                 werror("shift larger than type");
 198198                         if (RV(p) == 0)
 199199                                 p = zapleft(p);
 200200                 }
 201201                 break;
 202202 
 203203         case LS:
 204204                 if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
 205205                         goto zapright;
 206206 
 207207                 sz = tsize(p->n_type, p->n_df, p->n_ap);
 208208 
 209209                 if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
 210210                         /* two left-shift  by constants */
 211211                         RV(p) += RV(p->n_left);
 212212                         p->n_left = zapleft(p->n_left);
 213213                 }
 214214 #if 0
 215215                   else if (LO(p) == RS && RCON(p->n_left) && RCON(p)) {
 216216                         RV(p) -= RV(p->n_left);
 217217                         p->n_left = zapleft(p->n_left);
 218218                 }
 219219 #endif
 220220                 if (RO(p) == ICON) {
 221221                         if (RV(p) < 0) {
 222222                                 RV(p) = -RV(p);
 223223                                 p->n_op = RS;
 224224                                 goto again;
 225225                         }
 226226 #ifdef notyet /* must check for side effects */
 227227                         if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue)) {
 228228                                 /* too many shifts */
 229229                                 tfree(p->n_left);
 230230                                 nfree(p->n_right);
 231231                                 p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
 232232                         } else
 233233 #endif
 234234                         /* avoid larger shifts than type size */
 235235                         if (RV(p) >= sz)
 236236                                 werror("shift larger than type");
 237237                         if (RV(p) == 0
 238238                                 p = zapleft(p);
 239239                 }
 240240                 break;
 241241 
 242242         case QUEST:
<>243 -                if (LCON(p) == 0)
  243+                if (!LCON(p))
<_244244                         break;
 245245                 if (LV(p) == 0) {
 246246                         q = p->n_right->n_right;
 247247                 } else {
 248248                         q = p->n_right->n_left;
 249249                         p->n_right->n_left = p->n_right->n_right;
 250250                 }
 251251                 p->n_right->n_op = UMUL; /* for tfree() */
 252252                 tfree(p);
 253253                 p = q;
 254254                 break;
 255255 
 256256         case MINUS:
 257257                 if (LCON(p) && RCON(p) && p->n_left->n_sp == p->n_right->n_sp) {
 258258                         /* link-time constants, but both are the same */
 259259                         /* solve it now by forgetting the symbols */
 260260                         p->n_left->n_sp = p->n_right->n_sp = NULL;
 261261                 }
 262262                 if( !nncon(p->n_right) ) break;
 263263                 RV(p) = -RV(p);
 264264                 o = p->n_op = PLUS;
 265265                 /* FALLTHROUGH */
 266266         case MUL:
 267267                 /*
 268268                  * Check for u=(x-y)+z; where all vars are pointers to
 269269                  * the same struct. This has two advantages:
 270270                  * 1: avoid a mul+div
 271271                  * 2: even if not allowed, people may get surprised if this
 272272                  *    calculation do not give correct result if using
 273273                  *    unaligned structs.
 274274                  */
 275275                 if (o == MUL && p->n_type == INTPTR && RCON(p) &&
 276276                     LO(p) == DIV && RCON(p->n_left) &&
 277277                     RV(p) == RV(p->n_left) &&
 278278                     LO(p->n_left) == MINUS) {
 279279                         q = p->n_left->n_left;
 280280                         if (q->n_left->n_type == PTR+STRTY &&
 281281                             q->n_right->n_type == PTR+STRTY &&
 282282                             strmemb(q->n_left->n_ap) ==
 283283                             strmemb(q->n_right->n_ap)) {
 284284                                 p = zapleft(p);
 285285                                 p = zapleft(p);
 286286                         }
 287287                 }
 288288                 /* FALLTHROUGH */
 289289         case PLUS:
 290290         case AND:
 291291         case OR:
 292292         case ER:
 293293                 /* commutative ops; for now, just collect constants */
 294294                 /* someday, do it right */
 295295                 if( nncon(p->n_left) || ( LCON(p) && !RCON(p) ) )
 296296                         SWAP( p->n_left, p->n_right );
 297297                 /* make ops tower to the left, not the right */
 298298                 if( RO(p) == o ){
 299299                         NODE *t1, *t2, *t3;
 300300                         t1 = p->n_left;
 301301                         sp = p->n_right;
 302302                         t2 = sp->n_left;
 303303                         t3 = sp->n_right;
 304304                         /* now, put together again */
 305305                         p->n_left = sp;
 306306                         sp->n_left = t1;
 307307                         sp->n_right = t2;
 308308                         sp->n_type = p->n_type;
 309309                         p->n_right = t3;
 310310                         }
 311311                 if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->n_left) &&
 312312                    conval(p->n_right, MINUS, p->n_left->n_right)){
 313313                         zapleft:
 314314 
 315315                         q = p->n_left->n_left;
 316316                         nfree(p->n_left->n_right);
 317317                         nfree(p->n_left);
 318318                         p->n_left = q;
 319319                 }
 320320                 if( RCON(p) && LO(p)==o && RCON(p->n_left) &&
 321321                     conval( p->n_right, o, p->n_left->n_right ) ){
 322322                         goto zapleft;
 323323                         }
 324324                 else if( LCON(p) && RCON(p) && conval( p->n_left, o, p->n_right ) ){
 325325                         zapright:
 326326                         nfree(p->n_right);
 327327                         q = makety(p->n_left, p->n_type, p->n_qual,
 328328                             p->n_df, p->n_ap);
 329329                         nfree(p);
 330330                         p = clocal(q);
 331331                         break;
 332332                         }
 333333 
 334334                 /* change muls to shifts */
 335335 
 336336                 if( o == MUL && nncon(p->n_right) && (i=ispow2(RV(p)))>=0){
 337337                         if( i == 0 ) { /* multiplication by 1 */
 338338                                 goto zapright;
 339339                                 }
 340340                         o = p->n_op = LS;
 341341                         p->n_right->n_type = INT;
 342342                         p->n_right->n_df = NULL;
 343343                         RV(p) = i;
 344344                         }
 345345 
 346346                 /* change +'s of negative consts back to - */
 347347                 if( o==PLUS && nncon(p->n_right) && RV(p)<0 ){
 348348                         RV(p) = -RV(p);
 349349                         o = p->n_op = MINUS;
 350350                         }
 351351 
 352352                 /* remove ops with RHS 0 */
 353353                 if ((o == PLUS || o == MINUS || o == OR || o == ER) &&
 354354                     nncon(p->n_right) && RV(p) == 0) {
 355355                         goto zapright;
 356356                 }
 357357                 break;
 358358 
 359359         case DIV:
 360360                 if( nncon( p->n_right ) && p->n_right->n_lval == 1 )
 361361                         goto zapright;
 362362                 if (LCON(p) && RCON(p) && conval(p->n_left, DIV, p->n_right))
 363363                         goto zapright;
 364364                 if (RCON(p) && ISUNSIGNED(p->n_type) && (i=ispow2(RV(p))) > 0) {
 365365                         p->n_op = RS;
 366366                         RV(p) = i;
 367367                         q = p->n_right;
 368368                         if(tsize(q->n_type, q->n_df, q->n_ap) > SZINT)
 369369                                 p->n_right = makety(q, INT, 0, 0, 0);
 370370 
 371371                         break;
 372372                 }
 373373                 break;
 374374 
 375375         case MOD:
 376376                 if (RCON(p) && ISUNSIGNED(p->n_type) && ispow2(RV(p)) > 0) {
 377377                         p->n_op = AND;
 378378                         RV(p) = RV(p) -1;
 379379                         break;
 380380                 }
 381381                 break;
 382382 
 383383         case EQ:
 384384         case NE:
 385385         case LT:
 386386         case LE:
 387387         case GT:
 388388         case GE:
 389389         case ULT:
 390390         case ULE:
 391391         case UGT:
 392392         case UGE:
 393393                 if (LCON(p) && RCON(p) &&
 394394                     !ISPTR(p->n_left->n_type) && !ISPTR(p->n_right->n_type)) {
 395395                         /* Do constant evaluation */
 396396                         q = p->n_left;
 397397                         if (conval(q, o, p->n_right)) {
 398398                                 nfree(p->n_right);
 399399                                 nfree(p);
 400400                                 p = q;
 401401                                 break;
 402402                         }
 403403                 }
 404404 
 405405                 if( !LCON(p) ) break;
 406406 
 407407                 /* exchange operands */
 408408 
 409409                 sp = p->n_left;
 410410                 p->n_left = p->n_right;
 411411                 p->n_right = sp;
 412412                 p->n_op = revrel[p->n_op - EQ ];
 413413                 break;
 414414 
 415415         case CBRANCH:
 416416                 if (LCON(p)) {
 417417                         if (LV(p) == 0) {
 418418                                 tfree(p);
 419419                                 p = bcon(0);
 420420                         } else {
 421421                                 tfree(p->n_left);
 422422                                 p->n_left = p->n_right;
 423423                                 p->n_op = GOTO;
 424424                         }
 425425                 }
 426426                 break;
 427427                                 
 428428 
 429429 #ifdef notyet
 430430         case ASSIGN:
 431431                 /* Simple test to avoid two branches */
 432432                 if (RO(p) != NE)
 433433                         break;
 434434                 q = p->n_right;
 435435                 if (RCON(q) && RV(q) == 0 && LO(q) == AND &&
 436436                     RCON(q->n_left) && (i = ispow2(RV(q->n_left))) &&
 437437                     q->n_left->n_type == INT) {
 438438                         q->n_op = RS;
 439439                         RV(q) = i;
 440440                 }
 441441                 break;
 442442 #endif
 443443         }
 444444 
 445445         return(p);
 446446         }
 447447 
 448448 int
 449449 ispow2(CONSZ c)
 450450 {
 451451         int i;
 452452         if( c <= 0 || (c&(c-1)) ) return(-1);
 453453         for( i=0; c>1; ++i) c >>= 1;
 454454         return(i);
 455455 }
 456456 
 457457 int
 458458 nncon(NODE *p)
 459459 {
 460460         /* is p a constant without a name */
 461461         return( p->n_op == ICON && p->n_sp == NULL );
 462462 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-08-29 11:59 +0200