- eBBlock *lBlock ;
- set *indVars = NULL ;
-
- /* i.e. all assignments of the form a := a +/- const*/
- /* for all blocks within the loop do */
- for ( lBlock = setFirstItem(loopReg->regBlocks); lBlock ;
- lBlock = setNextItem(loopReg->regBlocks)) {
-
- iCode *ic, *dic ;
-
- /* for all instructions in the blocks do */
- for ( ic = lBlock->sch ; ic ; ic = ic->next ) {
-
- operand *aSym ;
- unsigned long litValue ;
- induction *ip;
- iCode *indIc;
- eBBlock *owner = NULL;
- int nexits;
-
- /* look for assignments of the form */
- /* symbolVar := iTempNN */
- if ( ic->op != '=')
- continue ;
-
- if (!IS_TRUE_SYMOP(IC_RESULT(ic)) &&
- !OP_SYMBOL(IC_RESULT(ic))->isreqv)
- continue ;
-
- if (isOperandGlobal(IC_RESULT(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 the address of this was taken inside the loop then continue */
- if (addressTaken (loopReg->regBlocks,IC_RESULT(ic)))
- 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 ;
-
- aSym = (IS_OP_LITERAL(IC_RIGHT(dic)) ?
- (litValue = operandLitValue(IC_RIGHT(dic)),IC_LEFT(dic)) :
- (litValue = operandLitValue(IC_LEFT(dic)),IC_RIGHT(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 it has only one exit then remove it from here
- and put it in the exit block */
- nexits = elementsInSet (loopReg->exits);
- 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) {
- iCode *saveic = ic->prev;
- /* remove it */
- remiCodeFromeBBlock(lBlock,ic);
- /* clear the definition */
- bitVectUnSetBit(lBlock->defSet,ic->key);
- /* add it to the exit */
- addiCodeToeBBlock(exit,ic,NULL);
- /* set the definition bit */
- exit->defSet = bitVectSetBit(exit->defSet,ic->key);
- ic = saveic ;
- }
- }
-
- /* 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
- and insert a new definition in them */
- if ( nexits > 1) {
-
- bitVect *loopSuccs = intersectLoopSucc (loopReg->exits,ebbs);
-
- /* loopSuccs now contains intersection
- of all the loops successors */
- if (loopSuccs) {
- int i;
- for (i = 0 ; i < loopSuccs->size; i++) {
- if (bitVectBitValue(loopSuccs,i)) {
-
- eBBlock *eblock = ebbs[i];
-
- /* if the successor does not belong to the loop
- and will be executed after the loop : then
- add a definition to the block */
- if ( !isinSet(loopReg->regBlocks,eblock) &&
- eblock->dfnum > loopReg->entry->dfnum) {
- /* create the definition */
- iCode *newic = newiCode('=',NULL,
- operandFromOperand(IC_RIGHT(ic)));
- IC_RESULT(newic) = operandFromOperand(IC_RESULT(ic));
- OP_DEFS(IC_RESULT(newic)) =
- bitVectSetBit(OP_DEFS(IC_RESULT(newic)),newic->key);
- OP_USES(IC_RIGHT(newic)) =
- bitVectSetBit(OP_USES(IC_RIGHT(newic)),newic->key);
- /* and add it */
- if (eblock->sch && eblock->sch->op == LABEL)
- addiCodeToeBBlock(eblock,newic,eblock->sch->next);
- else
- addiCodeToeBBlock(eblock,newic,eblock->sch);
- /* set the definition bit */
- eblock->defSet = bitVectSetBit(eblock->defSet,ic->key);
- }
- }
- }
- }
- }
-
- addSet (&indVars,ip);
- }
-
- } /* end of all blocks for basic induction variables */
-
- return indVars;
+ eBBlock *lBlock;
+ set *indVars = NULL;
+
+ /* i.e. all assignments of the form a := a +/- const */
+ /* for all blocks within the loop do */
+ for (lBlock = setFirstItem (loopReg->regBlocks); lBlock;
+ lBlock = setNextItem (loopReg->regBlocks))
+ {
+
+ iCode *ic, *dic;
+
+ /* for all instructions in the blocks do */
+ for (ic = lBlock->sch; ic; ic = ic->next)
+ {
+
+ operand *aSym;
+ unsigned long litValue;
+ induction *ip;
+ iCode *indIc;
+ eBBlock *owner = NULL;
+ int nexits;
+
+ /* look for assignments of the form */
+ /* symbolVar := iTempNN */
+ if (ic->op != '=')
+ continue;
+
+ if (!IS_TRUE_SYMOP (IC_RESULT (ic)) &&
+ !OP_SYMBOL (IC_RESULT (ic))->isreqv)
+ continue;
+
+ if (isOperandGlobal (IC_RESULT (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 the address of this was taken inside the loop then continue */
+ if (addressTaken (loopReg->regBlocks, IC_RESULT (ic)))
+ 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;
+
+ aSym = (IS_OP_LITERAL (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))
+ {
+ 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 it has only one exit then remove it from here
+ and put it in the exit block */
+ nexits = elementsInSet (loopReg->exits);
+ 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)
+ {
+ iCode *saveic = ic->prev;
+ /* remove it */
+ remiCodeFromeBBlock (lBlock, ic);
+ /* clear the definition */
+ bitVectUnSetBit (lBlock->defSet, ic->key);
+ /* add it to the exit */
+ addiCodeToeBBlock (exit, ic, NULL);
+ /* set the definition bit */
+ exit->defSet = bitVectSetBit (exit->defSet, ic->key);
+ ic = saveic;
+ }
+ }
+
+ /* 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
+ and insert a new definition in them */
+ if (nexits > 1)
+ {
+
+ bitVect *loopSuccs = intersectLoopSucc (loopReg->exits, ebbs);
+
+ /* loopSuccs now contains intersection
+ of all the loops successors */
+ if (loopSuccs)
+ {
+ int i;
+ for (i = 0; i < loopSuccs->size; i++)
+ {
+ if (bitVectBitValue (loopSuccs, i))
+ {
+
+ eBBlock *eblock = ebbs[i];
+
+ /* if the successor does not belong to the loop
+ and will be executed after the loop : then
+ add a definition to the block */
+ if (!isinSet (loopReg->regBlocks, eblock) &&
+ eblock->dfnum > loopReg->entry->dfnum)
+ {
+ /* create the definition */
+ iCode *newic = newiCode ('=', NULL,
+ operandFromOperand (IC_RIGHT (ic)));
+ IC_RESULT (newic) = operandFromOperand (IC_RESULT (ic));
+ OP_DEFS (IC_RESULT (newic)) =
+ bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
+ OP_USES (IC_RIGHT (newic)) =
+ bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key);
+ /* and add it */
+ if (eblock->sch && eblock->sch->op == LABEL)
+ addiCodeToeBBlock (eblock, newic, eblock->sch->next);
+ else
+ addiCodeToeBBlock (eblock, newic, eblock->sch);
+ /* set the definition bit */
+ eblock->defSet = bitVectSetBit (eblock->defSet, ic->key);
+ }
+ }
+ }
+ }
+ }
+
+ addSet (&indVars, ip);
+ }
+
+ } /* end of all blocks for basic induction variables */
+
+ return indVars;