- IC_RIGHT(ic) = pdop;
- change = 1;
- }
- }
-
- /* if left or right changed then do algebraic */
- if (change) {
- algebraicOpts(ic);
- while(constFold(ic,cseSet));
- }
-
- /* if after all this it becomes a assignment to self
- then delete it and continue */
- if (ASSIGNMENT_TO_SELF(ic)) {
- remiCodeFromeBBlock(ebb,ic);
- continue;
- }
-
- /* now we will check to see if the entire */
- /* operation has been performed before */
- /* and is available */
- /* don't do assignments they will be killed */
- /* by dead code elimination if required do */
- /* it only if result is a temporary */
- pdic = NULL ;
- if (!( POINTER_GET(ic) &&
- (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
- 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*/
- /* to cseSet an element containing result */
- /* of this with previous opcode */
- if (pdic) {
-
- if (IS_ITEMP(IC_RESULT(ic))) {
-
- /* replace in the remaining of this block */
- 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 */
- for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
- applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
- IC_RESULT(pdic),ebb);
-
- /* if this was moved from another block */
- /* then replace in those blocks too */
- if ( ic->movedFrom ) {
- eBBlock *owner ;
- for (owner = setFirstItem(ic->movedFrom); owner ;
- owner = setNextItem(ic->movedFrom))
- replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic),&owner->ndompset);
- }
- pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
- }
+ /* set of common subexpressions */
+ cseSet = setFromSet (ebb->inExprs);
+
+ /* these will be computed by this routine */
+ setToNull ((void **) &ebb->outDefs);
+ setToNull ((void **) &ebb->defSet);
+ setToNull ((void **) &ebb->usesDefs);
+ setToNull ((void **) &ebb->ptrsSet);
+ setToNull ((void **) &ebb->addrOf);
+ setToNull ((void **) &ebb->ldefs);
+
+ ebb->outDefs = bitVectCopy (ebb->inDefs);
+ bitVectDefault = iCodeKey;
+ ebb->defSet = newBitVect (iCodeKey);
+ ebb->usesDefs = newBitVect (iCodeKey);
+
+ /* for all the instructions in this block do */
+ for (ic = ebb->sch; ic; ic = ic->next)
+ {
+
+ iCode *pdic;
+ operand *pdop;
+ iCode *defic;
+
+ 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);
+
+ if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
+ {
+ /* add to defSet of the symbol */
+ OP_DEFS (IC_RESULT (ic)) =
+ bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+ /* add to the definition set of this block */
+ ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
+ ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
+ ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
+ setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+ /* delete global variables from the cseSet
+ since they can be modified by the function call */
+ deleteItemIf (&cseSet, ifDefGlobal);
+ /* delete all getpointer iCodes from cseSet, this should
+ be done only for global arrays & pointers but at this
+ point we don't know if globals, so to be safe do all */
+ deleteItemIf (&cseSet, ifAnyGetPointer);
+ }
+
+ /* for pcall & ipush we need to add to the useSet */
+ if ((ic->op == PCALL ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == SEND) &&
+ IS_SYMOP (IC_LEFT (ic)))
+ {
+
+ /* check if they can be replaced */
+ if (!computeOnly)
+ {
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
+ if (pdop)
+ IC_LEFT (ic) = pdop;
+ }
+ /* the lookup could have changed it */
+ if (IS_SYMOP (IC_LEFT (ic)))
+ {
+ OP_USES (IC_LEFT (ic)) =
+ bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+ setUsesDefs (IC_LEFT (ic), ebb->defSet,
+ ebb->outDefs, &ebb->usesDefs);
+ }
+
+
+ /* if we a sending a pointer as a parameter
+ then kill all cse since the pointed to item
+ might be changed in the function being called */
+ if ((ic->op == IPUSH || ic->op == SEND) &&
+ IS_PTR (operandType (IC_LEFT (ic))))
+ {
+ deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
+ ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
+ for (i = 0; i < count; ebbs[i++]->visited = 0);
+ applyToSet (ebb->succList, delGetPointerSucc,
+ IC_LEFT (ic), ebb->dfnum);
+ }
+ continue;
+ }
+
+ /* if jumptable then mark the usage */
+ if (ic->op == JUMPTABLE)
+ {
+ OP_USES (IC_JTCOND (ic)) =
+ bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
+ setUsesDefs (IC_JTCOND (ic), ebb->defSet,
+ ebb->outDefs, &ebb->usesDefs);
+ continue;
+ }
+
+ if (SKIP_IC (ic))
+ continue;
+
+ /* do some algebraic optimizations if possible */
+ algebraicOpts (ic);
+ while (constFold (ic, cseSet));
+
+ /* small klugde */
+ 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),
+ aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+ }
+
+ /* if this is a condition statment then */
+ /* check if the condition can be replaced */
+ if (ic->op == IFX)
+ {
+ ifxOptimize (ic, cseSet, computeOnly,
+ ebb, &change,
+ ebbs, count);
+ continue;
+ }
+
+ /* if the assignment & result is a temp */
+ /* see if we can replace it */
+ if (ic->op == '=')
+ {
+
+ /* update the spill location for this */
+ updateSpillLocation (ic);
+
+ if (POINTER_SET (ic) &&
+ !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
+ {
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop);
+ if (pdop && IS_ITEMP (pdop) && !computeOnly)
+ IC_RESULT (ic) = pdop;
+ }
+ }
+
+ /* do the operand lookup i.e. for both the */
+ /* right & left operand : check the cseSet */
+ /* to see if they have been replaced if yes */
+ /* then replace them with those from cseSet */
+ /* left operand */
+ /* and left is a symbol */
+ if (IS_SYMOP (IC_LEFT (ic)) &&
+ !computeOnly && ic->op != ADDRESS_OF)
+ {
+
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
+ if (pdop)
+ {
+ if (POINTER_GET (ic))
+ {
+ if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
+ {
+ IC_LEFT (ic) = pdop;
+ change = 1;
+ }
+ /* check if there is a pointer set
+ for the same pointer visible if yes
+ then change this into an assignment */
+ pdop = NULL;
+ if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
+ !bitVectBitValue (ebb->ptrsSet, pdop->key))
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ IC_RIGHT (ic) = pdop;
+ SET_ISADDR (IC_RESULT (ic), 0);
+ }
+
+ }
+ else
+ {
+ IC_LEFT (ic) = pdop;
+ change = 1;
+ }
+ }
+ }
+
+ /*right operand */
+ if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
+ {
+
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
+ if (pdop)
+ {
+
+ IC_RIGHT (ic) = pdop;
+ change = 1;
+ }
+ }
+
+ /* if left or right changed then do algebraic */
+ if (change)
+ {
+ algebraicOpts (ic);
+ while (constFold (ic, cseSet));
+ }
+
+ /* if after all this it becomes a assignment to self
+ then delete it and continue */
+ if (ASSIGNMENT_TO_SELF (ic))
+ {
+ remiCodeFromeBBlock (ebb, ic);
+ continue;
+ }
+
+ /* now we will check to see if the entire */
+ /* operation has been performed before */
+ /* and is available */
+ /* don't do assignments they will be killed */
+ /* by dead code elimination if required do */
+ /* it only if result is a temporary */
+ pdic = NULL;
+ if (!(POINTER_GET (ic) &&
+ (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
+ 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 */
+ /* to cseSet an element containing result */
+ /* of this with previous opcode */
+ if (pdic)
+ {
+
+ if (IS_ITEMP (IC_RESULT (ic)))
+ {
+
+ /* replace in the remaining of this block */
+ 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 */
+ for (i = 0; i < count; ebbs[i++]->visited = 0);
+ applyToSet (ebb->succList, removeFromInExprs, ic, IC_RESULT (ic),
+ IC_RESULT (pdic), ebb);
+
+ /* if this was moved from another block */
+ /* then replace in those blocks too */
+ if (ic->movedFrom)
+ {
+ eBBlock *owner;
+ for (owner = setFirstItem (ic->movedFrom); owner;
+ owner = setNextItem (ic->movedFrom))
+ replaceAllSymBySym (owner->sch, IC_RESULT (ic), IC_RESULT (pdic), &owner->ndompset);
+ }
+ pdic->movedFrom = unionSets (pdic->movedFrom, ic->movedFrom, THROW_NONE);
+ }
+ else
+ addSetHead (&cseSet, newCseDef (IC_RESULT (ic), pdic));
+
+ if (!computeOnly)
+ /* eliminate this */
+ remiCodeFromeBBlock (ebb, ic);
+
+ defic = pdic;
+ change++;
+
+ if (IS_ITEMP (IC_RESULT (ic)))
+ continue;
+
+ }