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