Skip to content

Commit 39cad27

Browse files
committed
reconvergence_heuristics: fix stale versions of loop variables being used
1 parent e0a2989 commit 39cad27

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

include/shady/ir.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ Nodes filter_out_annotation(IrArena*, Nodes, const char* name);
140140
bool is_abstraction (const Node*);
141141
String get_abstraction_name (const Node* abs);
142142
String get_abstraction_name_unsafe(const Node* abs);
143+
String get_abstraction_name_safe(const Node* abs);
143144
const Node* get_abstraction_body (const Node* abs);
144145
Nodes get_abstraction_params(const Node* abs);
145146

src/shady/node.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ String get_abstraction_name_unsafe(const Node* abs) {
274274
}
275275
}
276276

277+
String get_abstraction_name_safe(const Node* abs) {
278+
String name = get_abstraction_name_unsafe(abs);
279+
if (name)
280+
return name;
281+
return format_string_interned(abs->arena, "%%%d", abs->id);
282+
}
283+
277284
const Node* get_abstraction_body(const Node* abs) {
278285
assert(is_abstraction(abs));
279286
switch (abs->tag) {

src/shady/passes/reconvergence_heuristics.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,30 @@ static void gather_exiting_nodes(LoopTree* lt, const CFNode* entry, const CFNode
6060
}
6161
}
6262

63-
static void find_unbound_vars(const Node* node, struct Dict* bound_set, struct Dict* free_set, struct List* leaking) {
63+
static bool find_in_nodes(Nodes nodes, const Node* n) {
64+
for (size_t i = 0; i < nodes.count; i++)
65+
if (nodes.nodes[i] == n)
66+
return true;
67+
return false;
68+
}
69+
70+
static void find_unbound_vars(const Node* loop_header, const Node* exiting_node, struct Dict* bound_set, struct Dict* free_set, struct List* leaking) {
6471
const Node* free_post;
6572
size_t i = 0;
73+
Nodes ignore = get_abstraction_params(loop_header);
6674
while (dict_iter(free_set, &i, &free_post, NULL)) {
6775
const Node* bound_pre;
6876
size_t j = 0;
6977
while (dict_iter(bound_set, &j, &bound_pre, NULL)) {
70-
if (bound_pre == free_post) {
78+
if (bound_pre == free_post && !find_in_nodes(ignore, bound_pre)) {
7179
goto next;
7280
}
7381
}
7482

7583
log_string(DEBUGVV, "Found variable used outside it's control scope: ");
7684
log_node(DEBUGVV, free_post);
7785
log_string(DEBUGVV, " (original:");
78-
log_node(DEBUGVV, node);
86+
log_node(DEBUGVV, exiting_node);
7987
log_string(DEBUGVV, " )\n");
8088

8189
append_list(const Node*, leaking, free_post);
@@ -117,7 +125,7 @@ static const Node* process_abstraction(Context* ctx, const Node* node) {
117125
gather_exiting_nodes(ctx->current_looptree, current_node, current_node, exiting_nodes);
118126

119127
for (size_t i = 0; i < entries_count_list(exiting_nodes); i++) {
120-
debugv_print("Node %s exits the loop headed at %s\n", get_abstraction_name(read_list(CFNode*, exiting_nodes)[i]->node), get_abstraction_name(node));
128+
debugv_print("Node %s exits the loop headed at %s\n", get_abstraction_name_safe(read_list(CFNode*, exiting_nodes)[i]->node), get_abstraction_name_safe(node));
121129
}
122130

123131
BodyBuilder* outer_bb = begin_body(arena);
@@ -148,7 +156,7 @@ static const Node* process_abstraction(Context* ctx, const Node* node) {
148156
CFNode* cf_post = cfg_lookup(ctx->fwd_cfg, exiting_node->node);
149157
CFNodeVariables* post = *find_value_dict(CFNode*, CFNodeVariables*, ctx->live_vars, cf_post);
150158
leaking[i] = new_list(const Type*);
151-
find_unbound_vars(exiting_node->node, pre->bound_set, post->free_set, leaking[i]);
159+
find_unbound_vars(node, exiting_node->node, pre->bound_set, post->free_set, leaking[i]);
152160

153161
size_t leaking_count = entries_count_list(leaking[i]);
154162
LARRAY(const Node*, exit_fwd_allocas_tmp, leaking_count);
@@ -267,7 +275,7 @@ static const Node* process_abstraction(Context* ctx, const Node* node) {
267275

268276
destroy_dict(rewriter->map);
269277
rewriter->map = old_map;
270-
register_processed_list(rewriter, get_abstraction_params(node), nparams);
278+
//register_processed_list(rewriter, get_abstraction_params(node), nparams);
271279

272280
// restore the old context
273281
for (size_t i = 0; i < exiting_nodes_count; i++) {
@@ -321,7 +329,7 @@ static const Node* process_abstraction(Context* ctx, const Node* node) {
321329
recovered_args[j] = gen_load(exit_recover_bb, exit_param_allocas[i].nodes[j]);
322330

323331
exit_numbers[i] = int32_literal(arena, i);
324-
Node* exit_bb = basic_block(arena, fn, empty(arena), format_string_arena(arena->arena, "exit_recover_values_%s", get_abstraction_name(exiting_node->node)));
332+
Node* exit_bb = basic_block(arena, fn, empty(arena), format_string_arena(arena->arena, "exit_recover_values_%s", get_abstraction_name_safe(exiting_node->node)));
325333
if (recreated_exit->tag == BasicBlock_TAG) {
326334
exit_bb->payload.basic_block.body = finish_body(exit_recover_bb, jump(arena, (Jump) {
327335
.target = recreated_exit,
@@ -502,7 +510,7 @@ static const Node* process_node(Context* ctx, const Node* node) {
502510
.yield_types = yield_types
503511
}), true), "jp_postdom");
504512

505-
Node* pre_join = basic_block(arena, fn, exit_args, format_string_arena(arena->arena, "merge_%s_%s", get_abstraction_name(ctx->current_abstraction) , get_abstraction_name(idom)));
513+
Node* pre_join = basic_block(arena, fn, exit_args, format_string_arena(arena->arena, "merge_%s_%s", get_abstraction_name_safe(ctx->current_abstraction) , get_abstraction_name_safe(idom)));
506514
pre_join->payload.basic_block.body = join(arena, (Join) {
507515
.join_point = join_token,
508516
.args = exit_args

0 commit comments

Comments
 (0)