mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
elide redundant safety check when switching on tagged unions
This commit is contained in:
parent
3c4b255a3c
commit
86f362ce8e
@ -2540,6 +2540,7 @@ struct IrInstructionStructFieldPtr {
|
||||
struct IrInstructionUnionFieldPtr {
|
||||
IrInstruction base;
|
||||
|
||||
bool safety_check_on;
|
||||
bool initializing;
|
||||
IrInstruction *union_ptr;
|
||||
TypeUnionField *field;
|
||||
|
||||
@ -3890,7 +3890,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
|
||||
LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
|
||||
&field->enum_field->value);
|
||||
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
|
||||
} else if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
} else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
|
||||
LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
|
||||
LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
|
||||
|
||||
|
||||
@ -1384,10 +1384,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||
IrInstruction *union_ptr, TypeUnionField *field, bool initializing)
|
||||
IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing)
|
||||
{
|
||||
IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);
|
||||
instruction->initializing = initializing;
|
||||
instruction->safety_check_on = safety_check_on;
|
||||
instruction->union_ptr = union_ptr;
|
||||
instruction->field = field;
|
||||
|
||||
@ -17514,7 +17515,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
|
||||
IrInstruction *result;
|
||||
if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
|
||||
result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, container_ptr, field, initializing);
|
||||
source_instr->source_node, container_ptr, field, true, initializing);
|
||||
result->value.type = ptr_type;
|
||||
result->value.special = ConstValSpecialStatic;
|
||||
} else {
|
||||
@ -17529,7 +17530,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
|
||||
}
|
||||
|
||||
IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, container_ptr, field, initializing);
|
||||
source_instr->source_node, container_ptr, field, true, initializing);
|
||||
result->value.type = ptr_type;
|
||||
return result;
|
||||
}
|
||||
@ -19005,7 +19006,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
|
||||
}
|
||||
|
||||
IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,
|
||||
instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false);
|
||||
instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false);
|
||||
result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,
|
||||
target_value_ptr->value.type->data.pointer.is_const);
|
||||
return result;
|
||||
|
||||
@ -939,10 +939,10 @@ fn renderExpression(
|
||||
}
|
||||
|
||||
switch (container_decl.init_arg_expr) {
|
||||
ast.Node.ContainerDecl.InitArg.None => {
|
||||
.None => {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
|
||||
},
|
||||
ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
|
||||
.Enum => |enum_tag_type| {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
|
||||
|
||||
const lparen = tree.nextToken(container_decl.kind_token);
|
||||
@ -962,7 +962,7 @@ fn renderExpression(
|
||||
try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
|
||||
}
|
||||
},
|
||||
ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
|
||||
.Type => |type_expr| {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
|
||||
|
||||
const lparen = tree.nextToken(container_decl.kind_token);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user