X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCBBlock.c;h=e7f0fe9e7cdc9c55b539d5a04f966389ee027a7f;hb=fd94924a3d743c1c82f4b370d9401d7239172789;hp=2059b3d7a622a76d49d0a8b531e0b694126aca5e;hpb=aed2b39c46fcdfdd017adbf9e50c254efc5dea42;p=fw%2Fsdcc diff --git a/src/SDCCBBlock.c b/src/SDCCBBlock.c index 2059b3d7..e7f0fe9e 100644 --- a/src/SDCCBBlock.c +++ b/src/SDCCBBlock.c @@ -8,632 +8,830 @@ under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "common.h" -#include "newalloc.h" int eBBNum = 0; -set *graphEdges = NULL ; /* list of edges in this flow graph */ +set *graphEdges = NULL; /* list of edges in this flow graph */ + +struct _dumpFiles dumpFiles[] = { + {DUMP_RAW0, ".dumpraw0", NULL}, + {DUMP_RAW1, ".dumpraw1", NULL}, + {DUMP_CSE, ".dumpcse", NULL}, + {DUMP_DFLOW, ".dumpdflow", NULL}, + {DUMP_GCSE, ".dumpgcse", NULL}, + {DUMP_DEADCODE, ".dumpdeadcode", NULL}, + {DUMP_LOOP, ".dumploop", NULL}, + {DUMP_LOOPG, ".dumploopg", NULL}, + {DUMP_LOOPD, ".dumploopd", NULL}, + {DUMP_RANGE, ".dumprange", NULL}, + {DUMP_PACK, ".dumppack", NULL}, + {DUMP_RASSGN, ".dumprassgn", NULL}, + {DUMP_LRANGE, ".dumplrange", NULL}, + {0, NULL, NULL} +}; /*-----------------------------------------------------------------*/ /* printEntryLabel - prints entry label of a ebblock */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(printEntryLabel) +DEFSETFUNC (printEntryLabel) { - eBBlock *bp = item; + eBBlock *bp = item; - fprintf (stdout," %-20s ",bp->entryLabel->name); - return 0; + fprintf (stdout, " %-20s ", bp->entryLabel->name); + return 0; } /*-----------------------------------------------------------------*/ /* neweBBlock - allocate & return a new extended basic block */ /*-----------------------------------------------------------------*/ -eBBlock *neweBBlock () +eBBlock * +neweBBlock () { - eBBlock *ebb; + eBBlock *ebb; - ebb = Safe_calloc(sizeof(eBBlock)); - return ebb ; + ebb = Safe_alloc (sizeof (eBBlock)); + return ebb; } /*-----------------------------------------------------------------*/ /* newEdge - allocates & initialises an edge to given values */ /*-----------------------------------------------------------------*/ -edge *newEdge (eBBlock *from, eBBlock *to) +edge * +newEdge (eBBlock * from, eBBlock * to) { - edge *ep ; + edge *ep; + + ep = Safe_alloc (sizeof (edge)); + + ep->from = from; + ep->to = to; + return ep; +} + +/*-----------------------------------------------------------------*/ +/* createDumpFile - create the dump file */ +/*-----------------------------------------------------------------*/ +FILE *createDumpFile (int id) { + struct _dumpFiles *dumpFilesPtr=dumpFiles; + static int dumpIndex=0; + static char dumpIndexStr[32]; + + while (dumpFilesPtr->id) { + if (dumpFilesPtr->id==id) + break; + dumpFilesPtr++; + } + + if (!dumpFilesPtr->id) { + fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n"); + exit (1); + } + + sprintf(dumpIndexStr, ".%d", dumpIndex); + dumpIndex++; + + if (!dumpFilesPtr->filePtr) { + // not used before, create it + strncpyz (scratchFileName, dstFileName, PATH_MAX); +#if 0 + strncatz (scratchFileName, dumpIndexStr, PATH_MAX); +#endif + strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX); + if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) { + werror (E_FILE_OPEN_ERR, scratchFileName); + exit (1); + } + } + +#if 0 + fprintf(dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex); +#endif - ep = Safe_calloc(sizeof(edge)); - - ep->from = from; - ep->to = to; - return ep; + return dumpFilesPtr->filePtr; +} + +/*-----------------------------------------------------------------*/ +/* closeDumpFiles - close possible opened dumpfiles */ +/*-----------------------------------------------------------------*/ +void closeDumpFiles() { + struct _dumpFiles *dumpFilesPtr; + + for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) { + if (dumpFilesPtr->filePtr) { + fclose (dumpFilesPtr->filePtr); + } + } } /*-----------------------------------------------------------------*/ /* dumpLiveRanges - dump liverange information into a file */ /*-----------------------------------------------------------------*/ -void dumpLiveRanges (char *ext,hTab *liveRanges) +void +dumpLiveRanges (int id, hTab * liveRanges) { - FILE *file; - symbol *sym; - int k; - - if (ext) { - /* create the file name */ - strcpy(buffer,srcFileName); - strcat(buffer,ext); - - if (!(file = fopen(buffer,"a+"))) { - werror(E_FILE_OPEN_ERR,buffer); - exit(1); - } - } else - file = stdout; - - for (sym = hTabFirstItem(liveRanges,&k); sym ; - sym = hTabNextItem(liveRanges,&k)) { - - fprintf (file,"%s [k%d lr%d:%d so:%d]{ re%d rm%d}", - (sym->rname[0] ? sym->rname : sym->name), - sym->key, - sym->liveFrom,sym->liveTo, - sym->stack, - sym->isreqv,sym->remat - ); - - fprintf(file,"{"); printTypeChain(sym->type,file); - if (sym->usl.spillLoc) { - fprintf(file,"}{ sir@ %s",sym->usl.spillLoc->rname); - } - fprintf(file,"}"); - - /* if assigned to registers */ - if (sym->nRegs) { - if (sym->isspilt) { - if (!sym->remat) - if (sym->usl.spillLoc) - fprintf(file,"[%s]",(sym->usl.spillLoc->rname[0] ? - sym->usl.spillLoc->rname : - sym->usl.spillLoc->name)); - else - fprintf(file,"[err]"); - else - fprintf(file,"[remat]"); - } - else { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ", port->getRegName(sym->regs[i])); - fprintf(file,"]"); - } - } - fprintf(file,"\n"); + FILE *file; + symbol *sym; + int k; + + if (id) { + file=createDumpFile(id); + } else { + file = stdout; + } + + if (currFunc) + fprintf(file,"------------- Func %s -------------\n",currFunc->name); + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) + { + + fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}", + (sym->rname[0] ? sym->rname : sym->name), + sym->key, + sym->liveFrom, sym->liveTo, + sym->stack, + sym->isreqv, sym->remat + ); + + fprintf (file, "{"); + printTypeChain (sym->type, file); + if (sym->usl.spillLoc) + { + fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname); + } + fprintf (file, "} clashes with "); + bitVectDebugOn(sym->clashes,file); + fprintf (file, "\n"); } - - fclose(file); + + fflush(file); } + + /*-----------------------------------------------------------------*/ /* dumpEbbsToFileExt - writeall the basic blocks to a file */ /*-----------------------------------------------------------------*/ -void dumpEbbsToFileExt (char *ext,eBBlock **ebbs, int count) +void +dumpEbbsToFileExt (int id, ebbIndex * ebbi) { - FILE *of; - int i; - - if (ext) { - /* create the file name */ - strcpy(buffer,srcFileName); - strcat(buffer,ext); - - if (!(of = fopen(buffer,"a+"))) { - werror(E_FILE_OPEN_ERR,buffer); - exit(1); - } - } else - of = stdout; - - for (i=0; i < count ; i++ ) { - fprintf(of,"\n----------------------------------------------------------------\n"); - fprintf(of,"Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n", - ebbs[i]->entryLabel->name, - ebbs[i]->depth, - ebbs[i]->noPath, - ebbs[i]->isLastInLoop); - fprintf(of,"\ndefines bitVector :"); - bitVectDebugOn(ebbs[i]->defSet,of); - fprintf(of,"\nlocal defines bitVector :"); - bitVectDebugOn(ebbs[i]->ldefs,of); - fprintf(of,"\npointers Set bitvector :"); - bitVectDebugOn(ebbs[i]->ptrsSet,of); - fprintf(of,"\n----------------------------------------------------------------\n"); - printiCChain(ebbs[i]->sch,of); + FILE *of; + int i; + eBBlock *bb; + set *cseSet; + eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder; + int count = ebbi->count; + + if (id) { + of=createDumpFile(id); + } else { + of = stdout; + } + + for (i = 0; i < count; i++) + { + fprintf (of, "\n----------------------------------------------------------------\n"); + fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%d): loopDepth=%d%s%s%s\n", + ebbs[i]->entryLabel->name, + ebbs[i]->dfnum, ebbs[i]->bbnum, ebbs[i]->entryLabel->level, + ebbs[i]->depth, + ebbs[i]->noPath ? " noPath" : "", + ebbs[i]->partOfLoop ? " partOfLoop" : "", + ebbs[i]->isLastInLoop ? " isLastInLoop" : ""); + + // a --nolabelopt makes this more readable + fprintf (of, "\nsuccessors: "); + for (bb=setFirstItem(ebbs[i]->succList); + bb; + bb=setNextItem(ebbs[i]->succList)) { + fprintf (of, "%s ", bb->entryLabel->name); + } + fprintf (of, "\npredecessors: "); + for (bb=setFirstItem(ebbs[i]->predList); + bb; + bb=setNextItem(ebbs[i]->predList)) { + fprintf (of, "%s ", bb->entryLabel->name); + } + { + int d; + fprintf (of, "\ndominators: "); + for (d=0; ddomVect->size; d++) { + if (bitVectBitValue(ebbs[i]->domVect, d)) { + fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name); + } + } + } + fprintf (of, "\n"); + + fprintf (of, "\ndefines bitVector :"); + bitVectDebugOn (ebbs[i]->defSet, of); + fprintf (of, "\nlocal defines bitVector :"); + bitVectDebugOn (ebbs[i]->ldefs, of); + fprintf (of, "\npointers Set bitvector :"); + bitVectDebugOn (ebbs[i]->ptrsSet, of); +#if 0 + fprintf (of, "\nin coming definitions :"); + bitVectDebugOn (ebbs[i]->inDefs, of); + fprintf (of, "\nout going definitions :"); + bitVectDebugOn (ebbs[i]->outDefs, of); + fprintf (of, "\ndefines used :"); + bitVectDebugOn (ebbs[i]->usesDefs, of); +#endif + + if (ebbs[i]->isLastInLoop) { + fprintf (of, "\nInductions Set bitvector :"); + bitVectDebugOn (ebbs[i]->linds, of); + } + + fprintf (of, "\ninExprs:"); + for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) { + cseDef *item=cseSet->item; + fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key); + if (item->fromGlobal) + fprintf (of, "g"); + } + fprintf (of, "\noutExprs:"); + for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) { + cseDef *item=cseSet->item; + fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key); + if (item->fromGlobal) + fprintf (of, "g"); + } + fprintf (of, "\nkilledExprs:"); + for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) { + cseDef *item=cseSet->item; + fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key); + if (item->fromGlobal) + fprintf (of, "g"); + } + + fprintf (of, "\n----------------------------------------------------------------\n"); + printiCChain (ebbs[i]->sch, of); } - fclose(of); + fflush(of); } /*-----------------------------------------------------------------*/ /* iCode2eBBlock - converts a sequnce till label to a ebb */ /*-----------------------------------------------------------------*/ -eBBlock *iCode2eBBlock (iCode *ic) +eBBlock * +iCode2eBBlock (iCode * ic) { - iCode *loop ; - eBBlock *ebb = neweBBlock(); /* a llocate an entry */ - - /* put the first one unconditionally */ - ebb->sch = ic ; - - /* if this is a label then */ - if (ic->op == LABEL) - ebb->entryLabel = ic->argLabel.label ; - else { - sprintf(buffer,"_eBBlock%d",eBBNum++); - ebb->entryLabel = newSymbol(buffer,1); - ebb->entryLabel->key = labelKey++; + iCode *loop; + eBBlock *ebb = neweBBlock (); /* allocate an entry */ + + /* put the first one unconditionally */ + ebb->sch = ic; + + /* if this is a label then */ + if (ic->op == LABEL) + ebb->entryLabel = ic->label; + else + { + SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++); + ebb->entryLabel = newSymbol (buffer, 1); + ebb->entryLabel->key = labelKey++; + } + + if (ic && + (ic->op == GOTO || + ic->op == JUMPTABLE || + ic->op == IFX)) + { + ebb->ech = ebb->sch; + return ebb; } - - if (ic && - ( ic->op == GOTO || - ic->op == JUMPTABLE || - ic->op == IFX )) { - ebb->ech = ebb->sch; - return ebb; + + /* if this is a function call */ + if (ic->op == CALL || ic->op == PCALL) + { + ebb->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL(currFunc->type) = 1; } - if ((ic->next && ic->next->op == LABEL) || - !ic->next ) { - ebb->ech = ebb->sch ; - return ebb ; + if ((ic->next && ic->next->op == LABEL) || + !ic->next) + { + ebb->ech = ebb->sch; + return ebb; } - - /* loop thru till we find one with a label */ - for ( loop = ic->next ; loop ; loop = loop->next ) { - - /* if this is the last one */ - if (!loop->next) - break; - /* if this is a function call */ - if (loop->op == CALL || loop->op == PCALL) { - ebb->hasFcall = 1; - if (currFunc) - currFunc->hasFcall = 1; - } - - /* if the next one is a label */ - /* if this is a goto or ifx */ - if (loop->next->op == LABEL || - loop->op == GOTO || - loop->op == JUMPTABLE || - loop->op == IFX ) - break ; + + /* loop thru till we find one with a label */ + for (loop = ic->next; loop; loop = loop->next) + { + + /* if this is the last one */ + if (!loop->next) + break; + /* if this is a function call */ + if (loop->op == CALL || loop->op == PCALL) + { + ebb->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL(currFunc->type) = 1; + } + + /* if the next one is a label */ + /* if this is a goto or ifx */ + if (loop->next->op == LABEL || + loop->op == GOTO || + loop->op == JUMPTABLE || + loop->op == IFX) + break; } - - /* mark the end of the chain */ - ebb->ech = loop ; - - return ebb; + + /* mark the end of the chain */ + ebb->ech = loop; + + return ebb; } /*-----------------------------------------------------------------*/ /* eBBWithEntryLabel - finds the basic block with the entry label */ /*-----------------------------------------------------------------*/ -eBBlock *eBBWithEntryLabel ( eBBlock **ebbs , symbol *eLabel, int count) +eBBlock * +eBBWithEntryLabel (ebbIndex * ebbi, symbol * eLabel) { - int i; - - for ( i = 0 ; i < count ; i++ ) { - if (isSymbolEqual(ebbs[i]->entryLabel,eLabel)) - return ebbs[i] ; + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; + int i; + + for (i = 0; i < count; i++) + { + if (isSymbolEqual (ebbs[i]->entryLabel, eLabel)) + return ebbs[i]; } - - return NULL ; + + return NULL; } /*-----------------------------------------------------------------*/ /* ifFromIs - will return 1 if the from block matches this */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifFromIs) +DEFSETFUNC (ifFromIs) { - edge *ep = item; - V_ARG(eBBlock *,this); + edge *ep = item; + V_ARG (eBBlock *, this); - if (ep->from == this) - return 1; + if (ep->from == this) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* edgesTo - returns a set of edges with to == supplied value */ /*-----------------------------------------------------------------*/ -set *edgesTo ( eBBlock *to ) +set * +edgesTo (eBBlock * to) { - set *result = NULL ; - edge *loop ; - - for (loop = setFirstItem(graphEdges) ; loop ; loop = setNextItem(graphEdges)) - if (loop->to == to && !loop->from->noPath) - addSet(&result,loop->from); - - return result ; + set *result = NULL; + edge *loop; + + for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges)) + if (loop->to == to && !loop->from->noPath) + addSet (&result, loop->from); + + return result; } /*-----------------------------------------------------------------*/ /* addiCodeToeBBlock - will add an iCode to the end of a block */ /*-----------------------------------------------------------------*/ -void addiCodeToeBBlock ( eBBlock *ebp, iCode *ic , iCode *ip) +void +addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip) { - ic->prev = ic->next = NULL; - /* if the insert point is given */ - if (ip) { - ic->lineno = ip->lineno; - ic->prev = ip->prev; - ip->prev = ic; - ic->next = ip; - if (!ic->prev) - ebp->sch = ic; - else - ic->prev->next = ic; - return; + ic->prev = ic->next = NULL; + /* if the insert point is given */ + if (ip) + { + ic->filename = ip->filename; + ic->lineno = ip->lineno; + ic->prev = ip->prev; + ip->prev = ic; + ic->next = ip; + if (!ic->prev) + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - /* if the block has no instructions */ - if (ebp->ech == NULL ) { - ebp->sch = ebp->ech = ic; - ic->next = NULL; - return ; + /* if the block has no instructions */ + if (ebp->ech == NULL) + { + ebp->sch = ebp->ech = ic; + ic->next = NULL; + return; } - /* if the last instruction is a goto */ - /* we add it just before the goto */ - if ( ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE - || ebp->ech->op == RETURN) + /* if the last instruction is a goto */ + /* we add it just before the goto */ + if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE + || ebp->ech->op == RETURN) { - ic->lineno = ebp->ech->lineno; - ic->prev = ebp->ech->prev; - ebp->ech->prev = ic; - ic->next = ebp->ech; - if (!ic->prev) /* was the last only on in the block */ - ebp->sch = ic; - else - ic->prev->next = ic; - return; + ic->filename = ebp->ech->filename; + ic->lineno = ebp->ech->lineno; + ic->prev = ebp->ech->prev; + ebp->ech->prev = ic; + ic->next = ebp->ech; + if (!ic->prev) /* was the last only on in the block */ + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - /* if the last one was a ifx statement we check to see */ - /* if the condition was defined in the previous instruction */ - /* if this is true then we put it before the condition else */ - /* we put it before if, this is to reduce register pressure,*/ - /* we don't have to hold condition too long in a register */ - if ( ebp->ech->op == IFX ) { - iCode *ipoint ; - -/* if ( !ebp->ech->prev ) */ -/* ipoint = ebp->ech ; */ -/* else */ -/* if (!IC_RESULT(ebp->ech->prev)) */ -/* ipoint = ebp->ech ; */ -/* else */ -/* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */ -/* ipoint = ebp->ech->prev; */ -/* else */ -/* ipoint = ebp->ech ; */ - ipoint = ebp->ech ; - ic->lineno = ipoint->lineno; - ic->prev = ipoint->prev; - ipoint->prev = ic; - ic->next = ipoint; - if (!ic->prev) - ebp->sch = ic; - else - ic->prev->next = ic; - return; + /* if the last one was a ifx statement we check to see */ + /* if the condition was defined in the previous instruction */ + /* if this is true then we put it before the condition else */ + /* we put it before if, this is to reduce register pressure, */ + /* we don't have to hold condition too long in a register */ + + /* loop induction sometimes appends a GOTO instruction, */ + /* it must be at the very end */ + if (ebp->ech->op == IFX && ic->op != GOTO) + { + iCode *ipoint; + +/* if ( !ebp->ech->prev ) */ +/* ipoint = ebp->ech ; */ +/* else */ +/* if (!IC_RESULT(ebp->ech->prev)) */ +/* ipoint = ebp->ech ; */ +/* else */ +/* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */ +/* ipoint = ebp->ech->prev; */ +/* else */ +/* ipoint = ebp->ech ; */ + ipoint = ebp->ech; + ic->filename = ipoint->filename; + ic->lineno = ipoint->lineno; + ic->prev = ipoint->prev; + ipoint->prev = ic; + ic->next = ipoint; + if (!ic->prev) + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - - /* will add it to the very end */ - ip = ebp->ech; - ip->next = ic; - ic->prev = ip; - ic->next = NULL; - ebp->ech = ic; - - return ; + + /* will add it to the very end */ + ip = ebp->ech; + ip->next = ic; + ic->prev = ip; + ic->next = NULL; + ebp->ech = ic; + + return; } /*-----------------------------------------------------------------*/ /* remiCodeFromeBBlock - remove an iCode from BBlock */ /*-----------------------------------------------------------------*/ -void remiCodeFromeBBlock (eBBlock *ebb, iCode *ic) +void +remiCodeFromeBBlock (eBBlock * ebb, iCode * ic) { - if (ic->prev) - ic->prev->next = ic->next ; - else - ebb->sch = ic->next ; - - if (ic->next) - ic->next->prev = ic->prev; - else - ebb->ech = ic->prev; + wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq); + if (ic->prev) + ic->prev->next = ic->next; + else + ebb->sch = ic->next; + + if (ic->next) + ic->next->prev = ic->prev; + else + ebb->ech = ic->prev; } /*-----------------------------------------------------------------*/ /* iCodeBreakDown : breakDown iCode chain to blocks */ /*-----------------------------------------------------------------*/ -eBBlock **iCodeBreakDown (iCode *ic, int *count) +ebbIndex * +iCodeBreakDown (iCode * ic) { - eBBlock **ebbs = NULL ; - iCode *loop = ic; - - *count = 0 ; - - /* allocate for the first entry */ - - ebbs = Safe_calloc(sizeof(eBBlock **)); - - while (loop) { - - /* convert 2 block */ - eBBlock *ebb = iCode2eBBlock(loop); - loop = ebb->ech->next ; - - ebb->ech->next = NULL ; /* mark the end of this chain */ - if (loop) - loop->prev = NULL ; - ebb->bbnum = *count ; /* save this block number */ - /* put it in the array */ - ebbs[(*count)++] = ebb ; - - /* allocate for the next one. Remember to clear the new */ - /* pointer at the end, that was created by realloc. */ - - ebbs = Safe_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)) ; - - ebbs[*count] = 0; - - /* if this one ends in a goto or a conditional */ - /* branch then check if the block it is going */ - /* to already exists, if yes then this could */ - /* be a loop, add a preheader to the block it */ - /* goes to if it does not already have one */ - if (ebbs[(*count) - 1]->ech && - (ebbs[(*count) - 1]->ech->op == GOTO || - ebbs[(*count) - 1]->ech->op == IFX )) { - - symbol *label ; - eBBlock *destBlock; - - if (ebbs[(*count) - 1]->ech->op == GOTO) - label = IC_LABEL(ebbs[(*count)-1]->ech); - else - if (!(label = IC_TRUE(ebbs[(*count)-1]->ech))) - label = IC_FALSE(ebbs[(*count)-1]->ech); - - if ((destBlock = eBBWithEntryLabel(ebbs,label,(*count))) && - destBlock->preHeader == NULL && - otherPathsPresent(ebbs,destBlock) ) { - - symbol *preHeaderLabel = newiTempPreheaderLabel(); - int i,j ; - eBBlock *pBlock ; - - /* go thru all block replacing the entryLabel with new label */ - /* till we reach the block , then we insert a new ebblock */ - for ( i = 0 ; i < (*count) ; i++ ) { - if ( ebbs[i] == destBlock ) - break ; - replaceLabel(ebbs[i],label,preHeaderLabel); - } - - (*count)++ ; - - /* if we have stopped at the block , allocate for an extra one */ - - ebbs = Safe_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)) ; - - ebbs[*count] = 0; - - /* then move the block down one count */ - pBlock = ebbs[j = i]; - for ( i += 1; i < (*count) ; i++ ) { - eBBlock *xBlock; - - xBlock = ebbs[i]; - ebbs[i] = pBlock; - ebbs[i]->bbnum = i; - pBlock = xBlock ; - } - - destBlock->preHeader = ebbs[j] = neweBBlock(); - ebbs[j]->bbnum = j; - ebbs[j]->entryLabel = preHeaderLabel ; - ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto(LABEL,preHeaderLabel); - ebbs[j]->sch->lineno = destBlock->sch->lineno; - } - } + eBBlock **ebbs = NULL; + iCode *loop = ic; + ebbIndex *ebbi; + + ebbi = Safe_alloc (sizeof (ebbIndex)); + ebbi->count = 0; + ebbi->dfOrder = NULL; /* no depth first order information yet */ + + /* allocate for the first entry */ + + ebbs = Safe_alloc (sizeof (eBBlock *)); + ebbi->bbOrder = ebbs; + + while (loop) + { + + /* convert 2 block */ + eBBlock *ebb = iCode2eBBlock (loop); + loop = ebb->ech->next; + + ebb->ech->next = NULL; /* mark the end of this chain */ + if (loop) + loop->prev = NULL; + ebb->bbnum = ebbi->count; /* save this block number */ + /* put it in the array */ + ebbs[(ebbi->count)++] = ebb; + + /* allocate for the next one. Remember to clear the new */ + /* pointer at the end, that was created by realloc. */ + + ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *)); + ebbi->bbOrder = ebbs; + + ebbs[ebbi->count] = 0; + + /* if this one ends in a goto or a conditional */ + /* branch then check if the block it is going */ + /* to already exists, if yes then this could */ + /* be a loop, add a preheader to the block it */ + /* goes to if it does not already have one */ + if (ebbs[(ebbi->count) - 1]->ech && + (ebbs[(ebbi->count) - 1]->ech->op == GOTO || + ebbs[(ebbi->count) - 1]->ech->op == IFX)) + { + + symbol *label; + eBBlock *destBlock; + + if (ebbs[(ebbi->count) - 1]->ech->op == GOTO) + label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech); + else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech))) + label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech); + + if ((destBlock = eBBWithEntryLabel (ebbi, label)) && + destBlock->preHeader == NULL && + otherPathsPresent (ebbs, destBlock)) + { + + symbol *preHeaderLabel = newiTempLoopHeaderLabel (1); + int i, j; + eBBlock *pBlock; + + /* go thru all block replacing the entryLabel with new label */ + /* till we reach the block , then we insert a new ebblock */ + for (i = 0; i < (ebbi->count); i++) + { + if (ebbs[i] == destBlock) + break; + replaceLabel (ebbs[i], label, preHeaderLabel); + } + + (ebbi->count)++; + + /* if we have stopped at the block , allocate for an extra one */ + + ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *)); + ebbi->bbOrder = ebbs; + + ebbs[ebbi->count] = 0; + + /* then move the block down one count */ + pBlock = ebbs[j = i]; + for (i += 1; i < (ebbi->count); i++) + { + eBBlock *xBlock; + + xBlock = ebbs[i]; + ebbs[i] = pBlock; + ebbs[i]->bbnum = i; + pBlock = xBlock; + } + + destBlock->preHeader = ebbs[j] = neweBBlock (); + ebbs[j]->bbnum = j; + ebbs[j]->entryLabel = preHeaderLabel; + ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel); + ebbs[j]->sch->filename = destBlock->sch->filename; + ebbs[j]->sch->lineno = destBlock->sch->lineno; + } + } } - - /* mark the end */ - ebbs[*count] = NULL ; - return ebbs ; + /* mark the end */ + ebbs[ebbi->count] = NULL; + + return ebbi; } /*-----------------------------------------------------------------*/ /* replaceSymBySym : - replace operand by operand in blocks */ /* replaces only left & right in blocks */ /*-----------------------------------------------------------------*/ - void replaceSymBySym (set *sset, operand *src, operand *dest) +void +replaceSymBySym (set * sset, operand * src, operand * dest) { - set *loop ; - eBBlock *rBlock ; - - /* for all blocks in the set do */ - for ( loop = sset ; loop ; loop = loop->next) { - iCode *ic ; - - rBlock = loop->item ; - /* for all instructions in this block do */ - for ( ic = rBlock->sch ; ic ; ic = ic->next ) { - - /* if we find usage */ - if (ic->op == IFX && isOperandEqual(src,IC_COND(ic))) { - bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key); - IC_COND(ic) = operandFromOperand(dest); - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - continue ; - } - - if (isOperandEqual(IC_RIGHT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key); - IC_RIGHT(ic) = operandFromOperand(dest); - IC_RIGHT(ic)->isaddr = 0; - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - } - - if (isOperandEqual(IC_LEFT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key); - if (POINTER_GET(ic) && IS_ITEMP(dest)) { - IC_LEFT(ic) = operandFromOperand(dest); - IC_LEFT(ic)->isaddr = 1; - } else { - IC_LEFT(ic) = operandFromOperand(dest); - IC_LEFT(ic)->isaddr = 0; - } - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - } - - /* special case for pointer sets */ - if (POINTER_SET(ic) && - isOperandEqual(IC_RESULT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_RESULT(ic)),ic->key); - IC_RESULT(ic) = operandFromOperand(dest); - IC_RESULT(ic)->isaddr = 1; - OP_USES(dest) = bitVectSetBit(OP_USES(dest),ic->key); - } - } + set *loop; + eBBlock *rBlock; + + /* for all blocks in the set do */ + for (loop = sset; loop; loop = loop->next) + { + iCode *ic; + + rBlock = loop->item; + /* for all instructions in this block do */ + for (ic = rBlock->sch; ic; ic = ic->next) + { + + /* if we find usage */ + if (ic->op == IFX && isOperandEqual (src, IC_COND (ic))) + { + bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key); + IC_COND (ic) = operandFromOperand (dest); + OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key); + continue; + } + + if (isOperandEqual (IC_RIGHT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key); + IC_RIGHT (ic) = operandFromOperand (dest); + IC_RIGHT (ic)->isaddr = 0; + OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key); + } + + if (isOperandEqual (IC_LEFT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key); + if (POINTER_GET (ic) && IS_ITEMP (dest)) + { + IC_LEFT (ic) = operandFromOperand (dest); + IC_LEFT (ic)->isaddr = 1; + } + else + { + IC_LEFT (ic) = operandFromOperand (dest); + IC_LEFT (ic)->isaddr = 0; + } + OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key); + } + + /* special case for pointer sets */ + if (POINTER_SET (ic) && + isOperandEqual (IC_RESULT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key); + IC_RESULT (ic) = operandFromOperand (dest); + IC_RESULT (ic)->isaddr = 1; + OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key); + } + } } } /*-----------------------------------------------------------------*/ /* replaceLabel - replace reference to one label by another */ /*-----------------------------------------------------------------*/ - void replaceLabel(eBBlock *ebp, symbol *fromLbl, symbol *toLbl) -{ - iCode *ic; - - if (!ebp) - return ; - - for (ic = ebp->sch ; ic ; ic = ic->next ) { - switch (ic->op) { - - case GOTO : - if (isSymbolEqual(IC_LABEL(ic),fromLbl)) - IC_LABEL(ic) = toLbl; - break; - - case IFX: - if (IC_TRUE(ic) && isSymbolEqual(IC_TRUE(ic),fromLbl)) - IC_TRUE(ic) = toLbl ; - else - if (isSymbolEqual(IC_FALSE(ic),fromLbl)) - IC_FALSE(ic) = toLbl; - break; - } - } +void +replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl) +{ + iCode *ic; + if (!ebp) return; - + + for (ic = ebp->sch; ic; ic = ic->next) + { + switch (ic->op) + { + + case GOTO: + if (isSymbolEqual (IC_LABEL (ic), fromLbl)) + IC_LABEL (ic) = toLbl; + break; + + case IFX: + if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl)) + IC_TRUE (ic) = toLbl; + else if (isSymbolEqual (IC_FALSE (ic), fromLbl)) + IC_FALSE (ic) = toLbl; + break; + } + } + + return; + } /*-----------------------------------------------------------------*/ /* iCodeFromeBBlock - convert basic block to iCode chain */ /*-----------------------------------------------------------------*/ -iCode *iCodeFromeBBlock ( eBBlock **ebbs, int count) +iCode * +iCodeFromeBBlock (eBBlock ** ebbs, int count) { - int i = 1 ; - iCode *ric = ebbs[0]->sch ; - iCode *lic = ebbs[0]->ech ; - - for ( ; i < count; i++ ) { - if ( ebbs[i]->sch == NULL) - continue ; - - if ( ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) { - werror(W_CODE_UNREACH,ebbs[i]->sch->filename,ebbs[i]->sch->lineno); - continue ; - } - - lic->next = ebbs[i]->sch ; - lic->next->prev = lic; - lic = ebbs[i]->ech ; + int i = 1; + iCode *ric = ebbs[0]->sch; + iCode *lic = ebbs[0]->ech; + + for (; i < count; i++) + { + if (ebbs[i]->sch == NULL) + continue; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + { + iCode *ic = NULL; + bool foundNonlabel = 0; + ic=ebbs[i]->sch; + do + { + if (ic->op != LABEL) + { + foundNonlabel = 1; + break; + } + if (ic==ebbs[i]->ech) + break; + ic = ic->next; + } + while (ic); + if (foundNonlabel && ic) + { + werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH); + continue; + } + } + + lic->next = ebbs[i]->sch; + lic->next->prev = lic; + lic = ebbs[i]->ech; + } - return ric; + return ric; } /*-----------------------------------------------------------------*/ /* otherPathsPresent - determines if there is a path from _entry */ /* to this block in a half constructed set of blocks */ /*-----------------------------------------------------------------*/ -int otherPathsPresent (eBBlock **ebbs, eBBlock *this) +int +otherPathsPresent (eBBlock ** ebbs, eBBlock * this) { - int i ; - - /* for all blocks preceding this block */ - for ( i = 0 ; i < this->bbnum ; i++ ) { - iCode *ic ; - - /* if there is a reference to the entry label of this block */ - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - switch (ic->op) { - case GOTO : - if (IC_LABEL(ic)->key == this->entryLabel->key) - return 1; - break; - - case IFX : - if (IC_TRUE(ic)) { - if (IC_TRUE(ic)->key == this->entryLabel->key) - return 1; - } else - if (IC_FALSE(ic)->key == this->entryLabel->key) - return 1 ; - break; - } - } + int i; + + /* for all blocks preceding this block */ + for (i = 0; i < this->bbnum; i++) + { + iCode *ic; + + /* if there is a reference to the entry label of this block */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + switch (ic->op) + { + case GOTO: + if (IC_LABEL (ic)->key == this->entryLabel->key) + return 1; + break; + + case IFX: + if (IC_TRUE (ic)) + { + if (IC_TRUE (ic)->key == this->entryLabel->key) + return 1; + } + else if (IC_FALSE (ic)->key == this->entryLabel->key) + return 1; + break; + } + } } - /* comes here means we have not found it yet */ - /* in this case check if the previous block */ - /* ends in a goto if it does then we have no */ - /* path else we have a path */ - if (this->bbnum && ebbs[this->bbnum - 1]->ech && - ebbs[this->bbnum - 1]->ech->op == GOTO ) - return 0; - else - return 1; + /* comes here means we have not found it yet */ + /* in this case check if the previous block */ + /* ends in a goto if it does then we have no */ + /* path else we have a path */ + if (this->bbnum && ebbs[this->bbnum - 1]->ech && + ebbs[this->bbnum - 1]->ech->op == GOTO) + return 0; + else + return 1; } -