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