Skip to content

Commit 7a77581

Browse files
committed
Use an if-else chain for a type switch on any
1 parent adcbfb7 commit 7a77581

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

src/llvm_backend_stmt.cpp

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,9 +1972,11 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
19721972
if (type_size_of(parent_base_type) == 0) {
19731973
GB_ASSERT(tag.value == nullptr);
19741974
switch_instr = LLVMBuildSwitch(p->builder, lb_const_bool(p->module, t_llvm_bool, false).value, else_block->block, cast(unsigned)num_cases);
1975-
} else {
1975+
} else if (switch_kind == TypeSwitch_Union) {
19761976
GB_ASSERT(tag.value != nullptr);
19771977
switch_instr = LLVMBuildSwitch(p->builder, tag.value, else_block->block, cast(unsigned)num_cases);
1978+
} else if (switch_kind == TypeSwitch_Any) {
1979+
// gb_printf_err("HERE!\n");
19781980
}
19791981

19801982
bool all_by_reference = false;
@@ -2025,28 +2027,38 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
20252027
}
20262028
lbValue backing_ptr = backing_data.addr;
20272029

2030+
2031+
Ast *default_clause = nullptr;
2032+
20282033
for (Ast *clause : body->stmts) {
20292034
ast_node(cc, CaseClause, clause);
20302035

20312036
Entity *case_entity = implicit_entity_of_node(clause);
2032-
lb_open_scope(p, cc->scope);
20332037

20342038
if (cc->list.count == 0) {
2035-
lb_start_block(p, default_block);
2036-
if (case_entity->flags & EntityFlag_Value) {
2037-
lb_store_type_case_implicit(p, clause, parent_value, true);
2038-
} else {
2039-
lb_store_type_case_implicit(p, clause, parent_ptr, true);
2039+
default_clause = clause;
2040+
if (switch_instr != nullptr) {
2041+
lb_open_scope(p, cc->scope);
2042+
2043+
lb_start_block(p, default_block);
2044+
if (case_entity->flags & EntityFlag_Value) {
2045+
lb_store_type_case_implicit(p, clause, parent_value, true);
2046+
} else {
2047+
lb_store_type_case_implicit(p, clause, parent_ptr, true);
2048+
}
2049+
lb_type_case_body(p, ss->label, clause, p->curr_block, done);
20402050
}
2041-
lb_type_case_body(p, ss->label, clause, p->curr_block, done);
20422051
continue;
20432052
}
20442053

2054+
lb_open_scope(p, cc->scope);
2055+
20452056
lbBlock *body = lb_create_block(p, "typeswitch.body");
20462057
if (p->debug_info != nullptr) {
20472058
LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, clause));
20482059
}
20492060

2061+
lbBlock *next_cond = nullptr;
20502062
bool saw_nil = false;
20512063
for (Ast *type_expr : cc->list) {
20522064
Type *case_type = type_of_expr(type_expr);
@@ -2064,7 +2076,16 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
20642076
}
20652077
}
20662078
GB_ASSERT(on_val.value != nullptr);
2067-
LLVMAddCase(switch_instr, on_val.value, body->block);
2079+
2080+
if (switch_instr != nullptr) {
2081+
LLVMAddCase(switch_instr, on_val.value, body->block);
2082+
} else {
2083+
next_cond = lb_create_block(p, "typeswitch.case.next");
2084+
lbValue cond = lb_emit_comp(p, Token_CmpEq, on_val, tag);
2085+
2086+
lb_emit_if(p, cond, body, next_cond);
2087+
lb_start_block(p, next_cond);
2088+
}
20682089
}
20692090

20702091

@@ -2111,6 +2132,27 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
21112132
}
21122133

21132134
lb_type_case_body(p, ss->label, clause, body, done);
2135+
2136+
if (switch_instr == nullptr) {
2137+
lb_start_block(p, next_cond);
2138+
}
2139+
}
2140+
2141+
if (default_block != nullptr && switch_instr == nullptr) {
2142+
GB_ASSERT(default_clause != nullptr);
2143+
2144+
Entity *case_entity = implicit_entity_of_node(default_clause);
2145+
ast_node(cc, CaseClause, default_clause);
2146+
2147+
lb_open_scope(p, cc->scope);
2148+
2149+
lb_start_block(p, else_block);
2150+
if (case_entity->flags & EntityFlag_Value) {
2151+
lb_store_type_case_implicit(p, default_clause, parent_value, true);
2152+
} else {
2153+
lb_store_type_case_implicit(p, default_clause, parent_ptr, true);
2154+
}
2155+
lb_type_case_body(p, ss->label, default_clause, p->curr_block, done);
21142156
}
21152157

21162158
lb_emit_jump(p, done);

0 commit comments

Comments
 (0)