authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-04 17:43:23-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-04 17:43:23-05:00
log3e3d46488419445c1b3a4b1da384f084c71cddb0
tree4db754e6b5986fe676664a2427342dfac608c56f
parent2e3e8d0c74d7b5aac3d1996bc8ce9735f2d3f8c6
signaturelock-open Commit is signed but in an unrecognized format.

`@TypeOf` avoids heap allocation for only 1 parameter


3 files changed, 48 insertions(+), 21 deletions(-)

src/all_types.hpp+4-1
...@@ -3286,7 +3286,10 @@ struct IrInstGenUnreachable {...@@ -3286,7 +3286,10 @@ struct IrInstGenUnreachable {
3286struct IrInstSrcTypeOf {3286struct IrInstSrcTypeOf {
3287 IrInstSrc base;3287 IrInstSrc base;
32883288
3289 IrInstSrc **values;3289 union {
3290 IrInstSrc *scalar; // value_count == 1
3291 IrInstSrc **list; // value_count > 1
3292 } value;
3290 size_t value_count;3293 size_t value_count;
3291};3294};
32923295
src/ir.cpp+38-18
...@@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi...@@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi
2766 return &instruction->base;2766 return &instruction->base;
2767}2767}
27682768
2769static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc **values, size_t value_count) {2769static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2770 IrInstSrc **values, size_t value_count)
2771{
2772 assert(value_count >= 2);
2773
2770 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);2774 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2771 instruction->values = values;2775 instruction->value.list = values;
2772 instruction->value_count = value_count;2776 instruction->value_count = value_count;
27732777
2774 for (size_t i = 0; i < value_count; i++)2778 for (size_t i = 0; i < value_count; i++)
...@@ -2777,6 +2781,15 @@ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *sour...@@ -2777,6 +2781,15 @@ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *sour
2777 return &instruction->base;2781 return &instruction->base;
2778}2782}
27792783
2784static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
2785 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2786 instruction->value.scalar = value;
2787
2788 ir_ref_instruction(value, irb->current_basic_block);
2789
2790 return &instruction->base;
2791}
2792
2780static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) {2793static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) {
2781 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node);2794 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node);
2782 instruction->is_cold = is_cold;2795 instruction->is_cold = is_cold;
...@@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN...@@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN
6045 if (fn_ref == irb->codegen->invalid_inst_src)6058 if (fn_ref == irb->codegen->invalid_inst_src)
6046 return fn_ref;6059 return fn_ref;
60476060
6048 IrInstSrc **typeof_args = heap::c_allocator.allocate<IrInstSrc*>(1);6061 IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref);
6049 typeof_args[0] = fn_ref;
6050 IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, typeof_args, 1);
60516062
6052 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);6063 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
6053 for (size_t i = 0; i < args_len; i += 1) {6064 for (size_t i = 0; i < args_len; i += 1) {
...@@ -6110,22 +6121,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -6110,22 +6121,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
61106121
6111 size_t arg_count = node->data.fn_call_expr.params.length;6122 size_t arg_count = node->data.fn_call_expr.params.length;
61126123
6113 if (arg_count < 1) {6124 IrInstSrc *type_of;
6125
6126 if (arg_count == 0) {
6114 add_node_error(irb->codegen, node,6127 add_node_error(irb->codegen, node,
6115 buf_sprintf("expected at least 1 argument, found 0"));6128 buf_sprintf("expected at least 1 argument, found 0"));
6116 return irb->codegen->invalid_inst_src;6129 return irb->codegen->invalid_inst_src;
6117 }6130 } else if (arg_count == 1) {
6131 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6132 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope);
6133 if (arg0_value == irb->codegen->invalid_inst_src)
6134 return arg0_value;
61186135
6119 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);6136 type_of = ir_build_typeof_1(irb, scope, node, arg0_value);
6120 for (size_t i = 0; i < arg_count; i += 1) {6137 } else {
6121 AstNode *arg_node = node->data.fn_call_expr.params.at(i);6138 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
6122 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);6139 for (size_t i = 0; i < arg_count; i += 1) {
6123 if (arg == irb->codegen->invalid_inst_src)6140 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
6124 return irb->codegen->invalid_inst_src;6141 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
6125 args[i] = arg;6142 if (arg == irb->codegen->invalid_inst_src)
6126 }6143 return irb->codegen->invalid_inst_src;
6144 args[i] = arg;
6145 }
61276146
6128 IrInstSrc *type_of = ir_build_typeof(irb, scope, node, args, arg_count);6147 type_of = ir_build_typeof_n(irb, scope, node, args, arg_count);
6148 }
6129 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);6149 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
6130 }6150 }
6131 case BuiltinFnIdSetCold:6151 case BuiltinFnIdSetCold:
...@@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf...@@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf
2168421704
21685 // Fast path for the common case of TypeOf with a single argument21705 // Fast path for the common case of TypeOf with a single argument
21686 if (value_count < 2) {21706 if (value_count < 2) {
21687 type_entry = typeof_instruction->values[0]->child->value->type;21707 type_entry = typeof_instruction->value.scalar->child->value->type;
21688 } else {21708 } else {
21689 IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count);21709 IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count);
21690 for (size_t i = 0; i < value_count; i += 1) {21710 for (size_t i = 0; i < value_count; i += 1) {
21691 IrInstGen *value = typeof_instruction->values[i]->child;21711 IrInstGen *value = typeof_instruction->value.list[i]->child;
21692 if (type_is_invalid(value->value->type))21712 if (type_is_invalid(value->value->type))
21693 return ira->codegen->invalid_inst_gen;21713 return ira->codegen->invalid_inst_gen;
21694 args[i] = value;21714 args[i] = value;
src/ir_print.cpp+6-2
...@@ -1118,8 +1118,12 @@ static void ir_print_vector_store_elem(IrPrintGen *irp, IrInstGenVectorStoreElem...@@ -1118,8 +1118,12 @@ static void ir_print_vector_store_elem(IrPrintGen *irp, IrInstGenVectorStoreElem
11181118
1119static void ir_print_typeof(IrPrintSrc *irp, IrInstSrcTypeOf *instruction) {1119static void ir_print_typeof(IrPrintSrc *irp, IrInstSrcTypeOf *instruction) {
1120 fprintf(irp->f, "@TypeOf(");1120 fprintf(irp->f, "@TypeOf(");
1121 for (size_t i = 0; i < instruction->value_count; i += 1) {1121 if (instruction->value_count == 1) {
1122 ir_print_other_inst_src(irp, instruction->values[i]);1122 ir_print_other_inst_src(irp, instruction->value.scalar);
1123 } else {
1124 for (size_t i = 0; i < instruction->value_count; i += 1) {
1125 ir_print_other_inst_src(irp, instruction->value.list[i]);
1126 }
1123 }1127 }
1124 fprintf(irp->f, ")");1128 fprintf(irp->f, ")");
1125}1129}