- {
- 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 */
+ {
+ 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 */