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