@@ -19,6 +19,7 @@ typedef struct {
19
19
20
20
typedef struct {
21
21
Rewriter rewriter ;
22
+ const CompilerConfig * config ;
22
23
CallGraph * graph ;
23
24
const Node * old_fun ;
24
25
Node * fun ;
@@ -59,7 +60,7 @@ typedef struct {
59
60
bool can_be_eliminated ;
60
61
} FnInliningCriteria ;
61
62
62
- static FnInliningCriteria get_inlining_heuristic (CGNode * fn_node ) {
63
+ static FnInliningCriteria get_inlining_heuristic (const CompilerConfig * config , CGNode * fn_node ) {
63
64
FnInliningCriteria crit = { 0 };
64
65
65
66
CGEdge e ;
@@ -70,10 +71,8 @@ static FnInliningCriteria get_inlining_heuristic(CGNode* fn_node) {
70
71
crit .num_inlineable_calls ++ ;
71
72
}
72
73
73
- debugv_print ("%s has %d callers\n" , get_abstraction_name (fn_node -> fn ), crit .num_calls );
74
-
75
74
// a function can be inlined if it has exactly one inlineable call...
76
- if (crit .num_inlineable_calls <= 1 )
75
+ if (crit .num_inlineable_calls <= 1 || config -> optimisations . inline_everything )
77
76
crit .can_be_inlined = true;
78
77
79
78
// avoid inlining recursive things for now
@@ -91,14 +90,24 @@ static FnInliningCriteria get_inlining_heuristic(CGNode* fn_node) {
91
90
if (!is_call_safely_removable (fn_node -> fn ))
92
91
crit .can_be_eliminated = false;
93
92
93
+ debugv_print ("inlining heuristic for '%s': num_calls=%d num_inlineable_calls=%d safely_removable=%d address_leaks=%d recursive=%d inlineable=%d can_be_eliminated=%d\n" ,
94
+ get_abstraction_name (fn_node -> fn ),
95
+ crit .num_calls ,
96
+ crit .num_inlineable_calls ,
97
+ is_call_safely_removable (fn_node -> fn ),
98
+ fn_node -> is_address_captured ,
99
+ fn_node -> is_recursive ,
100
+ crit .can_be_inlined ,
101
+ crit .can_be_eliminated );
102
+
94
103
return crit ;
95
104
}
96
105
97
106
/// inlines the abstraction with supplied arguments
98
107
static const Node * inline_call (Context * ctx , const Node * ocallee , Nodes nargs , const Node * return_to ) {
99
108
assert (is_abstraction (ocallee ));
100
109
101
- log_string (DEBUG , "Inlining '%s' inside '%s'\n" , get_abstraction_name (ctx -> fun ), get_abstraction_name (ocallee ));
110
+ log_string (DEBUG , "Inlining '%s' inside '%s'\n" , get_abstraction_name (ocallee ), get_abstraction_name (ctx -> fun ));
102
111
Context inline_context = * ctx ;
103
112
inline_context .rewriter .map = clone_dict (inline_context .rewriter .map );
104
113
@@ -136,7 +145,7 @@ static const Node* process(Context* ctx, const Node* node) {
136
145
case Function_TAG : {
137
146
if (ctx -> graph ) {
138
147
CGNode * fn_node = * find_value_dict (const Node * , CGNode * , ctx -> graph -> fn2cgn , node );
139
- if (get_inlining_heuristic (fn_node ).can_be_eliminated ) {
148
+ if (get_inlining_heuristic (ctx -> config , fn_node ).can_be_eliminated ) {
140
149
debugv_print ("Eliminating %s because it has exactly one caller\n" , get_abstraction_name (fn_node -> fn ));
141
150
return NULL ;
142
151
}
@@ -166,7 +175,7 @@ static const Node* process(Context* ctx, const Node* node) {
166
175
ocallee = ignore_immediate_fn_addr (ocallee );
167
176
if (ocallee -> tag == Function_TAG ) {
168
177
CGNode * fn_node = * find_value_dict (const Node * , CGNode * , ctx -> graph -> fn2cgn , ocallee );
169
- if (get_inlining_heuristic (fn_node ).can_be_inlined && is_call_potentially_inlineable (ctx -> old_fun , ocallee )) {
178
+ if (get_inlining_heuristic (ctx -> config , fn_node ).can_be_inlined && is_call_potentially_inlineable (ctx -> old_fun , ocallee )) {
170
179
debugv_print ("Inlining call to %s\n" , get_abstraction_name (ocallee ));
171
180
Nodes nargs = rewrite_nodes (& ctx -> rewriter , oargs );
172
181
@@ -211,7 +220,7 @@ static const Node* process(Context* ctx, const Node* node) {
211
220
ocallee = ignore_immediate_fn_addr (ocallee );
212
221
if (ocallee -> tag == Function_TAG ) {
213
222
CGNode * fn_node = * find_value_dict (const Node * , CGNode * , ctx -> graph -> fn2cgn , ocallee );
214
- if (get_inlining_heuristic (fn_node ).can_be_inlined ) {
223
+ if (get_inlining_heuristic (ctx -> config , fn_node ).can_be_inlined ) {
215
224
debugv_print ("Inlining tail call to %s\n" , get_abstraction_name (ocallee ));
216
225
Nodes nargs = rewrite_nodes (& ctx -> rewriter , node -> payload .tail_call .args );
217
226
return inline_call (ctx , ocallee , nargs , NULL );
@@ -231,9 +240,10 @@ static const Node* process(Context* ctx, const Node* node) {
231
240
KeyHash hash_node (const Node * * );
232
241
bool compare_node (const Node * * , const Node * * );
233
242
234
- void opt_simplify_cf (SHADY_UNUSED const CompilerConfig * config , Module * src , Module * dst ) {
243
+ void opt_simplify_cf (const CompilerConfig * config , Module * src , Module * dst ) {
235
244
Context ctx = {
236
245
.rewriter = create_rewriter (src , dst , (RewriteNodeFn ) process ),
246
+ .config = config ,
237
247
.graph = NULL ,
238
248
.fun = NULL ,
239
249
.inlined_call = NULL ,
0 commit comments