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