1 /*-------------------------------------------------------------------------
3 SDCCBBlock.c - routines to manipulate basic Blocks
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
29 set *graphEdges = NULL ; /* list of edges in this flow graph */
32 /*-----------------------------------------------------------------*/
33 /* printEntryLabel - prints entry label of a ebblock */
34 /*-----------------------------------------------------------------*/
35 DEFSETFUNC(printEntryLabel)
39 fprintf (stdout," %-20s ",bp->entryLabel->name);
43 /*-----------------------------------------------------------------*/
44 /* neweBBlock - allocate & return a new extended basic block */
45 /*-----------------------------------------------------------------*/
46 eBBlock *neweBBlock ()
50 ALLOC(ebb,sizeof(eBBlock));
54 /*-----------------------------------------------------------------*/
55 /* newEdge - allocates & initialises an edge to given values */
56 /*-----------------------------------------------------------------*/
57 edge *newEdge (eBBlock *from, eBBlock *to)
61 ALLOC(ep,sizeof(edge));
68 /*-----------------------------------------------------------------*/
69 /* dumpLiveRanges - dump liverange information into a file */
70 /*-----------------------------------------------------------------*/
71 void dumpLiveRanges (char *ext,hTab *liveRanges)
78 /* create the file name */
79 strcpy(buffer,srcFileName);
82 if (!(file = fopen(buffer,"a+"))) {
83 werror(E_FILE_OPEN_ERR,buffer);
89 for (sym = hTabFirstItem(liveRanges,&k); sym ;
90 sym = hTabNextItem(liveRanges,&k)) {
92 fprintf (file,"%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
93 (sym->rname[0] ? sym->rname : sym->name),
95 sym->liveFrom,sym->liveTo,
97 sym->isreqv,sym->remat
100 fprintf(file,"{"); printTypeChain(sym->type,file);
101 if (sym->usl.spillLoc) {
102 fprintf(file,"}{ sir@ %s",sym->usl.spillLoc->rname);
106 /* if assigned to registers */
110 if (sym->usl.spillLoc)
111 fprintf(file,"[%s]",(sym->usl.spillLoc->rname[0] ?
112 sym->usl.spillLoc->rname :
113 sym->usl.spillLoc->name));
115 fprintf(file,"[err]");
117 fprintf(file,"[remat]");
122 for(i=0;i<sym->nRegs;i++)
123 fprintf(file,"%s ", port->getRegName(sym->regs[i]));
132 /*-----------------------------------------------------------------*/
133 /* dumpEbbsToFileExt - writeall the basic blocks to a file */
134 /*-----------------------------------------------------------------*/
135 void dumpEbbsToFileExt (char *ext,eBBlock **ebbs, int count)
141 /* create the file name */
142 strcpy(buffer,srcFileName);
145 if (!(of = fopen(buffer,"a+"))) {
146 werror(E_FILE_OPEN_ERR,buffer);
152 for (i=0; i < count ; i++ ) {
153 fprintf(of,"\n----------------------------------------------------------------\n");
154 fprintf(of,"Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
155 ebbs[i]->entryLabel->name,
158 ebbs[i]->isLastInLoop);
159 fprintf(of,"\ndefines bitVector :");
160 bitVectDebugOn(ebbs[i]->defSet,of);
161 fprintf(of,"\nlocal defines bitVector :");
162 bitVectDebugOn(ebbs[i]->ldefs,of);
163 fprintf(of,"\npointers Set bitvector :");
164 bitVectDebugOn(ebbs[i]->ptrsSet,of);
165 fprintf(of,"\n----------------------------------------------------------------\n");
166 printiCChain(ebbs[i]->sch,of);
171 /*-----------------------------------------------------------------*/
172 /* iCode2eBBlock - converts a sequnce till label to a ebb */
173 /*-----------------------------------------------------------------*/
174 eBBlock *iCode2eBBlock (iCode *ic)
177 eBBlock *ebb = neweBBlock(); /* a llocate an entry */
179 /* put the first one unconditionally */
182 /* if this is a label then */
184 ebb->entryLabel = ic->argLabel.label ;
186 sprintf(buffer,"_eBBlock%d",eBBNum++);
187 ebb->entryLabel = newSymbol(buffer,1);
188 ebb->entryLabel->key = labelKey++;
193 ic->op == JUMPTABLE ||
199 if ((ic->next && ic->next->op == LABEL) ||
201 ebb->ech = ebb->sch ;
205 /* loop thru till we find one with a label */
206 for ( loop = ic->next ; loop ; loop = loop->next ) {
208 /* if this is the last one */
211 /* if this is a function call */
212 if (loop->op == CALL || loop->op == PCALL) {
215 currFunc->hasFcall = 1;
218 /* if the next one is a label */
219 /* if this is a goto or ifx */
220 if (loop->next->op == LABEL ||
222 loop->op == JUMPTABLE ||
227 /* mark the end of the chain */
233 /*-----------------------------------------------------------------*/
234 /* eBBWithEntryLabel - finds the basic block with the entry label */
235 /*-----------------------------------------------------------------*/
236 eBBlock *eBBWithEntryLabel ( eBBlock **ebbs , symbol *eLabel, int count)
240 for ( i = 0 ; i < count ; i++ ) {
241 if (isSymbolEqual(ebbs[i]->entryLabel,eLabel))
249 /*-----------------------------------------------------------------*/
250 /* ifFromIs - will return 1 if the from block matches this */
251 /*-----------------------------------------------------------------*/
255 V_ARG(eBBlock *,this);
257 if (ep->from == this)
264 /*-----------------------------------------------------------------*/
265 /* edgesTo - returns a set of edges with to == supplied value */
266 /*-----------------------------------------------------------------*/
267 set *edgesTo ( eBBlock *to )
272 for (loop = setFirstItem(graphEdges) ; loop ; loop = setNextItem(graphEdges))
273 if (loop->to == to && !loop->from->noPath)
274 addSet(&result,loop->from);
280 /*-----------------------------------------------------------------*/
281 /* addiCodeToeBBlock - will add an iCode to the end of a block */
282 /*-----------------------------------------------------------------*/
283 void addiCodeToeBBlock ( eBBlock *ebp, iCode *ic , iCode *ip)
285 ic->prev = ic->next = NULL;
286 /* if the insert point is given */
288 ic->lineno = ip->lineno;
299 /* if the block has no instructions */
300 if (ebp->ech == NULL ) {
301 ebp->sch = ebp->ech = ic;
306 /* if the last instruction is a goto */
307 /* we add it just before the goto */
308 if ( ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE) {
309 ic->lineno = ebp->ech->lineno;
310 ic->prev = ebp->ech->prev;
313 if (!ic->prev) /* was the last only on in the block */
320 /* if the last one was a ifx statement we check to see */
321 /* if the condition was defined in the previous instruction */
322 /* if this is true then we put it before the condition else */
323 /* we put it before if, this is to reduce register pressure,*/
324 /* we don't have to hold condition too long in a register */
325 if ( ebp->ech->op == IFX ) {
328 /* if ( !ebp->ech->prev ) */
329 /* ipoint = ebp->ech ; */
331 /* if (!IC_RESULT(ebp->ech->prev)) */
332 /* ipoint = ebp->ech ; */
334 /* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
335 /* ipoint = ebp->ech->prev; */
337 /* ipoint = ebp->ech ; */
339 ic->lineno = ipoint->lineno;
340 ic->prev = ipoint->prev;
350 /* will add it to the very end */
360 /*-----------------------------------------------------------------*/
361 /* remiCodeFromeBBlock - remove an iCode from BBlock */
362 /*-----------------------------------------------------------------*/
363 void remiCodeFromeBBlock (eBBlock *ebb, iCode *ic)
366 ic->prev->next = ic->next ;
368 ebb->sch = ic->next ;
371 ic->next->prev = ic->prev;
376 /*-----------------------------------------------------------------*/
377 /* iCodeBreakDown : breakDown iCode chain to blocks */
378 /*-----------------------------------------------------------------*/
379 eBBlock **iCodeBreakDown (iCode *ic, int *count)
381 eBBlock **ebbs = NULL ;
386 /* allocate for the first entry */
387 ALLOC(ebbs,sizeof(eBBlock **));
391 /* convert 2 block */
392 eBBlock *ebb = iCode2eBBlock(loop);
393 loop = ebb->ech->next ;
395 ebb->ech->next = NULL ; /* mark the end of this chain */
398 ebb->bbnum = *count ; /* save this block number */
399 /* put it in the array */
400 ebbs[(*count)++] = ebb ;
402 /* allocate for the next one */
403 if (!(ebbs = GC_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)))) {
404 werror(E_OUT_OF_MEM,__FILE__,(*count + 1)*sizeof(eBBlock **));
408 /* if this one ends in a goto or a conditional */
409 /* branch then check if the block it is going */
410 /* to already exists, if yes then this could */
411 /* be a loop, add a preheader to the block it */
412 /* goes to if it does not already have one */
413 if (ebbs[(*count) - 1]->ech &&
414 (ebbs[(*count) - 1]->ech->op == GOTO ||
415 ebbs[(*count) - 1]->ech->op == IFX )) {
420 if (ebbs[(*count) - 1]->ech->op == GOTO)
421 label = IC_LABEL(ebbs[(*count)-1]->ech);
423 if (!(label = IC_TRUE(ebbs[(*count)-1]->ech)))
424 label = IC_FALSE(ebbs[(*count)-1]->ech);
426 if ((destBlock = eBBWithEntryLabel(ebbs,label,(*count))) &&
427 destBlock->preHeader == NULL &&
428 otherPathsPresent(ebbs,destBlock) ) {
430 symbol *preHeaderLabel = newiTempPreheaderLabel();
434 /* go thru all block replacing the entryLabel with new label */
435 /* till we reach the block , then we insert a new ebblock */
436 for ( i = 0 ; i < (*count) ; i++ ) {
437 if ( ebbs[i] == destBlock )
439 replaceLabel(ebbs[i],label,preHeaderLabel);
443 /* if we have stopped at the block , allocate for an extra one */
444 if (!(ebbs = GC_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)))) {
445 werror(E_OUT_OF_MEM,__FILE__,(*count + 1)*sizeof(eBBlock **));
449 /* then move the block down one count */
450 pBlock = ebbs[j = i];
451 for ( i += 1; i < (*count) ; i++ ) {
460 destBlock->preHeader = ebbs[j] = neweBBlock();
462 ebbs[j]->entryLabel = preHeaderLabel ;
463 ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto(LABEL,preHeaderLabel);
464 ebbs[j]->sch->lineno = destBlock->sch->lineno;
470 ebbs[*count] = NULL ;
475 /*-----------------------------------------------------------------*/
476 /* replaceSymBySym : - replace operand by operand in blocks */
477 /* replaces only left & right in blocks */
478 /*-----------------------------------------------------------------*/
479 void replaceSymBySym (set *sset, operand *src, operand *dest)
484 /* for all blocks in the set do */
485 for ( loop = sset ; loop ; loop = loop->next) {
488 rBlock = loop->item ;
489 /* for all instructions in this block do */
490 for ( ic = rBlock->sch ; ic ; ic = ic->next ) {
492 /* if we find usage */
493 if (ic->op == IFX && isOperandEqual(src,IC_COND(ic))) {
494 bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);
495 IC_COND(ic) = operandFromOperand(dest);
496 OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key);
500 if (isOperandEqual(IC_RIGHT(ic),src)) {
501 bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
502 IC_RIGHT(ic) = operandFromOperand(dest);
503 IC_RIGHT(ic)->isaddr = 0;
504 OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key);
507 if (isOperandEqual(IC_LEFT(ic),src)) {
508 bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
509 if (POINTER_GET(ic) && IS_ITEMP(dest)) {
510 IC_LEFT(ic) = operandFromOperand(dest);
511 IC_LEFT(ic)->isaddr = 1;
513 IC_LEFT(ic) = operandFromOperand(dest);
514 IC_LEFT(ic)->isaddr = 0;
516 OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key);
519 /* special case for pointer sets */
520 if (POINTER_SET(ic) &&
521 isOperandEqual(IC_RESULT(ic),src)) {
522 bitVectUnSetBit (OP_USES(IC_RESULT(ic)),ic->key);
523 IC_RESULT(ic) = operandFromOperand(dest);
524 IC_RESULT(ic)->isaddr = 1;
525 OP_USES(dest) = bitVectSetBit(OP_USES(dest),ic->key);
531 /*-----------------------------------------------------------------*/
532 /* replaceLabel - replace reference to one label by another */
533 /*-----------------------------------------------------------------*/
534 void replaceLabel(eBBlock *ebp, symbol *fromLbl, symbol *toLbl)
541 for (ic = ebp->sch ; ic ; ic = ic->next ) {
545 if (isSymbolEqual(IC_LABEL(ic),fromLbl))
546 IC_LABEL(ic) = toLbl;
550 if (IC_TRUE(ic) && isSymbolEqual(IC_TRUE(ic),fromLbl))
551 IC_TRUE(ic) = toLbl ;
553 if (isSymbolEqual(IC_FALSE(ic),fromLbl))
554 IC_FALSE(ic) = toLbl;
564 /*-----------------------------------------------------------------*/
565 /* iCodeFromeBBlock - convert basic block to iCode chain */
566 /*-----------------------------------------------------------------*/
567 iCode *iCodeFromeBBlock ( eBBlock **ebbs, int count)
570 iCode *ric = ebbs[0]->sch ;
571 iCode *lic = ebbs[0]->ech ;
573 for ( ; i < count; i++ ) {
574 if ( ebbs[i]->sch == NULL)
577 if ( ebbs[i]->noPath &&
578 (ebbs[i]->entryLabel != entryLabel &&
579 ebbs[i]->entryLabel != returnLabel )) {
580 werror(W_CODE_UNREACH,ebbs[i]->sch->filename,ebbs[i]->sch->lineno);
584 lic->next = ebbs[i]->sch ;
585 lic->next->prev = lic;
592 /*-----------------------------------------------------------------*/
593 /* otherPathsPresent - determines if there is a path from _entry */
594 /* to this block in a half constructed set of blocks */
595 /*-----------------------------------------------------------------*/
596 int otherPathsPresent (eBBlock **ebbs, eBBlock *this)
600 /* for all blocks preceding this block */
601 for ( i = 0 ; i < this->bbnum ; i++ ) {
604 /* if there is a reference to the entry label of this block */
605 for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
608 if (IC_LABEL(ic)->key == this->entryLabel->key)
614 if (IC_TRUE(ic)->key == this->entryLabel->key)
617 if (IC_FALSE(ic)->key == this->entryLabel->key)
624 /* comes here means we have not found it yet */
625 /* in this case check if the previous block */
626 /* ends in a goto if it does then we have no */
627 /* path else we have a path */
628 if (this->bbnum && ebbs[this->bbnum - 1]->ech &&
629 ebbs[this->bbnum - 1]->ech->op == GOTO )