cseDef *cdp = item;
iCodeTable *icTab ;
+ (void)ap;
+
if (!cdp->sym)
fprintf(stdout,"**null op**");
printOperand(cdp->sym,stdout);
/* 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 ;
}
- if (IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
+ if (IS_SYMOP(to) &&
+ IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
bitVectUnSetBit (OP_USES(from),lic->key);
OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
siaddr = IC_RIGHT(lic)->isaddr ;
IC_RIGHT(lic)->isaddr = siaddr ;
}
- if (IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
+ if (IS_SYMOP(to) &&
+ IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
bitVectUnSetBit (OP_USES(from),lic->key);
OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
siaddr = IC_LEFT(lic)->isaddr ;
IC_LEFT(lic) = operandFromOperand(to);
IC_LEFT(lic)->isaddr = siaddr ;
- }
+ }
}
}
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;
suggested by Jean-Louis VERN, with 8051s we have no
advantage of putting variables in near space into
registers */
- if (isOperandGlobal(op) &&
+ if (isOperandGlobal(op) && !IN_FARSPACE(SPEC_OCLS(type)) &&
IN_DIRSPACE(SPEC_OCLS(type)))
return TRUE;
else
return (isOperandGlobal(cdp->sym));
}
+/*-----------------------------------------------------------------*/
+/* ifAnyGetPointer - if get pointer icode */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(ifAnyGetPointer)
+{
+ cseDef *cdp = item;
+
+ if (cdp->diCode && POINTER_GET(cdp->diCode)) return 1;
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* ifOperandsHave - if any of the operand are the same as this */
/*-----------------------------------------------------------------*/
/* if the conditional is a literal then */
if (IS_OP_LITERAL(IC_COND(ic))) {
- if ( operandLitValue(IC_COND(ic)) && IC_TRUE(ic)) {
+ if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
/* change to a goto */
ic->op = GOTO ;
int constFold (iCode *ic, set *cseSet)
{
iCode *dic = NULL;
+ iCode *ldic= NULL;
/* this routine will change
a = b + 10;
c = a + 10;
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));
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;
+
+ if (IS_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 */
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);
/* 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 (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),
/* update the spill location for this */
updateSpillLocation (ic);
- if (POINTER_SET(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)
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*/
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 */
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);
}
/* 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);
}
}