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 "dbuf_string.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 {DUMP_LOSPRE, ".dumplospre", NULL},
47 {DUMP_CUSTOM, ".dumpcustom", NULL},
48 {0, NULL, NULL}
49 };
50
51 /*-----------------------------------------------------------------*/
52 /* printEntryLabel - prints entry label of a ebblock */
53 /*-----------------------------------------------------------------*/
DEFSETFUNC(printEntryLabel)54 DEFSETFUNC (printEntryLabel)
55 {
56 eBBlock *bp = item;
57
58 fprintf (stdout, " %-20s ", bp->entryLabel->name);
59 return 0;
60 }
61
62 /*-----------------------------------------------------------------*/
63 /* neweBBlock - allocate & return a new extended basic block */
64 /*-----------------------------------------------------------------*/
65 eBBlock *
neweBBlock()66 neweBBlock ()
67 {
68 eBBlock *ebb;
69
70 ebb = Safe_alloc (sizeof (eBBlock));
71 return ebb;
72 }
73
74 /*-----------------------------------------------------------------*/
75 /* newEdge - allocates & initialises an edge to given values */
76 /*-----------------------------------------------------------------*/
77 edge *
newEdge(eBBlock * from,eBBlock * to)78 newEdge (eBBlock * from, eBBlock * to)
79 {
80 edge *ep;
81
82 ep = Safe_alloc (sizeof (edge));
83
84 ep->from = from;
85 ep->to = to;
86 return ep;
87 }
88
89 /*-----------------------------------------------------------------*/
90 /* createDumpFile - create the dump file */
91 /*-----------------------------------------------------------------*/
92 FILE *
createDumpFile(int id)93 createDumpFile (int id)
94 {
95 struct _dumpFiles *dumpFilesPtr = dumpFiles;
96 static int dumpIndex = 0;
97 static char dumpIndexStr[32];
98
99 while (dumpFilesPtr->id)
100 {
101 if (dumpFilesPtr->id == id)
102 break;
103 dumpFilesPtr++;
104 }
105
106 if (!dumpFilesPtr->id)
107 {
108 fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
109 exit (1);
110 }
111
112 sprintf (dumpIndexStr, ".%d", dumpIndex);
113 dumpIndex++;
114
115 if (!dumpFilesPtr->filePtr)
116 {
117 // not used before, create it
118 struct dbuf_s dumpFileName;
119
120 dbuf_init (&dumpFileName, PATH_MAX);
121 dbuf_append_str (&dumpFileName, dstFileName);
122 #ifdef _DEBUG
123 dbuf_append_str (&dumpFileName, dumpIndexStr);
124 #endif
125 dbuf_append_str (&dumpFileName, dumpFilesPtr->ext);
126 if (!(dumpFilesPtr->filePtr = fopen (dbuf_c_str (&dumpFileName), "w")))
127 {
128 werror (E_FILE_OPEN_ERR, dbuf_c_str (&dumpFileName));
129 dbuf_destroy (&dumpFileName);
130 exit (1);
131 }
132 dbuf_destroy (&dumpFileName);
133 }
134
135 #if 0
136 fprintf (dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex);
137 #endif
138
139 return dumpFilesPtr->filePtr;
140 }
141
142 /*-----------------------------------------------------------------*/
143 /* closeDumpFiles - close possible opened dumpfiles */
144 /*-----------------------------------------------------------------*/
145 void
closeDumpFiles()146 closeDumpFiles ()
147 {
148 struct _dumpFiles *dumpFilesPtr;
149
150 for (dumpFilesPtr = dumpFiles; dumpFilesPtr->id; dumpFilesPtr++)
151 {
152 if (dumpFilesPtr->filePtr)
153 {
154 fclose (dumpFilesPtr->filePtr);
155 }
156 }
157 }
158
159 /*-----------------------------------------------------------------*/
160 /* dumpLiveRanges - dump liverange information into a file */
161 /*-----------------------------------------------------------------*/
162 void
dumpLiveRanges(int id,hTab * liveRanges)163 dumpLiveRanges (int id, hTab * liveRanges)
164 {
165 FILE *file;
166 symbol *sym;
167 int k;
168
169 if (id)
170 {
171 file = createDumpFile (id);
172 }
173 else
174 {
175 file = stdout;
176 }
177
178 if (currFunc)
179 fprintf (file, "------------- Func %s -------------\n", currFunc->name);
180 for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k))
181 {
182
183 fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
184 (sym->rname[0] ? sym->rname : sym->name),
185 sym->key, sym->liveFrom, sym->liveTo, sym->stack, sym->isreqv, sym->remat);
186
187 fprintf (file, "{");
188 printTypeChain (sym->type, file);
189 if (sym->usl.spillLoc)
190 {
191 fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
192 }
193 fprintf (file, "} clashes with ");
194 bitVectDebugOn (sym->clashes, file);
195 fprintf (file, "\n");
196 }
197
198 fflush (file);
199 }
200
201
202 /*-----------------------------------------------------------------*/
203 /* dumpEbbsToFileExt - write all the basic blocks to a file */
204 /*-----------------------------------------------------------------*/
205 void
dumpEbbsToFileExt(int id,ebbIndex * ebbi)206 dumpEbbsToFileExt (int id, ebbIndex * ebbi)
207 {
208 FILE *of;
209 int i, d;
210 eBBlock *bb;
211 set *cseSet;
212 eBBlock **ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
213 int count = ebbi->count;
214
215 if (id)
216 {
217 of = createDumpFile (id);
218 }
219 else
220 {
221 of = stdout;
222 }
223
224 for (i = 0; i < count; i++)
225 {
226 fprintf (of, "\n----------------------------------------------------------------\n");
227 fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%ld:%ld): loopDepth=%d%s%s%s\n",
228 ebbs[i]->entryLabel->name,
229 ebbs[i]->dfnum, ebbs[i]->bbnum,
230 ebbs[i]->entryLabel->level / LEVEL_UNIT, ebbs[i]->entryLabel->level % LEVEL_UNIT,
231 ebbs[i]->depth,
232 ebbs[i]->noPath ? " noPath" : "",
233 ebbs[i]->partOfLoop ? " partOfLoop" : "", ebbs[i]->isLastInLoop ? " isLastInLoop" : "");
234
235 // a --nolabelopt makes this more readable
236 fprintf (of, "\nsuccessors: ");
237 for (bb = setFirstItem (ebbs[i]->succList); bb; bb = setNextItem (ebbs[i]->succList))
238 {
239 fprintf (of, "%s ", bb->entryLabel->name);
240 }
241 fprintf (of, "\npredecessors: ");
242 for (bb = setFirstItem (ebbs[i]->predList); bb; bb = setNextItem (ebbs[i]->predList))
243 {
244 fprintf (of, "%s ", bb->entryLabel->name);
245 }
246 fprintf (of, "\ndominators: ");
247 for (d = 0; d < ebbs[i]->domVect->size; d++)
248 {
249 if (bitVectBitValue (ebbs[i]->domVect, d))
250 {
251 fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
252 }
253 }
254 fprintf (of, "\n");
255
256 fprintf (of, "\ndefines bitVector :");
257 bitVectDebugOn (ebbs[i]->defSet, of);
258 fprintf (of, "\nlocal defines bitVector :");
259 bitVectDebugOn (ebbs[i]->ldefs, of);
260 fprintf (of, "\npointers Set bitvector :");
261 bitVectDebugOn (ebbs[i]->ptrsSet, of);
262 #if 0
263 fprintf (of, "\nin coming definitions :");
264 bitVectDebugOn (ebbs[i]->inDefs, of);
265 fprintf (of, "\nout going definitions :");
266 bitVectDebugOn (ebbs[i]->outDefs, of);
267 fprintf (of, "\ndefines used :");
268 bitVectDebugOn (ebbs[i]->usesDefs, of);
269 #endif
270
271 if (ebbs[i]->isLastInLoop)
272 {
273 fprintf (of, "\nInductions Set bitvector :");
274 bitVectDebugOn (ebbs[i]->linds, of);
275 }
276
277 fprintf (of, "\ninExprs:");
278 for (cseSet = ebbs[i]->inExprs; cseSet; cseSet = cseSet->next)
279 {
280 cseDef *item = cseSet->item;
281 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
282 if (item->fromGlobal)
283 fprintf (of, "g");
284 }
285 fprintf (of, "\noutExprs:");
286 for (cseSet = ebbs[i]->outExprs; cseSet; cseSet = cseSet->next)
287 {
288 cseDef *item = cseSet->item;
289 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
290 if (item->fromGlobal)
291 fprintf (of, "g");
292 }
293 fprintf (of, "\nkilledExprs:");
294 for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet = cseSet->next)
295 {
296 cseDef *item = cseSet->item;
297 fprintf (of, " %s(%d)", OP_SYMBOL (item->sym)->name, item->diCode->key);
298 if (item->fromGlobal)
299 fprintf (of, "g");
300 }
301
302 fprintf (of, "\n----------------------------------------------------------------\n");
303 printiCChain (ebbs[i]->sch, of);
304 }
305 fflush (of);
306 }
307
308 /*-----------------------------------------------------------------*/
309 /* iCode2eBBlock - converts a sequnce till label to a ebb */
310 /*-----------------------------------------------------------------*/
311 eBBlock *
iCode2eBBlock(iCode * ic)312 iCode2eBBlock (iCode * ic)
313 {
314 iCode *loop;
315 eBBlock *ebb = neweBBlock (); /* allocate an entry */
316
317 /* put the first one unconditionally */
318 ebb->sch = ic;
319 ic->seq = 0;
320
321 /* if this is a label then */
322 if (ic->op == LABEL)
323 ebb->entryLabel = ic->label;
324 else
325 {
326 struct dbuf_s dbuf;
327
328 dbuf_init (&dbuf, 128);
329 dbuf_printf (&dbuf, "_eBBlock%d", eBBNum++);
330 ebb->entryLabel = newSymbol (dbuf_c_str (&dbuf), 1);
331 dbuf_destroy (&dbuf);
332 ebb->entryLabel->key = labelKey++;
333 }
334
335 if (ic && (ic->op == GOTO || ic->op == JUMPTABLE || ic->op == IFX))
336 {
337 ebb->ech = ebb->sch;
338 return ebb;
339 }
340
341 /* if this is a function call */
342 if (ic->op == CALL || ic->op == PCALL)
343 {
344 sym_link *type = operandType (IC_LEFT (ic));
345 ebb->hasFcall = 1;
346 if (currFunc)
347 FUNC_HASFCALL (currFunc->type) = 1;
348 if (IS_FUNCPTR (type))
349 type = type->next;
350 if (type && FUNC_ISNORETURN (type))
351 {
352 ebb->ech = ebb->sch;
353 return ebb;
354 }
355 }
356
357 if ((ic->next && ic->next->op == LABEL) || !ic->next)
358 {
359 ebb->ech = ebb->sch;
360 return ebb;
361 }
362
363 /* loop thru till we find one with a label */
364 for (loop = ic->next; loop; loop = loop->next)
365 {
366 loop->seq = 0;
367
368 /* if this is the last one */
369 if (!loop->next)
370 break;
371 /* if this is a function call */
372 if (loop->op == CALL || loop->op == PCALL)
373 {
374 sym_link *type = operandType (IC_LEFT (loop));
375 ebb->hasFcall = 1;
376 if (currFunc)
377 FUNC_HASFCALL (currFunc->type) = 1;
378 if (IS_FUNCPTR (type))
379 type = type->next;
380 if (type && FUNC_ISNORETURN (type))
381 break;
382 }
383
384 /* if the next one is a label */
385 /* if this is a goto or ifx */
386 if (loop->next->op == LABEL || loop->op == GOTO || loop->op == JUMPTABLE || loop->op == IFX)
387 break;
388 }
389
390 /* mark the end of the chain */
391 ebb->ech = loop;
392
393 return ebb;
394 }
395
396 /*-----------------------------------------------------------------*/
397 /* eBBWithEntryLabel - finds the basic block with the entry label */
398 /*-----------------------------------------------------------------*/
399 eBBlock *
eBBWithEntryLabel(ebbIndex * ebbi,const symbol * eLabel)400 eBBWithEntryLabel (ebbIndex* ebbi, const symbol *eLabel)
401 {
402 eBBlock **ebbs = ebbi->bbOrder;
403 int count = ebbi->count;
404 int i;
405
406 for (i = 0; i < count; i++)
407 {
408 if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
409 return ebbs[i];
410 }
411
412 return NULL;
413 }
414
415
416 /*-----------------------------------------------------------------*/
417 /* ifFromIs - will return 1 if the from block matches this */
418 /*-----------------------------------------------------------------*/
DEFSETFUNC(ifFromIs)419 DEFSETFUNC (ifFromIs)
420 {
421 edge *ep = item;
422 V_ARG (eBBlock *, this);
423
424 if (ep->from == this)
425 return 1;
426
427 return 0;
428 }
429
430
431 /*-----------------------------------------------------------------*/
432 /* edgesTo - returns a set of edges with to == supplied value */
433 /*-----------------------------------------------------------------*/
434 set *
edgesTo(eBBlock * to)435 edgesTo (eBBlock * to)
436 {
437 set *result = NULL;
438 edge *loop;
439
440 for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges))
441 if (loop->to == to && !loop->from->noPath)
442 addSet (&result, loop->from);
443
444 return result;
445 }
446
447
448 /*-----------------------------------------------------------------*/
449 /* addiCodeToeBBlock - will add an iCode to the end of a block */
450 /*-----------------------------------------------------------------*/
451 void
addiCodeToeBBlock(eBBlock * ebp,iCode * ic,iCode * ip)452 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
453 {
454 ic->prev = ic->next = NULL;
455 /* if the insert point is given */
456 if (ip)
457 {
458 ic->filename = ip->filename;
459 ic->lineno = ip->lineno;
460 ic->eBBlockNum = ip->eBBlockNum;
461 ic->prev = ip->prev;
462 ip->prev = ic;
463 ic->next = ip;
464 if (!ic->prev)
465 ebp->sch = ic;
466 else
467 ic->prev->next = ic;
468 return;
469 }
470
471 /* if the block has no instructions */
472 if (ebp->ech == NULL)
473 {
474 ebp->sch = ebp->ech = ic;
475 ic->next = NULL;
476 return;
477 }
478
479 /* if the last instruction is a goto */
480 /* we add it just before the goto */
481 if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE || ebp->ech->op == RETURN)
482 {
483 ic->filename = ebp->ech->filename;
484 ic->lineno = ebp->ech->lineno;
485 ic->prev = ebp->ech->prev;
486 ebp->ech->prev = ic;
487 ic->next = ebp->ech;
488 if (!ic->prev) /* was the last only on in the block */
489 ebp->sch = ic;
490 else
491 ic->prev->next = ic;
492 return;
493 }
494
495 /* if the last one was a ifx statement we check to see */
496 /* if the condition was defined in the previous instruction */
497 /* if this is true then we put it before the condition else */
498 /* we put it before if, this is to reduce register pressure, */
499 /* we don't have to hold condition too long in a register */
500
501 /* loop induction sometimes appends a GOTO instruction, */
502 /* it must be at the very end */
503 if (ebp->ech->op == IFX && ic->op != GOTO)
504 {
505 iCode *ipoint;
506
507 /* if ( !ebp->ech->prev ) */
508 /* ipoint = ebp->ech ; */
509 /* else */
510 /* if (!IC_RESULT(ebp->ech->prev)) */
511 /* ipoint = ebp->ech ; */
512 /* else */
513 /* if (IC_COND(ebp->ech)->key == IC_RESULT(ebp->ech->prev)->key) */
514 /* ipoint = ebp->ech->prev; */
515 /* else */
516 /* ipoint = ebp->ech ; */
517 ipoint = ebp->ech;
518 ic->filename = ipoint->filename;
519 ic->lineno = ipoint->lineno;
520 ic->prev = ipoint->prev;
521 ipoint->prev = ic;
522 ic->next = ipoint;
523 if (!ic->prev)
524 ebp->sch = ic;
525 else
526 ic->prev->next = ic;
527 return;
528 }
529
530 /* will add it to the very end */
531 ip = ebp->ech;
532 ip->next = ic;
533 ic->prev = ip;
534 ic->next = NULL;
535 ebp->ech = ic;
536
537 return;
538 }
539
540 /*-----------------------------------------------------------------*/
541 /* remiCodeFromeBBlock - remove an iCode from BBlock */
542 /*-----------------------------------------------------------------*/
543 void
remiCodeFromeBBlock(eBBlock * ebb,iCode * ic)544 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
545 {
546 wassert (ic->seq >= ebb->fSeq && ic->seq <= ebb->lSeq);
547 if (ic->prev)
548 ic->prev->next = ic->next;
549 else
550 ebb->sch = ic->next;
551
552 if (ic->next)
553 ic->next->prev = ic->prev;
554 else
555 ebb->ech = ic->prev;
556 }
557
558 /*-----------------------------------------------------------------*/
559 /* iCodeBreakDown : breakDown iCode chain to blocks */
560 /*-----------------------------------------------------------------*/
561 ebbIndex *
iCodeBreakDown(iCode * ic)562 iCodeBreakDown (iCode * ic)
563 {
564 eBBlock **ebbs = NULL;
565 iCode *loop = ic;
566 ebbIndex *ebbi;
567
568 ebbi = Safe_alloc (sizeof (ebbIndex));
569 ebbi->count = 0;
570 ebbi->dfOrder = NULL; /* no depth first order information yet */
571
572 /* allocate for the first entry */
573
574 ebbs = Safe_alloc (sizeof (eBBlock *));
575 ebbi->bbOrder = ebbs;
576
577 while (loop)
578 {
579
580 /* convert 2 block */
581 eBBlock *ebb = iCode2eBBlock (loop);
582 loop = ebb->ech->next;
583
584 ebb->ech->next = NULL; /* mark the end of this chain */
585 if (loop)
586 loop->prev = NULL;
587 ebb->bbnum = ebbi->count; /* save this block number */
588 /* put it in the array */
589 ebbs[(ebbi->count)++] = ebb;
590
591 /* allocate for the next one. Remember to clear the new */
592 /* pointer at the end, that was created by realloc. */
593
594 ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
595 ebbi->bbOrder = ebbs;
596
597 ebbs[ebbi->count] = 0;
598
599 /* if this one ends in a goto or a conditional */
600 /* branch then check if the block it is going */
601 /* to already exists, if yes then this could */
602 /* be a loop, add a preheader to the block it */
603 /* goes to if it does not already have one */
604 if (ebbs[(ebbi->count) - 1]->ech && (ebbs[(ebbi->count) - 1]->ech->op == GOTO || ebbs[(ebbi->count) - 1]->ech->op == IFX))
605 {
606
607 symbol *label;
608 eBBlock *destBlock;
609
610 if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
611 label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
612 else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
613 label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);
614
615 if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
616 destBlock->preHeader == NULL && otherPathsPresent (ebbs, destBlock))
617 {
618
619 symbol *preHeaderLabel = newiTempLoopHeaderLabel (1);
620 int i, j;
621 eBBlock *pBlock;
622
623 /* go thru all block replacing the entryLabel with new label */
624 /* till we reach the block , then we insert a new ebblock */
625 for (i = 0; i < (ebbi->count); i++)
626 {
627 if (ebbs[i] == destBlock)
628 break;
629 replaceLabel (ebbs[i], label, preHeaderLabel);
630 }
631
632 (ebbi->count)++;
633
634 /* if we have stopped at the block , allocate for an extra one */
635
636 ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
637 ebbi->bbOrder = ebbs;
638
639 ebbs[ebbi->count] = 0;
640
641 /* then move the block down one count */
642 pBlock = ebbs[j = i];
643 for (i += 1; i < (ebbi->count); i++)
644 {
645 eBBlock *xBlock;
646
647 xBlock = ebbs[i];
648 ebbs[i] = pBlock;
649 ebbs[i]->bbnum = i;
650 pBlock = xBlock;
651 }
652
653 destBlock->preHeader = ebbs[j] = neweBBlock ();
654 ebbs[j]->bbnum = j;
655 ebbs[j]->entryLabel = preHeaderLabel;
656 ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
657 ebbs[j]->sch->filename = destBlock->sch->filename;
658 ebbs[j]->sch->lineno = destBlock->sch->lineno;
659 }
660 }
661 }
662
663 /* mark the end */
664 ebbs[ebbi->count] = NULL;
665
666 return ebbi;
667 }
668
669 /*-----------------------------------------------------------------*/
670 /* replaceSymBySym : - replace operand by operand in blocks */
671 /* replaces only left & right in blocks */
672 /*-----------------------------------------------------------------*/
673 void
replaceSymBySym(set * sset,operand * src,operand * dest)674 replaceSymBySym (set * sset, operand * src, operand * dest)
675 {
676 set *loop;
677 eBBlock *rBlock;
678
679 /* for all blocks in the set do */
680 for (loop = sset; loop; loop = loop->next)
681 {
682 iCode *ic;
683
684 rBlock = loop->item;
685 /* for all instructions in this block do */
686 for (ic = rBlock->sch; ic; ic = ic->next)
687 {
688
689 /* if we find usage */
690 if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
691 {
692 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
693 IC_COND (ic) = operandFromOperand (dest);
694 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
695 continue;
696 }
697
698 if (isOperandEqual (IC_RIGHT (ic), src))
699 {
700 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
701 IC_RIGHT (ic) = operandFromOperand (dest);
702 IC_RIGHT (ic)->isaddr = 0;
703 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
704 }
705
706 if (isOperandEqual (IC_LEFT (ic), src))
707 {
708 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
709 if (POINTER_GET (ic) && IS_ITEMP (dest))
710 {
711 IC_LEFT (ic) = operandFromOperand (dest);
712 IC_LEFT (ic)->isaddr = 1;
713 }
714 else
715 {
716 IC_LEFT (ic) = operandFromOperand (dest);
717 IC_LEFT (ic)->isaddr = 0;
718 }
719 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
720 }
721
722 /* special case for pointer sets */
723 if (POINTER_SET (ic) && isOperandEqual (IC_RESULT (ic), src))
724 {
725 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
726 IC_RESULT (ic) = operandFromOperand (dest);
727 IC_RESULT (ic)->isaddr = 1;
728 OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
729 }
730 }
731 }
732 }
733
734 /*-----------------------------------------------------------------*/
735 /* replaceLabel - replace reference to one label by another */
736 /*-----------------------------------------------------------------*/
737 void
replaceLabel(eBBlock * ebp,symbol * fromLbl,symbol * toLbl)738 replaceLabel (eBBlock *ebp, symbol *fromLbl, symbol *toLbl)
739 {
740 iCode *ic;
741
742 if (!ebp)
743 return;
744
745 for (ic = ebp->sch; ic; ic = ic->next)
746 {
747 switch (ic->op)
748 {
749
750 case GOTO:
751 if (isSymbolEqual (IC_LABEL (ic), fromLbl))
752 IC_LABEL (ic) = toLbl;
753 break;
754
755 case IFX:
756 if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
757 IC_TRUE (ic) = toLbl;
758 else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
759 IC_FALSE (ic) = toLbl;
760 break;
761
762 case JUMPTABLE:
763 replaceSetItem (IC_JTLABELS (ic), fromLbl, toLbl);
764 }
765 }
766
767 return;
768
769 }
770
771
772 /*-----------------------------------------------------------------*/
773 /* iCodeFromeBBlock - convert basic block to iCode chain */
774 /*-----------------------------------------------------------------*/
775 iCode *
iCodeFromeBBlock(eBBlock ** ebbs,int count)776 iCodeFromeBBlock (eBBlock ** ebbs, int count)
777 {
778 int i = 1;
779 iCode *ric = ebbs[0]->sch;
780 iCode *lic = ebbs[0]->ech;
781
782 for (; i < count; i++)
783 {
784 if (ebbs[i]->sch == NULL)
785 continue;
786
787 if (ebbs[i]->noPath && optimize.label4 && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel))
788 {
789 iCode *ic = NULL;
790 bool foundNonlabel = 0;
791 ic = ebbs[i]->sch;
792 do
793 {
794 if (ic->op != LABEL)
795 {
796 foundNonlabel = 1;
797 break;
798 }
799 if (ic == ebbs[i]->ech)
800 break;
801 ic = ic->next;
802 }
803 while (ic);
804 if (foundNonlabel && ic)
805 {
806 werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH);
807 continue;
808 }
809 }
810
811 lic->next = ebbs[i]->sch;
812 lic->next->prev = lic;
813 lic = ebbs[i]->ech;
814
815 }
816
817 return ric;
818 }
819
820 /*-----------------------------------------------------------------*/
821 /* otherPathsPresent - determines if there is a path from _entry */
822 /* to this block in a half constructed set of blocks */
823 /*-----------------------------------------------------------------*/
824 int
otherPathsPresent(eBBlock ** ebbs,eBBlock * this)825 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
826 {
827 int i;
828
829 /* for all blocks preceding this block */
830 for (i = 0; i < this->bbnum; i++)
831 {
832 iCode *ic;
833
834 /* if there is a reference to the entry label of this block */
835 for (ic = ebbs[i]->sch; ic; ic = ic->next)
836 {
837 switch (ic->op)
838 {
839 case GOTO:
840 if (IC_LABEL (ic)->key == this->entryLabel->key)
841 return 1;
842 break;
843
844 case IFX:
845 if (IC_TRUE (ic))
846 {
847 if (IC_TRUE (ic)->key == this->entryLabel->key)
848 return 1;
849 }
850 else if (IC_FALSE (ic)->key == this->entryLabel->key)
851 return 1;
852 break;
853 }
854 }
855 }
856
857 /* comes here means we have not found it yet */
858 /* in this case check if the previous block */
859 /* ends in a goto if it does then we have no */
860 /* path else we have a path */
861 if (this->bbnum && ebbs[this->bbnum - 1]->ech && ebbs[this->bbnum - 1]->ech->op == GOTO)
862 return 0;
863 else
864 return 1;
865 }
866
867
868 /*-----------------------------------------------------------------*/
869 /* freeBBlockData - Deallocate data structures associated with */
870 /* the current blocks. They will all be recomputed if the */
871 /* iCode chain is divided into blocks again later. */
872 /*-----------------------------------------------------------------*/
873 void
freeeBBlockData(ebbIndex * ebbi)874 freeeBBlockData(ebbIndex * ebbi)
875 {
876 int i;
877 eBBlock ** ebbs = ebbi->bbOrder;
878
879 for (i=0; i < ebbi->count; i++)
880 {
881 deleteSet (&ebbs[i]->succList);
882 deleteSet (&ebbs[i]->predList);
883 freeBitVect (ebbs[i]->succVect);
884 freeBitVect (ebbs[i]->domVect);
885
886 freeCSEdata(ebbs[i]);
887 }
888 }
889
890