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