X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2FSDCClrange.c;h=a85c5ff19b64fa6c5eb532e1058650473e4c6375;hb=d5e163c45df3f0603c1f52c7d4467b60a5e0afee;hp=6d0a3cb976623c95e8dc2fb1252ac133dce2c0e4;hpb=5d300e8e6ba1957072a5d795a06771ad1eaa89cc;p=fw%2Fsdcc diff --git a/src/SDCClrange.c b/src/SDCClrange.c index 6d0a3cb9..a85c5ff1 100644 --- a/src/SDCClrange.c +++ b/src/SDCClrange.c @@ -29,6 +29,7 @@ int iCodeSeq = 0; hTab *liveRanges = NULL; hTab *iCodehTab = NULL; +hTab *iCodeSeqhTab = NULL; /*-----------------------------------------------------------------*/ /* sequenceiCode - creates a sequence number for the iCode & add */ @@ -48,6 +49,7 @@ sequenceiCode (eBBlock ** ebbs, int count) ic->seq = ++iCodeSeq; ic->depth = ebbs[i]->depth; hTabAddItem (&iCodehTab, ic->key, ic); + hTabAddItem (&iCodeSeqhTab, ic->seq, ic); } ebbs[i]->lSeq = iCodeSeq; } @@ -278,7 +280,9 @@ useDefLoopCheck (operand * op, iCode * ic) OP_SYMBOL (op)->name, ic->filename, ic->lineno); } +#if 0 // this will create a segfault: bug #498971 OP_SYMBOL (op)->isspilt = 1; +#endif } } @@ -300,14 +304,26 @@ operandLUse (operand * op, eBBlock ** ebbs, (OP_LIVETO (op) && OP_LIVETO (op) < ic->seq)) { int torange = ic->seq; + + /* if this is a SEND then the toRange should be extended + to the call */ + if (ic->op == SEND) { + iCode *lic ; + for (lic = ic->next ; lic ; lic = lic->next) { + if (lic->op == CALL || lic->op == PCALL) break; + } + /* found it : mark */ + if (lic) torange = lic->prev->seq; + } /* if this is the last use then if this block belongs to a loop & some definition comes into the loop then extend the live range to the end of the loop */ - if (ebp->partOfLoop && - hasIncomingDefs (ebp->partOfLoop, op)) + if (ebp->partOfLoop + && hasIncomingDefs (ebp->partOfLoop, op)) { torange = findLoopEndSeq (ebp->partOfLoop); } + op = operandFromOperand (op); setToRange (op, torange, FALSE); } @@ -328,7 +344,7 @@ operandLUse (operand * op, eBBlock ** ebbs, !IS_STATIC (etype)) { - if (bitVectIsZero (op->usesDefs)) + if (bitVectIsZero (op->usesDefs) && OP_SYMBOL(op)->ival==NULL) { OP_SYMBOL (op)->isspilt = 1; @@ -411,10 +427,10 @@ markLiveRanges (eBBlock * ebp, eBBlock ** ebbs, int count) bitVect *defsUsed = NULL; bitVect *defsNotUsed = NULL; int i; + /* for all the instructions */ for (ic = ebp->sch; ic; ic = ic->next) { - if (ic->op == CALL || ic->op == PCALL) { setFromRange (IC_RESULT (ic), ic->seq); @@ -525,7 +541,6 @@ markLiveRanges (eBBlock * ebp, eBBlock ** ebbs, int count) if (bitVectBitValue (defsNotUsed, i) && (dic = hTabItemWithKey (iCodehTab, i))) { - setToRange (IC_RESULT (dic), (ebp->fSeq - 1), TRUE); } } @@ -545,42 +560,138 @@ markLiveRanges (eBBlock * ebp, eBBlock ** ebbs, int count) void rlivePoint (eBBlock ** ebbs, int count) { - int i; - - /* for all blocks do */ - for (i = 0; i < count; i++) { - iCode *ic; - - /* for all instruction in the block do */ - for (ic = ebbs[i]->sch; ic; ic = ic->next) { - symbol *lrange; - int k; - - ic->rlive = newBitVect (operandKey); - /* for all symbols in the liverange table */ - for (lrange = hTabFirstItem (liveRanges, &k); lrange; - lrange = hTabNextItem (liveRanges, &k)) { - - /* if it is live then add the lrange to ic->rlive */ - if (lrange->liveFrom <= ic->seq && - lrange->liveTo >= ic->seq) { - lrange->isLiveFcall |= (ic->op == CALL || ic->op == PCALL || ic->op == SEND); - ic->rlive = bitVectSetBit (ic->rlive, lrange->key); - } - } - /* overlapping live ranges should be eliminated */ - if (ASSIGN_ITEMP_TO_ITEMP (ic)) { - - if (SPIL_LOC(IC_RIGHT(ic)) == SPIL_LOC(IC_RESULT(ic)) && /* left & right share the same spil location */ - OP_SYMBOL(IC_RESULT(ic))->isreqv && /* left of assign is a register requivalent */ - !OP_SYMBOL(IC_RIGHT(ic))->isreqv && /* right side is not */ - OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->key && /* right side live beyond this point */ - bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1 ) { /* left has multiple definitions */ - SPIL_LOC(IC_RIGHT(ic)) = NULL; /* then cannot share */ - } - } + int i; + + /* for all blocks do */ + for (i = 0; i < count; i++) { + iCode *ic; + + /* for all instruction in the block do */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) { + symbol *lrange; + int k; + + ic->rlive = newBitVect (operandKey); + /* for all symbols in the liverange table */ + for (lrange = hTabFirstItem (liveRanges, &k); lrange; + lrange = hTabNextItem (liveRanges, &k)) { + + /* if it is live then add the lrange to ic->rlive */ + if (lrange->liveFrom <= ic->seq && + lrange->liveTo >= ic->seq) { + lrange->isLiveFcall |= ((lrange->liveFrom < ic->seq) && + (ic->op == CALL || ic->op == PCALL || ic->op == SEND)); + if (ic->op == CALL && lrange->liveFrom == ic->seq) continue; + ic->rlive = bitVectSetBit (ic->rlive, lrange->key); } + } +#if 0 + /* overlapping live ranges should be eliminated */ + if (ASSIGN_ITEMP_TO_ITEMP (ic)) { + if (SPIL_LOC(IC_RIGHT(ic)) == SPIL_LOC(IC_RESULT(ic)) && /* left & right share the same spil location */ + OP_SYMBOL(IC_RESULT(ic))->isreqv && /* left of assign is a register requivalent */ + !OP_SYMBOL(IC_RIGHT(ic))->isreqv && /* right side is not */ + OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->key && /* right side live beyond this point */ + bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1 ) { /* left has multiple definitions */ + SPIL_LOC(IC_RIGHT(ic)) = NULL; /* then cannot share */ + } + } +#endif } + } +} + +/*-----------------------------------------------------------------*/ +/* computeClash - find out which live ranges collide with others */ +/*-----------------------------------------------------------------*/ +static void computeClash () +{ + hTab *lRangeCopy = newHashTable(hTabMaxKey(liveRanges)); + void *item; + symbol *outer, *inner; + int key, key1; + + /* have to make a copy of the liveRanges hashTable :: UGHH .*/ + for (item = hTabFirstItem(liveRanges,&key); item ; + item = hTabNextItem(liveRanges,&key)) { + hTabAddItem(&lRangeCopy,key,item); + } + + /* outerloop : for each liverange do */ + for (outer = hTabFirstItem(liveRanges,&key); outer ; + outer = hTabNextItem(liveRanges,&key)) { + + /* if the liveFrom & To are the same then skip, + could happen for unused return values from functions */ + if (outer->liveFrom == outer->liveTo) continue; + + /* innerloop : for the inner loop we can start from the + item after the outer loop */ + inner = hTabFirstItemWK (lRangeCopy,outer->key); + inner = hTabNextItem (lRangeCopy,&key1 ); + for (; inner ; inner = hTabNextItem( lRangeCopy ,&key1)) { + + if (inner->liveFrom == inner->liveTo) continue; + if (inner->liveTo < outer->liveFrom) continue; + if (inner->liveFrom > outer->liveTo) continue; + + /* if one of them are being defined where the other + one end , then no overlap (i.e. they can goto same registers */ + if (inner->liveFrom == outer->liveTo || + outer->liveFrom == inner->liveTo) continue; + + /* so they overlap : set both their clashes */ + inner->clashes = bitVectSetBit(inner->clashes,outer->key); + outer->clashes = bitVectSetBit(outer->clashes,inner->key); + + /* check if they share the same spillocation */ + if (SYM_SPIL_LOC(inner) && SYM_SPIL_LOC(outer) && + SYM_SPIL_LOC(inner) == SYM_SPIL_LOC(outer)) { + if (inner->reqv && !outer->reqv) SYM_SPIL_LOC(outer)=NULL; + else if (outer->reqv && !inner->reqv) SYM_SPIL_LOC(inner)=NULL; + else if (inner->used > outer->used) SYM_SPIL_LOC(outer)=NULL; + else SYM_SPIL_LOC(inner)=NULL; + } + + } + } +} + +/*-----------------------------------------------------------------*/ +/* allDefsOutOfRange - all definitions are out of a range */ +/*-----------------------------------------------------------------*/ +bool +allDefsOutOfRange (bitVect * defs, int fseq, int toseq) +{ + int i; + + if (!defs) + return TRUE; + + for (i = 0; i < defs->size; i++) + { + iCode *ic; + + if (bitVectBitValue (defs, i) && + (ic = hTabItemWithKey (iCodehTab, i)) && + (ic->seq >= fseq && ic->seq <= toseq)) + + return FALSE; + + } + + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* notUsedInBlock - not used in this block */ +/*-----------------------------------------------------------------*/ +int +notUsedInBlock (symbol * sym, eBBlock * ebp, iCode *ic) +{ + return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) && + allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq) && + allDefsOutOfRange (sym->uses, ebp->fSeq, ebp->lSeq)); } @@ -597,6 +708,8 @@ computeLiveRanges (eBBlock ** ebbs, int count) iCodeSeq = 0; setToNull ((void **) &iCodehTab); iCodehTab = newHashTable (iCodeKey); + setToNull ((void **) &iCodeSeqhTab); + iCodeSeqhTab = newHashTable (iCodeKey); sequenceiCode (ebbs, count); /* call routine to mark the from & to live ranges for @@ -607,4 +720,8 @@ computeLiveRanges (eBBlock ** ebbs, int count) /* mark the ranges live for each point */ rlivePoint (ebbs, count); + + /* compute which overlaps with what */ + computeClash(); } +