8 int iddeclcmp(const void *l
, const void *r
)
10 return strcmp((char *)l
, (*(struct decl
**)r
)->data
.dfun
->ident
);
13 struct list
*edges_expr(int ndecls
, struct decl
**decls
, void *parent
,
14 struct expr
*expr
, struct list
*l
)
20 l
= edges_expr(ndecls
, decls
, parent
, expr
->data
.ebinop
.l
, l
);
21 l
= edges_expr(ndecls
, decls
, parent
, expr
->data
.ebinop
.r
, l
);
28 for(int i
= 0; i
<expr
->data
.efuncall
.nargs
; i
++)
29 l
= edges_expr(ndecls
, decls
, parent
,
30 expr
->data
.efuncall
.args
[i
], l
);
31 struct decl
**to
= bsearch(expr
->data
.efuncall
.ident
, decls
,
32 ndecls
, sizeof(struct decl
*), iddeclcmp
);
34 fprintf(stderr
, "calling an unknown function\n");
36 struct edge
*edge
= safe_malloc(sizeof(struct edge
));
38 edge
->to
= (void *)*to
;
39 l
= list_cons(edge
, l
);
49 l
= edges_expr(ndecls
, decls
, parent
,
50 expr
->data
.etuple
.left
, l
);
51 l
= edges_expr(ndecls
, decls
, parent
,
52 expr
->data
.etuple
.right
, l
);
57 l
= edges_expr(ndecls
, decls
, parent
, expr
->data
.eunop
.l
, l
);
60 die("Unsupported expr node\n");
65 struct list
*edges_stmt(int ndecls
, struct decl
**decls
, void *parent
,
66 struct stmt
*stmt
, struct list
*l
)
70 l
= edges_expr(ndecls
, decls
, parent
,
71 stmt
->data
.sassign
.expr
, l
);
74 l
= edges_expr(ndecls
, decls
, parent
, stmt
->data
.sif
.pred
, l
);
75 for (int i
= 0; i
<stmt
->data
.sif
.nthen
; i
++)
76 l
= edges_stmt(ndecls
, decls
, parent
,
77 stmt
->data
.sif
.then
[i
], l
);
78 for (int i
= 0; i
<stmt
->data
.sif
.nels
; i
++)
79 l
= edges_stmt(ndecls
, decls
, parent
,
80 stmt
->data
.sif
.els
[i
], l
);
83 l
= edges_expr(ndecls
, decls
, parent
, stmt
->data
.sreturn
, l
);
86 l
= edges_expr(ndecls
, decls
, parent
, stmt
->data
.sexpr
, l
);
89 l
= edges_expr(ndecls
, decls
, parent
,
90 stmt
->data
.svardecl
->expr
, l
);
93 l
= edges_expr(ndecls
, decls
, parent
,
94 stmt
->data
.swhile
.pred
, l
);
95 for (int i
= 0; i
<stmt
->data
.swhile
.nbody
; i
++)
96 l
= edges_stmt(ndecls
, decls
, parent
,
97 stmt
->data
.swhile
.body
[i
], l
);
100 die("Unsupported stmt node\n");
105 int declcmp(const void *l
, const void *r
)
107 return (*(struct decl
**)l
)->type
- (*(struct decl
**)r
)->type
;
110 struct ast
*ast_scc(struct ast
*ast
)
112 //Sort so that the functions are at the end
113 qsort(ast
->decls
, ast
->ndecls
, sizeof(struct decl
*), declcmp
);
114 //Index of the first function
116 for (ffun
= 0; ffun
<ast
->ndecls
; ffun
++)
117 if (ast
->decls
[ffun
]->type
== dfundecl
)
119 //Number of functions
120 int nfun
= ast
->ndecls
-ffun
;
122 //Calculate the edges
123 struct decl
**fundecls
= ast
->decls
+ffun
;
124 struct list
*edges
= NULL
;
125 for (int i
= 0; i
<nfun
; i
++)
126 for (int j
= 0; j
<fundecls
[i
]->data
.dfun
->nbody
; j
++)
127 edges
= edges_stmt(nfun
, fundecls
, fundecls
[i
],
128 fundecls
[i
]->data
.dfun
->body
[j
], edges
);
130 struct edge
**edgedata
= (struct edge
**)
131 list_to_array(edges
, &nedges
, false);
133 // Do tarjan's and convert back into the declaration list
135 struct components
*cs
= tarjans(nfun
, (void **)fundecls
, nedges
, edgedata
, &err
);
138 die("malformed edges in tarjan's????");
145 struct decl
*d
= safe_malloc(sizeof(struct decl
));
148 d
->data
.dcomp
.ndecls
= c
->nnodes
;
149 d
->data
.dcomp
.decls
= safe_malloc(
150 c
->nnodes
*sizeof(struct fundecl
*));
151 for (int i
= 0; i
<c
->nnodes
; i
++)
152 d
->data
.dcomp
.decls
[i
] =
153 ((struct decl
*)c
->nodes
[i
])->data
.dfun
;
156 d
->data
.dfun
= ((struct decl
*)c
->nodes
[0])->data
.dfun
;
163 for (int i
= 0; i
<nedges
; i
++)
166 components_free(cs
, free
);