X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCloop.c;h=2819c859dcbf689953057e3b814b12baf14dfbef;hb=275002aa4adfc706244119c7333ae5c319f3b7d0;hp=ef79a6b90a0df3a210ef3fb3bf002723343ff1c8;hpb=a590148d0d137cc50667b37a3f630953a56c39a4;p=fw%2Fsdcc diff --git a/src/SDCCloop.c b/src/SDCCloop.c index ef79a6b9..2819c859 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -39,14 +39,14 @@ newInduction (operand * sym, unsigned int op, { 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; } @@ -58,7 +58,7 @@ newRegion () { region *lp; - lp = Safe_calloc (1, sizeof (region)); + lp = Safe_alloc ( sizeof (region)); return lp; } @@ -231,7 +231,8 @@ DEFSETFUNC (addToExitsMarkDepth) V_ARG (region *, lr); /* mark the loop depth of this block */ - if (!ebp->depth) + //if (!ebp->depth) + if (ebp->depthdepth = depth; /* put the loop region info in the block */ @@ -258,8 +259,11 @@ DEFSETFUNC (createLoop) { edge *ep = item; V_ARG (set **, allRegion); + V_ARG (eBBlock **,ebbs); + V_ARG (int,count); region *aloop = newRegion (); eBBlock *block; + int dfMin = count ,dfMax =0, i; /* make sure regionStack is empty */ while (!STACK_EMPTY (regionStack)) @@ -278,6 +282,22 @@ DEFSETFUNC (createLoop) } aloop->entry = ep->to; + /* set max & min dfNum for loopRegion */ + for ( block = setFirstItem(aloop->regBlocks); block; + block = setNextItem(aloop->regBlocks)) { + if (block->dfnum > dfMax) dfMax = block->dfnum; + if (block->dfnum < dfMin) dfMin = block->dfnum; + } + + /* all blocks that have dfnumbers between dfMin & dfMax are also + part of loop */ + for (i = 0 ; i < count ; i++) { + if (ebbs[i]->dfnum > dfMin && + ebbs[i]->dfnum < dfMax && + !isinSet(aloop->regBlocks,ebbs[i])) { + if (!ebbs[i]->partOfLoop) ebbs[i]->partOfLoop = aloop; + } + } /* now add it to the set */ addSetHead (allRegion, aloop); @@ -408,6 +428,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count) 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 */ @@ -429,6 +450,12 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count) 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 */ @@ -438,6 +465,23 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count) int lin, rin; cseDef *ivar; + /* jwk: 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; @@ -453,26 +497,28 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count) 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 + 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); - + /* 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 @@ -742,8 +788,8 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count) 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)) @@ -841,10 +887,10 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count) 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); + OP_DEFS_SET ((IC_RESULT (newic)), + bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key)); + OP_USES_SET ((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); @@ -921,8 +967,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count) 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 */ @@ -931,8 +977,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count) /* 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 @@ -1027,7 +1073,7 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count) /* 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); @@ -1127,7 +1173,7 @@ createLoopRegions (eBBlock ** ebbs, int count) /* for each of these back edges get the blocks that */ /* constitute the loops */ - applyToSet (bEdges, createLoop, &allRegion); + applyToSet (bEdges, createLoop, &allRegion, ebbs,count); /* now we will create regions from these loops */ /* loops with the same entry points are considered to be the */