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
signature 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 {
32863286struct IrInstSrcTypeOf {
32873287 IrInstSrc base;
32883288
3289 IrInstSrc **values;
3289 union {
3290 IrInstSrc *scalar; // value_count == 1
3291 IrInstSrc **list; // value_count > 1
3292 } value;
32903293 size_t value_count;
32913294};
32923295
src/ir.cpp+38-18
......@@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi
27662766 return &instruction->base;
27672767}
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
27702774 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2771 instruction->values = values;
2775 instruction->value.list = values;
27722776 instruction->value_count = value_count;
27732777
27742778 for (size_t i = 0; i < value_count; i++)
......@@ -2777,6 +2781,15 @@ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *sour
27772781 return &instruction->base;
27782782}
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
27802793static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) {
27812794 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node);
27822795 instruction->is_cold = is_cold;
......@@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN
60456058 if (fn_ref == irb->codegen->invalid_inst_src)
60466059 return fn_ref;
60476060
6048 IrInstSrc **typeof_args = heap::c_allocator.allocate<IrInstSrc*>(1);
6049 typeof_args[0] = fn_ref;
6050 IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, typeof_args, 1);
6061 IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref);
60516062
60526063 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
60536064 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
61106121
61116122 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) {
61146127 add_node_error(irb->codegen, node,
61156128 buf_sprintf("expected at least 1 argument, found 0"));
61166129 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);
6120 for (size_t i = 0; i < arg_count; i += 1) {
6121 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
6122 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
6123 if (arg == irb->codegen->invalid_inst_src)
6124 return irb->codegen->invalid_inst_src;
6125 args[i] = arg;
6126 }
6136 type_of = ir_build_typeof_1(irb, scope, node, arg0_value);
6137 } else {
6138 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
6139 for (size_t i = 0; i < arg_count; i += 1) {
6140 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
6141 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
6142 if (arg == irb->codegen->invalid_inst_src)
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 }
61296149 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
61306150 }
61316151 case BuiltinFnIdSetCold:
......@@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf
2168421704
2168521705 // Fast path for the common case of TypeOf with a single argument
2168621706 if (value_count < 2) {
21687 type_entry = typeof_instruction->values[0]->child->value->type;
21707 type_entry = typeof_instruction->value.scalar->child->value->type;
2168821708 } else {
2168921709 IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count);
2169021710 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;
2169221712 if (type_is_invalid(value->value->type))
2169321713 return ira->codegen->invalid_inst_gen;
2169421714 args[i] = value;
src/ir_print.cpp+6-2
......@@ -1118,8 +1118,12 @@ static void ir_print_vector_store_elem(IrPrintGen *irp, IrInstGenVectorStoreElem
11181118
11191119static void ir_print_typeof(IrPrintSrc *irp, IrInstSrcTypeOf *instruction) {
11201120 fprintf(irp->f, "@TypeOf(");
1121 for (size_t i = 0; i < instruction->value_count; i += 1) {
1122 ir_print_other_inst_src(irp, instruction->values[i]);
1121 if (instruction->value_count == 1) {
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 }
11231127 }
11241128 fprintf(irp->f, ")");
11251129}