/*-----------------------------------------------------------------*/
static induction *
newInduction (operand * sym, unsigned int op,
- long constVal, iCode * ic, operand * asym)
+ long constVal, iCode * ic, operand * asym)
{
induction *ip;
exit = setNextItem (lexits))
{
succVect = bitVectIntersect (succVect,
- exit->succVect);
+ exit->succVect);
}
return succVect;
block = setNextItem (lreg->regBlocks))
{
if (block != lblock && block->lSeq > lblock->lSeq)
- lblock = block;
+ lblock = block;
}
return lblock->lSeq;
block = STACK_POP (regionStack);
/* if block != entry */
if (block != ep->to)
- applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks);
+ applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks);
}
aloop->entry = ep->to;
if (op)
{
if (IS_OP_LITERAL (op))
- opin = 1;
+ opin = 1;
else if (IS_SYMOP (op) &&
- OP_SYMBOL (op)->addrtaken)
- opin = 0;
+ OP_SYMBOL (op)->addrtaken)
+ opin = 0;
else if (ifDefSymIs (theLoop->entry->inExprs, op))
- opin = 1;
+ opin = 1;
else if (ifDefSymIs (lInvars, op))
- opin = 1;
+ opin = 1;
else if (IS_SYMOP (op) &&
- !IS_OP_GLOBAL (op) &&
- !IS_OP_VOLATILE (op) &&
- assignmentsToSym (theLoop->regBlocks, op) == 0)
- opin = 1;
+ !IS_OP_GLOBAL (op) &&
+ !IS_OP_VOLATILE (op) &&
+ assignmentsToSym (theLoop->regBlocks, op) == 0)
+ opin = 1;
}
else
opin++;
/* mark the dominates all exits flag */
domsAllExits = (applyToSet (theLoop->exits, dominatedBy, lBlock) ==
- elementsInSet (theLoop->exits));
+ elementsInSet (theLoop->exits));
/* find out if we have a function call in this block */
- for (ic = lBlock->sch, fCallsInBlock=0; ic; ic = ic->next) {
- if (SKIP_IC(ic)) {
- fCallsInBlock++;
- }
- }
+ for (ic = lBlock->sch, fCallsInBlock=0; ic; ic = ic->next)
+ {
+ if (SKIP_IC(ic))
+ {
+ fCallsInBlock++;
+ }
+ }
/* now we go thru the instructions of this block and */
/* collect those instructions with invariant operands */
for (ic = lBlock->sch; ic; ic = ic->next)
- {
-
- int lin, rin;
- cseDef *ivar;
-
- /* TODO this is only needed if the call is between
- here and the definition, but I am too lazy to do that now */
-
- /* if there are function calls in this block */
- if (fCallsInBlock) {
-
- /* if this is a pointer get */
- if (POINTER_GET(ic)) {
- continue;
- }
-
- /* if this is an assignment from a global */
- if (ic->op=='=' && isOperandGlobal(IC_RIGHT(ic))) {
- continue;
- }
- }
-
- if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX)
- continue;
-
- /* iTemp assignment from a literal may be invariant, but it
- will needlessly increase register pressure if the
- iCode(s) that use this iTemp are not also invariant */
- if (ic->op=='=' && IS_ITEMP (IC_RESULT (ic))
- && IS_OP_LITERAL (IC_RIGHT (ic)))
- continue;
-
- /* if result is volatile then skip */
- if (IC_RESULT (ic) &&
- (isOperandVolatile (IC_RESULT (ic), TRUE) ||
- IS_OP_PARM (IC_RESULT (ic))))
- continue;
-
- /* if result depends on a volatile then skip */
- if ((IC_LEFT(ic) && isOperandVolatile(IC_LEFT(ic), TRUE)) ||
- (IC_RIGHT(ic) && isOperandVolatile(IC_RIGHT(ic), TRUE)))
- continue;
-
- lin = rin = 0;
-
- /* special case */
- /* if address of then it is an invariant */
- if (ic->op == ADDRESS_OF &&
- IS_SYMOP (IC_LEFT (ic)) &&
- IS_AGGREGATE (operandType (IC_LEFT (ic))))
- lin++;
- else {
- /* check if left operand is an invariant */
- if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars)))
- /* if this is a pointer get then make sure
- that the pointer set does not exist in
- any of the blocks */
- if (POINTER_GET (ic) &&
- (applyToSet (theLoop->regBlocks,
- pointerAssigned, IC_LEFT (ic))))
- lin = 0;
- }
-
- /* do the same for right */
- rin = isOperandInvariant (IC_RIGHT (ic), theLoop, lInvars);
-
- /* if this is a POINTER_GET then special case, make sure all
- usages within the loop are POINTER_GET any other usage
- would mean that this is not an invariant , since the pointer
- could then be passed as a parameter */
- if (POINTER_GET (ic) &&
- applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic)))
- continue;
+ {
+
+ int lin, rin;
+ cseDef *ivar;
+
+ /* TODO this is only needed if the call is between
+ here and the definition, but I am too lazy to do that now */
+
+ /* if there are function calls in this block */
+ if (fCallsInBlock)
+ {
+ /* if this is a pointer get */
+ if (POINTER_GET(ic))
+ {
+ continue;
+ }
+
+ /* if this is an assignment from a global */
+ if (ic->op=='=' && isOperandGlobal(IC_RIGHT(ic)))
+ {
+ continue;
+ }
+
+ /* Bug 1717943,
+ * if this is an assignment to a global */
+ if (ic->op=='=' && isOperandGlobal(IC_RESULT(ic)))
+ {
+ continue;
+ }
+ }
+
+ if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX)
+ continue;
+
+ /* iTemp assignment from a literal may be invariant, but it
+ will needlessly increase register pressure if the
+ iCode(s) that use this iTemp are not also invariant */
+ if (ic->op=='=' && IS_ITEMP (IC_RESULT (ic))
+ && IS_OP_LITERAL (IC_RIGHT (ic)))
+ continue;
+
+ /* if result is volatile then skip */
+ if (IC_RESULT (ic) &&
+ (isOperandVolatile (IC_RESULT (ic), TRUE) ||
+ IS_OP_PARM (IC_RESULT (ic))))
+ continue;
+
+ /* if result depends on a volatile then skip */
+ if ((IC_LEFT(ic) && isOperandVolatile(IC_LEFT(ic), TRUE)) ||
+ (IC_RIGHT(ic) && isOperandVolatile(IC_RIGHT(ic), TRUE)))
+ continue;
+
+ lin = rin = 0;
+
+ /* special case */
+ /* if address of then it is an invariant */
+ if (ic->op == ADDRESS_OF &&
+ IS_SYMOP (IC_LEFT (ic)) &&
+ IS_AGGREGATE (operandType (IC_LEFT (ic))))
+ {
+ lin++;
+ }
+ else
+ {
+ /* check if left operand is an invariant */
+ if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars)) &&
+ /* if this is a pointer get then make sure
+ that the pointer set does not exist in
+ any of the blocks */
+ POINTER_GET (ic) &&
+ applyToSet (theLoop->regBlocks, pointerAssigned, IC_LEFT (ic)))
+ {
+ lin = 0;
+ }
+ }
+
+ /* do the same for right */
+ rin = isOperandInvariant (IC_RIGHT (ic), theLoop, lInvars);
+
+ /* if this is a POINTER_GET then special case, make sure all
+ usages within the loop are POINTER_GET any other usage
+ would mean that this is not an invariant , since the pointer
+ could then be passed as a parameter */
+ if (POINTER_GET (ic) &&
+ applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic)))
+ continue;
/* if both the left & right are invariants : then check that */
- /* this definition exists in the out definition of all the */
- /* blocks, this will ensure that this is not assigned any */
- /* other value in the loop, and not used in this block */
- /* prior to this definition which means only this definition */
- /* is used in this loop */
- if (lin && rin && IC_RESULT (ic))
- {
- eBBlock *sBlock;
- set *lSet = setFromSet (theLoop->regBlocks);
-
- /* if this block does not dominate all exits */
- /* make sure this defintion is not used anywhere else */
- if (!domsAllExits)
- {
-
- if (isOperandGlobal (IC_RESULT (ic)))
- continue;
- /* for successors for all exits */
- for (sBlock = setFirstItem (theLoop->exits); sBlock;
- sBlock = setNextItem (theLoop->exits))
- {
-
- for (i = 0; i < count; ebbs[i++]->visited = 0);
- lBlock->visited = 1;
- if (applyToSet (sBlock->succList, isDefAlive, ic))
- break;
- }
-
- /* we have found usage */
- if (sBlock)
- continue;
- }
-
- /* now make sure this is the only definition */
- for (sBlock = setFirstItem (lSet); sBlock;
- sBlock = setNextItem (lSet))
- {
+ /* this definition exists in the out definition of all the */
+ /* blocks, this will ensure that this is not assigned any */
+ /* other value in the loop, and not used in this block */
+ /* prior to this definition which means only this definition */
+ /* is used in this loop */
+ if (lin && rin && IC_RESULT (ic))
+ {
+ eBBlock *sBlock;
+ set *lSet = setFromSet (theLoop->regBlocks);
+
+ /* if this block does not dominate all exits */
+ /* make sure this defintion is not used anywhere else */
+ if (!domsAllExits)
+ {
+
+ if (isOperandGlobal (IC_RESULT (ic)))
+ continue;
+ /* for successors for all exits */
+ for (sBlock = setFirstItem (theLoop->exits); sBlock;
+ sBlock = setNextItem (theLoop->exits))
+ {
+
+ for (i = 0; i < count; ebbs[i++]->visited = 0);
+ lBlock->visited = 1;
+ if (applyToSet (sBlock->succList, isDefAlive, ic))
+ break;
+ }
+
+ /* we have found usage */
+ if (sBlock)
+ continue;
+ }
+
+ /* now make sure this is the only definition */
+ for (sBlock = setFirstItem (lSet); sBlock;
+ sBlock = setNextItem (lSet))
+ {
iCode *ic2;
int used;
int defDominates;
- /* if this is the block make sure the definition */
- /* reaches the end of the block */
- if (sBlock == lBlock)
- {
- if (!ifDiCodeIs (sBlock->outExprs, ic))
- break;
- }
- else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
- break;
+ /* if this is the block make sure the definition */
+ /* reaches the end of the block */
+ if (sBlock == lBlock)
+ {
+ if (!ifDiCodeIs (sBlock->outExprs, ic))
+ break;
+ }
+ else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
+ break;
/* Check that this definition is not assigned */
/* any other value in this block. Also check */
}
if (ic2) /* found another definition or a usage before the definition */
break;
- }
+ }
+
+ if (sBlock)
+ continue; /* another definition present in the block */
- if (sBlock)
- continue; /* another definition present in the block */
-
/* now check if it exists in the in of this block */
- /* if not then it was killed before this instruction */
- if (!bitVectBitValue (lBlock->inDefs, ic->key))
- continue;
+ /* if not then it was killed before this instruction */
+ if (!bitVectBitValue (lBlock->inDefs, ic->key))
+ continue;
- /* now we know it is a true invariant */
- /* remove it from the insts chain & put */
- /* in the invariant set */
+ /* now we know it is a true invariant */
+ /* remove it from the insts chain & put */
+ /* in the invariant set */
OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1;
SPIL_LOC (IC_RESULT (ic)) = NULL;
- remiCodeFromeBBlock (lBlock, ic);
-
- /* maintain the data flow */
- /* this means removing from definition from the */
- /* defset of this block and adding it to the */
- /* inexpressions of all blocks within the loop */
- bitVectUnSetBit (lBlock->defSet, ic->key);
- bitVectUnSetBit (lBlock->ldefs, ic->key);
- ivar = newCseDef (IC_RESULT (ic), ic);
- applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
- addSet (&lInvars, ivar);
- }
- }
- } /* for all loop blocks */
+ remiCodeFromeBBlock (lBlock, ic);
+
+ /* maintain the data flow */
+ /* this means removing from definition from the */
+ /* defset of this block and adding it to the */
+ /* inexpressions of all blocks within the loop */
+ bitVectUnSetBit (lBlock->defSet, ic->key);
+ bitVectUnSetBit (lBlock->ldefs, ic->key);
+ ivar = newCseDef (IC_RESULT (ic), ic);
+ applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
+ addSet (&lInvars, ivar);
+ }
+ }
+ } /* for all loop blocks */
/* if we have some invariants then */
if (lInvars)
/* create an iCode chain from it */
for (cdp = setFirstItem (lInvars); cdp; cdp = setNextItem (lInvars))
- {
-
- /* maintain data flow .. add it to the */
- /* ldefs defSet & outExprs of the preheader */
- preHdr->defSet = bitVectSetBit (preHdr->defSet, cdp->diCode->key);
- preHdr->ldefs = bitVectSetBit (preHdr->ldefs, cdp->diCode->key);
- cdp->diCode->lineno = preHdr->ech->lineno;
- addSetHead (&preHdr->outExprs, cdp);
-
-
- if (!icFirst)
- icFirst = cdp->diCode;
- if (icLast)
- {
- icLast->next = cdp->diCode;
- cdp->diCode->prev = icLast;
- icLast = cdp->diCode;
- }
- else
- icLast = cdp->diCode;
- change++;
- }
+ {
+
+ /* maintain data flow .. add it to the */
+ /* ldefs defSet & outExprs of the preheader */
+ preHdr->defSet = bitVectSetBit (preHdr->defSet, cdp->diCode->key);
+ preHdr->ldefs = bitVectSetBit (preHdr->ldefs, cdp->diCode->key);
+ cdp->diCode->filename = preHdr->ech->filename;
+ cdp->diCode->lineno = preHdr->ech->lineno;
+ addSetHead (&preHdr->outExprs, cdp);
+
+
+ if (!icFirst)
+ icFirst = cdp->diCode;
+ if (icLast)
+ {
+ icLast->next = cdp->diCode;
+ cdp->diCode->prev = icLast;
+ icLast = cdp->diCode;
+ }
+ else
+ icLast = cdp->diCode;
+ change++;
+ }
/* add the instruction chain to the end of the
preheader for this loop, preheaders will always
ebp = loop->item;
loop2 = ebp->addrOf;
while (loop2)
- {
- if (isOperandEqual ((operand *) loop2->item, sym))
- return 1;
- loop2 = loop2->next;
- }
+ {
+ if (isOperandEqual ((operand *) loop2->item, sym))
+ return 1;
+ loop2 = loop2->next;
+ }
}
return 0;
/* if a definition for this exists */
if (bitVectBitsInCommon (lBlock->defSet, OP_DEFS (defOp)))
- {
- iCode *ic;
-
- /* go thru the instruction chain to find it */
- for (ic = lBlock->sch; ic; ic = ic->next)
- if (bitVectBitValue (OP_DEFS (defOp), ic->key))
- {
- if (owner)
- *owner = lBlock;
- return ic;
- }
- }
+ {
+ iCode *ic;
+
+ /* go thru the instruction chain to find it */
+ for (ic = lBlock->sch; ic; ic = ic->next)
+ if (bitVectBitValue (OP_DEFS (defOp), ic->key))
+ {
+ if (owner)
+ *owner = lBlock;
+ return ic;
+ }
+ }
}
return NULL;
bitVect *loopSuccs;
int i;
- /* if the number of exits is greater than one then
+ /* if the number of exits is greater than one then
we use another trick: we will create an intersection
of succesors of the exits, then take those that are not
part of the loop and have dfNumber greater loop entry (eblock),
/* and add it */
addiCodeToeBBlock (postLoopBlk, newic, NULL);
+ postLoopBlk->sch->filename =
+ postLoopBlk->ech->filename = eblock->sch->filename;
postLoopBlk->sch->lineno =
postLoopBlk->ech->lineno = eblock->sch->lineno;
/* for all instructions in the blocks do */
for (ic = lBlock->sch; ic; ic = ic->next)
- {
-
- operand *aSym;
- long litValue;
- induction *ip;
- iCode *indIc;
- eBBlock *owner = NULL;
- int nexits;
+ {
+
+ operand *aSym;
+ long litValue;
+ induction *ip;
+ iCode *indIc;
+ eBBlock *owner = NULL;
+ int nexits;
sym_link *optype;
- /* To find an induction variable, we need to */
+ /* To find an induction variable, we need to */
/* find within the loop three iCodes in this */
/* general form: */
/* */
/* */
/* (symbolVar may also be an iTemp if it is */
/* register equivalent) */
-
+
/* look for assignments of the form */
- /* symbolVar := iTempNN */
- if (ic->op != '=')
- continue;
+ /* symbolVar := iTempNN */
+ if (ic->op != '=')
+ continue;
- if (!IS_TRUE_SYMOP (IC_RESULT (ic)) &&
- !OP_SYMBOL (IC_RESULT (ic))->isreqv)
- continue;
+ if (!IS_TRUE_SYMOP (IC_RESULT (ic)) &&
+ !OP_SYMBOL (IC_RESULT (ic))->isreqv)
+ continue;
- if (isOperandGlobal (IC_RESULT (ic)))
- continue;
+ if (isOperandGlobal (IC_RESULT (ic)))
+ continue;
- if (!IS_ITEMP (IC_RIGHT (ic)))
- continue;
+ if (!IS_ITEMP (IC_RIGHT (ic)))
+ continue;
- /* if it has multiple assignments within the loop then skip */
- if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
- continue;
+ /* if it has multiple assignments within the loop then skip */
+ if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
+ continue;
- /* if the address of this was taken inside the loop then continue */
- if (addressTaken (loopReg->regBlocks, IC_RESULT (ic)))
- continue;
+ /* if the address of this was taken inside the loop then continue */
+ if (addressTaken (loopReg->regBlocks, IC_RESULT (ic)))
+ continue;
/* Only consider variables with integral type. */
/* (2004/12/06 - EEP - ds390 fails regression tests unless */
if (!IS_INTEGRAL (optype) && !IS_PTR (optype))
continue;
- /* find the definition for the result in the block */
- if (!(dic = findDefInRegion (setFromSet (loopReg->regBlocks),
- IC_RIGHT (ic), &owner)))
- continue;
-
- /* if not +/- continue */
- if (dic->op != '+' && dic->op != '-')
- continue;
-
- /* make sure definition is of the form a +/- c */
- if (!IS_OP_LITERAL (IC_LEFT (dic)) && !IS_OP_LITERAL (IC_RIGHT (dic)))
- continue;
-
+ /* find the definition for the result in the block */
+ if (!(dic = findDefInRegion (setFromSet (loopReg->regBlocks),
+ IC_RIGHT (ic), &owner)))
+ continue;
+
+ /* if not +/- continue */
+ if (dic->op != '+' && dic->op != '-')
+ continue;
+
+ /* make sure definition is of the form a +/- c */
+ if (!IS_OP_LITERAL (IC_LEFT (dic)) && !IS_OP_LITERAL (IC_RIGHT (dic)))
+ continue;
+
/* make sure the definition found is the only one */
if (assignmentsToSym (loopReg->regBlocks, IC_RIGHT (ic)) > 1)
- continue;
+ continue;
- if (IS_OP_LITERAL (IC_RIGHT (dic)))
+ if (IS_OP_LITERAL (IC_RIGHT (dic)))
{
aSym = IC_LEFT (dic);
litValue = (long) operandLitValue (IC_RIGHT (dic));
litValue = (long) operandLitValue (IC_LEFT (dic));
}
- if (!isOperandEqual (IC_RESULT (ic), aSym) &&
- !isOperandEqual (IC_RIGHT (ic), aSym))
- {
- iCode *ddic;
- /* find the definition for this and check */
- if (!(ddic = findDefInRegion (setFromSet (loopReg->regBlocks),
- aSym, &owner)))
- continue;
-
- if (ddic->op != '=')
- continue;
-
- if (!isOperandEqual (IC_RESULT (ddic), aSym) ||
- !isOperandEqual (IC_RIGHT (ddic), IC_RESULT (ic)))
- continue;
- }
-
- /* if the right hand side has more than one usage then
- don't make it an induction (will have to think some more) */
- if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) > 1)
- continue;
-
- /* if the definition is volatile then it cannot be
- an induction object */
- if (isOperandVolatile (IC_RIGHT (ic), FALSE) ||
- isOperandVolatile (IC_RESULT (ic), FALSE))
- continue;
-
- /* whew !! that was a lot of work to find the definition */
- /* create an induction object */
- indIc = newiCode ('=', NULL, IC_RESULT (ic));
- indIc->lineno = ic->lineno;
- IC_RESULT (indIc) = operandFromOperand (IC_RIGHT (ic));
- IC_RESULT (indIc)->isaddr = 0;
- OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
- ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL);
-
- /* replace the inducted variable by the iTemp */
- replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic));
+ if (!isOperandEqual (IC_RESULT (ic), aSym) &&
+ !isOperandEqual (IC_RIGHT (ic), aSym))
+ {
+ iCode *ddic;
+ /* find the definition for this and check */
+ if (!(ddic = findDefInRegion (setFromSet (loopReg->regBlocks),
+ aSym, &owner)))
+ continue;
+
+ if (ddic->op != '=')
+ continue;
+
+ if (!isOperandEqual (IC_RESULT (ddic), aSym) ||
+ !isOperandEqual (IC_RIGHT (ddic), IC_RESULT (ic)))
+ continue;
+ }
+
+ /* if the right hand side has more than one usage then
+ don't make it an induction (will have to think some more) */
+ if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) > 1)
+ continue;
+
+ /* if the definition is volatile then it cannot be
+ an induction object */
+ if (isOperandVolatile (IC_RIGHT (ic), FALSE) ||
+ isOperandVolatile (IC_RESULT (ic), FALSE))
+ continue;
+
+ /* whew !! that was a lot of work to find the definition */
+ /* create an induction object */
+ indIc = newiCode ('=', NULL, IC_RESULT (ic));
+ indIc->filename = ic->filename;
+ indIc->lineno = ic->lineno;
+ IC_RESULT (indIc) = operandFromOperand (IC_RIGHT (ic));
+ IC_RESULT (indIc)->isaddr = 0;
+ OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
+ ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL);
+
+ /* replace the inducted variable by the iTemp */
+ replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic));
/* ic should now be moved to the exit block(s) */
nexits = elementsInSet (loopReg->exits);
/* last block is the one with the highest block
number */
if (lastBlock->bbnum < lBlock->bbnum)
- lastBlock = lBlock;
+ lastBlock = lBlock;
for (ic = lBlock->sch; ic; ic = ic->next)
- {
- operand *aSym;
- long litVal;
+ {
+ operand *aSym;
+ long litVal;
- /* consider only * & / */
- if (ic->op != '*' && ic->op != '/')
- continue;
+ /* consider only * & / */
+ if (ic->op != '*' && ic->op != '/')
+ continue;
/* only consider variables with integral type */
if (!IS_INTEGRAL (operandType (IC_RESULT (ic))))
continue;
-
+
/* if the result has more definitions then */
- if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
- continue;
+ if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
+ continue;
- /* check if the operands are what we want */
- /* i.e. one of them an symbol the other a literal */
- if (!((IS_SYMOP (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic))) ||
- (IS_OP_LITERAL (IC_LEFT (ic)) && IS_SYMOP (IC_RIGHT (ic)))))
- continue;
+ /* check if the operands are what we want */
+ /* i.e. one of them an symbol the other a literal */
+ if (!((IS_SYMOP (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic))) ||
+ (IS_OP_LITERAL (IC_LEFT (ic)) && IS_SYMOP (IC_RIGHT (ic)))))
+ continue;
- if (IS_SYMOP (IC_LEFT (ic)))
+ if (IS_SYMOP (IC_LEFT (ic)))
{
aSym = IC_LEFT (ic);
litVal = (long) operandLitValue (IC_RIGHT (ic));
litVal = (long) operandLitValue (IC_LEFT (ic));
}
- ip = NULL;
- /* check if this is an induction variable */
- if (!applyToSetFTrue (basicInd, findInduction, aSym, &ip))
- continue;
-
- /* ask port for size not worth if native instruction
- exist for multiply & divide */
- if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->support.muldiv ||
- getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->support.muldiv)
- continue;
-
- /* if this is a division then the remainder should be zero
- for it to be inducted */
- if (ic->op == '/' && (ip->cval % litVal))
- continue;
-
- /* create the iCode to be placed in the loop header */
- /* and create the induction object */
-
- /* create an instruction */
- /* this will be put on the loop header */
- indIc = newiCode (ic->op,
- operandFromOperand (aSym),
- operandFromLit (litVal));
- indIc->lineno = ic->lineno;
- IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
- OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
-
- /* keep track of the inductions */
- litVal = (ic->op == '*' ? (litVal * ip->cval) :
- (ip->cval / litVal));
-
- addSet (&indVars,
- newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL));
-
- /* Replace mul/div with assignment to self; killDeadCode() will */
+ ip = NULL;
+ /* check if this is an induction variable */
+ if (!applyToSetFTrue (basicInd, findInduction, aSym, &ip))
+ continue;
+
+ /* ask port for size not worth if native instruction
+ exist for multiply & divide */
+ if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->support.muldiv ||
+ getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->support.muldiv)
+ continue;
+
+ /* if this is a division then the remainder should be zero
+ for it to be inducted */
+ if (ic->op == '/' && (ip->cval % litVal))
+ continue;
+
+ /* create the iCode to be placed in the loop header */
+ /* and create the induction object */
+
+ /* create an instruction */
+ /* this will be put on the loop header */
+ indIc = newiCode (ic->op,
+ operandFromOperand (aSym),
+ operandFromLit (litVal));
+ indIc->filename = ic->filename;
+ indIc->lineno = ic->lineno;
+ IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
+ OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
+
+ /* keep track of the inductions */
+ litVal = (ic->op == '*' ? (litVal * ip->cval) :
+ (ip->cval / litVal));
+
+ addSet (&indVars,
+ newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL));
+
+ /* Replace mul/div with assignment to self; killDeadCode() will */
/* clean this up since we can't use remiCodeFromeBBlock() here. */
ic->op = '=';
IC_LEFT (ic) = NULL;
operandFromOperand (IC_RESULT (ic)),
operandFromLit (litVal));
IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
- owner = NULL;
+ owner = NULL;
dic = findDefInRegion (setFromSet (loopReg->regBlocks), aSym, &owner);
assert (dic);
- addiCodeToeBBlock (owner, indIc, dic);
+ addiCodeToeBBlock (owner, indIc, dic);
- }
+ }
}
/* if we have some induction variables then */
/* create an iCode chain from it */
for (ip = setFirstItem (indVars);
- ip;
- ip = setNextItem (indVars))
- {
- indVect = bitVectSetBit (indVect, ip->ic->key);
- ip->ic->lineno = preHdr->ech->lineno;
- if (!icFirst)
- icFirst = ip->ic;
- if (icLast)
- {
- icLast->next = ip->ic;
- ip->ic->prev = icLast;
- icLast = ip->ic;
- }
- else
- icLast = ip->ic;
- change++;
- }
+ ip;
+ ip = setNextItem (indVars))
+ {
+ indVect = bitVectSetBit (indVect, ip->ic->key);
+ ip->ic->filename = preHdr->ech->filename;
+ ip->ic->lineno = preHdr->ech->lineno;
+ if (!icFirst)
+ icFirst = ip->ic;
+ if (icLast)
+ {
+ icLast->next = ip->ic;
+ ip->ic->prev = icLast;
+ icLast = ip->ic;
+ }
+ else
+ icLast = ip->ic;
+ change++;
+ }
/* add the instruction chain to the end of the */
/* preheader for this loop */
{
if (lp == theLoop)
- continue;
+ continue;
if (lp->entry == theLoop->entry)
- {
- theLoop->regBlocks = unionSets (theLoop->regBlocks,
- lp->regBlocks, THROW_DEST);
- lp->merged = 1;
- }
+ {
+ theLoop->regBlocks = unionSets (theLoop->regBlocks,
+ lp->regBlocks, THROW_DEST);
+ lp->merged = 1;
+ }
}
return 1;
{
if (lp == theLoop)
- continue;
+ continue;
if (isinSet (lp->regBlocks, theLoop->entry))
- {
- lp->containsLoops += theLoop->containsLoops + 1;
- if (lp->containsLoops > (*maxDepth))
- *maxDepth = lp->containsLoops;
-
- lp->regBlocks = unionSets (lp->regBlocks,
- theLoop->regBlocks, THROW_DEST);
- }
+ {
+ lp->containsLoops += theLoop->containsLoops + 1;
+ if (lp->containsLoops > (*maxDepth))
+ *maxDepth = lp->containsLoops;
+
+ lp->regBlocks = unionSets (lp->regBlocks,
+ theLoop->regBlocks, THROW_DEST);
+ }
}
return 1;
hTab *
createLoopRegions (ebbIndex * ebbi)
{
- set *allRegion = NULL; /* set of all loops */
+ set *allRegion = NULL; /* set of all loops */
hTab *orderedLoops = NULL;
set *bEdges = NULL;
int maxDepth = 0;
/* get all the back edges in the graph */
if (!applyToSet (graphEdges, backEdges, &bEdges))
- return 0; /* found no loops */
+ return 0; /* found no loops */
/* for each of these back edges get the blocks that */
/* constitute the loops */
for (lp = setFirstItem (allRegion); lp; lp = setNextItem (allRegion))
{
applyToSet (lp->regBlocks, addToExitsMarkDepth,
- lp->regBlocks, &lp->exits,
- (maxDepth - lp->containsLoops), lp);
+ lp->regBlocks, &lp->exits,
+ (maxDepth - lp->containsLoops), lp);
hTabAddItem (&orderedLoops, lp->containsLoops, lp);
{
if (optimize.loopInvariant)
- change += loopInvariants (lp, ebbi);
+ change += loopInvariants (lp, ebbi);
if (optimize.loopInduction)
- change += loopInduction (lp, ebbi);
+ change += loopInduction (lp, ebbi);
}
return change;