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
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 -------------------------------------------------------------------------*/
28 static void computeDFOrdering (eBBlock
*, int *);
30 /*-----------------------------------------------------------------*/
31 /* domSetFromVect - creates a domset from the vector */
32 /*-----------------------------------------------------------------*/
34 domSetFromVect (ebbIndex
*ebbi
, bitVect
* domVect
)
42 for (i
= 0; i
< domVect
->size
; i
++)
43 if (bitVectBitValue (domVect
, i
))
44 addSet (&domSet
, ebbi
->bbOrder
[i
]);
49 /*-----------------------------------------------------------------*/
50 /* addSuccessor - will add bb to succ also add it to the pred of */
52 /*-----------------------------------------------------------------*/
54 addSuccessor (eBBlock
* thisBlock
, eBBlock
* succ
)
56 /* check for boundary conditions */
57 if (!thisBlock
|| !succ
)
60 /* add it to the succ of thisBlock */
61 addSetIfnotP (&thisBlock
->succList
, succ
);
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 /*-----------------------------------------------------------------*/
74 eBBPredecessors (ebbIndex
* ebbi
)
76 eBBlock
** ebbs
= ebbi
->bbOrder
;
77 int count
= ebbi
->count
;
80 /* for each block do */
81 for (i
= 0; i
< count
; i
++)
84 /* if there is no path to this then 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 /*-----------------------------------------------------------------*/
104 eBBSuccessors (ebbIndex
* ebbi
)
106 eBBlock
** ebbs
= ebbi
->bbOrder
;
107 int count
= ebbi
->count
;
110 /* for all the blocks do */
111 for (; i
< count
; i
++)
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 */
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
))
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
)
145 while (ebbs
[j
] && ebbs
[j
]->noPath
)
148 addSuccessor (ebbs
[i
], ebbs
[j
]); /* add it */
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 */
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
))
168 /* special case for jumptable */
169 if (ic
->op
== JUMPTABLE
)
172 for (lbl
= setFirstItem (IC_JTLABELS (ic
)); lbl
;
173 lbl
= setNextItem (IC_JTLABELS (ic
)))
174 addSuccessor (ebbs
[i
],
175 eBBWithEntryLabel (ebbi
, lbl
));
181 /* depending on the instruction operator */
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
)
193 addSuccessor (ebbs
[i
], succ
); /* add the GOTO target */
194 ic
= ic
->prev
; /* get ready to handle IFX too. */
199 case IFX
: /* conditional jump */
200 /* if true label is present */
202 succ
= eBBWithEntryLabel (ebbi
, IC_TRUE (ic
));
204 succ
= eBBWithEntryLabel (ebbi
, IC_FALSE (ic
));
207 case RETURN
: /* block with return */
208 succ
= eBBWithEntryLabel (ebbi
, returnLabel
);
212 /* if there is a successor add to the list */
213 /* if it is not already present in the list */
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 /*-----------------------------------------------------------------*/
226 computeDominance (ebbIndex
* ebbi
)
228 eBBlock
** ebbs
= ebbi
->bbOrder
;
229 int count
= ebbi
->count
;
232 /* now do the initialisation */
233 /* D(n0) := { n0 } */
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
++)
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)) */
259 for (i
= 1; i
< count
; i
++)
266 /* get the intersection of the dominance of all predecessors */
267 for (pred
= setFirstItem (ebbs
[i
]->predList
),
268 cDomVect
= (pred
? bitVectCopy (pred
->domVect
) : NULL
);
270 pred
= setNextItem (ebbs
[i
]->predList
))
272 cDomVect
= bitVectInplaceIntersect (cDomVect
, pred
->domVect
);
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
;
288 /* if no change then exit */
295 /*-----------------------------------------------------------------*/
296 /* immedDom - returns the immediate dominator of a block */
297 /*-----------------------------------------------------------------*/
299 immedDom (ebbIndex
* ebbi
, eBBlock
* ebp
)
301 /* first delete self from the list */
302 set
*iset
= domSetFromVect (ebbi
, ebp
->domVect
);
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
)))
311 for (; loop
; loop
= setNextItem (iset
))
312 if (loop
->dfnum
> idom
->dfnum
)
315 setToNull ((void *) &iset
);
320 /*-----------------------------------------------------------------*/
321 /* DFOrdering - is visited then nothing else call DFOrdering this */
322 /*-----------------------------------------------------------------*/
323 DEFSETFUNC (DFOrdering
)
325 eBBlock
*ebbp
= item
;
326 V_ARG (int *, count
);
331 computeDFOrdering (ebbp
, count
); /* depthfirst */
336 /*-----------------------------------------------------------------*/
337 /* computeDFOrdering - computes the depth first ordering of the */
339 /*-----------------------------------------------------------------*/
341 computeDFOrdering (eBBlock
* ebbp
, int *count
)
345 /* for each successor that is not visited */
346 applyToSet (ebbp
->succList
, DFOrdering
, count
);
348 /* set the depth first number */
349 ebbp
->dfnum
= *count
;
353 /*-----------------------------------------------------------------*/
354 /* disconBBlock - removes all control flow links for a block */
355 /*-----------------------------------------------------------------*/
357 disconBBlock (eBBlock
* ebp
, ebbIndex
* ebbi
)
359 /* mark this block as noPath & recompute control flow */
361 computeControlFlow (ebbi
);
364 /*-----------------------------------------------------------------*/
365 /* markNoPath - marks those blocks which cannot be reached from top */
366 /*-----------------------------------------------------------------*/
368 markNoPath (ebbIndex
* ebbi
)
370 eBBlock
** ebbs
= ebbi
->bbOrder
;
371 int count
= ebbi
->count
;
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
)
382 /*-----------------------------------------------------------------*/
383 /* dfNumCompare - used by qsort to sort by dfNumber */
384 /*-----------------------------------------------------------------*/
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
)
394 if ((*i
)->dfnum
< (*j
)->dfnum
)
400 /*-----------------------------------------------------------------*/
401 /* computeControlFlow - does the control flow computation */
402 /*-----------------------------------------------------------------*/
404 computeControlFlow (ebbIndex
* ebbi
)
406 eBBlock
** ebbs
= ebbi
->bbOrder
;
407 int dfCount
= ebbi
->count
;
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;
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 */
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 */
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 */
455 /*-----------------------------------------------------------------*/
456 int returnAtEnd (eBBlock
*ebp
)
459 This basic block ends in a return statement
461 if (ebp
->ech
&& ebp
->ech
->op
== RETURN
) return 1;
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;