Skip to content

Commit cc24ad2

Browse files
committed
fix LLVM front-end for the 10 trillionth time
1 parent eb37f77 commit cc24ad2

File tree

4 files changed

+59
-58
lines changed

4 files changed

+59
-58
lines changed

src/frontends/llvm/l2s.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ static bool cmp_opaque_ptr(OpaqueRef* a, OpaqueRef* b) {
3636
KeyHash hash_node(Node**);
3737
bool compare_node(Node**, Node**);
3838

39-
static const Node* write_bb_tail(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVMBasicBlockRef bb, LLVMValueRef first_instr) {
39+
static const Node* write_bb_tail(Parser* p, FnParseCtx* fn_ctx, Node* fn_or_bb, LLVMBasicBlockRef bb, LLVMValueRef first_instr) {
40+
BodyBuilder* b = begin_body(fn_or_bb->arena);
4041
LLVMValueRef instr;
4142
for (instr = first_instr; instr; instr = LLVMGetNextInstruction(instr)) {
4243
bool last = instr == LLVMGetLastInstruction(bb);
4344
if (last)
4445
assert(LLVMGetBasicBlockTerminator(bb) == instr);
4546
// LLVMDumpValue(instr);
4647
// printf("\n");
47-
EmittedInstr emitted = convert_instruction(p, fn_or_bb, b, instr);
48+
EmittedInstr emitted = convert_instruction(p, fn_ctx, fn_or_bb, b, instr);
4849
if (emitted.terminator)
4950
return finish_body(b, emitted.terminator);
5051
if (!emitted.instruction)
@@ -65,7 +66,7 @@ typedef struct {
6566
Node* nbb;
6667
} TodoBB;
6768

68-
static TodoBB prepare_bb(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
69+
static TodoBB prepare_bb(Parser* p, FnParseCtx* fn_ctx, LLVMBasicBlockRef bb) {
6970
IrArena* a = get_module_arena(p->dst);
7071
debug_print("l2s: preparing BB %s %d\n", LLVMGetBasicBlockName(bb), bb);
7172
if (get_log_level() <= DEBUG)
@@ -92,9 +93,9 @@ static TodoBB prepare_bb(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
9293
String name = LLVMGetBasicBlockName(bb);
9394
if (!name || strlen(name) == 0)
9495
name = unique_name(a, "bb");
95-
Node* nbb = basic_block(a, fn, params, name);
96+
Node* nbb = basic_block(a, fn_ctx->fn, params, name);
9697
insert_dict(LLVMValueRef, const Node*, p->map, bb, nbb);
97-
insert_dict(const Node*, struct List*, p->phis, nbb, phis);
98+
insert_dict(const Node*, struct List*, fn_ctx->phis, nbb, phis);
9899
TodoBB todo = {
99100
.bb = bb,
100101
.instr = instr,
@@ -106,15 +107,14 @@ static TodoBB prepare_bb(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
106107
}
107108
}
108109

109-
const Node* convert_basic_block(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
110+
const Node* convert_basic_block(Parser* p, FnParseCtx* fn_ctx, LLVMBasicBlockRef bb) {
110111
IrArena* a = get_module_arena(p->dst);
111112
const Node** found = find_value_dict(LLVMValueRef, const Node*, p->map, bb);
112113
if (found) return *found;
113114
// assert(false);
114115

115-
TodoBB todo = prepare_bb(p, fn, bb);
116-
BodyBuilder* bb_bb = begin_body(a);
117-
todo.nbb->payload.basic_block.body = write_bb_tail(p, todo.nbb, bb_bb, todo.bb, todo.instr);
116+
TodoBB todo = prepare_bb(p, fn_ctx, bb);
117+
todo.nbb->payload.basic_block.body = write_bb_tail(p, fn_ctx, todo.nbb, todo.bb, todo.instr);
118118
return todo.nbb;
119119
}
120120

@@ -157,20 +157,33 @@ const Node* convert_function(Parser* p, LLVMValueRef fn) {
157157
break;
158158
}
159159
Node* f = function(p->dst, params, LLVMGetValueName(fn), annotations, fn_type->payload.fn_type.return_types);
160+
FnParseCtx fn_parse_ctx = {
161+
.fn = f,
162+
.phis = new_dict(const Node*, struct List*, (HashFn) hash_node, (CmpFn) compare_node),
163+
.jumps_todo = new_list(JumpTodo),
164+
};
160165
const Node* r = fn_addr_helper(a, f);
161166
insert_dict(LLVMValueRef, const Node*, p->map, fn, r);
162167

163168
if (LLVMCountBasicBlocks(fn) > 0) {
164169
LLVMBasicBlockRef first_bb = LLVMGetEntryBasicBlock(fn);
165170
insert_dict(LLVMValueRef, const Node*, p->map, first_bb, f);
166-
BodyBuilder* b = begin_body(a);
167-
f->payload.fun.body = write_bb_tail(p, f, b, first_bb, LLVMGetFirstInstruction(first_bb));
171+
f->payload.fun.body = write_bb_tail(p, &fn_parse_ctx, f, first_bb, LLVMGetFirstInstruction(first_bb));
168172
}
169173

170-
while (entries_count_list(p->jumps_todo) > 0) {
171-
JumpTodo todo = pop_last_list(JumpTodo, p->jumps_todo);
172-
convert_jump_finish(p, f, todo);
174+
while (entries_count_list(fn_parse_ctx.jumps_todo) > 0) {
175+
JumpTodo todo = pop_last_list(JumpTodo, fn_parse_ctx.jumps_todo);
176+
convert_jump_finish(p, &fn_parse_ctx, todo);
177+
}
178+
{
179+
size_t i = 0;
180+
struct List* phis_list;
181+
while (dict_iter(fn_parse_ctx.phis, &i, NULL, &phis_list)) {
182+
destroy_list(phis_list);
183+
}
173184
}
185+
destroy_dict(fn_parse_ctx.phis);
186+
destroy_list(fn_parse_ctx.jumps_todo);
174187

175188
return r;
176189
}
@@ -247,8 +260,6 @@ bool parse_llvm_into_shady(const CompilerConfig* config, size_t len, const char*
247260
.map = new_dict(LLVMValueRef, const Node*, (HashFn) hash_opaque_ptr, (CmpFn) cmp_opaque_ptr),
248261
.annotations = new_dict(LLVMValueRef, ParsedAnnotation, (HashFn) hash_opaque_ptr, (CmpFn) cmp_opaque_ptr),
249262
.scopes = new_dict(const Node*, Nodes, (HashFn) hash_node, (CmpFn) compare_node),
250-
.phis = new_dict(const Node*, struct List*, (HashFn) hash_node, (CmpFn) compare_node),
251-
.jumps_todo = new_list(JumpTodo),
252263
.annotations_arena = new_arena(),
253264
.src = src,
254265
.dst = dirty,
@@ -283,15 +294,6 @@ bool parse_llvm_into_shady(const CompilerConfig* config, size_t len, const char*
283294
destroy_dict(p.map);
284295
destroy_dict(p.annotations);
285296
destroy_dict(p.scopes);
286-
{
287-
size_t i = 0;
288-
struct List* phis_list;
289-
while (dict_iter(p.phis, &i, NULL, &phis_list)) {
290-
destroy_list(phis_list);
291-
}
292-
}
293-
destroy_dict(p.phis);
294-
destroy_list(p.jumps_todo);
295297
destroy_arena(p.annotations_arena);
296298

297299
LLVMContextDispose(context);

src/frontends/llvm/l2s_instr.c

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,30 @@ LLVMValueRef remove_ptr_bitcasts(Parser* p, LLVMValueRef v) {
5555
return v;
5656
}
5757

58-
static const Node* convert_jump_lazy(Parser* p, Node* fn, Node* fn_or_bb, LLVMBasicBlockRef dst) {
59-
IrArena* a = fn->arena;
60-
const Node* wrapper_bb = basic_block(a, fn, empty(a), NULL);
58+
static const Node* convert_jump_lazy(Parser* p, FnParseCtx* fn_ctx, Node* fn_or_bb, LLVMBasicBlockRef dst) {
59+
IrArena* a = fn_or_bb->arena;
60+
const Node* wrapper_bb = basic_block(a, fn_ctx->fn, empty(a), NULL);
6161
JumpTodo todo = {
6262
.wrapper = wrapper_bb,
6363
.src = fn_or_bb,
6464
.dst = dst,
6565
};
66-
append_list(JumpTodo, p->jumps_todo, todo);
66+
append_list(JumpTodo, fn_ctx->jumps_todo, todo);
67+
convert_basic_block(p, fn_ctx, dst);
6768
return jump_helper(a, wrapper_bb, empty(a));
6869
}
6970

70-
void convert_jump_finish(Parser* p, Node* fn, JumpTodo todo) {
71-
IrArena* a = fn->arena;
72-
const Node* dst_bb = convert_basic_block(p, fn, todo.dst);
73-
BBPhis* phis = find_value_dict(const Node*, BBPhis, p->phis, dst_bb);
71+
void convert_jump_finish(Parser* p, FnParseCtx* fn_ctx, JumpTodo todo) {
72+
IrArena* a = fn_ctx->fn->arena;
73+
const Node* dst_bb = convert_basic_block(p, fn_ctx, todo.dst);
74+
BBPhis* phis = find_value_dict(const Node*, BBPhis, fn_ctx->phis, dst_bb);
7475
assert(phis);
7576
size_t params_count = entries_count_list(phis->list);
7677
LARRAY(const Node*, params, params_count);
7778
for (size_t i = 0; i < params_count; i++) {
7879
LLVMValueRef phi = read_list(LLVMValueRef, phis->list)[i];
7980
for (size_t j = 0; j < LLVMCountIncoming(phi); j++) {
80-
if (convert_basic_block(p, fn, LLVMGetIncomingBlock(phi, j)) == todo.src) {
81+
if (convert_basic_block(p, fn_ctx, LLVMGetIncomingBlock(phi, j)) == todo.src) {
8182
params[i] = convert_value(p, LLVMGetIncomingValue(phi, j));
8283
goto next;
8384
}
@@ -98,13 +99,8 @@ static const Type* type_untyped_ptr(const Type* untyped_ptr_t, const Type* eleme
9899
}
99100

100101
/// instr may be an instruction or a constantexpr
101-
EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVMValueRef instr) {
102-
Node* fn = fn_or_bb;
103-
if (fn) {
104-
if (fn_or_bb->tag == BasicBlock_TAG)
105-
fn = (Node*) fn_or_bb->payload.basic_block.fn;
106-
assert(fn->tag == Function_TAG);
107-
}
102+
EmittedInstr convert_instruction(Parser* p, FnParseCtx* fn_ctx, Node* fn_or_bb, BodyBuilder* b, LLVMValueRef instr) {
103+
Node* fn = fn_ctx ? fn_ctx->fn : NULL;
108104

109105
IrArena* a = get_module_arena(p->dst);
110106
int num_ops = LLVMGetNumOperands(instr);
@@ -133,13 +129,13 @@ EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVM
133129
if (!found) {
134130
Nodes str = scope_to_string(p, dbgloc);
135131
insert_dict(const Node*, Nodes, p->scopes, fn_or_bb, str);
136-
debug_print("Found a debug location for ");
137-
log_node(DEBUG, fn_or_bb);
132+
debugv_print("Found a debug location for ");
133+
log_node(DEBUGV, fn_or_bb);
138134
for (size_t i = 0; i < str.count; i++) {
139-
log_node(DEBUG, str.nodes[i]);
140-
debug_print(" -> ");
135+
log_node(DEBUGV, str.nodes[i]);
136+
debugv_print(" -> ");
141137
}
142-
debug_print(" (depth= %zu)\n", str.count);
138+
debugv_print(" (depth= %zu)\n", str.count);
143139
}
144140
}
145141
}
@@ -162,26 +158,26 @@ EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVM
162158
return (EmittedInstr) {
163159
.terminator = branch(a, (Branch) {
164160
.branch_condition = condition,
165-
.true_jump = convert_jump_lazy(p, fn, fn_or_bb, targets[0]),
166-
.false_jump = convert_jump_lazy(p, fn, fn_or_bb, targets[1]),
161+
.true_jump = convert_jump_lazy(p, fn_ctx, fn_or_bb, targets[0]),
162+
.false_jump = convert_jump_lazy(p, fn_ctx, fn_or_bb, targets[1]),
167163
})
168164
};
169165
} else {
170166
assert(n_targets == 1);
171167
return (EmittedInstr) {
172-
.terminator = convert_jump_lazy(p, fn, fn_or_bb, targets[0])
168+
.terminator = convert_jump_lazy(p, fn_ctx, fn_or_bb, targets[0])
173169
};
174170
}
175171
}
176172
case LLVMSwitch: {
177173
const Node* inspectee = convert_value(p, LLVMGetOperand(instr, 0));
178-
const Node* default_jump = convert_jump_lazy(p, fn, fn_or_bb, LLVMGetOperand(instr, 1));
174+
const Node* default_jump = convert_jump_lazy(p, fn_ctx, fn_or_bb, LLVMGetOperand(instr, 1));
179175
int n_targets = LLVMGetNumOperands(instr) / 2 - 1;
180176
LARRAY(const Node*, targets, n_targets);
181177
LARRAY(const Node*, literals, n_targets);
182178
for (size_t i = 0; i < n_targets; i++) {
183179
literals[i] = convert_value(p, LLVMGetOperand(instr, i * 2 + 2));
184-
targets[i] = convert_jump_lazy(p, fn, fn_or_bb, LLVMGetOperand(instr, i * 2 + 3));
180+
targets[i] = convert_jump_lazy(p, fn_ctx, fn_or_bb, LLVMGetOperand(instr, i * 2 + 3));
185181
}
186182
return (EmittedInstr) {
187183
.terminator = br_switch(a, (Switch) {

src/frontends/llvm/l2s_private.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ typedef struct {
1616
struct Dict* map;
1717
struct Dict* annotations;
1818
struct Dict* scopes;
19-
struct Dict* phis;
20-
struct List* jumps_todo;
2119
Arena* annotations_arena;
2220
LLVMModuleRef src;
2321
Module* dst;
2422
} Parser;
2523

24+
typedef struct {
25+
Node* fn;
26+
struct Dict* phis;
27+
struct List* jumps_todo;
28+
} FnParseCtx;
29+
2630
#ifndef LLVM_VERSION_MAJOR
2731
#error "Missing LLVM_VERSION_MAJOR"
2832
#else
@@ -47,7 +51,7 @@ const Type* convert_type(Parser* p, LLVMTypeRef t);
4751
const Node* convert_metadata(Parser* p, LLVMMetadataRef meta);
4852
const Node* convert_global(Parser* p, LLVMValueRef global);
4953
const Node* convert_function(Parser* p, LLVMValueRef fn);
50-
const Node* convert_basic_block(Parser* p, Node* fn, LLVMBasicBlockRef bb);
54+
const Node* convert_basic_block(Parser* p, FnParseCtx* fn_ctx, LLVMBasicBlockRef bb);
5155

5256
typedef struct {
5357
const Node* terminator;
@@ -65,9 +69,8 @@ typedef struct {
6569
LLVMBasicBlockRef dst;
6670
} JumpTodo;
6771

68-
void convert_jump_finish(Parser* p, Node* fn, JumpTodo todo);
69-
70-
EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVMValueRef instr);
72+
void convert_jump_finish(Parser* p, FnParseCtx*, JumpTodo todo);
73+
EmittedInstr convert_instruction(Parser* p, FnParseCtx*, Node* fn_or_bb, BodyBuilder* b, LLVMValueRef instr);
7174

7275
Nodes scope_to_string(Parser* p, LLVMMetadataRef dbgloc);
7376

src/frontends/llvm/l2s_value.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const Node* convert_value(Parser* p, LLVMValueRef v) {
8585
r = ref_decl_helper(a, decl);
8686
insert_dict(LLVMTypeRef, const Type*, p->map, v, r);
8787
BodyBuilder* bb = begin_body(a);
88-
EmittedInstr emitted = convert_instruction(p, NULL, bb, v);
88+
EmittedInstr emitted = convert_instruction(p, NULL, NULL, bb, v);
8989
Nodes types = singleton(t);
9090
decl->payload.constant.instruction = bind_last_instruction_and_wrap_in_block_explicit_return_types(bb, emitted.instruction, &types);
9191
return r;

0 commit comments

Comments
 (0)