See Changelog 1.204
[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
92   while (dumpFilesPtr->id) {
93     if (dumpFilesPtr->id==id)
94       break;
95     dumpFilesPtr++;
96   }
97
98   if (!dumpFilesPtr->id) {
99     fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
100     exit (1);
101   }
102
103   if (!dumpFilesPtr->filePtr) {
104     // not used before, create it
105     strncpyz (scratchFileName, dstFileName, PATH_MAX);
106     strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX);
107     if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) {
108       werror (E_FILE_OPEN_ERR, scratchFileName);
109       exit (1);
110     }
111   } 
112   return dumpFilesPtr->filePtr;
113 }
114
115 /*-----------------------------------------------------------------*/
116 /* closeDumpFiles - close possible opened dumpfiles                */
117 /*-----------------------------------------------------------------*/
118 void closeDumpFiles() {
119   struct _dumpFiles *dumpFilesPtr;
120
121   for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
122     if (dumpFilesPtr->filePtr) {
123       fclose (dumpFilesPtr->filePtr);
124     }
125   }
126 }
127
128 /*-----------------------------------------------------------------*/
129 /* dumpLiveRanges - dump liverange information into a file         */
130 /*-----------------------------------------------------------------*/
131 void 
132 dumpLiveRanges (int id, hTab * liveRanges)
133 {
134   FILE *file;
135   symbol *sym;
136   int k;
137
138   if (id) {
139     file=createDumpFile(id);
140   } else {
141     file = stdout;
142   }
143   
144   if (currFunc) 
145       fprintf(file,"------------- Func %s -------------\n",currFunc->name);
146   for (sym = hTabFirstItem (liveRanges, &k); sym;
147        sym = hTabNextItem (liveRanges, &k))
148     {
149
150       fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
151                (sym->rname[0] ? sym->rname : sym->name),
152                sym->key,
153                sym->liveFrom, sym->liveTo,
154                sym->stack,
155                sym->isreqv, sym->remat
156         );
157
158       fprintf (file, "{");
159       printTypeChain (sym->type, file);
160       if (sym->usl.spillLoc)
161         {
162           fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
163         }
164       fprintf (file, "} clashes with ");
165       bitVectDebugOn(sym->clashes,file);
166       fprintf (file, "\n");
167     }
168
169   fflush(file);
170 }
171
172 /*-----------------------------------------------------------------*/
173 /* dumpEbbsToFileExt - writeall the basic blocks to a file         */
174 /*-----------------------------------------------------------------*/
175 void 
176 dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
177 {
178   FILE *of;
179   int i;
180
181   if (id) {
182     of=createDumpFile(id);
183   } else {
184     of = stdout;
185   }
186
187   for (i = 0; i < count; i++)
188     {
189       fprintf (of, "\n----------------------------------------------------------------\n");
190       fprintf (of, "Basic Block %d %s : loop Depth = %d noPath = %d lastinLoop = %d\n",
191                ebbs[i]->dfnum,
192                ebbs[i]->entryLabel->name,
193                ebbs[i]->depth,
194                ebbs[i]->noPath,
195                ebbs[i]->isLastInLoop);
196       fprintf (of, "\ndefines bitVector :");
197       bitVectDebugOn (ebbs[i]->defSet, of);
198       fprintf (of, "\nlocal defines bitVector :");
199       bitVectDebugOn (ebbs[i]->ldefs, of);
200       fprintf (of, "\npointers Set bitvector :");
201       bitVectDebugOn (ebbs[i]->ptrsSet, of);
202       if (ebbs[i]->isLastInLoop) {
203               fprintf (of, "\nInductions Set bitvector :");
204               bitVectDebugOn (ebbs[i]->linds, of);
205       }
206       fprintf (of, "\n----------------------------------------------------------------\n");
207       printiCChain (ebbs[i]->sch, of);
208     }
209   fflush(of);
210 }
211
212 /*-----------------------------------------------------------------*/
213 /* iCode2eBBlock - converts a sequnce till label to a ebb          */
214 /*-----------------------------------------------------------------*/
215 eBBlock *
216 iCode2eBBlock (iCode * ic)
217 {
218   iCode *loop;
219   eBBlock *ebb = neweBBlock (); /* allocate an entry */
220
221   /* put the first one unconditionally */
222   ebb->sch = ic;
223
224   /* if this is a label then */
225   if (ic->op == LABEL)
226     ebb->entryLabel = ic->label;
227   else
228     {
229       SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++);
230       ebb->entryLabel = newSymbol (buffer, 1);
231       ebb->entryLabel->key = labelKey++;
232     }
233
234   if (ic &&
235       (ic->op == GOTO ||
236        ic->op == JUMPTABLE ||
237        ic->op == IFX))
238     {
239       ebb->ech = ebb->sch;
240       return ebb;
241     }
242
243   if ((ic->next && ic->next->op == LABEL) ||
244       !ic->next)
245     {
246       ebb->ech = ebb->sch;
247       return ebb;
248     }
249
250   /* loop thru till we find one with a label */
251   for (loop = ic->next; loop; loop = loop->next)
252     {
253
254       /* if this is the last one */
255       if (!loop->next)
256         break;
257       /* if this is a function call */
258       if (loop->op == CALL || loop->op == PCALL)
259         {
260           ebb->hasFcall = 1;
261           if (currFunc)
262             FUNC_HASFCALL(currFunc->type) = 1;
263         }
264
265       /* if the next one is a label */
266       /* if this is a goto or ifx */
267       if (loop->next->op == LABEL ||
268           loop->op == GOTO ||
269           loop->op == JUMPTABLE ||
270           loop->op == IFX)
271         break;
272     }
273
274   /* mark the end of the chain */
275   ebb->ech = loop;
276
277   return ebb;
278 }
279
280 /*-----------------------------------------------------------------*/
281 /* eBBWithEntryLabel - finds the basic block with the entry label  */
282 /*-----------------------------------------------------------------*/
283 eBBlock *
284 eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count)
285 {
286   int i;
287
288   for (i = 0; i < count; i++)
289     {
290       if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
291         return ebbs[i];
292     }
293
294   return NULL;
295 }
296
297
298 /*-----------------------------------------------------------------*/
299 /* ifFromIs - will return 1 if the from block matches this         */
300 /*-----------------------------------------------------------------*/
301 DEFSETFUNC (ifFromIs)
302 {
303   edge *ep = item;
304   V_ARG (eBBlock *, this);
305
306   if (ep->from == this)
307     return 1;
308
309   return 0;
310 }
311
312
313 /*-----------------------------------------------------------------*/
314 /* edgesTo  - returns a set of edges with to == supplied value     */
315 /*-----------------------------------------------------------------*/
316 set *
317 edgesTo (eBBlock * to)
318 {
319   set *result = NULL;
320   edge *loop;
321
322   for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
323     if (loop->to == to && !loop->from->noPath)
324       addSet (&result, loop->from);
325
326   return result;
327 }
328
329
330 /*-----------------------------------------------------------------*/
331 /* addiCodeToeBBlock - will add an iCode to the end of a block     */
332 /*-----------------------------------------------------------------*/
333 void 
334 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
335 {
336   ic->prev = ic->next = NULL;
337   /* if the insert point is given */
338   if (ip)
339     {
340       ic->lineno = ip->lineno;
341       ic->prev = ip->prev;
342       ip->prev = ic;
343       ic->next = ip;
344       if (!ic->prev)
345         ebp->sch = ic;
346       else
347         ic->prev->next = ic;
348       return;
349     }
350
351   /* if the block has no  instructions */
352   if (ebp->ech == NULL)
353     {
354       ebp->sch = ebp->ech = ic;
355       ic->next = NULL;
356       return;
357     }
358
359   /* if the last instruction is a goto */
360   /* we add it just before the goto    */
361   if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE
362       || ebp->ech->op == RETURN)
363     {
364       ic->lineno = ebp->ech->lineno;
365       ic->prev = ebp->ech->prev;
366       ebp->ech->prev = ic;
367       ic->next = ebp->ech;
368       if (!ic->prev)            /* was the last only on in the block */
369         ebp->sch = ic;
370       else
371         ic->prev->next = ic;
372       return;
373     }
374
375   /* if the last one was a ifx statement we check to see */
376   /* if the condition was defined in the previous instruction */
377   /* if this is true then we put it before the condition else */
378   /* we put it before if, this is to reduce register pressure, */
379   /* we don't have to hold  condition too long in a register  */
380   if (ebp->ech->op == IFX)
381     {
382       iCode *ipoint;
383
384 /*  if ( !ebp->ech->prev )  */
385 /*      ipoint = ebp->ech ; */
386 /*  else  */
387 /*      if (!IC_RESULT(ebp->ech->prev)) */
388 /*    ipoint = ebp->ech ; */
389 /*      else */
390 /*    if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
391 /*        ipoint = ebp->ech->prev; */
392 /*    else */
393 /*        ipoint = ebp->ech ; */
394       ipoint = ebp->ech;
395       ic->lineno = ipoint->lineno;
396       ic->prev = ipoint->prev;
397       ipoint->prev = ic;
398       ic->next = ipoint;
399       if (!ic->prev)
400         ebp->sch = ic;
401       else
402         ic->prev->next = ic;
403       return;
404     }
405
406   /* will add it to the very end */
407   ip = ebp->ech;
408   ip->next = ic;
409   ic->prev = ip;
410   ic->next = NULL;
411   ebp->ech = ic;
412
413   return;
414 }
415
416 /*-----------------------------------------------------------------*/
417 /* remiCodeFromeBBlock - remove an iCode from BBlock               */
418 /*-----------------------------------------------------------------*/
419 void 
420 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
421 {
422   wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq);
423   if (ic->prev)
424     ic->prev->next = ic->next;
425   else
426     ebb->sch = ic->next;
427
428   if (ic->next)
429     ic->next->prev = ic->prev;
430   else
431     ebb->ech = ic->prev;
432 }
433
434 /*-----------------------------------------------------------------*/
435 /* iCodeBreakDown : breakDown iCode chain to blocks                */
436 /*-----------------------------------------------------------------*/
437 eBBlock **
438 iCodeBreakDown (iCode * ic, int *count)
439 {
440   eBBlock **ebbs = NULL;
441   iCode *loop = ic;
442
443   *count = 0;
444
445   /* allocate for the first entry */
446
447   ebbs = Safe_alloc (sizeof (eBBlock **));
448
449   while (loop)
450     {
451
452       /* convert 2 block */
453       eBBlock *ebb = iCode2eBBlock (loop);
454       loop = ebb->ech->next;
455
456       ebb->ech->next = NULL;    /* mark the end of this chain */
457       if (loop)
458         loop->prev = NULL;
459       ebb->bbnum = *count;      /* save this block number     */
460       /* put it in the array */
461       ebbs[(*count)++] = ebb;
462
463       /* allocate for the next one. Remember to clear the new */
464       /*  pointer at the end, that was created by realloc. */
465
466       ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
467
468       ebbs[*count] = 0;
469
470       /* if this one ends in a goto or a conditional */
471       /* branch then check if the block it is going  */
472       /* to already exists, if yes then this could   */
473       /* be a loop, add a preheader to the block it  */
474       /* goes to  if it does not already have one    */
475       if (ebbs[(*count) - 1]->ech &&
476           (ebbs[(*count) - 1]->ech->op == GOTO ||
477            ebbs[(*count) - 1]->ech->op == IFX))
478         {
479
480           symbol *label;
481           eBBlock *destBlock;
482
483           if (ebbs[(*count) - 1]->ech->op == GOTO)
484             label = IC_LABEL (ebbs[(*count) - 1]->ech);
485           else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech)))
486             label = IC_FALSE (ebbs[(*count) - 1]->ech);
487
488           if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) &&
489               destBlock->preHeader == NULL &&
490               otherPathsPresent (ebbs, destBlock))
491             {
492
493               symbol *preHeaderLabel = newiTempPreheaderLabel ();
494               int i, j;
495               eBBlock *pBlock;
496
497               /* go thru all block replacing the entryLabel with new label */
498               /* till we reach the block , then we insert a new ebblock    */
499               for (i = 0; i < (*count); i++)
500                 {
501                   if (ebbs[i] == destBlock)
502                     break;
503                   replaceLabel (ebbs[i], label, preHeaderLabel);
504                 }
505
506               (*count)++;
507
508               /* if we have stopped at the block , allocate for an extra one */
509
510               ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
511
512               ebbs[*count] = 0;
513
514               /* then move the block down one count */
515               pBlock = ebbs[j = i];
516               for (i += 1; i < (*count); i++)
517                 {
518                   eBBlock *xBlock;
519
520                   xBlock = ebbs[i];
521                   ebbs[i] = pBlock;
522                   ebbs[i]->bbnum = i;
523                   pBlock = xBlock;
524                 }
525
526               destBlock->preHeader = ebbs[j] = neweBBlock ();
527               ebbs[j]->bbnum = j;
528               ebbs[j]->entryLabel = preHeaderLabel;
529               ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
530               ebbs[j]->sch->lineno = destBlock->sch->lineno;
531             }
532         }
533     }
534
535   /* mark the end */
536   ebbs[*count] = NULL;
537
538   return ebbs;
539 }
540
541 /*-----------------------------------------------------------------*/
542 /* replaceSymBySym : - replace operand by operand in blocks        */
543 /*                     replaces only left & right in blocks        */
544 /*-----------------------------------------------------------------*/
545 void 
546 replaceSymBySym (set * sset, operand * src, operand * dest)
547 {
548   set *loop;
549   eBBlock *rBlock;
550
551   /* for all blocks in the set do */
552   for (loop = sset; loop; loop = loop->next)
553     {
554       iCode *ic;
555
556       rBlock = loop->item;
557       /* for all instructions in this block do */
558       for (ic = rBlock->sch; ic; ic = ic->next)
559         {
560
561           /* if we find usage */
562           if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
563             {
564               bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
565               IC_COND (ic) = operandFromOperand (dest);
566               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
567               continue;
568             }
569
570           if (isOperandEqual (IC_RIGHT (ic), src))
571             {
572               bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
573               IC_RIGHT (ic) = operandFromOperand (dest);
574               IC_RIGHT (ic)->isaddr = 0;
575               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
576             }
577
578           if (isOperandEqual (IC_LEFT (ic), src))
579             {
580               bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
581               if (POINTER_GET (ic) && IS_ITEMP (dest))
582                 {
583                   IC_LEFT (ic) = operandFromOperand (dest);
584                   IC_LEFT (ic)->isaddr = 1;
585                 }
586               else
587                 {
588                   IC_LEFT (ic) = operandFromOperand (dest);
589                   IC_LEFT (ic)->isaddr = 0;
590                 }
591               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
592             }
593
594           /* special case for pointer sets */
595           if (POINTER_SET (ic) &&
596               isOperandEqual (IC_RESULT (ic), src))
597             {
598               bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
599               IC_RESULT (ic) = operandFromOperand (dest);
600               IC_RESULT (ic)->isaddr = 1;
601               OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
602             }
603         }
604     }
605 }
606
607 /*-----------------------------------------------------------------*/
608 /* replaceLabel - replace reference to one label by another        */
609 /*-----------------------------------------------------------------*/
610 void 
611 replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
612 {
613   iCode *ic;
614
615   if (!ebp)
616     return;
617
618   for (ic = ebp->sch; ic; ic = ic->next)
619     {
620       switch (ic->op)
621         {
622
623         case GOTO:
624           if (isSymbolEqual (IC_LABEL (ic), fromLbl))
625             IC_LABEL (ic) = toLbl;
626           break;
627
628         case IFX:
629           if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
630             IC_TRUE (ic) = toLbl;
631           else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
632             IC_FALSE (ic) = toLbl;
633           break;
634         }
635     }
636
637   return;
638
639 }
640
641
642 /*-----------------------------------------------------------------*/
643 /* iCodeFromeBBlock - convert basic block to iCode chain           */
644 /*-----------------------------------------------------------------*/
645 iCode *
646 iCodeFromeBBlock (eBBlock ** ebbs, int count)
647 {
648   int i = 1;
649   iCode *ric = ebbs[0]->sch;
650   iCode *lic = ebbs[0]->ech;
651
652   for (; i < count; i++)
653     {
654       if (ebbs[i]->sch == NULL)
655         continue;
656
657       if (ebbs[i]->noPath &&
658           (ebbs[i]->entryLabel != entryLabel &&
659            ebbs[i]->entryLabel != returnLabel))
660         {
661           werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno);
662           continue;
663         }
664
665       lic->next = ebbs[i]->sch;
666       lic->next->prev = lic;
667       lic = ebbs[i]->ech;
668     }
669
670   return ric;
671 }
672
673 /*-----------------------------------------------------------------*/
674 /* otherPathsPresent - determines if there is a path from _entry   */
675 /*      to this block in a half constructed set of blocks          */
676 /*-----------------------------------------------------------------*/
677 int 
678 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
679 {
680   int i;
681
682   /* for all blocks preceding this block */
683   for (i = 0; i < this->bbnum; i++)
684     {
685       iCode *ic;
686
687       /* if there is a reference to the entry label of this block */
688       for (ic = ebbs[i]->sch; ic; ic = ic->next)
689         {
690           switch (ic->op)
691             {
692             case GOTO:
693               if (IC_LABEL (ic)->key == this->entryLabel->key)
694                 return 1;
695               break;
696
697             case IFX:
698               if (IC_TRUE (ic))
699                 {
700                   if (IC_TRUE (ic)->key == this->entryLabel->key)
701                     return 1;
702                 }
703               else if (IC_FALSE (ic)->key == this->entryLabel->key)
704                 return 1;
705               break;
706             }
707         }
708     }
709
710   /* comes here means we have not found it yet */
711   /* in this case check if the previous block  */
712   /* ends in a goto if it does then we have no */
713   /* path else we have a path                  */
714   if (this->bbnum && ebbs[this->bbnum - 1]->ech &&
715       ebbs[this->bbnum - 1]->ech->op == GOTO)
716     return 0;
717   else
718     return 1;
719 }