[ucsim] Intro -U, -u options and configurable NL in UART display
[sdcc.git] / sdcc / src / SDCCBBlock.c
blob4b05ee2d5a0098ec8487f9a6d1a8a5d0793201aa
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
10 later version.
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 -------------------------------------------------------------------------*/
26 #include "common.h"
27 #include "dbuf_string.h"
29 int eBBNum = 0;
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_LOSPRE, ".dumplospre", NULL},
43 {DUMP_GENCONSTPROP, ".dumpgenconstprop", NULL},
44 {DUMP_RANGE, ".dumprange", NULL},
45 {DUMP_PACK, ".dumppack", NULL},
46 {DUMP_RASSGN, ".dumprassgn", NULL},
47 {DUMP_LRANGE, ".dumplrange", NULL},
48 {DUMP_CUSTOM0, ".dumpcustom0", NULL},
49 {DUMP_CUSTOM1, ".dumpcustom1", NULL},
50 {0, NULL, NULL}
53 /*-----------------------------------------------------------------*/
54 /* printEntryLabel - prints entry label of a ebblock */
55 /*-----------------------------------------------------------------*/
56 DEFSETFUNC (printEntryLabel)
58 eBBlock *bp = item;
60 fprintf (stdout, " %-20s ", bp->entryLabel->name);
61 return 0;
64 /*-----------------------------------------------------------------*/
65 /* neweBBlock - allocate & return a new extended basic block */
66 /*-----------------------------------------------------------------*/
67 eBBlock *
68 neweBBlock ()
70 eBBlock *ebb;
72 ebb = Safe_alloc (sizeof (eBBlock));
73 return ebb;
76 /*-----------------------------------------------------------------*/
77 /* newEdge - allocates & initialises an edge to given values */
78 /*-----------------------------------------------------------------*/
79 edge *
80 newEdge (eBBlock * from, eBBlock * to)
82 edge *ep;
84 ep = Safe_alloc (sizeof (edge));
86 ep->from = from;
87 ep->to = to;
88 return ep;
91 /*-----------------------------------------------------------------*/
92 /* createDumpFile - create the dump file */
93 /*-----------------------------------------------------------------*/
94 FILE *
95 createDumpFile (int id)
97 struct _dumpFiles *dumpFilesPtr = dumpFiles;
98 static int dumpIndex = 0;
99 static char dumpIndexStr[32];
101 while (dumpFilesPtr->id)
103 if (dumpFilesPtr->id == id)
104 break;
105 dumpFilesPtr++;
108 if (!dumpFilesPtr->id)
110 fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
111 exit (1);
114 sprintf (dumpIndexStr, ".%d", dumpIndex);
115 dumpIndex++;
117 if (!dumpFilesPtr->filePtr)
119 // not used before, create it
120 struct dbuf_s dumpFileName;
122 dbuf_init (&dumpFileName, PATH_MAX);
123 dbuf_append_str (&dumpFileName, dstFileName);
124 #ifdef _DEBUG
125 dbuf_append_str (&dumpFileName, dumpIndexStr);
126 #endif
127 dbuf_append_str (&dumpFileName, dumpFilesPtr->ext);
128 if (!(dumpFilesPtr->filePtr = fopen (dbuf_c_str (&dumpFileName), "w")))
130 werror (E_OUTPUT_FILE_OPEN_ERR, dbuf_c_str (&dumpFileName), strerror (errno));
131 dbuf_destroy (&dumpFileName);
132 exit (1);
134 dbuf_destroy (&dumpFileName);
137 #if 0
138 fprintf (dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex);
139 #endif
141 return dumpFilesPtr->filePtr;
144 /*-----------------------------------------------------------------*/
145 /* closeDumpFiles - close possible opened dumpfiles */
146 /*-----------------------------------------------------------------*/
147 void
148 closeDumpFiles ()
150 struct _dumpFiles *dumpFilesPtr;
152 for (dumpFilesPtr = dumpFiles; dumpFilesPtr->id; dumpFilesPtr++)
154 if (dumpFilesPtr->filePtr)
156 fclose (dumpFilesPtr->filePtr);
161 /*-----------------------------------------------------------------*/
162 /* dumpLiveRanges - dump liverange information into a file */
163 /*-----------------------------------------------------------------*/
164 void
165 dumpLiveRanges (int id, hTab * liveRanges)
167 FILE *file;
168 symbol *sym;
169 int k;
171 if (id)
173 file = createDumpFile (id);
175 else
177 file = stdout;
180 if (currFunc)
181 fprintf (file, "------------- Func %s -------------\n", currFunc->name);
182 for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k))
185 fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
186 (sym->rname[0] ? sym->rname : sym->name),
187 sym->key, sym->liveFrom, sym->liveTo, sym->stack, sym->isreqv, sym->remat);
189 fprintf (file, "{");
190 printTypeChain (sym->type, file);
191 if (sym->usl.spillLoc)
193 fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
195 fprintf (file, "} clashes with ");
196 bitVectDebugOn (sym->clashes, file);
197 fprintf (file, "\n");
200 fflush (file);
204 /*-----------------------------------------------------------------*/
205 /* dumpEbbsToFileExt - write all the basic blocks to a file */
206 /*-----------------------------------------------------------------*/
207 void
208 dumpEbbsToFileExt (int id, ebbIndex * ebbi)
210 FILE *of;
211 int i, d;
212 eBBlock *bb;
213 set *cseSet;
214 eBBlock **ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
215 int count = ebbi->count;
217 if (id)
219 of = createDumpFile (id);
221 else
223 of = stdout;
226 for (i = 0; i < count; i++)
228 fprintf (of, "\n----------------------------------------------------------------\n");
229 fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%ld:%ld): loopDepth=%d%s%s%s\n",
230 ebbs[i]->entryLabel->name,
231 ebbs[i]->dfnum, ebbs[i]->bbnum,
232 ebbs[i]->entryLabel->level / LEVEL_UNIT, ebbs[i]->entryLabel->level % LEVEL_UNIT,
233 ebbs[i]->depth,
234 ebbs[i]->noPath ? " noPath" : "",
235 ebbs[i]->partOfLoop ? " partOfLoop" : "", ebbs[i]->isLastInLoop ? " isLastInLoop" : "");
237 // a --nolabelopt makes this more readable
238 fprintf (of, "\nsuccessors: ");
239 for (bb = setFirstItem (ebbs[i]->succList); bb; bb = setNextItem (ebbs[i]->succList))
241 fprintf (of, "%s ", bb->entryLabel->name);
243 fprintf (of, "\npredecessors: ");
244 for (bb = setFirstItem (ebbs[i]->predList); bb; bb = setNextItem (ebbs[i]->predList))
246 fprintf (of, "%s ", bb->entryLabel->name);
248 fprintf (of, "\ndominators: ");
249 for (d = 0; d < ebbs[i]->domVect->size; d++)
251 if (bitVectBitValue (ebbs[i]->domVect, d))
253 fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
256 fprintf (of, "\n");
258 fprintf (of, "\ndefines bitVector :");
259 bitVectDebugOn (ebbs[i]->defSet, of);
260 fprintf (of, "\nlocal defines bitVector :");
261 bitVectDebugOn (ebbs[i]->ldefs, of);
262 fprintf (of, "\npointers Set bitvector :");
263 bitVectDebugOn (ebbs[i]->ptrsSet, of);
264 #if 0
265 fprintf (of, "\nin coming definitions :");
266 bitVectDebugOn (ebbs[i]->inDefs, of);
267 fprintf (of, "\nout going definitions :");
268 bitVectDebugOn (ebbs[i]->outDefs, of);
269 fprintf (of, "\ndefines used :");
270 bitVectDebugOn (ebbs[i]->usesDefs, of);
271 #endif
273 if (ebbs[i]->isLastInLoop)
275 fprintf (of, "\nInductions Set bitvector :");
276 bitVectDebugOn (ebbs[i]->linds, of);
279 fprintf (of, "\ninExprs:");
280 for (cseSet = ebbs[i]->inExprs; cseSet; cseSet = cseSet->next)
282 cseDef *item = cseSet->item;
283 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
284 if (item->fromGlobal)
285 fprintf (of, "g");
287 fprintf (of, "\noutExprs:");
288 for (cseSet = ebbs[i]->outExprs; cseSet; cseSet = cseSet->next)
290 cseDef *item = cseSet->item;
291 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
292 if (item->fromGlobal)
293 fprintf (of, "g");
295 fprintf (of, "\nkilledExprs:");
296 for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet = cseSet->next)
298 cseDef *item = cseSet->item;
299 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
300 if (item->fromGlobal)
301 fprintf (of, "g");
304 fprintf (of, "\n----------------------------------------------------------------\n");
305 printiCChain (ebbs[i]->sch, of);
307 fflush (of);
310 /*-----------------------------------------------------------------*/
311 /* iCode2eBBlock - converts a sequnce till label to a ebb */
312 /*-----------------------------------------------------------------*/
313 eBBlock *
314 iCode2eBBlock (iCode * ic)
316 iCode *loop;
317 eBBlock *ebb = neweBBlock (); /* allocate an entry */
319 /* put the first one unconditionally */
320 ebb->sch = ic;
321 ic->seq = 0;
323 /* if this is a label then */
324 if (ic->op == LABEL)
325 ebb->entryLabel = ic->label;
326 else
328 struct dbuf_s dbuf;
330 dbuf_init (&dbuf, 128);
331 dbuf_printf (&dbuf, "_eBBlock%d", eBBNum++);
332 ebb->entryLabel = newSymbol (dbuf_c_str (&dbuf), 1);
333 dbuf_destroy (&dbuf);
334 ebb->entryLabel->key = labelKey++;
337 if (ic && (ic->op == GOTO || ic->op == JUMPTABLE || ic->op == IFX))
339 ebb->ech = ebb->sch;
340 return ebb;
343 /* if this is a function call */
344 if (ic->op == CALL || ic->op == PCALL)
346 sym_link *type = operandType (IC_LEFT (ic));
347 ebb->hasFcall = 1;
348 if (currFunc)
349 FUNC_HASFCALL (currFunc->type) = 1;
350 if (IS_FUNCPTR (type))
351 type = type->next;
352 if (type && FUNC_ISNORETURN (type))
354 ebb->ech = ebb->sch;
355 return ebb;
359 if ((ic->next && ic->next->op == LABEL) || !ic->next)
361 ebb->ech = ebb->sch;
362 return ebb;
365 /* loop thru till we find one with a label */
366 for (loop = ic->next; loop; loop = loop->next)
368 loop->seq = 0;
370 /* if this is the last one */
371 if (!loop->next)
372 break;
373 /* if this is a function call */
374 if (loop->op == CALL || loop->op == PCALL)
376 sym_link *type = operandType (IC_LEFT (loop));
377 ebb->hasFcall = 1;
378 if (currFunc)
379 FUNC_HASFCALL (currFunc->type) = 1;
380 if (IS_FUNCPTR (type))
381 type = type->next;
382 if (type && FUNC_ISNORETURN (type))
383 break;
386 /* if the next one is a label */
387 /* if this is a goto or ifx */
388 if (loop->next->op == LABEL || loop->op == GOTO || loop->op == JUMPTABLE || loop->op == IFX)
389 break;
392 /* mark the end of the chain */
393 ebb->ech = loop;
395 return ebb;
398 /*-----------------------------------------------------------------*/
399 /* eBBWithEntryLabel - finds the basic block with the entry label */
400 /*-----------------------------------------------------------------*/
401 eBBlock *
402 eBBWithEntryLabel (ebbIndex* ebbi, const symbol *eLabel)
404 eBBlock **ebbs = ebbi->bbOrder;
405 int count = ebbi->count;
406 int i;
408 for (i = 0; i < count; i++)
410 if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
411 return ebbs[i];
414 return NULL;
418 /*-----------------------------------------------------------------*/
419 /* ifFromIs - will return 1 if the from block matches this */
420 /*-----------------------------------------------------------------*/
421 DEFSETFUNC (ifFromIs)
423 edge *ep = item;
424 V_ARG (eBBlock *, this);
426 if (ep->from == this)
427 return 1;
429 return 0;
433 /*-----------------------------------------------------------------*/
434 /* edgesTo - returns a set of edges with to == supplied value */
435 /*-----------------------------------------------------------------*/
436 set *
437 edgesTo (eBBlock * to)
439 set *result = NULL;
440 edge *loop;
442 for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
443 if (loop->to == to && !loop->from->noPath)
444 addSet (&result, loop->from);
446 return result;
450 /*-----------------------------------------------------------------*/
451 /* addiCodeToeBBlock - will add an iCode to the end of a block */
452 /*-----------------------------------------------------------------*/
453 void
454 addiCodeToeBBlock (eBBlock *ebp, iCode *ic, iCode *ip)
456 ic->prev = ic->next = NULL;
457 /* if the insert point is given */
458 if (ip)
460 ic->filename = ip->filename;
461 ic->lineno = ip->lineno;
462 ic->eBBlockNum = ip->eBBlockNum;
463 ic->prev = ip->prev;
464 ip->prev = ic;
465 ic->next = ip;
466 if (!ic->prev)
468 wassert (ebp);
469 ebp->sch = ic;
471 else
472 ic->prev->next = ic;
473 return;
476 wassert (ebp);
478 /* if the block has no instructions */
479 if (ebp->ech == NULL)
481 ebp->sch = ebp->ech = ic;
482 ic->next = NULL;
483 return;
486 /* if the last instruction is a goto */
487 /* we add it just before the goto */
488 if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE || ebp->ech->op == RETURN)
490 ic->filename = ebp->ech->filename;
491 ic->lineno = ebp->ech->lineno;
492 ic->prev = ebp->ech->prev;
493 ebp->ech->prev = ic;
494 ic->next = ebp->ech;
495 if (!ic->prev) /* was the last only on in the block */
496 ebp->sch = ic;
497 else
498 ic->prev->next = ic;
499 return;
502 /* if the last one was a ifx statement we check to see */
503 /* if the condition was defined in the previous instruction */
504 /* if this is true then we put it before the condition else */
505 /* we put it before if, this is to reduce register pressure, */
506 /* we don't have to hold condition too long in a register */
508 /* loop induction sometimes appends a GOTO instruction, */
509 /* it must be at the very end */
510 if (ebp->ech->op == IFX && ic->op != GOTO)
512 iCode *ipoint;
514 /* if ( !ebp->ech->prev ) */
515 /* ipoint = ebp->ech ; */
516 /* else */
517 /* if (!IC_RESULT(ebp->ech->prev)) */
518 /* ipoint = ebp->ech ; */
519 /* else */
520 /* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
521 /* ipoint = ebp->ech->prev; */
522 /* else */
523 /* ipoint = ebp->ech ; */
524 ipoint = ebp->ech;
525 ic->filename = ipoint->filename;
526 ic->lineno = ipoint->lineno;
527 ic->prev = ipoint->prev;
528 ipoint->prev = ic;
529 ic->next = ipoint;
530 if (!ic->prev)
531 ebp->sch = ic;
532 else
533 ic->prev->next = ic;
534 return;
537 /* will add it to the very end */
538 ip = ebp->ech;
539 ip->next = ic;
540 ic->prev = ip;
541 ic->next = NULL;
542 ebp->ech = ic;
544 return;
547 /*-----------------------------------------------------------------*/
548 /* remiCodeFromeBBlock - remove an iCode from BBlock */
549 /*-----------------------------------------------------------------*/
550 void
551 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
553 wassert (ic->seq >= ebb->fSeq && ic->seq <= ebb->lSeq);
554 if (ic->prev)
555 ic->prev->next = ic->next;
556 else
557 ebb->sch = ic->next;
559 if (ic->next)
560 ic->next->prev = ic->prev;
561 else
562 ebb->ech = ic->prev;
565 /*-----------------------------------------------------------------*/
566 /* iCodeBreakDown : breakDown iCode chain to blocks */
567 /*-----------------------------------------------------------------*/
568 ebbIndex *
569 iCodeBreakDown (iCode * ic)
571 eBBlock **ebbs = NULL;
572 iCode *loop = ic;
573 ebbIndex *ebbi;
575 ebbi = Safe_alloc (sizeof (ebbIndex));
576 ebbi->count = 0;
577 ebbi->dfOrder = NULL; /* no depth first order information yet */
579 /* allocate for the first entry */
581 ebbs = Safe_alloc (sizeof (eBBlock *));
582 ebbi->bbOrder = ebbs;
584 while (loop)
587 /* convert 2 block */
588 eBBlock *ebb = iCode2eBBlock (loop);
589 loop = ebb->ech->next;
591 ebb->ech->next = NULL; /* mark the end of this chain */
592 if (loop)
593 loop->prev = NULL;
594 ebb->bbnum = ebbi->count; /* save this block number */
595 /* put it in the array */
596 ebbs[(ebbi->count)++] = ebb;
598 /* allocate for the next one. Remember to clear the new */
599 /* pointer at the end, that was created by realloc. */
601 ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
602 ebbi->bbOrder = ebbs;
604 ebbs[ebbi->count] = 0;
606 /* if this one ends in a goto or a conditional */
607 /* branch then check if the block it is going */
608 /* to already exists, if yes then this could */
609 /* be a loop, add a preheader to the block it */
610 /* goes to if it does not already have one */
611 if (ebbs[(ebbi->count) - 1]->ech && (ebbs[(ebbi->count) - 1]->ech->op == GOTO || ebbs[(ebbi->count) - 1]->ech->op == IFX))
614 symbol *label;
615 eBBlock *destBlock;
617 if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
618 label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
619 else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
620 label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);
622 if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
623 destBlock->preHeader == NULL && otherPathsPresent (ebbs, destBlock))
626 symbol *preHeaderLabel = newiTempLoopHeaderLabel (1);
627 int i, j;
628 eBBlock *pBlock;
630 /* go thru all block replacing the entryLabel with new label */
631 /* till we reach the block , then we insert a new ebblock */
632 for (i = 0; i < (ebbi->count); i++)
634 if (ebbs[i] == destBlock)
635 break;
636 replaceLabel (ebbs[i], label, preHeaderLabel);
639 (ebbi->count)++;
641 /* if we have stopped at the block , allocate for an extra one */
643 ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
644 ebbi->bbOrder = ebbs;
646 ebbs[ebbi->count] = 0;
648 /* then move the block down one count */
649 pBlock = ebbs[j = i];
650 for (i += 1; i < (ebbi->count); i++)
652 eBBlock *xBlock;
654 xBlock = ebbs[i];
655 ebbs[i] = pBlock;
656 ebbs[i]->bbnum = i;
657 pBlock = xBlock;
660 destBlock->preHeader = ebbs[j] = neweBBlock ();
661 ebbs[j]->bbnum = j;
662 ebbs[j]->entryLabel = preHeaderLabel;
663 ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
664 ebbs[j]->sch->filename = destBlock->sch->filename;
665 ebbs[j]->sch->lineno = destBlock->sch->lineno;
670 /* mark the end */
671 ebbs[ebbi->count] = NULL;
673 return ebbi;
676 /*-----------------------------------------------------------------*/
677 /* replaceSymBySym : - replace operand by operand in blocks */
678 /* replaces only left & right in blocks */
679 /*-----------------------------------------------------------------*/
680 void
681 replaceSymBySym (set * sset, operand * src, operand * dest)
683 set *loop;
684 eBBlock *rBlock;
686 /* for all blocks in the set do */
687 for (loop = sset; loop; loop = loop->next)
689 iCode *ic;
691 rBlock = loop->item;
692 /* for all instructions in this block do */
693 for (ic = rBlock->sch; ic; ic = ic->next)
695 if (isOperandEqual (IC_RIGHT (ic), src))
697 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
698 IC_RIGHT (ic) = operandFromOperand (dest);
699 IC_RIGHT (ic)->isaddr = 0;
700 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
703 if (isOperandEqual (IC_LEFT (ic), src))
705 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
706 if (POINTER_GET (ic) && IS_ITEMP (dest))
708 IC_LEFT (ic) = operandFromOperand (dest);
709 IC_LEFT (ic)->isaddr = 1;
711 else
713 IC_LEFT (ic) = operandFromOperand (dest);
714 IC_LEFT (ic)->isaddr = 0;
716 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
719 /* special case for pointer sets */
720 if (POINTER_SET (ic) && isOperandEqual (IC_RESULT (ic), src))
722 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
723 IC_RESULT (ic) = operandFromOperand (dest);
724 IC_RESULT (ic)->isaddr = 1;
725 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
731 /*-----------------------------------------------------------------*/
732 /* replaceLabel - replace reference to one label by another */
733 /*-----------------------------------------------------------------*/
734 void
735 replaceLabel (eBBlock *ebp, symbol *fromLbl, symbol *toLbl)
737 iCode *ic;
739 if (!ebp)
740 return;
742 for (ic = ebp->sch; ic; ic = ic->next)
744 switch (ic->op)
747 case GOTO:
748 if (isSymbolEqual (IC_LABEL (ic), fromLbl))
749 IC_LABEL (ic) = toLbl;
750 break;
752 case IFX:
753 if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
754 IC_TRUE (ic) = toLbl;
755 else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
756 IC_FALSE (ic) = toLbl;
757 break;
759 case JUMPTABLE:
760 replaceSetItem (IC_JTLABELS (ic), fromLbl, toLbl);
764 return;
769 /*-----------------------------------------------------------------*/
770 /* iCodeFromeBBlock - convert basic block to iCode chain */
771 /*-----------------------------------------------------------------*/
772 iCode *
773 iCodeFromeBBlock (eBBlock ** ebbs, int count)
775 int i = 1;
776 iCode *ric = ebbs[0]->sch;
777 iCode *lic = ebbs[0]->ech;
779 for (; i < count; i++)
781 if (ebbs[i]->sch == NULL)
782 continue;
784 if (ebbs[i]->noPath && optimize.label4 && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel))
786 iCode *ic = NULL;
787 bool foundNonlabel = 0;
788 ic = ebbs[i]->sch;
791 if (ic->op != LABEL)
793 foundNonlabel = 1;
794 break;
796 if (ic == ebbs[i]->ech)
797 break;
798 ic = ic->next;
800 while (ic);
801 if (foundNonlabel && ic)
803 if (!ic->mergedElsewhere)
804 werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH);
805 continue;
809 lic->next = ebbs[i]->sch;
810 lic->next->prev = lic;
811 lic = ebbs[i]->ech;
815 return ric;
818 /*-----------------------------------------------------------------*/
819 /* otherPathsPresent - determines if there is a path from _entry */
820 /* to this block in a half constructed set of blocks */
821 /*-----------------------------------------------------------------*/
823 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
825 int i;
827 /* for all blocks preceding this block */
828 for (i = 0; i < this->bbnum; i++)
830 iCode *ic;
832 /* if there is a reference to the entry label of this block */
833 for (ic = ebbs[i]->sch; ic; ic = ic->next)
835 switch (ic->op)
837 case GOTO:
838 if (IC_LABEL (ic)->key == this->entryLabel->key)
839 return 1;
840 break;
842 case IFX:
843 if (IC_TRUE (ic))
845 if (IC_TRUE (ic)->key == this->entryLabel->key)
846 return 1;
848 else if (IC_FALSE (ic)->key == this->entryLabel->key)
849 return 1;
850 break;
855 /* comes here means we have not found it yet */
856 /* in this case check if the previous block */
857 /* ends in a goto if it does then we have no */
858 /* path else we have a path */
859 if (this->bbnum && ebbs[this->bbnum - 1]->ech && ebbs[this->bbnum - 1]->ech->op == GOTO)
860 return 0;
861 else
862 return 1;
866 /*-----------------------------------------------------------------*/
867 /* freeBBlockData - Deallocate data structures associated with */
868 /* the current blocks. They will all be recomputed if the */
869 /* iCode chain is divided into blocks again later. */
870 /*-----------------------------------------------------------------*/
871 void
872 freeeBBlockData(ebbIndex * ebbi)
874 int i;
875 eBBlock ** ebbs = ebbi->bbOrder;
877 for (i=0; i < ebbi->count; i++)
879 deleteSet (&ebbs[i]->succList);
880 deleteSet (&ebbs[i]->predList);
881 freeBitVect (ebbs[i]->succVect);
882 freeBitVect (ebbs[i]->domVect);
884 freeCSEdata(ebbs[i]);