authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-22 16:18:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-22 16:18:42-04:00
log86f362ce8e878188d40393e6f2feba0c60ddbcf0
tree640b917eb1c5bbc1d4270a90bfd68905e68e7818
parent3c4b255a3c184e43e70bb8380f6e388c5594f149
signaturelock-open Commit is signed but in an unrecognized format.

elide redundant safety check when switching on tagged unions


4 files changed, 10 insertions(+), 8 deletions(-)

src/all_types.hpp+1
...@@ -2540,6 +2540,7 @@ struct IrInstructionStructFieldPtr {...@@ -2540,6 +2540,7 @@ struct IrInstructionStructFieldPtr {
2540struct IrInstructionUnionFieldPtr {2540struct IrInstructionUnionFieldPtr {
2541 IrInstruction base;2541 IrInstruction base;
25422542
2543 bool safety_check_on;
2543 bool initializing;2544 bool initializing;
2544 IrInstruction *union_ptr;2545 IrInstruction *union_ptr;
2545 TypeUnionField *field;2546 TypeUnionField *field;
src/codegen.cpp+1-1
...@@ -3890,7 +3890,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -3890,7 +3890,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
3890 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),3890 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
3891 &field->enum_field->value);3891 &field->enum_field->value);
3892 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);3892 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3893 } else if (ir_want_runtime_safety(g, &instruction->base)) {3893 } else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
3894 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");3894 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
3895 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");3895 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
38963896
src/ir.cpp+5-4
...@@ -1384,10 +1384,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As...@@ -1384,10 +1384,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As
1384}1384}
13851385
1386static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1386static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1387 IrInstruction *union_ptr, TypeUnionField *field, bool initializing)1387 IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing)
1388{1388{
1389 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);1389 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);
1390 instruction->initializing = initializing;1390 instruction->initializing = initializing;
1391 instruction->safety_check_on = safety_check_on;
1391 instruction->union_ptr = union_ptr;1392 instruction->union_ptr = union_ptr;
1392 instruction->field = field;1393 instruction->field = field;
13931394
...@@ -17514,7 +17515,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -17514,7 +17515,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
17514 IrInstruction *result;17515 IrInstruction *result;
17515 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {17516 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17516 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,17517 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
17517 source_instr->source_node, container_ptr, field, initializing);17518 source_instr->source_node, container_ptr, field, true, initializing);
17518 result->value.type = ptr_type;17519 result->value.type = ptr_type;
17519 result->value.special = ConstValSpecialStatic;17520 result->value.special = ConstValSpecialStatic;
17520 } else {17521 } else {
...@@ -17529,7 +17530,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -17529,7 +17530,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
17529 }17530 }
1753017531
17531 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,17532 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
17532 source_instr->source_node, container_ptr, field, initializing);17533 source_instr->source_node, container_ptr, field, true, initializing);
17533 result->value.type = ptr_type;17534 result->value.type = ptr_type;
17534 return result;17535 return result;
17535 }17536 }
...@@ -19005,7 +19006,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru...@@ -19005,7 +19006,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
19005 }19006 }
1900619007
19007 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,19008 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,
19008 instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false);19009 instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false);
19009 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,19010 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,
19010 target_value_ptr->value.type->data.pointer.is_const);19011 target_value_ptr->value.type->data.pointer.is_const);
19011 return result;19012 return result;
std/zig/render.zig+3-3
...@@ -939,10 +939,10 @@ fn renderExpression(...@@ -939,10 +939,10 @@ fn renderExpression(
939 }939 }
940940
941 switch (container_decl.init_arg_expr) {941 switch (container_decl.init_arg_expr) {
942 ast.Node.ContainerDecl.InitArg.None => {942 .None => {
943 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union943 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
944 },944 },
945 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {945 .Enum => |enum_tag_type| {
946 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union946 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
947947
948 const lparen = tree.nextToken(container_decl.kind_token);948 const lparen = tree.nextToken(container_decl.kind_token);
...@@ -962,7 +962,7 @@ fn renderExpression(...@@ -962,7 +962,7 @@ fn renderExpression(
962 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )962 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
963 }963 }
964 },964 },
965 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {965 .Type => |type_expr| {
966 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union966 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
967967
968 const lparen = tree.nextToken(container_decl.kind_token);968 const lparen = tree.nextToken(container_decl.kind_token);