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 */
31 struct _dumpFiles dumpFiles[] = {
32 {DUMP_RAW0, ".dumpraw0", NULL},
33 {DUMP_RAW1, ".dumpraw1", NULL},
34 {DUMP_CSE, ".dumpcse", NULL},
35 {DUMP_DFLOW, ".dumpdflow", NULL},
36 {DUMP_GCSE, ".dumpgcse", NULL},
37 {DUMP_DEADCODE, ".dumpdeadcode", NULL},
38 {DUMP_LOOP, ".dumploop", NULL},
39 {DUMP_LOOPG, ".dumploopg", NULL},
40 {DUMP_LOOPD, ".dumploopd", NULL},
41 {DUMP_RANGE, ".dumprange", NULL},
42 {DUMP_PACK, ".dumppack", NULL},
43 {DUMP_RASSGN, ".dumprassgn", NULL},
44 {DUMP_LRANGE, ".dumplrange", NULL},
48 /*-----------------------------------------------------------------*/
49 /* printEntryLabel - prints entry label of a ebblock */
50 /*-----------------------------------------------------------------*/
51 DEFSETFUNC (printEntryLabel)
55 fprintf (stdout, " %-20s ", bp->entryLabel->name);
59 /*-----------------------------------------------------------------*/
60 /* neweBBlock - allocate & return a new extended basic block */
61 /*-----------------------------------------------------------------*/
67 ebb = Safe_alloc (sizeof (eBBlock));
71 /*-----------------------------------------------------------------*/
72 /* newEdge - allocates & initialises an edge to given values */
73 /*-----------------------------------------------------------------*/
75 newEdge (eBBlock * from, eBBlock * to)
79 ep = Safe_alloc (sizeof (edge));
86 /*-----------------------------------------------------------------*/
87 /* createDumpFile - create the dump file */
88 /*-----------------------------------------------------------------*/
89 FILE *createDumpFile (int id) {
90 struct _dumpFiles *dumpFilesPtr=dumpFiles;
92 while (dumpFilesPtr->id) {
93 if (dumpFilesPtr->id==id)
98 if (!dumpFilesPtr->id) {
99 fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
103 if (!dumpFilesPtr->filePtr) {
104 // not used before, create it
105 strncpyz (scratchFileName, dstFileName, PATH_MAX);
106 strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX);
107 if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) {
108 werror (E_FILE_OPEN_ERR, scratchFileName);
112 return dumpFilesPtr->filePtr;
115 /*-----------------------------------------------------------------*/
116 /* closeDumpFiles - close possible opened dumpfiles */
117 /*-----------------------------------------------------------------*/
118 void closeDumpFiles() {
119 struct _dumpFiles *dumpFilesPtr;
121 for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
122 if (dumpFilesPtr->filePtr) {
123 fclose (dumpFilesPtr->filePtr);
128 /*-----------------------------------------------------------------*/
129 /* dumpLiveRanges - dump liverange information into a file */
130 /*-----------------------------------------------------------------*/
132 dumpLiveRanges (int id, hTab * liveRanges)
139 file=createDumpFile(id);
145 fprintf(file,"------------- Func %s -------------\n",currFunc->name);
146 for (sym = hTabFirstItem (liveRanges, &k); sym;
147 sym = hTabNextItem (liveRanges, &k))
150 fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
151 (sym->rname[0] ? sym->rname : sym->name),
153 sym->liveFrom, sym->liveTo,
155 sym->isreqv, sym->remat
159 printTypeChain (sym->type, file);
160 if (sym->usl.spillLoc)
162 fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
164 fprintf (file, "} clashes with ");
165 bitVectDebugOn(sym->clashes,file);
166 fprintf (file, "\n");
172 /*-----------------------------------------------------------------*/
173 /* dumpEbbsToFileExt - writeall the basic blocks to a file */
174 /*-----------------------------------------------------------------*/
176 dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
183 of=createDumpFile(id);
188 for (i = 0; i < count; i++)
190 fprintf (of, "\n----------------------------------------------------------------\n");
191 fprintf (of, "Basic Block %d %s : loop Depth = %d noPath = %d lastinLoop = %d\n",
193 ebbs[i]->entryLabel->name,
196 ebbs[i]->isLastInLoop);
198 if (!optimize.label4) {
199 // this only makes sense with --nolabelopt
200 fprintf (of, "\nsuccessors: ");
201 for (bb=setFirstItem(ebbs[i]->succList);
203 bb=setNextItem(ebbs[i]->succList)) {
204 fprintf (of, "%s ", bb->entryLabel->name);
206 fprintf (of, "\npredecessors: ");
207 for (bb=setFirstItem(ebbs[i]->predList);
209 bb=setNextItem(ebbs[i]->predList)) {
210 fprintf (of, "%s ", bb->entryLabel->name);
212 #if 0 // jwk: TODO: this can't be true
215 fprintf (of, "\ndominators ???: ");
216 for (d=0; d<ebbs[i]->domVect->size; d++) {
217 if (bitVectBitValue(ebbs[d]->domVect, d)) {
218 fprintf (of, "%s ", ebbs[d]->entryLabel->name);
226 fprintf (of, "\ndefines bitVector :");
227 bitVectDebugOn (ebbs[i]->defSet, of);
228 fprintf (of, "\nlocal defines bitVector :");
229 bitVectDebugOn (ebbs[i]->ldefs, of);
230 fprintf (of, "\npointers Set bitvector :");
231 bitVectDebugOn (ebbs[i]->ptrsSet, of);
232 if (ebbs[i]->isLastInLoop) {
233 fprintf (of, "\nInductions Set bitvector :");
234 bitVectDebugOn (ebbs[i]->linds, of);
236 fprintf (of, "\n----------------------------------------------------------------\n");
237 printiCChain (ebbs[i]->sch, of);
242 /*-----------------------------------------------------------------*/
243 /* iCode2eBBlock - converts a sequnce till label to a ebb */
244 /*-----------------------------------------------------------------*/
246 iCode2eBBlock (iCode * ic)
249 eBBlock *ebb = neweBBlock (); /* allocate an entry */
251 /* put the first one unconditionally */
254 /* if this is a label then */
256 ebb->entryLabel = ic->label;
259 SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++);
260 ebb->entryLabel = newSymbol (buffer, 1);
261 ebb->entryLabel->key = labelKey++;
266 ic->op == JUMPTABLE ||
273 if ((ic->next && ic->next->op == LABEL) ||
280 /* loop thru till we find one with a label */
281 for (loop = ic->next; loop; loop = loop->next)
284 /* if this is the last one */
287 /* if this is a function call */
288 if (loop->op == CALL || loop->op == PCALL)
292 FUNC_HASFCALL(currFunc->type) = 1;
295 /* if the next one is a label */
296 /* if this is a goto or ifx */
297 if (loop->next->op == LABEL ||
299 loop->op == JUMPTABLE ||
304 /* mark the end of the chain */
310 /*-----------------------------------------------------------------*/
311 /* eBBWithEntryLabel - finds the basic block with the entry label */
312 /*-----------------------------------------------------------------*/
314 eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count)
318 for (i = 0; i < count; i++)
320 if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
328 /*-----------------------------------------------------------------*/
329 /* ifFromIs - will return 1 if the from block matches this */
330 /*-----------------------------------------------------------------*/
331 DEFSETFUNC (ifFromIs)
334 V_ARG (eBBlock *, this);
336 if (ep->from == this)
343 /*-----------------------------------------------------------------*/
344 /* edgesTo - returns a set of edges with to == supplied value */
345 /*-----------------------------------------------------------------*/
347 edgesTo (eBBlock * to)
352 for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
353 if (loop->to == to && !loop->from->noPath)
354 addSet (&result, loop->from);
360 /*-----------------------------------------------------------------*/
361 /* addiCodeToeBBlock - will add an iCode to the end of a block */
362 /*-----------------------------------------------------------------*/
364 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
366 ic->prev = ic->next = NULL;
367 /* if the insert point is given */
370 ic->lineno = ip->lineno;
381 /* if the block has no instructions */
382 if (ebp->ech == NULL)
384 ebp->sch = ebp->ech = ic;
389 /* if the last instruction is a goto */
390 /* we add it just before the goto */
391 if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE
392 || ebp->ech->op == RETURN)
394 ic->lineno = ebp->ech->lineno;
395 ic->prev = ebp->ech->prev;
398 if (!ic->prev) /* was the last only on in the block */
405 /* if the last one was a ifx statement we check to see */
406 /* if the condition was defined in the previous instruction */
407 /* if this is true then we put it before the condition else */
408 /* we put it before if, this is to reduce register pressure, */
409 /* we don't have to hold condition too long in a register */
410 if (ebp->ech->op == IFX)
414 /* if ( !ebp->ech->prev ) */
415 /* ipoint = ebp->ech ; */
417 /* if (!IC_RESULT(ebp->ech->prev)) */
418 /* ipoint = ebp->ech ; */
420 /* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
421 /* ipoint = ebp->ech->prev; */
423 /* ipoint = ebp->ech ; */
425 ic->lineno = ipoint->lineno;
426 ic->prev = ipoint->prev;
436 /* will add it to the very end */
446 /*-----------------------------------------------------------------*/
447 /* remiCodeFromeBBlock - remove an iCode from BBlock */
448 /*-----------------------------------------------------------------*/
450 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
452 wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq);
454 ic->prev->next = ic->next;
459 ic->next->prev = ic->prev;
464 /*-----------------------------------------------------------------*/
465 /* iCodeBreakDown : breakDown iCode chain to blocks */
466 /*-----------------------------------------------------------------*/
468 iCodeBreakDown (iCode * ic, int *count)
470 eBBlock **ebbs = NULL;
475 /* allocate for the first entry */
477 ebbs = Safe_alloc (sizeof (eBBlock **));
482 /* convert 2 block */
483 eBBlock *ebb = iCode2eBBlock (loop);
484 loop = ebb->ech->next;
486 ebb->ech->next = NULL; /* mark the end of this chain */
489 ebb->bbnum = *count; /* save this block number */
490 /* put it in the array */
491 ebbs[(*count)++] = ebb;
493 /* allocate for the next one. Remember to clear the new */
494 /* pointer at the end, that was created by realloc. */
496 ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
500 /* if this one ends in a goto or a conditional */
501 /* branch then check if the block it is going */
502 /* to already exists, if yes then this could */
503 /* be a loop, add a preheader to the block it */
504 /* goes to if it does not already have one */
505 if (ebbs[(*count) - 1]->ech &&
506 (ebbs[(*count) - 1]->ech->op == GOTO ||
507 ebbs[(*count) - 1]->ech->op == IFX))
513 if (ebbs[(*count) - 1]->ech->op == GOTO)
514 label = IC_LABEL (ebbs[(*count) - 1]->ech);
515 else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech)))
516 label = IC_FALSE (ebbs[(*count) - 1]->ech);
518 if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) &&
519 destBlock->preHeader == NULL &&
520 otherPathsPresent (ebbs, destBlock))
523 symbol *preHeaderLabel = newiTempPreheaderLabel ();
527 /* go thru all block replacing the entryLabel with new label */
528 /* till we reach the block , then we insert a new ebblock */
529 for (i = 0; i < (*count); i++)
531 if (ebbs[i] == destBlock)
533 replaceLabel (ebbs[i], label, preHeaderLabel);
538 /* if we have stopped at the block , allocate for an extra one */
540 ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
544 /* then move the block down one count */
545 pBlock = ebbs[j = i];
546 for (i += 1; i < (*count); i++)
556 destBlock->preHeader = ebbs[j] = neweBBlock ();
558 ebbs[j]->entryLabel = preHeaderLabel;
559 ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
560 ebbs[j]->sch->lineno = destBlock->sch->lineno;
571 /*-----------------------------------------------------------------*/
572 /* replaceSymBySym : - replace operand by operand in blocks */
573 /* replaces only left & right in blocks */
574 /*-----------------------------------------------------------------*/
576 replaceSymBySym (set * sset, operand * src, operand * dest)
581 /* for all blocks in the set do */
582 for (loop = sset; loop; loop = loop->next)
587 /* for all instructions in this block do */
588 for (ic = rBlock->sch; ic; ic = ic->next)
591 /* if we find usage */
592 if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
594 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
595 IC_COND (ic) = operandFromOperand (dest);
596 OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
600 if (isOperandEqual (IC_RIGHT (ic), src))
602 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
603 IC_RIGHT (ic) = operandFromOperand (dest);
604 IC_RIGHT (ic)->isaddr = 0;
605 OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
608 if (isOperandEqual (IC_LEFT (ic), src))
610 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
611 if (POINTER_GET (ic) && IS_ITEMP (dest))
613 IC_LEFT (ic) = operandFromOperand (dest);
614 IC_LEFT (ic)->isaddr = 1;
618 IC_LEFT (ic) = operandFromOperand (dest);
619 IC_LEFT (ic)->isaddr = 0;
621 OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
624 /* special case for pointer sets */
625 if (POINTER_SET (ic) &&
626 isOperandEqual (IC_RESULT (ic), src))
628 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
629 IC_RESULT (ic) = operandFromOperand (dest);
630 IC_RESULT (ic)->isaddr = 1;
631 OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
637 /*-----------------------------------------------------------------*/
638 /* replaceLabel - replace reference to one label by another */
639 /*-----------------------------------------------------------------*/
641 replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
648 for (ic = ebp->sch; ic; ic = ic->next)
654 if (isSymbolEqual (IC_LABEL (ic), fromLbl))
655 IC_LABEL (ic) = toLbl;
659 if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
660 IC_TRUE (ic) = toLbl;
661 else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
662 IC_FALSE (ic) = toLbl;
672 /*-----------------------------------------------------------------*/
673 /* iCodeFromeBBlock - convert basic block to iCode chain */
674 /*-----------------------------------------------------------------*/
676 iCodeFromeBBlock (eBBlock ** ebbs, int count)
679 iCode *ric = ebbs[0]->sch;
680 iCode *lic = ebbs[0]->ech;
682 for (; i < count; i++)
684 if (ebbs[i]->sch == NULL)
687 if (ebbs[i]->noPath &&
688 (ebbs[i]->entryLabel != entryLabel &&
689 ebbs[i]->entryLabel != returnLabel))
691 werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno);
695 lic->next = ebbs[i]->sch;
696 lic->next->prev = lic;
703 /*-----------------------------------------------------------------*/
704 /* otherPathsPresent - determines if there is a path from _entry */
705 /* to this block in a half constructed set of blocks */
706 /*-----------------------------------------------------------------*/
708 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
712 /* for all blocks preceding this block */
713 for (i = 0; i < this->bbnum; i++)
717 /* if there is a reference to the entry label of this block */
718 for (ic = ebbs[i]->sch; ic; ic = ic->next)
723 if (IC_LABEL (ic)->key == this->entryLabel->key)
730 if (IC_TRUE (ic)->key == this->entryLabel->key)
733 else if (IC_FALSE (ic)->key == this->entryLabel->key)
740 /* comes here means we have not found it yet */
741 /* in this case check if the previous block */
742 /* ends in a goto if it does then we have no */
743 /* path else we have a path */
744 if (this->bbnum && ebbs[this->bbnum - 1]->ech &&
745 ebbs[this->bbnum - 1]->ech->op == GOTO)