{
induction *ip;
- ip = Safe_calloc (1, sizeof (induction));
+ ip = Safe_alloc ( sizeof (induction));
ip->sym = sym;
ip->asym = asym;
ip->op = op;
ip->cval = constVal;
ip->ic = ic;
-
+//updateSpillLocation(ic,1);
return ip;
}
{
region *lp;
- lp = Safe_calloc (1, sizeof (region));
+ lp = Safe_alloc ( sizeof (region));
return lp;
}
/*-----------------------------------------------------------------*/
/* loopInsert will insert a block into the loop set */
/*-----------------------------------------------------------------*/
-static void
+static void
loopInsert (set ** regionSet, eBBlock * block)
{
if (!isinSet (*regionSet, block))
/* hasIncomingDefs - has definitions coming into the loop. i.e. */
/* check to see if the preheaders outDefs has any definitions */
/*-----------------------------------------------------------------*/
-int
+int
hasIncomingDefs (region * lreg, operand * op)
{
eBBlock *preHdr = lreg->entry->preHeader;
/* findLoopEndSeq - will return the sequence number of the last */
/* iCode with the maximum dfNumber in the region */
/*-----------------------------------------------------------------*/
-int
+int
findLoopEndSeq (region * lreg)
{
eBBlock *block;
V_ARG (region *, lr);
/* mark the loop depth of this block */
- if (!ebp->depth)
+ //if (!ebp->depth)
+ if (ebp->depth<depth)
ebp->depth = depth;
- /* put the loop region info in the block */
/* NOTE: here we will update only the inner most loop
that it is a part of */
if (!ebp->partOfLoop)
V_ARG (int, count);
addSetHead (&ebp->inExprs, cdp);
- cseBBlock (ebp, 0, ebbs, count);
+ cseBBlock (ebp, optimize.global_cse, ebbs, count);
return 0;
}
/*-----------------------------------------------------------------*/
/* assignmentsToSym - for a set of blocks determine # time assigned */
/*-----------------------------------------------------------------*/
-int
+int
assignmentsToSym (set * sset, operand * sym)
{
eBBlock *ebp;
in this block */
bitVect *defs = bitVectIntersect (ebp->ldefs, OP_DEFS (sym));
assigns += bitVectnBitsOn (defs);
- setToNull ((void **) &defs);
+ setToNull ((void *) &defs);
}
/*-----------------------------------------------------------------*/
/* isOperandInvariant - determines if an operand is an invariant */
/*-----------------------------------------------------------------*/
-int
+int
isOperandInvariant (operand * op, region * theLoop, set * lInvars)
{
int opin = 0;
eBBlock *ebp = item;
V_ARG (operand *, op);
- return ebp->hasFcall || bitVectBitValue (ebp->ptrsSet, op->key);
+ if (ebp->hasFcall)
+ return 1;
+
+ if (bitVectBitValue (ebp->ptrsSet, op->key))
+ return 1;
+
+ /* Unfortunately, one of the other pointer set operations */
+ /* may be using an alias of this operand, and the above */
+ /* test would miss it. To be thorough, some aliasing */
+ /* analysis should be done here. In the meantime, be */
+ /* conservative and assume any other pointer set operation */
+ /* is dangerous */
+ if (!bitVectIsZero (ebp->ptrsSet))
+ return 1;
+
+ return 0;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* loopInvariants - takes loop invariants out of region */
/*-----------------------------------------------------------------*/
-int
+int
loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
{
eBBlock *lBlock;
set *lInvars = NULL;
int change = 0;
+ int fCallsInBlock;
/* if the preHeader does not exist then do nothing */
/* or no exits then do nothing ( have to think about this situation */
theLoop->exits == NULL)
return 0;
- /* we will do the elimination for those blocks */
- /* in the loop that dominates all exits from the loop */
+ /* we will do the elimination for those blocks */
+ /* in the loop that dominate all exits from the loop */
for (lBlock = setFirstItem (theLoop->regBlocks); lBlock;
lBlock = setNextItem (theLoop->regBlocks))
{
domsAllExits = (applyToSet (theLoop->exits, dominatedBy, lBlock) ==
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++;
+ }
+ }
/* now we go thru the instructions of this block and */
/* collect those instructions with invariant operands */
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 */
IS_SYMOP (IC_LEFT (ic)) &&
IS_AGGREGATE (operandType (IC_LEFT (ic))))
lin++;
- else
+ 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;
+ 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);
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 */
+
+ /* 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 */
+ /* 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 exists */
+ /* if this block does not dominate all exits */
/* make sure this defintion is not used anywhere else */
if (!domsAllExits)
{
}
else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
break;
+
+ if (IC_RESULT(ic))
+ {
+ iCode *ic2;
+ /* check that this definition is not assigned */
+ /* any other value in this block */
+ for (ic2 = sBlock->sch; ic2; ic2 = ic2->next)
+ {
+ if ((ic != ic2) && (isOperandEqual(IC_RESULT(ic), IC_RESULT(ic2))))
+ break;
+ }
+ if (ic2) /* found another definition */
+ break;
+ }
}
if (sBlock)
/* 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;
+
+ OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1;
+ SPIL_LOC (IC_RESULT (ic)) = NULL;
remiCodeFromeBBlock (lBlock, ic);
/* maintain the data flow */
/*-----------------------------------------------------------------*/
/* addressTaken - returns true if the symbol is found in the addrof */
/*-----------------------------------------------------------------*/
-int
+int
addressTaken (set * sset, operand * sym)
{
set *loop;
continue;
aSym = (IS_OP_LITERAL (IC_RIGHT (dic)) ?
- (litValue = operandLitValue (IC_RIGHT (dic)), IC_LEFT (dic)) :
- (litValue = operandLitValue (IC_LEFT (dic)), IC_RIGHT (dic)));
+ (litValue = (unsigned long) operandLitValue (IC_RIGHT (dic)), IC_LEFT (dic)) :
+ (litValue = (unsigned long) operandLitValue (IC_LEFT (dic)), IC_RIGHT (dic)));
if (!isOperandEqual (IC_RESULT (ic), aSym) &&
!isOperandEqual (IC_RIGHT (ic), aSym))
if (nexits == 1)
{
eBBlock *exit = setFirstItem (loopReg->exits);
-
/* if it is the same block then there is no
need to move it about */
if (exit != lBlock)
if (bitVectBitValue (loopSuccs, i))
{
- eBBlock *eblock = ebbs[i];
+ eBBlock *eblock = NULL;
+ int j;
+
+ /* Need to search for bbnum == i since ebbs is */
+ /* sorted by dfnum; a direct index won't do. */
+ for (j=0; j<count; j++)
+ if (ebbs[j]->bbnum == i)
+ {
+ eblock = ebbs[j];
+ break;
+ }
+ assert(eblock);
/* if the successor does not belong to the loop
and will be executed after the loop : then
iCode *newic = newiCode ('=', NULL,
operandFromOperand (IC_RIGHT (ic)));
IC_RESULT (newic) = operandFromOperand (IC_RESULT (ic));
- OP_DEFS (IC_RESULT (newic)) =
+ OP_DEFS(IC_RESULT (newic))=
bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
- OP_USES (IC_RIGHT (newic)) =
+ OP_USES(IC_RIGHT (newic))=
bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key);
/* and add it */
if (eblock->sch && eblock->sch->op == LABEL)
/*-----------------------------------------------------------------*/
/* loopInduction - remove induction variables from a loop */
/*-----------------------------------------------------------------*/
-int
+int
loopInduction (region * loopReg, eBBlock ** ebbs, int count)
{
int change = 0;
continue;
aSym = (IS_SYMOP (IC_LEFT (ic)) ?
- (lr = 1, litVal = operandLitValue (IC_RIGHT (ic)), IC_LEFT (ic)) :
- (litVal = operandLitValue (IC_LEFT (ic)), IC_RIGHT (ic)));
+ (lr = 1, litVal = (unsigned long) operandLitValue (IC_RIGHT (ic)), IC_LEFT (ic)) :
+ (litVal = (unsigned long) operandLitValue (IC_LEFT (ic)), IC_RIGHT (ic)));
ip = NULL;
/* check if this is an induction variable */
/* ask port for size not worth if native instruction
exist for multiply & divide */
- if (getSize (operandType (IC_LEFT (ic))) <= port->muldiv.native_below ||
- getSize (operandType (IC_RIGHT (ic))) <= port->muldiv.native_below)
+ 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
/* add the induction variable vector to the last
block in the loop */
lastBlock->isLastInLoop = 1;
- lastBlock->linds = indVect;
+ lastBlock->linds = bitVectUnion(lastBlock->linds,indVect);
}
- setToNull ((void **) &indVars);
+ setToNull ((void *) &indVars);
return change;
}
if (lp->entry == theLoop->entry)
{
theLoop->regBlocks = unionSets (theLoop->regBlocks,
- lp->regBlocks, THROW_BOTH);
+ lp->regBlocks, THROW_DEST);
lp->merged = 1;
}
}
applyToSet (allRegion, mergeInnerLoops, allRegion, &maxDepth);
maxDepth++;
+
/* now create all the exits .. also */
/* create an ordered set of loops */
/* i.e. we process loops in the inner to outer order */
/*-----------------------------------------------------------------*/
/* loopOptimizations - identify region & remove invariants & ind */
/*-----------------------------------------------------------------*/
-int
+int
loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
{
region *lp;
int change = 0;
int k;
-
/* if no loop optimizations requested */
if (!optimize.loopInvariant &&
!optimize.loopInduction)