Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / src / SDCCcflow.c
blob810f4cd78e854d45569ce95b0f26c205dc18ec31
1 /*-------------------------------------------------------------------------
3 SDCCcflow.c - source file for control flow analysis
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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.
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.
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.
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 -------------------------------------------------------------------------*/
26 #include "common.h"
28 static void computeDFOrdering (eBBlock *, int *);
30 /*-----------------------------------------------------------------*/
31 /* domSetFromVect - creates a domset from the vector */
32 /*-----------------------------------------------------------------*/
33 static set *
34 domSetFromVect (ebbIndex *ebbi, bitVect * domVect)
36 int i = 0;
37 set *domSet = NULL;
39 if (!domVect)
40 return NULL;
42 for (i = 0; i < domVect->size; i++)
43 if (bitVectBitValue (domVect, i))
44 addSet (&domSet, ebbi->bbOrder[i]);
45 return domSet;
49 /*-----------------------------------------------------------------*/
50 /* addSuccessor - will add bb to succ also add it to the pred of */
51 /* the next one : */
52 /*-----------------------------------------------------------------*/
53 static void
54 addSuccessor (eBBlock * thisBlock, eBBlock * succ)
56 /* check for boundary conditions */
57 if (!thisBlock || !succ)
58 return;
60 /* add it to the succ of thisBlock */
61 addSetIfnotP (&thisBlock->succList, succ);
63 thisBlock->succVect =
64 bitVectSetBit (thisBlock->succVect, succ->bbnum);
65 /* add this edge to the list of edges */
66 addSet (&graphEdges, newEdge (thisBlock, succ));
70 /*-----------------------------------------------------------------*/
71 /* eBBPredecessors - find the predecessors for each block */
72 /*-----------------------------------------------------------------*/
73 static void
74 eBBPredecessors (ebbIndex * ebbi)
76 eBBlock ** ebbs = ebbi->bbOrder;
77 int count = ebbi->count;
78 int i = 0, j;
80 /* for each block do */
81 for (i = 0; i < count; i++)
84 /* if there is no path to this then continue */
85 if (ebbs[i]->noPath)
86 continue;
88 /* for each successor of this block if */
89 /* it has depth first number > this block */
90 /* then this block precedes the successor */
91 for (j = 0; j < ebbs[i]->succVect->size; j++)
93 if (bitVectBitValue (ebbs[i]->succVect, j) &&
94 ebbs[j]->dfnum > ebbs[i]->dfnum)
96 addSet (&ebbs[j]->predList, ebbs[i]);
100 /*-----------------------------------------------------------------*/
101 /* eBBSuccessors- find out the successors of all the nodes */
102 /*-----------------------------------------------------------------*/
103 static void
104 eBBSuccessors (ebbIndex * ebbi)
106 eBBlock ** ebbs = ebbi->bbOrder;
107 int count = ebbi->count;
108 int i = 0;
110 /* for all the blocks do */
111 for (; i < count; i++)
113 iCode *ic;
115 if (ebbs[i]->noPath)
116 continue;
118 ebbs[i]->succVect = newBitVect (count);
120 /* if the next on exists & this one does not */
121 /* end in a GOTO or RETURN then the next is */
122 /* a natural successor of this. Note we have */
123 /* consider eBBlocks with no instructions */
124 if (ebbs[i + 1])
127 if (ebbs[i]->ech)
129 bool foundNoReturn = FALSE;
130 if (ebbs[i]->ech->op == CALL || ebbs[i]->ech->op == PCALL)
132 sym_link *type = operandType (IC_LEFT (ebbs[i]->ech));
133 if (IS_FUNCPTR (type))
134 type = type->next;
135 if (type && FUNC_ISNORETURN (type))
136 foundNoReturn = TRUE;
138 if (!foundNoReturn &&
139 ebbs[i]->ech->op != GOTO &&
140 ebbs[i]->ech->op != RETURN &&
141 ebbs[i]->ech->op != JUMPTABLE)
143 int j = i + 1;
145 while (ebbs[j] && ebbs[j]->noPath)
146 j++;
148 addSuccessor (ebbs[i], ebbs[j]); /* add it */
150 else
152 if (i && ebbs[i-1]->ech && ebbs[i-1]->ech->op==IFX) {
153 ebbs[i]->isConditionalExitFrom=ebbs[i-1];
156 } /* no instructions in the block */
157 /* could happen for dummy blocks */
158 else
159 addSuccessor (ebbs[i], ebbs[i + 1]);
162 /* go thru all the instructions: if we find a */
163 /* goto or ifx or a return then we have a succ */
164 if ((ic = ebbs[i]->ech))
166 eBBlock *succ;
168 /* special case for jumptable */
169 if (ic->op == JUMPTABLE)
171 symbol *lbl;
172 for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl;
173 lbl = setNextItem (IC_JTLABELS (ic)))
174 addSuccessor (ebbs[i],
175 eBBWithEntryLabel (ebbi, lbl));
177 else
180 succ = NULL;
181 /* depending on the instruction operator */
182 switch (ic->op)
184 case GOTO: /* goto has edge to label */
185 succ = eBBWithEntryLabel (ebbi, ic->label);
187 /* Sometimes a block has a GOTO added after the original */
188 /* final IFX (due to loop optimizations). If IFX found, */
189 /* fall through to handle the IFX too. */
190 if (ic->prev && ic->prev->op == IFX)
192 if (succ)
193 addSuccessor (ebbs[i], succ); /* add the GOTO target */
194 ic = ic->prev; /* get ready to handle IFX too. */
196 else
197 break;
199 case IFX: /* conditional jump */
200 /* if true label is present */
201 if (IC_TRUE (ic))
202 succ = eBBWithEntryLabel (ebbi, IC_TRUE (ic));
203 else
204 succ = eBBWithEntryLabel (ebbi, IC_FALSE (ic));
205 break;
207 case RETURN: /* block with return */
208 succ = eBBWithEntryLabel (ebbi, returnLabel);
209 break;
212 /* if there is a successor add to the list */
213 /* if it is not already present in the list */
214 if (succ)
215 addSuccessor (ebbs[i], succ);
221 /*-----------------------------------------------------------------*/
222 /* computeDominance - computes the dominance graph */
223 /* for algorithm look at Dragon book section 10.10, algo 10.16 */
224 /*-----------------------------------------------------------------*/
225 static void
226 computeDominance (ebbIndex * ebbi)
228 eBBlock ** ebbs = ebbi->bbOrder;
229 int count = ebbi->count;
230 int i, j;
232 /* now do the initialisation */
233 /* D(n0) := { n0 } */
234 ebbs[0]->domVect =
235 bitVectSetBit (ebbs[0]->domVect = newBitVect (count), ebbs[0]->bbnum);
238 /* for n in N - { n0 } do D(n) = N */
239 for (i = 1; i < count; i++)
241 ebbs[i]->domVect = newBitVect (count);
242 for (j = 0; j < count; j++)
244 ebbs[i]->domVect =
245 bitVectSetBit (ebbs[i]->domVect, ebbs[j]->bbnum);
249 /* end of initialisation */
251 /* while changes to any D(n) occur do */
252 /* for n in N - { n0 } do */
253 /* D(n) := { n } U (intersection of D( all predecessors of n)) */
254 while (1)
256 int change;
258 change = 0;
259 for (i = 1; i < count; i++)
261 bitVect *cDomVect;
262 eBBlock *pred;
264 cDomVect = NULL;
266 /* get the intersection of the dominance of all predecessors */
267 for (pred = setFirstItem (ebbs[i]->predList),
268 cDomVect = (pred ? bitVectCopy (pred->domVect) : NULL);
269 pred;
270 pred = setNextItem (ebbs[i]->predList))
272 cDomVect = bitVectInplaceIntersect (cDomVect, pred->domVect);
274 if (!cDomVect)
275 cDomVect = newBitVect (count);
276 /* this node to the list */
277 cDomVect = bitVectSetBit (cDomVect, ebbs[i]->bbnum);
280 if (!bitVectEqual (cDomVect, ebbs[i]->domVect))
282 freeBitVect (ebbs[i]->domVect);
283 ebbs[i]->domVect = cDomVect;
284 change = 1;
288 /* if no change then exit */
289 if (!change)
290 break;
295 /*-----------------------------------------------------------------*/
296 /* immedDom - returns the immediate dominator of a block */
297 /*-----------------------------------------------------------------*/
298 eBBlock *
299 immedDom (ebbIndex * ebbi, eBBlock * ebp)
301 /* first delete self from the list */
302 set *iset = domSetFromVect (ebbi, ebp->domVect);
303 eBBlock *loop;
304 eBBlock *idom = NULL;
306 deleteSetItem (&iset, ebp);
307 /* then just return the one with the greatest */
308 /* depthfirst number, this will be the immed dominator */
309 if ((loop = setFirstItem (iset)))
310 idom = loop;
311 for (; loop; loop = setNextItem (iset))
312 if (loop->dfnum > idom->dfnum)
313 idom = loop;
315 setToNull ((void *) &iset);
316 return idom;
320 /*-----------------------------------------------------------------*/
321 /* DFOrdering - is visited then nothing else call DFOrdering this */
322 /*-----------------------------------------------------------------*/
323 DEFSETFUNC (DFOrdering)
325 eBBlock *ebbp = item;
326 V_ARG (int *, count);
328 if (ebbp->visited)
329 return 0;
331 computeDFOrdering (ebbp, count); /* depthfirst */
333 return 0;
336 /*-----------------------------------------------------------------*/
337 /* computeDFOrdering - computes the depth first ordering of the */
338 /* flowgraph */
339 /*-----------------------------------------------------------------*/
340 static void
341 computeDFOrdering (eBBlock * ebbp, int *count)
344 ebbp->visited = 1;
345 /* for each successor that is not visited */
346 applyToSet (ebbp->succList, DFOrdering, count);
348 /* set the depth first number */
349 ebbp->dfnum = *count;
350 *count -= 1;
353 /*-----------------------------------------------------------------*/
354 /* disconBBlock - removes all control flow links for a block */
355 /*-----------------------------------------------------------------*/
356 void
357 disconBBlock (eBBlock * ebp, ebbIndex * ebbi)
359 /* mark this block as noPath & recompute control flow */
360 ebp->noPath = 1;
361 computeControlFlow (ebbi);
364 /*-----------------------------------------------------------------*/
365 /* markNoPath - marks those blocks which cannot be reached from top */
366 /*-----------------------------------------------------------------*/
367 static void
368 markNoPath (ebbIndex * ebbi)
370 eBBlock ** ebbs = ebbi->bbOrder;
371 int count = ebbi->count;
372 int i;
374 /* for all blocks if the visited flag is not set : then there */
375 /* is no path from _entry to this block push them down in the */
376 /* depth first order */
377 for (i = 0; i < count; i++)
378 if (!ebbs[i]->visited)
379 ebbs[i]->noPath = 1;
382 /*-----------------------------------------------------------------*/
383 /* dfNumCompare - used by qsort to sort by dfNumber */
384 /*-----------------------------------------------------------------*/
385 int
386 dfNumCompare (const void *a, const void *b)
388 const eBBlock *const *i = a;
389 const eBBlock *const *j = b;
391 if ((*i)->dfnum > (*j)->dfnum)
392 return 1;
394 if ((*i)->dfnum < (*j)->dfnum)
395 return -1;
397 return 0;
400 /*-----------------------------------------------------------------*/
401 /* computeControlFlow - does the control flow computation */
402 /*-----------------------------------------------------------------*/
403 void
404 computeControlFlow (ebbIndex * ebbi)
406 eBBlock ** ebbs = ebbi->bbOrder;
407 int dfCount = ebbi->count;
408 int i;
410 /* initialise some things */
412 for (i = 0; i < ebbi->count; i++)
414 deleteSet (&ebbs[i]->predList);
415 freeBitVect (ebbs[i]->domVect); ebbs[i]->domVect = NULL;
416 deleteSet (&ebbs[i]->succList);
417 freeBitVect (ebbs[i]->succVect); ebbs[i]->succVect = NULL;
418 ebbs[i]->visited = 0;
419 ebbs[i]->dfnum = 0;
422 setToNull ((void *) &graphEdges);
423 /* this will put in the */
424 /* successor information for each blk */
425 eBBSuccessors (ebbi);
427 /* compute the depth first ordering */
428 computeDFOrdering (ebbi->bbOrder[0], &dfCount);
430 /* mark blocks with no paths to them */
431 markNoPath (ebbi);
433 /* with the depth first info in place */
434 /* add the predecessors for the blocks */
435 eBBPredecessors (ebbi);
437 /* compute the dominance graph */
438 computeDominance (ebbi);
440 /* sort it by dfnumber */
441 if (!ebbi->dfOrder)
442 ebbi->dfOrder = Safe_alloc ((ebbi->count+1) * sizeof (eBBlock *));
443 for (i = 0; i < (ebbi->count+1); i++)
445 ebbi->dfOrder[i] = ebbi->bbOrder[i];
448 qsort (ebbi->dfOrder, ebbi->count, sizeof (eBBlock *), dfNumCompare);
452 /*-----------------------------------------------------------------*/
453 /* returnAtEnd - returns 1 if Basic Block has a return at the end */
454 /* of it */
455 /*-----------------------------------------------------------------*/
456 int returnAtEnd (eBBlock *ebp)
458 /* case 1.
459 This basic block ends in a return statement
461 if (ebp->ech && ebp->ech->op == RETURN) return 1;
463 /* case 2.
464 This basic block has only one successor and that
465 successor has only one return statement
467 if (elementsInSet(ebp->succList) == 1) {
468 eBBlock *succ = setFirstItem(ebp->succList);
469 /* could happen for dummy blocks */
470 if (!succ->sch || !succ->ech) return 0;
472 /* first iCode is a return */
473 if (succ->sch->op == RETURN) return 2;
475 /* or first iCode is a label & the next &
476 last icode is a return */
477 if (succ->sch->op == LABEL && succ->sch->next == succ->ech &&
478 succ->ech->op == RETURN ) return 2;
481 return 0;