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 -------------------------------------------------------------------------*/
30 set *graphEdges = NULL; /* list of edges in this flow graph */
32 struct _dumpFiles dumpFiles[] = {
33 {DUMP_RAW0, ".dumpraw0", NULL},
34 {DUMP_RAW1, ".dumpraw1", NULL},
35 {DUMP_CSE, ".dumpcse", NULL},
36 {DUMP_DFLOW, ".dumpdflow", NULL},
37 {DUMP_GCSE, ".dumpgcse", NULL},
38 {DUMP_DEADCODE, ".dumpdeadcode", NULL},
39 {DUMP_LOOP, ".dumploop", NULL},
40 {DUMP_LOOPG, ".dumploopg", NULL},
41 {DUMP_LOOPD, ".dumploopd", NULL},
42 {DUMP_RANGE, ".dumprange", NULL},
43 {DUMP_PACK, ".dumppack", NULL},
44 {DUMP_RASSGN, ".dumprassgn", NULL},
45 {DUMP_LRANGE, ".dumplrange", NULL},
49 /*-----------------------------------------------------------------*/
50 /* printEntryLabel - prints entry label of a ebblock */
51 /*-----------------------------------------------------------------*/
52 DEFSETFUNC (printEntryLabel)
56 fprintf (stdout, " %-20s ", bp->entryLabel->name);
60 /*-----------------------------------------------------------------*/
61 /* neweBBlock - allocate & return a new extended basic block */
62 /*-----------------------------------------------------------------*/
68 ebb = Safe_calloc (1, sizeof (eBBlock));
72 /*-----------------------------------------------------------------*/
73 /* newEdge - allocates & initialises an edge to given values */
74 /*-----------------------------------------------------------------*/
76 newEdge (eBBlock * from, eBBlock * to)
80 ep = Safe_calloc (1, sizeof (edge));
87 /*-----------------------------------------------------------------*/
88 /* appendDumpFile - if not already created, create the dump file */
89 /*-----------------------------------------------------------------*/
90 FILE *appendDumpFile (int id) {
91 struct _dumpFiles *dumpFilesPtr=dumpFiles;
93 while (dumpFilesPtr->id) {
94 if (dumpFilesPtr->id==id)
99 if (!dumpFilesPtr->id) {
100 fprintf (stdout, "internal error: appendDumpFile: unknown dump file.\n");
104 if (!dumpFilesPtr->filePtr) {
105 // not used before, create it
106 strcpy (buffer, srcFileName);
107 strcat (buffer, dumpFilesPtr->ext);
108 if (!(dumpFilesPtr->filePtr = fopen (buffer, "w"))) {
109 werror (E_FILE_OPEN_ERR, buffer);
112 //dprintf ("created: %s\n", buffer);
114 //dprintf ("appended: %s%s\n", srcFileName, dumpFilesPtr->ext);
116 return dumpFilesPtr->filePtr;
119 /*-----------------------------------------------------------------*/
120 /* closeDumpFiles - close possible opened dumpfiles */
121 /*-----------------------------------------------------------------*/
122 void closeDumpFiles() {
123 struct _dumpFiles *dumpFilesPtr;
125 for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
126 if (dumpFilesPtr->filePtr) {
127 fclose (dumpFilesPtr->filePtr);
128 //dprintf ("closed %s\n", dumpFilesPtr->ext);
133 /*-----------------------------------------------------------------*/
134 /* dumpLiveRanges - dump liverange information into a file */
135 /*-----------------------------------------------------------------*/
137 dumpLiveRanges (int id, hTab * liveRanges)
144 file=appendDumpFile(id);
149 for (sym = hTabFirstItem (liveRanges, &k); sym;
150 sym = hTabNextItem (liveRanges, &k))
153 fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
154 (sym->rname[0] ? sym->rname : sym->name),
156 sym->liveFrom, sym->liveTo,
158 sym->isreqv, sym->remat
162 printTypeChain (sym->type, file);
163 if (sym->usl.spillLoc)
165 fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
169 /* if assigned to registers */
175 if (sym->usl.spillLoc)
176 fprintf (file, "[%s]", (sym->usl.spillLoc->rname[0] ?
177 sym->usl.spillLoc->rname :
178 sym->usl.spillLoc->name));
180 fprintf (file, "[err]");
182 fprintf (file, "[remat]");
188 for (i = 0; i < sym->nRegs; i++)
189 fprintf (file, "%s ", port->getRegName (sym->regs[i]));
193 fprintf (file, "\n");
199 /*-----------------------------------------------------------------*/
200 /* dumpEbbsToFileExt - writeall the basic blocks to a file */
201 /*-----------------------------------------------------------------*/
203 dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
209 of=appendDumpFile(id);
214 for (i = 0; i < count; i++)
216 fprintf (of, "\n----------------------------------------------------------------\n");
217 fprintf (of, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
218 ebbs[i]->entryLabel->name,
221 ebbs[i]->isLastInLoop);
222 fprintf (of, "\ndefines bitVector :");
223 bitVectDebugOn (ebbs[i]->defSet, of);
224 fprintf (of, "\nlocal defines bitVector :");
225 bitVectDebugOn (ebbs[i]->ldefs, of);
226 fprintf (of, "\npointers Set bitvector :");
227 bitVectDebugOn (ebbs[i]->ptrsSet, of);
228 fprintf (of, "\n----------------------------------------------------------------\n");
229 printiCChain (ebbs[i]->sch, of);
234 /*-----------------------------------------------------------------*/
235 /* iCode2eBBlock - converts a sequnce till label to a ebb */
236 /*-----------------------------------------------------------------*/
238 iCode2eBBlock (iCode * ic)
241 eBBlock *ebb = neweBBlock (); /* a llocate an entry */
243 /* put the first one unconditionally */
246 /* if this is a label then */
248 ebb->entryLabel = ic->argLabel.label;
251 sprintf (buffer, "_eBBlock%d", eBBNum++);
252 ebb->entryLabel = newSymbol (buffer, 1);
253 ebb->entryLabel->key = labelKey++;
258 ic->op == JUMPTABLE ||
265 if ((ic->next && ic->next->op == LABEL) ||
272 /* loop thru till we find one with a label */
273 for (loop = ic->next; loop; loop = loop->next)
276 /* if this is the last one */
279 /* if this is a function call */
280 if (loop->op == CALL || loop->op == PCALL)
284 currFunc->hasFcall = 1;
287 /* if the next one is a label */
288 /* if this is a goto or ifx */
289 if (loop->next->op == LABEL ||
291 loop->op == JUMPTABLE ||
296 /* mark the end of the chain */
302 /*-----------------------------------------------------------------*/
303 /* eBBWithEntryLabel - finds the basic block with the entry label */
304 /*-----------------------------------------------------------------*/
306 eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count)
310 for (i = 0; i < count; i++)
312 if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
320 /*-----------------------------------------------------------------*/
321 /* ifFromIs - will return 1 if the from block matches this */
322 /*-----------------------------------------------------------------*/
323 DEFSETFUNC (ifFromIs)
326 V_ARG (eBBlock *, this);
328 if (ep->from == this)
335 /*-----------------------------------------------------------------*/
336 /* edgesTo - returns a set of edges with to == supplied value */
337 /*-----------------------------------------------------------------*/
339 edgesTo (eBBlock * to)
344 for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
345 if (loop->to == to && !loop->from->noPath)
346 addSet (&result, loop->from);
352 /*-----------------------------------------------------------------*/
353 /* addiCodeToeBBlock - will add an iCode to the end of a block */
354 /*-----------------------------------------------------------------*/
356 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
358 ic->prev = ic->next = NULL;
359 /* if the insert point is given */
362 ic->lineno = ip->lineno;
373 /* if the block has no instructions */
374 if (ebp->ech == NULL)
376 ebp->sch = ebp->ech = ic;
381 /* if the last instruction is a goto */
382 /* we add it just before the goto */
383 if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE
384 || ebp->ech->op == RETURN)
386 ic->lineno = ebp->ech->lineno;
387 ic->prev = ebp->ech->prev;
390 if (!ic->prev) /* was the last only on in the block */
397 /* if the last one was a ifx statement we check to see */
398 /* if the condition was defined in the previous instruction */
399 /* if this is true then we put it before the condition else */
400 /* we put it before if, this is to reduce register pressure, */
401 /* we don't have to hold condition too long in a register */
402 if (ebp->ech->op == IFX)
406 /* if ( !ebp->ech->prev ) */
407 /* ipoint = ebp->ech ; */
409 /* if (!IC_RESULT(ebp->ech->prev)) */
410 /* ipoint = ebp->ech ; */
412 /* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
413 /* ipoint = ebp->ech->prev; */
415 /* ipoint = ebp->ech ; */
417 ic->lineno = ipoint->lineno;
418 ic->prev = ipoint->prev;
428 /* will add it to the very end */
438 /*-----------------------------------------------------------------*/
439 /* remiCodeFromeBBlock - remove an iCode from BBlock */
440 /*-----------------------------------------------------------------*/
442 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
445 ic->prev->next = ic->next;
450 ic->next->prev = ic->prev;
455 /*-----------------------------------------------------------------*/
456 /* iCodeBreakDown : breakDown iCode chain to blocks */
457 /*-----------------------------------------------------------------*/
459 iCodeBreakDown (iCode * ic, int *count)
461 eBBlock **ebbs = NULL;
466 /* allocate for the first entry */
468 ebbs = Safe_calloc (1, sizeof (eBBlock **));
473 /* convert 2 block */
474 eBBlock *ebb = iCode2eBBlock (loop);
475 loop = ebb->ech->next;
477 ebb->ech->next = NULL; /* mark the end of this chain */
480 ebb->bbnum = *count; /* save this block number */
481 /* put it in the array */
482 ebbs[(*count)++] = ebb;
484 /* allocate for the next one. Remember to clear the new */
485 /* pointer at the end, that was created by realloc. */
487 ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
491 /* if this one ends in a goto or a conditional */
492 /* branch then check if the block it is going */
493 /* to already exists, if yes then this could */
494 /* be a loop, add a preheader to the block it */
495 /* goes to if it does not already have one */
496 if (ebbs[(*count) - 1]->ech &&
497 (ebbs[(*count) - 1]->ech->op == GOTO ||
498 ebbs[(*count) - 1]->ech->op == IFX))
504 if (ebbs[(*count) - 1]->ech->op == GOTO)
505 label = IC_LABEL (ebbs[(*count) - 1]->ech);
506 else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech)))
507 label = IC_FALSE (ebbs[(*count) - 1]->ech);
509 if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) &&
510 destBlock->preHeader == NULL &&
511 otherPathsPresent (ebbs, destBlock))
514 symbol *preHeaderLabel = newiTempPreheaderLabel ();
518 /* go thru all block replacing the entryLabel with new label */
519 /* till we reach the block , then we insert a new ebblock */
520 for (i = 0; i < (*count); i++)
522 if (ebbs[i] == destBlock)
524 replaceLabel (ebbs[i], label, preHeaderLabel);
529 /* if we have stopped at the block , allocate for an extra one */
531 ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
535 /* then move the block down one count */
536 pBlock = ebbs[j = i];
537 for (i += 1; i < (*count); i++)
547 destBlock->preHeader = ebbs[j] = neweBBlock ();
549 ebbs[j]->entryLabel = preHeaderLabel;
550 ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
551 ebbs[j]->sch->lineno = destBlock->sch->lineno;
562 /*-----------------------------------------------------------------*/
563 /* replaceSymBySym : - replace operand by operand in blocks */
564 /* replaces only left & right in blocks */
565 /*-----------------------------------------------------------------*/
567 replaceSymBySym (set * sset, operand * src, operand * dest)
572 /* for all blocks in the set do */
573 for (loop = sset; loop; loop = loop->next)
578 /* for all instructions in this block do */
579 for (ic = rBlock->sch; ic; ic = ic->next)
582 /* if we find usage */
583 if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
585 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
586 IC_COND (ic) = operandFromOperand (dest);
587 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
591 if (isOperandEqual (IC_RIGHT (ic), src))
593 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
594 IC_RIGHT (ic) = operandFromOperand (dest);
595 IC_RIGHT (ic)->isaddr = 0;
596 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
599 if (isOperandEqual (IC_LEFT (ic), src))
601 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
602 if (POINTER_GET (ic) && IS_ITEMP (dest))
604 IC_LEFT (ic) = operandFromOperand (dest);
605 IC_LEFT (ic)->isaddr = 1;
609 IC_LEFT (ic) = operandFromOperand (dest);
610 IC_LEFT (ic)->isaddr = 0;
612 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
615 /* special case for pointer sets */
616 if (POINTER_SET (ic) &&
617 isOperandEqual (IC_RESULT (ic), src))
619 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
620 IC_RESULT (ic) = operandFromOperand (dest);
621 IC_RESULT (ic)->isaddr = 1;
622 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
628 /*-----------------------------------------------------------------*/
629 /* replaceLabel - replace reference to one label by another */
630 /*-----------------------------------------------------------------*/
632 replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
639 for (ic = ebp->sch; ic; ic = ic->next)
645 if (isSymbolEqual (IC_LABEL (ic), fromLbl))
646 IC_LABEL (ic) = toLbl;
650 if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
651 IC_TRUE (ic) = toLbl;
652 else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
653 IC_FALSE (ic) = toLbl;
663 /*-----------------------------------------------------------------*/
664 /* iCodeFromeBBlock - convert basic block to iCode chain */
665 /*-----------------------------------------------------------------*/
667 iCodeFromeBBlock (eBBlock ** ebbs, int count)
670 iCode *ric = ebbs[0]->sch;
671 iCode *lic = ebbs[0]->ech;
673 for (; i < count; i++)
675 if (ebbs[i]->sch == NULL)
678 if (ebbs[i]->noPath &&
679 (ebbs[i]->entryLabel != entryLabel &&
680 ebbs[i]->entryLabel != returnLabel))
682 werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno);
686 lic->next = ebbs[i]->sch;
687 lic->next->prev = lic;
694 /*-----------------------------------------------------------------*/
695 /* otherPathsPresent - determines if there is a path from _entry */
696 /* to this block in a half constructed set of blocks */
697 /*-----------------------------------------------------------------*/
699 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
703 /* for all blocks preceding this block */
704 for (i = 0; i < this->bbnum; i++)
708 /* if there is a reference to the entry label of this block */
709 for (ic = ebbs[i]->sch; ic; ic = ic->next)
714 if (IC_LABEL (ic)->key == this->entryLabel->key)
721 if (IC_TRUE (ic)->key == this->entryLabel->key)
724 else if (IC_FALSE (ic)->key == this->entryLabel->key)
731 /* comes here means we have not found it yet */
732 /* in this case check if the previous block */
733 /* ends in a goto if it does then we have no */
734 /* path else we have a path */
735 if (this->bbnum && ebbs[this->bbnum - 1]->ech &&
736 ebbs[this->bbnum - 1]->ech->op == GOTO)