* src/SDCCBlock.c (addiCodeToeBBlock): fixed bug 1652207: GOTO icodes appended by...
[fw/sdcc] / src / SDCCBBlock.c
1 /*-------------------------------------------------------------------------
2
3   SDCCBBlock.c - routines to manipulate basic Blocks
4
5              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
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.
11
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.
16
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.
20
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 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27
28 int eBBNum = 0;
29 set *graphEdges = NULL;         /* list of edges in this flow graph */
30
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},
45   {0, NULL, NULL}
46 };
47
48 /*-----------------------------------------------------------------*/
49 /* printEntryLabel - prints entry label of a ebblock               */
50 /*-----------------------------------------------------------------*/
51 DEFSETFUNC (printEntryLabel)
52 {
53   eBBlock *bp = item;
54
55   fprintf (stdout, " %-20s ", bp->entryLabel->name);
56   return 0;
57 }
58
59 /*-----------------------------------------------------------------*/
60 /* neweBBlock - allocate & return a new extended basic block       */
61 /*-----------------------------------------------------------------*/
62 eBBlock *
63 neweBBlock ()
64 {
65   eBBlock *ebb;
66
67   ebb = Safe_alloc (sizeof (eBBlock));
68   return ebb;
69 }
70
71 /*-----------------------------------------------------------------*/
72 /* newEdge - allocates & initialises an edge to given values       */
73 /*-----------------------------------------------------------------*/
74 edge *
75 newEdge (eBBlock * from, eBBlock * to)
76 {
77   edge *ep;
78
79   ep = Safe_alloc (sizeof (edge));
80
81   ep->from = from;
82   ep->to = to;
83   return ep;
84 }
85
86 /*-----------------------------------------------------------------*/
87 /* createDumpFile - create the dump file                           */
88 /*-----------------------------------------------------------------*/
89 FILE *createDumpFile (int id) {
90   struct _dumpFiles *dumpFilesPtr=dumpFiles;
91   static int dumpIndex=0;
92   static char dumpIndexStr[32];
93   
94   while (dumpFilesPtr->id) {
95     if (dumpFilesPtr->id==id)
96       break;
97     dumpFilesPtr++;
98   }
99
100   if (!dumpFilesPtr->id) {
101     fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
102     exit (1);
103   }
104
105   sprintf(dumpIndexStr, ".%d", dumpIndex);
106   dumpIndex++;
107
108   if (!dumpFilesPtr->filePtr) {
109     // not used before, create it
110     strncpyz (scratchFileName, dstFileName, PATH_MAX);
111 #if 0
112     strncatz (scratchFileName, dumpIndexStr, PATH_MAX);
113 #endif
114     strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX);
115     if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) {
116       werror (E_FILE_OPEN_ERR, scratchFileName);
117       exit (1);
118     }
119   } 
120
121 #if 0
122   fprintf(dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex);
123 #endif
124
125   return dumpFilesPtr->filePtr;
126 }
127
128 /*-----------------------------------------------------------------*/
129 /* closeDumpFiles - close possible opened dumpfiles                */
130 /*-----------------------------------------------------------------*/
131 void closeDumpFiles() {
132   struct _dumpFiles *dumpFilesPtr;
133
134   for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
135     if (dumpFilesPtr->filePtr) {
136       fclose (dumpFilesPtr->filePtr);
137     }
138   }
139 }
140
141 /*-----------------------------------------------------------------*/
142 /* dumpLiveRanges - dump liverange information into a file         */
143 /*-----------------------------------------------------------------*/
144 void 
145 dumpLiveRanges (int id, hTab * liveRanges)
146 {
147   FILE *file;
148   symbol *sym;
149   int k;
150
151   if (id) {
152     file=createDumpFile(id);
153   } else {
154     file = stdout;
155   }
156   
157   if (currFunc) 
158       fprintf(file,"------------- Func %s -------------\n",currFunc->name);
159   for (sym = hTabFirstItem (liveRanges, &k); sym;
160        sym = hTabNextItem (liveRanges, &k))
161     {
162
163       fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
164                (sym->rname[0] ? sym->rname : sym->name),
165                sym->key,
166                sym->liveFrom, sym->liveTo,
167                sym->stack,
168                sym->isreqv, sym->remat
169         );
170
171       fprintf (file, "{");
172       printTypeChain (sym->type, file);
173       if (sym->usl.spillLoc)
174         {
175           fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
176         }
177       fprintf (file, "} clashes with ");
178       bitVectDebugOn(sym->clashes,file);
179       fprintf (file, "\n");
180     }
181
182   fflush(file);
183 }
184
185
186 /*-----------------------------------------------------------------*/
187 /* dumpEbbsToFileExt - writeall the basic blocks to a file         */
188 /*-----------------------------------------------------------------*/
189 void 
190 dumpEbbsToFileExt (int id, ebbIndex * ebbi)
191 {
192   FILE *of;
193   int i;
194   eBBlock *bb;
195   set *cseSet;
196   eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
197   int count = ebbi->count;
198
199   if (id) {
200     of=createDumpFile(id);
201   } else {
202     of = stdout;
203   }
204
205   for (i = 0; i < count; i++)
206     {
207       fprintf (of, "\n----------------------------------------------------------------\n");
208       fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%d): loopDepth=%d%s%s%s\n",
209                ebbs[i]->entryLabel->name,
210                ebbs[i]->dfnum, ebbs[i]->bbnum, ebbs[i]->entryLabel->level,
211                ebbs[i]->depth,
212                ebbs[i]->noPath ? " noPath" : "",
213                ebbs[i]->partOfLoop ? " partOfLoop" : "",
214                ebbs[i]->isLastInLoop ? " isLastInLoop" : "");
215
216       // a --nolabelopt makes this more readable
217       fprintf (of, "\nsuccessors: ");
218       for (bb=setFirstItem(ebbs[i]->succList); 
219            bb; 
220            bb=setNextItem(ebbs[i]->succList)) {
221         fprintf (of, "%s ", bb->entryLabel->name);
222       }
223       fprintf (of, "\npredecessors: ");
224       for (bb=setFirstItem(ebbs[i]->predList); 
225            bb; 
226            bb=setNextItem(ebbs[i]->predList)) {
227         fprintf (of, "%s ", bb->entryLabel->name);
228       }
229       {
230         int d;
231         fprintf (of, "\ndominators: ");
232         for (d=0; d<ebbs[i]->domVect->size; d++) {
233           if (bitVectBitValue(ebbs[i]->domVect, d)) {
234             fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
235           }
236         }
237       }
238       fprintf (of, "\n");
239   
240       fprintf (of, "\ndefines bitVector :");
241       bitVectDebugOn (ebbs[i]->defSet, of);
242       fprintf (of, "\nlocal defines bitVector :");
243       bitVectDebugOn (ebbs[i]->ldefs, of);
244       fprintf (of, "\npointers Set bitvector :");
245       bitVectDebugOn (ebbs[i]->ptrsSet, of);
246 #if 0
247       fprintf (of, "\nin coming definitions :");
248       bitVectDebugOn (ebbs[i]->inDefs, of);
249       fprintf (of, "\nout going definitions :");
250       bitVectDebugOn (ebbs[i]->outDefs, of);
251       fprintf (of, "\ndefines used :");
252       bitVectDebugOn (ebbs[i]->usesDefs, of);
253 #endif
254
255       if (ebbs[i]->isLastInLoop) {
256               fprintf (of, "\nInductions Set bitvector :");
257               bitVectDebugOn (ebbs[i]->linds, of);
258       }
259       
260       fprintf (of, "\ninExprs:");
261       for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) {
262         cseDef *item=cseSet->item;
263         fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
264         if (item->fromGlobal)
265           fprintf (of, "g");
266       }
267       fprintf (of, "\noutExprs:");
268       for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) {
269         cseDef *item=cseSet->item;
270         fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
271         if (item->fromGlobal)
272           fprintf (of, "g");
273       }
274       fprintf (of, "\nkilledExprs:");
275       for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) {
276         cseDef *item=cseSet->item;
277         fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
278         if (item->fromGlobal)
279           fprintf (of, "g");
280       }
281       
282       fprintf (of, "\n----------------------------------------------------------------\n");
283       printiCChain (ebbs[i]->sch, of);
284     }
285   fflush(of);
286 }
287
288 /*-----------------------------------------------------------------*/
289 /* iCode2eBBlock - converts a sequnce till label to a ebb          */
290 /*-----------------------------------------------------------------*/
291 eBBlock *
292 iCode2eBBlock (iCode * ic)
293 {
294   iCode *loop;
295   eBBlock *ebb = neweBBlock (); /* allocate an entry */
296
297   /* put the first one unconditionally */
298   ebb->sch = ic;
299
300   /* if this is a label then */
301   if (ic->op == LABEL)
302     ebb->entryLabel = ic->label;
303   else
304     {
305       SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++);
306       ebb->entryLabel = newSymbol (buffer, 1);
307       ebb->entryLabel->key = labelKey++;
308     }
309
310   if (ic &&
311       (ic->op == GOTO ||
312        ic->op == JUMPTABLE ||
313        ic->op == IFX))
314     {
315       ebb->ech = ebb->sch;
316       return ebb;
317     }
318   
319   /* if this is a function call */
320   if (ic->op == CALL || ic->op == PCALL)
321     {
322       ebb->hasFcall = 1;
323       if (currFunc)
324         FUNC_HASFCALL(currFunc->type) = 1;
325     }
326
327   if ((ic->next && ic->next->op == LABEL) ||
328       !ic->next)
329     {
330       ebb->ech = ebb->sch;
331       return ebb;
332     }
333
334   /* loop thru till we find one with a label */
335   for (loop = ic->next; loop; loop = loop->next)
336     {
337
338       /* if this is the last one */
339       if (!loop->next)
340         break;
341       /* if this is a function call */
342       if (loop->op == CALL || loop->op == PCALL)
343         {
344           ebb->hasFcall = 1;
345           if (currFunc)
346             FUNC_HASFCALL(currFunc->type) = 1;
347         }
348
349       /* if the next one is a label */
350       /* if this is a goto or ifx */
351       if (loop->next->op == LABEL ||
352           loop->op == GOTO ||
353           loop->op == JUMPTABLE ||
354           loop->op == IFX)
355         break;
356     }
357
358   /* mark the end of the chain */
359   ebb->ech = loop;
360
361   return ebb;
362 }
363
364 /*-----------------------------------------------------------------*/
365 /* eBBWithEntryLabel - finds the basic block with the entry label  */
366 /*-----------------------------------------------------------------*/
367 eBBlock *
368 eBBWithEntryLabel (ebbIndex * ebbi, symbol * eLabel)
369 {
370   eBBlock ** ebbs = ebbi->bbOrder;
371   int count = ebbi->count;
372   int i;
373
374   for (i = 0; i < count; i++)
375     {
376       if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
377         return ebbs[i];
378     }
379
380   return NULL;
381 }
382
383
384 /*-----------------------------------------------------------------*/
385 /* ifFromIs - will return 1 if the from block matches this         */
386 /*-----------------------------------------------------------------*/
387 DEFSETFUNC (ifFromIs)
388 {
389   edge *ep = item;
390   V_ARG (eBBlock *, this);
391
392   if (ep->from == this)
393     return 1;
394
395   return 0;
396 }
397
398
399 /*-----------------------------------------------------------------*/
400 /* edgesTo  - returns a set of edges with to == supplied value     */
401 /*-----------------------------------------------------------------*/
402 set *
403 edgesTo (eBBlock * to)
404 {
405   set *result = NULL;
406   edge *loop;
407
408   for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
409     if (loop->to == to && !loop->from->noPath)
410       addSet (&result, loop->from);
411
412   return result;
413 }
414
415
416 /*-----------------------------------------------------------------*/
417 /* addiCodeToeBBlock - will add an iCode to the end of a block     */
418 /*-----------------------------------------------------------------*/
419 void 
420 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
421 {
422   ic->prev = ic->next = NULL;
423   /* if the insert point is given */
424   if (ip)
425     {
426       ic->lineno = ip->lineno;
427       ic->prev = ip->prev;
428       ip->prev = ic;
429       ic->next = ip;
430       if (!ic->prev)
431         ebp->sch = ic;
432       else
433         ic->prev->next = ic;
434       return;
435     }
436
437   /* if the block has no  instructions */
438   if (ebp->ech == NULL)
439     {
440       ebp->sch = ebp->ech = ic;
441       ic->next = NULL;
442       return;
443     }
444
445   /* if the last instruction is a goto */
446   /* we add it just before the goto    */
447   if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE
448       || ebp->ech->op == RETURN)
449     {
450       ic->lineno = ebp->ech->lineno;
451       ic->prev = ebp->ech->prev;
452       ebp->ech->prev = ic;
453       ic->next = ebp->ech;
454       if (!ic->prev)            /* was the last only on in the block */
455         ebp->sch = ic;
456       else
457         ic->prev->next = ic;
458       return;
459     }
460
461   /* if the last one was a ifx statement we check to see */
462   /* if the condition was defined in the previous instruction */
463   /* if this is true then we put it before the condition else */
464   /* we put it before if, this is to reduce register pressure, */
465   /* we don't have to hold  condition too long in a register  */
466
467   /* loop induction sometimes appends a GOTO instruction, */
468   /* it must be at the very end */
469   if (ebp->ech->op == IFX && ic->op != GOTO)
470     {
471       iCode *ipoint;
472
473 /*  if ( !ebp->ech->prev )  */
474 /*      ipoint = ebp->ech ; */
475 /*  else  */
476 /*      if (!IC_RESULT(ebp->ech->prev)) */
477 /*    ipoint = ebp->ech ; */
478 /*      else */
479 /*    if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
480 /*        ipoint = ebp->ech->prev; */
481 /*    else */
482 /*        ipoint = ebp->ech ; */
483       ipoint = ebp->ech;
484       ic->lineno = ipoint->lineno;
485       ic->prev = ipoint->prev;
486       ipoint->prev = ic;
487       ic->next = ipoint;
488       if (!ic->prev)
489         ebp->sch = ic;
490       else
491         ic->prev->next = ic;
492       return;
493     }
494
495   /* will add it to the very end */
496   ip = ebp->ech;
497   ip->next = ic;
498   ic->prev = ip;
499   ic->next = NULL;
500   ebp->ech = ic;
501
502   return;
503 }
504
505 /*-----------------------------------------------------------------*/
506 /* remiCodeFromeBBlock - remove an iCode from BBlock               */
507 /*-----------------------------------------------------------------*/
508 void 
509 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
510 {
511   wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq);
512   if (ic->prev)
513     ic->prev->next = ic->next;
514   else
515     ebb->sch = ic->next;
516
517   if (ic->next)
518     ic->next->prev = ic->prev;
519   else
520     ebb->ech = ic->prev;
521 }
522
523 /*-----------------------------------------------------------------*/
524 /* iCodeBreakDown : breakDown iCode chain to blocks                */
525 /*-----------------------------------------------------------------*/
526 ebbIndex *
527 iCodeBreakDown (iCode * ic)
528 {
529   eBBlock **ebbs = NULL;
530   iCode *loop = ic;
531   ebbIndex *ebbi;
532   
533   ebbi = Safe_alloc (sizeof (ebbIndex));
534   ebbi->count = 0;
535   ebbi->dfOrder = NULL; /* no depth first order information yet */
536
537   /* allocate for the first entry */
538
539   ebbs = Safe_alloc (sizeof (eBBlock *));
540   ebbi->bbOrder = ebbs;
541
542   while (loop)
543     {
544
545       /* convert 2 block */
546       eBBlock *ebb = iCode2eBBlock (loop);
547       loop = ebb->ech->next;
548
549       ebb->ech->next = NULL;    /* mark the end of this chain */
550       if (loop)
551         loop->prev = NULL;
552       ebb->bbnum = ebbi->count; /* save this block number     */
553       /* put it in the array */
554       ebbs[(ebbi->count)++] = ebb;
555
556       /* allocate for the next one. Remember to clear the new */
557       /*  pointer at the end, that was created by realloc. */
558
559       ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
560       ebbi->bbOrder = ebbs;
561
562       ebbs[ebbi->count] = 0;
563
564       /* if this one ends in a goto or a conditional */
565       /* branch then check if the block it is going  */
566       /* to already exists, if yes then this could   */
567       /* be a loop, add a preheader to the block it  */
568       /* goes to  if it does not already have one    */
569       if (ebbs[(ebbi->count) - 1]->ech &&
570           (ebbs[(ebbi->count) - 1]->ech->op == GOTO ||
571            ebbs[(ebbi->count) - 1]->ech->op == IFX))
572         {
573
574           symbol *label;
575           eBBlock *destBlock;
576
577           if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
578             label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
579           else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
580             label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);
581
582           if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
583               destBlock->preHeader == NULL &&
584               otherPathsPresent (ebbs, destBlock))
585             {
586
587               symbol *preHeaderLabel  = newiTempLoopHeaderLabel (1);
588               int i, j;
589               eBBlock *pBlock;
590
591               /* go thru all block replacing the entryLabel with new label */
592               /* till we reach the block , then we insert a new ebblock    */
593               for (i = 0; i < (ebbi->count); i++)
594                 {
595                   if (ebbs[i] == destBlock)
596                     break;
597                   replaceLabel (ebbs[i], label, preHeaderLabel);
598                 }
599
600               (ebbi->count)++;
601
602               /* if we have stopped at the block , allocate for an extra one */
603
604               ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
605               ebbi->bbOrder = ebbs;
606
607               ebbs[ebbi->count] = 0;
608
609               /* then move the block down one count */
610               pBlock = ebbs[j = i];
611               for (i += 1; i < (ebbi->count); i++)
612                 {
613                   eBBlock *xBlock;
614
615                   xBlock = ebbs[i];
616                   ebbs[i] = pBlock;
617                   ebbs[i]->bbnum = i;
618                   pBlock = xBlock;
619                 }
620
621               destBlock->preHeader = ebbs[j] = neweBBlock ();
622               ebbs[j]->bbnum = j;
623               ebbs[j]->entryLabel = preHeaderLabel;
624               ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
625               ebbs[j]->sch->lineno = destBlock->sch->lineno;
626             }
627         }
628     }
629
630   /* mark the end */
631   ebbs[ebbi->count] = NULL;
632
633   return ebbi;
634 }
635
636 /*-----------------------------------------------------------------*/
637 /* replaceSymBySym : - replace operand by operand in blocks        */
638 /*                     replaces only left & right in blocks        */
639 /*-----------------------------------------------------------------*/
640 void 
641 replaceSymBySym (set * sset, operand * src, operand * dest)
642 {
643   set *loop;
644   eBBlock *rBlock;
645
646   /* for all blocks in the set do */
647   for (loop = sset; loop; loop = loop->next)
648     {
649       iCode *ic;
650
651       rBlock = loop->item;
652       /* for all instructions in this block do */
653       for (ic = rBlock->sch; ic; ic = ic->next)
654         {
655
656           /* if we find usage */
657           if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
658             {
659               bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
660               IC_COND (ic) = operandFromOperand (dest);
661               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
662               continue;
663             }
664
665           if (isOperandEqual (IC_RIGHT (ic), src))
666             {
667               bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
668               IC_RIGHT (ic) = operandFromOperand (dest);
669               IC_RIGHT (ic)->isaddr = 0;
670               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
671             }
672
673           if (isOperandEqual (IC_LEFT (ic), src))
674             {
675               bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
676               if (POINTER_GET (ic) && IS_ITEMP (dest))
677                 {
678                   IC_LEFT (ic) = operandFromOperand (dest);
679                   IC_LEFT (ic)->isaddr = 1;
680                 }
681               else
682                 {
683                   IC_LEFT (ic) = operandFromOperand (dest);
684                   IC_LEFT (ic)->isaddr = 0;
685                 }
686               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
687             }
688
689           /* special case for pointer sets */
690           if (POINTER_SET (ic) &&
691               isOperandEqual (IC_RESULT (ic), src))
692             {
693               bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
694               IC_RESULT (ic) = operandFromOperand (dest);
695               IC_RESULT (ic)->isaddr = 1;
696               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
697             }
698         }
699     }
700 }
701
702 /*-----------------------------------------------------------------*/
703 /* replaceLabel - replace reference to one label by another        */
704 /*-----------------------------------------------------------------*/
705 void 
706 replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
707 {
708   iCode *ic;
709
710   if (!ebp)
711     return;
712
713   for (ic = ebp->sch; ic; ic = ic->next)
714     {
715       switch (ic->op)
716         {
717
718         case GOTO:
719           if (isSymbolEqual (IC_LABEL (ic), fromLbl))
720             IC_LABEL (ic) = toLbl;
721           break;
722
723         case IFX:
724           if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
725             IC_TRUE (ic) = toLbl;
726           else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
727             IC_FALSE (ic) = toLbl;
728           break;
729         }
730     }
731
732   return;
733
734 }
735
736
737 /*-----------------------------------------------------------------*/
738 /* iCodeFromeBBlock - convert basic block to iCode chain           */
739 /*-----------------------------------------------------------------*/
740 iCode *
741 iCodeFromeBBlock (eBBlock ** ebbs, int count)
742 {
743   int i = 1;
744   iCode *ric = ebbs[0]->sch;
745   iCode *lic = ebbs[0]->ech;
746
747   for (; i < count; i++)
748     {
749       if (ebbs[i]->sch == NULL)
750         continue;
751
752       if (ebbs[i]->noPath &&
753           (ebbs[i]->entryLabel != entryLabel &&
754            ebbs[i]->entryLabel != returnLabel))
755         {
756           iCode *ic = NULL;
757           bool foundNonlabel = 0;
758           ic=ebbs[i]->sch;
759           do
760             {
761               if (ic->op != LABEL)
762                 {
763                   foundNonlabel = 1;
764                   break;
765                 }
766               if (ic==ebbs[i]->ech)
767                 break;
768               ic = ic->next;
769             }
770           while (ic);
771           if (foundNonlabel && ic)
772             {
773               werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH);
774               continue;
775             }
776         }
777
778       lic->next = ebbs[i]->sch;
779       lic->next->prev = lic;
780       lic = ebbs[i]->ech;
781
782     }
783
784   return ric;
785 }
786
787 /*-----------------------------------------------------------------*/
788 /* otherPathsPresent - determines if there is a path from _entry   */
789 /*      to this block in a half constructed set of blocks          */
790 /*-----------------------------------------------------------------*/
791 int 
792 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
793 {
794   int i;
795
796   /* for all blocks preceding this block */
797   for (i = 0; i < this->bbnum; i++)
798     {
799       iCode *ic;
800
801       /* if there is a reference to the entry label of this block */
802       for (ic = ebbs[i]->sch; ic; ic = ic->next)
803         {
804           switch (ic->op)
805             {
806             case GOTO:
807               if (IC_LABEL (ic)->key == this->entryLabel->key)
808                 return 1;
809               break;
810
811             case IFX:
812               if (IC_TRUE (ic))
813                 {
814                   if (IC_TRUE (ic)->key == this->entryLabel->key)
815                     return 1;
816                 }
817               else if (IC_FALSE (ic)->key == this->entryLabel->key)
818                 return 1;
819               break;
820             }
821         }
822     }
823
824   /* comes here means we have not found it yet */
825   /* in this case check if the previous block  */
826   /* ends in a goto if it does then we have no */
827   /* path else we have a path                  */
828   if (this->bbnum && ebbs[this->bbnum - 1]->ech &&
829       ebbs[this->bbnum - 1]->ech->op == GOTO)
830     return 0;
831   else
832     return 1;
833 }