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