Break DS80C390 support into seperate port (ds390); first pass at spilling temporaries...
[fw/sdcc] / src / SDCCcse.c
index d84c007d02a1a715ea8a4eddf04ce1091301e4cd..72129a291e2a34ff0a73cce002c24b3b20d77534 100644 (file)
@@ -81,24 +81,61 @@ int pcseDef (void *item, va_list ap)
 /* replaceAllSymBySym - replaces all operands by operand in an     */
 /*                      instruction chain                          */
 /*-----------------------------------------------------------------*/
-void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
+void replaceAllSymBySym (iCode *ic, operand *from , operand *to, bitVect **ndpset)
 {
     iCode *lic;
 
     for (lic = ic ; lic ; lic = lic->next ) {
        int siaddr ;
 
+       /* do the special cases first */
+       if (lic->op == IFX) {
+               if (IS_SYMOP(to) &&
+                   IC_COND(lic)->key == from->key) {
+                       
+                       bitVectUnSetBit (OP_USES(from),lic->key);
+                       OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+                       siaddr = IC_COND(lic)->isaddr ;
+                       IC_COND(lic) = operandFromOperand(to);
+                       IC_COND(lic)->isaddr = siaddr ;
+                       
+               }
+               continue ;
+       }
+
+       if (lic->op == JUMPTABLE) {
+               if (IS_SYMOP(to) &&
+                   IC_JTCOND(lic)->key == from->key) {
+                       
+                       bitVectUnSetBit (OP_USES(from),lic->key);
+                       OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+                       siaddr = IC_COND(lic)->isaddr ;
+                       IC_JTCOND(lic) = operandFromOperand(to);
+                       IC_JTCOND(lic)->isaddr = siaddr ;
+                       
+               }
+               continue ;
+       }
+
        if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
            /* maintain du chains */
            if (POINTER_SET(lic)) {
                bitVectUnSetBit (OP_USES(from),lic->key);
                OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
+
+               /* also check if the "from" was in the non-dominating 
+                  pointer sets and replace it with "to" in the bitVector */
+               if (bitVectBitValue(*ndpset,from->key)) {
+                   bitVectUnSetBit(*ndpset,from->key);
+                   bitVectSetBit(*ndpset,to->key);
+               }
+
            }
            else {              
                bitVectUnSetBit (OP_DEFS(from),lic->key);
                OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
-           }
-           siaddr = IC_RESULT(lic)->isaddr ;
+           }       
+           siaddr = IC_RESULT(lic)->isaddr ;       
            IC_RESULT(lic) = operandFromOperand(to);
            IC_RESULT(lic)->isaddr = siaddr ;
        }
@@ -119,7 +156,7 @@ void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
            siaddr = IC_LEFT(lic)->isaddr ;
            IC_LEFT(lic) = operandFromOperand(to);
            IC_LEFT(lic)->isaddr = siaddr ;
-       }
+       }       
     }
 }
 
@@ -154,7 +191,7 @@ DEFSETFUNC(removeFromInExprs)
     ebp->visited = 1;
     deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key);
     if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum))
-       replaceAllSymBySym(ebp->sch,from,to);
+       replaceAllSymBySym(ebp->sch,from,to,&ebp->ndompset);
 
     applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
     return 0;
@@ -936,6 +973,7 @@ DEFSETFUNC(diCodeForSym)
 int constFold (iCode *ic, set *cseSet)
 {
     iCode *dic = NULL;
+    iCode *ldic= NULL;
     /* this routine will change
        a = b + 10;
        c = a + 10;
@@ -969,6 +1007,16 @@ int constFold (iCode *ic, set *cseSet)
     if (!IS_OP_LITERAL(IC_RIGHT(dic)))
        return 0;
 
+    /* find the definition of the left operand
+       of dic.then check if this defined with a
+       get_pointer return 0 if the pointer size is
+       less than 2 (MCS51 specific) */
+    if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(dic),&ldic)))
+       return 0;
+
+    if (POINTER_GET(ldic) && getSize(operandType(IC_LEFT(ldic))) <= 1)
+       return 0;
+    
     /* it is if the operations are the same*/
     /* the literal parts need to be added  */
     IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));    
@@ -1060,6 +1108,29 @@ DEFSETFUNC(delGetPointerSucc)
     return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
 }    
 
+/*-----------------------------------------------------------------*/
+/* fixUpTypes - KLUGE HACK fixup a lowering problem                */
+/*-----------------------------------------------------------------*/
+static void fixUpTypes(iCode *ic)
+{
+       link *t1 = operandType(IC_LEFT(ic)) ,*t2;
+       
+       extern PORT ds390_port;
+       
+       if (port == &ds390_port)
+       {
+           /* hack-o-matic! */
+           return;
+       }
+       
+       /* for pointer_gets if the types of result & left r the
+          same then change it type of result to next */
+       if (IS_PTR(t1) &&
+           checkType(t2=operandType(IC_RESULT(ic)),t1) == 1) {
+               setOperandType(IC_RESULT(ic),t2->next);
+       }
+}
+
 /*-----------------------------------------------------------------*/
 /* cseBBlock - common subexpression elimination for basic blocks   */
 /*             this is the hackiest kludgiest routine in the whole */
@@ -1105,6 +1176,13 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
        if (SKIP_IC2(ic))
            continue ;
 
+       /* if this is an assignment from true symbol
+          to a temp then do pointer post inc/dec optimzation */
+       if (ic->op == '=' && !POINTER_SET(ic) &&
+           IS_PTR(operandType(IC_RESULT(ic)))) {
+           ptrPostIncDecOpt(ic);
+       }
+
        /* clear the def & use chains for the operands involved */
        /* in this operation . since it can change due to opts  */
        unsetDefsAndUses (ic);
@@ -1180,6 +1258,8 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
        if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
            setOperandType(IC_LEFT(ic),
                           aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
+           fixUpTypes(ic);
+
        }
        if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
            setOperandType(IC_RESULT(ic),
@@ -1281,11 +1361,15 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
        pdic = NULL ;   
        if (!( POINTER_GET(ic)                      &&
               (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
-              isOperandVolatile(IC_LEFT(ic),TRUE))) &&
+              isOperandVolatile(IC_LEFT(ic),TRUE)           ||
+              bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))) &&
            ! ASSIGNMENT(ic)                        && 
              IS_ITEMP(IC_RESULT(ic))               &&
            ! computeOnly) {
            applyToSet (cseSet,findPrevIc,ic,&pdic);
+           if (pdic && checkType(operandType(IC_RESULT(pdic)),
+                                 operandType(IC_RESULT(ic))) != 1)
+                   pdic = NULL;
        } 
        
        /* if found then eliminate this and add to*/
@@ -1296,7 +1380,7 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
            if (IS_ITEMP(IC_RESULT(ic))) {
 
                /* replace in the remaining of this block */
-               replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
+               replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic),&ebb->ndompset);
                /* remove this iCode from inexpressions of all
                   its successors, it cannot be in the in expressions
                   of any of the predecessors */        
@@ -1310,7 +1394,7 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
                    eBBlock *owner ;
                    for (owner = setFirstItem(ic->movedFrom); owner ;
                         owner = setNextItem(ic->movedFrom))
-                       replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
+                       replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic),&owner->ndompset);
                }
                pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
            } 
@@ -1362,7 +1446,7 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
            /* if we find it then locally replace all
               references to the result with what we assigned */
            if (pdop) {
-               replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop);
+               replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop,&ebb->ndompset);
            }
        }