- int change = 1;
- int gchange = 0 ;
- int i = 0 ;
-
-
- /* basic algorithm :- */
- /* first the exclusion rules :- */
- /* 1. if result is a global or volatile then skip */
- /* 2. if assignment and result is a temp & isaddr then skip */
- /* since this means array & pointer access, will be taken */
- /* care of by alias analysis. */
- /* 3. if the result is used in the remainder of the block skip*/
- /* 4. if this definition does not reach the end of the block */
- /* i.e. the result is not present in the outExprs then KILL*/
- /* 5. if it reaches the end of block & is used by some success*/
- /* or then skip */
- /* else KILL */
- /* this whole process is carried on iteratively till no change */
- while (1) {
-
- change = 0 ;
- /* for all blocks do */
- for ( i = 0 ; i < count ; i++ ) {
- iCode *ic ;
-
- /* for all instructions in the block do */
- for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
- int kill, j ;
- kill = 0 ;
-
- if (SKIP_IC(ic) ||
- ic->op == IFX ||
- ic->op == RETURN )
- continue ;
-
- /* if the result is volatile then continue */
- if (IC_RESULT(ic) && isOperandVolatile(IC_RESULT(ic),FALSE))
- continue ;
-
- /* if the result is a temp & isaddr then skip */
- if (IC_RESULT(ic) && POINTER_SET(ic))
- continue ;
-
- /* if the result is used in the remainder of the */
- /* block then skip */
- if (usedInRemaining (IC_RESULT(ic),ic->next))
- continue ;
-
- /* does this definition reach the end of the block
- or the usage is zero then we can kill */
- if (! bitVectBitValue(ebbs[i]->outDefs,ic->key))
- kill = 1; /* if not we can kill it */
- else {
- /* if this is a global variable or function parameter */
- /* we cannot kill anyway */
- if (isOperandGlobal(IC_RESULT(ic)) ||
- (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
- !OP_SYMBOL(IC_RESULT(ic))->ismyparm))
- continue ;
-
- /* if we are sure there are no usages */
- if (bitVectIsZero(OP_USES(IC_RESULT(ic)))) {
- kill = 1 ;
- goto kill ;
- }
-
- /* reset visited flag */
- for(j=0; j < count ; ebbs[j++]->visited = 0);
-
- /* find out if this definition is alive */
- if ( applyToSet (ebbs[i]->succList,
- isDefAlive,
- ic))
- continue ;
-
- kill = 1;
- }
-
- kill :
- /* kill this one if required */
- if (kill) {
- change = 1;
- gchange++ ;
- /* eliminate this */
- remiCodeFromeBBlock(ebbs[i],ic);
-
- /* now delete from defUseSet */
- deleteItemIf (&ebbs[i]->outExprs,ifDiCodeIsX,ic);
- bitVectUnSetBit (ebbs[i]->outDefs,ic->key);
-
- /* and defset of the block */
- bitVectUnSetBit (ebbs[i]->defSet,ic->key);
-
- /* for the left & right remove the usage */
- if (IS_SYMOP(IC_LEFT(ic)))
- bitVectUnSetBit(OP_USES(IC_LEFT(ic)),ic->key);
-
- if (IS_SYMOP(IC_RIGHT(ic)))
- bitVectUnSetBit(OP_USES(IC_RIGHT(ic)),ic->key);
- }
-
- } /* end of all instructions */
-
- if (!ebbs[i]->sch && !ebbs[i]->noPath)
- disconBBlock(ebbs[i],ebbs,count);
-
- } /* end of for all blocks */
-
- if (!change)
- break;
- } /* end of while(1) */
-
- return gchange ;
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
+ int change = 1;
+ int gchange = 0;
+ int i = 0;
+
+
+ /* basic algorithm :- */
+ /* first the exclusion rules :- */
+ /* 1. if result is a global or volatile then skip */
+ /* 2. if assignment and result is a temp & isaddr then skip */
+ /* since this means array & pointer access, will be taken */
+ /* care of by alias analysis. */
+ /* 3. if the result is used in the remainder of the block skip */
+ /* 4. if this definition does not reach the end of the block */
+ /* i.e. the result is not present in the outExprs then KILL */
+ /* 5. if it reaches the end of block & is used by some success */
+ /* or then skip */
+ /* else KILL */
+ /* this whole process is carried on iteratively till no change */
+ while (1)
+ {
+
+ change = 0;
+ /* for all blocks do */
+ for (i = 0; i < count; i++)
+ {
+ iCode *ic;
+
+ /* for all instructions in the block do */
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ int kill, j;
+ kill = 0;
+
+ if (SKIP_IC (ic) ||
+ ic->op == IFX ||
+ ic->op == RETURN ||
+ ic->op == DUMMY_READ_VOLATILE ||
+ ic->op == CRITICAL ||
+ ic->op == ENDCRITICAL)
+ continue;
+
+ /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
+ /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
+ /* valid. */
+
+ /* if the result is volatile then continue */
+ if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
+ continue;
+
+ /* if the result is a temp & isaddr then skip */
+ if (IC_RESULT (ic) && POINTER_SET (ic))
+ continue;
+
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
+ && !SPIL_LOC (IC_RESULT (ic)))
+ continue;
+
+ /* if the result is used in the remainder of the */
+ /* block then skip */
+ if (usedInRemaining (IC_RESULT (ic), ic->next))
+ continue;
+
+ /* does this definition reach the end of the block
+ or the usage is zero then we can kill */
+ if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
+ kill = 1; /* if not we can kill it */
+ else
+ {
+ /* if this is a global variable or function parameter */
+ /* we cannot kill anyway */
+ if (isOperandGlobal (IC_RESULT (ic)) ||
+ (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
+ !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+ continue;
+
+ /* if we are sure there are no usages */
+ if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
+ {
+ kill = 1;
+ goto kill;
+ }
+
+ /* reset visited flag */
+ for (j = 0; j < count; ebbs[j++]->visited = 0);
+
+ /* find out if this definition is alive */
+ if (applyToSet (ebbs[i]->succList,
+ isDefAlive,
+ ic))
+ continue;
+
+ kill = 1;
+ }
+
+ kill:
+ /* kill this one if required */
+ if (kill)
+ {
+ bool volLeft = IS_SYMOP (IC_LEFT (ic))
+ && isOperandVolatile (IC_LEFT (ic), FALSE);
+ bool volRight = IS_SYMOP (IC_RIGHT (ic))
+ && isOperandVolatile (IC_RIGHT (ic), FALSE);
+
+ /* a dead address-of operation should die, even if volatile */
+ if (ic->op == ADDRESS_OF)
+ volLeft = FALSE;
+
+ if (ic->next && ic->seqPoint == ic->next->seqPoint
+ && (ic->next->op == '+' || ic->next->op == '-'))
+ {
+ if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
+ || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
+ volLeft = FALSE;
+ if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
+ || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
+ volRight = FALSE;
+ }
+
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+ {
+ if (SPIL_LOC (IC_RESULT (ic)))
+ {
+ IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
+ SPIL_LOC (IC_RESULT (ic)) = NULL;
+ }
+ continue;
+ }
+
+ change = 1;
+ gchange++;
+
+ /* now delete from defUseSet */
+ deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
+ bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
+
+ /* and defset of the block */
+ bitVectUnSetBit (ebbs[i]->defSet, ic->key);
+
+ /* If this is the last of a register equivalent, */
+ /* look for a successor register equivalent. */
+ bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+ if (IS_ITEMP (IC_RESULT (ic))
+ && OP_SYMBOL (IC_RESULT (ic))->isreqv
+ && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
+ {
+ symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
+ symbol * prereqv = resultsym->prereqv;
+
+ if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
+ {
+ operand * newreqv;
+
+ IC_RESULT (ic) = NULL;
+ newreqv = findReqv (prereqv, ebbs, count);
+ if (newreqv)
+ {
+ prereqv->reqv = newreqv;
+ }
+ }
+ }
+
+ /* delete the result */
+ IC_RESULT (ic) = NULL;
+
+ if (volLeft || volRight)
+ {
+ /* something is volatile, so keep the iCode */
+ /* and change the operator instead */
+ ic->op = DUMMY_READ_VOLATILE;
+
+ /* keep only the volatile operands */
+ if (!volLeft)
+ IC_LEFT (ic) = NULL;
+ if (!volRight)
+ IC_RIGHT (ic) = NULL;
+ }
+ else
+ {
+ /* nothing is volatile, eliminate the iCode */
+ remiCodeFromeBBlock (ebbs[i], ic);
+
+ /* for the left & right remove the usage */
+ if (IS_SYMOP (IC_LEFT (ic)))
+ bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+
+ if (IS_SYMOP (IC_RIGHT (ic)))
+ bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ }
+ }
+
+ } /* end of all instructions */
+
+ if (!ebbs[i]->sch && !ebbs[i]->noPath)
+ disconBBlock (ebbs[i], ebbi);
+
+ } /* end of for all blocks */
+
+ if (!change)
+ break;
+ } /* end of while(1) */
+
+ return gchange;