Skip to content

Commit e0a2989

Browse files
committed
l2s: rewrite bb in visiting order, do jumps later
1 parent d34bfea commit e0a2989

File tree

3 files changed

+51
-45
lines changed

3 files changed

+51
-45
lines changed

src/frontends/llvm/l2s.c

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,9 @@ typedef struct {
6565
Node* nbb;
6666
} TodoBB;
6767

68-
const Node* convert_basic_block(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
69-
const Node** found = find_value_dict(LLVMValueRef, const Node*, p->map, bb);
70-
if (found) return *found;
71-
assert(false);
72-
}
73-
7468
static TodoBB prepare_bb(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
7569
IrArena* a = get_module_arena(p->dst);
76-
debug_print("l2s: converting BB %s %d\n", LLVMGetBasicBlockName(bb), bb);
70+
debug_print("l2s: preparing BB %s %d\n", LLVMGetBasicBlockName(bb), bb);
7771
if (get_log_level() <= DEBUG)
7872
LLVMDumpValue(bb);
7973

@@ -112,6 +106,18 @@ static TodoBB prepare_bb(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
112106
}
113107
}
114108

109+
const Node* convert_basic_block(Parser* p, Node* fn, LLVMBasicBlockRef bb) {
110+
IrArena* a = get_module_arena(p->dst);
111+
const Node** found = find_value_dict(LLVMValueRef, const Node*, p->map, bb);
112+
if (found) return *found;
113+
// assert(false);
114+
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);
118+
return todo.nbb;
119+
}
120+
115121
const Node* convert_function(Parser* p, LLVMValueRef fn) {
116122
if (is_llvm_intrinsic(fn)) {
117123
warn_print("Skipping unknown LLVM intrinsic function: %s\n", LLVMGetValueName(fn));
@@ -154,39 +160,16 @@ const Node* convert_function(Parser* p, LLVMValueRef fn) {
154160
const Node* r = fn_addr_helper(a, f);
155161
insert_dict(LLVMValueRef, const Node*, p->map, fn, r);
156162

157-
/*if (LLVMCountBasicBlocks(fn) > 0) {
163+
if (LLVMCountBasicBlocks(fn) > 0) {
158164
LLVMBasicBlockRef first_bb = LLVMGetEntryBasicBlock(fn);
159-
BodyBuilder* b = begin_body(a);
160165
insert_dict(LLVMValueRef, const Node*, p->map, first_bb, f);
166+
BodyBuilder* b = begin_body(a);
161167
f->payload.fun.body = write_bb_tail(p, f, b, first_bb, LLVMGetFirstInstruction(first_bb));
162-
}*/
163-
164-
if (LLVMCountBasicBlocks(fn) > 0) {
165-
struct List* todo_bbs = new_list(TodoBB);
166-
167-
for (LLVMBasicBlockRef bb = LLVMGetEntryBasicBlock(fn); bb; bb = LLVMGetNextBasicBlock(bb)) {
168-
if (bb == LLVMGetEntryBasicBlock(fn)) {
169-
LLVMBasicBlockRef first_bb = LLVMGetEntryBasicBlock(fn);
170-
insert_dict(LLVMValueRef, const Node*, p->map, first_bb, f);
171-
} else {
172-
TodoBB todo = prepare_bb(p, f, bb);
173-
append_list(TodoBB, todo_bbs, todo);
174-
}
175-
if (bb == LLVMGetLastBasicBlock(fn))
176-
break;
177-
}
178-
179-
LLVMBasicBlockRef first_bb = LLVMGetEntryBasicBlock(fn);
180-
BodyBuilder* entry_bb = begin_body(a);
181-
f->payload.fun.body = write_bb_tail(p, f, entry_bb, first_bb, LLVMGetFirstInstruction(first_bb));
182-
183-
for (size_t i = 0; i < entries_count_list(todo_bbs); i++) {
184-
TodoBB todo = read_list(TodoBB, todo_bbs)[i];
185-
BodyBuilder* bb = begin_body(a);
186-
todo.nbb->payload.basic_block.body = write_bb_tail(p, todo.nbb, bb, todo.bb, todo.instr);
187-
}
168+
}
188169

189-
destroy_list(todo_bbs);
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);
190173
}
191174

192175
return r;
@@ -265,6 +248,7 @@ bool parse_llvm_into_shady(const CompilerConfig* config, size_t len, const char*
265248
.annotations = new_dict(LLVMValueRef, ParsedAnnotation, (HashFn) hash_opaque_ptr, (CmpFn) cmp_opaque_ptr),
266249
.scopes = new_dict(const Node*, Nodes, (HashFn) hash_node, (CmpFn) compare_node),
267250
.phis = new_dict(const Node*, struct List*, (HashFn) hash_node, (CmpFn) compare_node),
251+
.jumps_todo = new_list(JumpTodo),
268252
.annotations_arena = new_arena(),
269253
.src = src,
270254
.dst = dirty,
@@ -307,6 +291,7 @@ bool parse_llvm_into_shady(const CompilerConfig* config, size_t len, const char*
307291
}
308292
}
309293
destroy_dict(p.phis);
294+
destroy_list(p.jumps_todo);
310295
destroy_arena(p.annotations_arena);
311296

312297
LLVMContextDispose(context);

src/frontends/llvm/l2s_instr.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,37 @@ LLVMValueRef remove_ptr_bitcasts(Parser* p, LLVMValueRef v) {
5555
return v;
5656
}
5757

58-
static const Node* convert_jump(Parser* p, Node* fn, Node* fn_or_bb, LLVMBasicBlockRef dst) {
58+
static const Node* convert_jump_lazy(Parser* p, Node* fn, Node* fn_or_bb, LLVMBasicBlockRef dst) {
5959
IrArena* a = fn->arena;
60-
const Node* dst_bb = convert_basic_block(p, fn, dst);
60+
const Node* wrapper_bb = basic_block(a, fn, empty(a), NULL);
61+
JumpTodo todo = {
62+
.wrapper = wrapper_bb,
63+
.src = fn_or_bb,
64+
.dst = dst,
65+
};
66+
append_list(JumpTodo, p->jumps_todo, todo);
67+
return jump_helper(a, wrapper_bb, empty(a));
68+
}
69+
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);
6173
BBPhis* phis = find_value_dict(const Node*, BBPhis, p->phis, dst_bb);
6274
assert(phis);
6375
size_t params_count = entries_count_list(phis->list);
6476
LARRAY(const Node*, params, params_count);
6577
for (size_t i = 0; i < params_count; i++) {
6678
LLVMValueRef phi = read_list(LLVMValueRef, phis->list)[i];
6779
for (size_t j = 0; j < LLVMCountIncoming(phi); j++) {
68-
if (convert_basic_block(p, fn, LLVMGetIncomingBlock(phi, j)) == fn_or_bb) {
80+
if (convert_basic_block(p, fn, LLVMGetIncomingBlock(phi, j)) == todo.src) {
6981
params[i] = convert_value(p, LLVMGetIncomingValue(phi, j));
7082
goto next;
7183
}
7284
}
7385
assert(false && "failed to find the appropriate source");
7486
next: continue;
7587
}
76-
return jump_helper(a, dst_bb, nodes(a, params_count, params));
88+
todo.wrapper->payload.basic_block.body = jump_helper(a, dst_bb, nodes(a, params_count, params));
7789
}
7890

7991
static const Type* type_untyped_ptr(const Type* untyped_ptr_t, const Type* element_type) {
@@ -150,26 +162,26 @@ EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVM
150162
return (EmittedInstr) {
151163
.terminator = branch(a, (Branch) {
152164
.branch_condition = condition,
153-
.true_jump = convert_jump(p, fn, fn_or_bb, targets[0]),
154-
.false_jump = convert_jump(p, fn, fn_or_bb, targets[1]),
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]),
155167
})
156168
};
157169
} else {
158170
assert(n_targets == 1);
159171
return (EmittedInstr) {
160-
.terminator = convert_jump(p, fn, fn_or_bb, targets[0])
172+
.terminator = convert_jump_lazy(p, fn, fn_or_bb, targets[0])
161173
};
162174
}
163175
}
164176
case LLVMSwitch: {
165177
const Node* inspectee = convert_value(p, LLVMGetOperand(instr, 0));
166-
const Node* default_jump = convert_jump(p, fn, fn_or_bb, LLVMGetOperand(instr, 1));
178+
const Node* default_jump = convert_jump_lazy(p, fn, fn_or_bb, LLVMGetOperand(instr, 1));
167179
int n_targets = LLVMGetNumOperands(instr) / 2 - 1;
168180
LARRAY(const Node*, targets, n_targets);
169181
LARRAY(const Node*, literals, n_targets);
170182
for (size_t i = 0; i < n_targets; i++) {
171183
literals[i] = convert_value(p, LLVMGetOperand(instr, i * 2 + 2));
172-
targets[i] = convert_jump(p, fn, fn_or_bb, LLVMGetOperand(instr, i * 2 + 3));
184+
targets[i] = convert_jump_lazy(p, fn, fn_or_bb, LLVMGetOperand(instr, i * 2 + 3));
173185
}
174186
return (EmittedInstr) {
175187
.terminator = br_switch(a, (Switch) {

src/frontends/llvm/l2s_private.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ typedef struct {
1717
struct Dict* annotations;
1818
struct Dict* scopes;
1919
struct Dict* phis;
20+
struct List* jumps_todo;
2021
Arena* annotations_arena;
2122
LLVMModuleRef src;
2223
Module* dst;
@@ -58,6 +59,14 @@ typedef struct {
5859
struct List* list;
5960
} BBPhis;
6061

62+
typedef struct {
63+
Node* wrapper;
64+
Node* src;
65+
LLVMBasicBlockRef dst;
66+
} JumpTodo;
67+
68+
void convert_jump_finish(Parser* p, Node* fn, JumpTodo todo);
69+
6170
EmittedInstr convert_instruction(Parser* p, Node* fn_or_bb, BodyBuilder* b, LLVMValueRef instr);
6271

6372
Nodes scope_to_string(Parser* p, LLVMMetadataRef dbgloc);

0 commit comments

Comments
 (0)