authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-19 17:10:29-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-19 17:10:29-04:00
logcaaeab9882c84007b7ed84159a9736b06cb1d899
treecedbc24f79098988c234053456d89eeab6a75fbd
parenteb26aeb1e527b5f43f7f789d3a995dca8c73e2e9

add setEvalBranchQuota builtin function


6 files changed, 84 insertions(+), 1 deletions(-)

README.md+1-1
...@@ -137,4 +137,4 @@ produced .gcov files....@@ -137,4 +137,4 @@ produced .gcov files.
137 * Runtime crashes are better than bugs.137 * Runtime crashes are better than bugs.
138 * Compile errors are better than runtime crashes.138 * Compile errors are better than runtime crashes.
139 * Minimize energy spent on coding style.139 * Minimize energy spent on coding style.
140 * Together we serve the users.140 * Together we serve the end users.
src/all_types.hpp+8
...@@ -1232,6 +1232,7 @@ enum BuiltinFnId {...@@ -1232,6 +1232,7 @@ enum BuiltinFnId {
1232 BuiltinFnIdTypeId,1232 BuiltinFnIdTypeId,
1233 BuiltinFnIdShlExact,1233 BuiltinFnIdShlExact,
1234 BuiltinFnIdShrExact,1234 BuiltinFnIdShrExact,
1235 BuiltinFnIdSetEvalBranchQuota,
1235};1236};
12361237
1237struct BuiltinFnEntry {1238struct BuiltinFnEntry {
...@@ -1834,6 +1835,7 @@ enum IrInstructionId {...@@ -1834,6 +1835,7 @@ enum IrInstructionId {
1834 IrInstructionIdFieldParentPtr,1835 IrInstructionIdFieldParentPtr,
1835 IrInstructionIdOffsetOf,1836 IrInstructionIdOffsetOf,
1836 IrInstructionIdTypeId,1837 IrInstructionIdTypeId,
1838 IrInstructionIdSetEvalBranchQuota,
1837};1839};
18381840
1839struct IrInstruction {1841struct IrInstruction {
...@@ -2603,6 +2605,12 @@ struct IrInstructionTypeId {...@@ -2603,6 +2605,12 @@ struct IrInstructionTypeId {
2603 IrInstruction *type_value;2605 IrInstruction *type_value;
2604};2606};
26052607
2608struct IrInstructionSetEvalBranchQuota {
2609 IrInstruction base;
2610
2611 IrInstruction *new_quota;
2612};
2613
2606static const size_t slice_ptr_index = 0;2614static const size_t slice_ptr_index = 0;
2607static const size_t slice_len_index = 1;2615static const size_t slice_len_index = 1;
26082616
src/codegen.cpp+2
...@@ -3173,6 +3173,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3173,6 +3173,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3173 case IrInstructionIdSwitchVar:3173 case IrInstructionIdSwitchVar:
3174 case IrInstructionIdOffsetOf:3174 case IrInstructionIdOffsetOf:
3175 case IrInstructionIdTypeId:3175 case IrInstructionIdTypeId:
3176 case IrInstructionIdSetEvalBranchQuota:
3176 zig_unreachable();3177 zig_unreachable();
3177 case IrInstructionIdReturn:3178 case IrInstructionIdReturn:
3178 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);3179 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -4635,6 +4636,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4635,6 +4636,7 @@ static void define_builtin_fns(CodeGen *g) {
4635 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);4636 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
4636 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);4637 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);
4637 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);4638 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);
4639 create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1);
4638}4640}
46394641
4640static const char *bool_to_str(bool b) {4642static const char *bool_to_str(bool b) {
src/ir.cpp+51
...@@ -549,6 +549,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) {...@@ -549,6 +549,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) {
549 return IrInstructionIdTypeId;549 return IrInstructionIdTypeId;
550}550}
551551
552static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) {
553 return IrInstructionIdSetEvalBranchQuota;
554}
555
552template<typename T>556template<typename T>
553static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {557static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
554 T *special_instruction = allocate<T>(1);558 T *special_instruction = allocate<T>(1);
...@@ -2192,6 +2196,17 @@ static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *so...@@ -2192,6 +2196,17 @@ static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *so
2192 return &instruction->base;2196 return &instruction->base;
2193}2197}
21942198
2199static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node,
2200 IrInstruction *new_quota)
2201{
2202 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node);
2203 instruction->new_quota = new_quota;
2204
2205 ir_ref_instruction(new_quota, irb->current_basic_block);
2206
2207 return &instruction->base;
2208}
2209
2195static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {2210static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
2196 return nullptr;2211 return nullptr;
2197}2212}
...@@ -2881,6 +2896,13 @@ static IrInstruction *ir_instruction_typeid_get_dep(IrInstructionTypeId *instruc...@@ -2881,6 +2896,13 @@ static IrInstruction *ir_instruction_typeid_get_dep(IrInstructionTypeId *instruc
2881 }2896 }
2882}2897}
28832898
2899static IrInstruction *ir_instruction_setevalbranchquota_get_dep(IrInstructionSetEvalBranchQuota *instruction, size_t index) {
2900 switch (index) {
2901 case 0: return instruction->new_quota;
2902 default: return nullptr;
2903 }
2904}
2905
2884static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {2906static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
2885 switch (instruction->id) {2907 switch (instruction->id) {
2886 case IrInstructionIdInvalid:2908 case IrInstructionIdInvalid:
...@@ -3075,6 +3097,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -3075,6 +3097,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
3075 return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index);3097 return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index);
3076 case IrInstructionIdTypeId:3098 case IrInstructionIdTypeId:
3077 return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index);3099 return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index);
3100 case IrInstructionIdSetEvalBranchQuota:
3101 return ir_instruction_setevalbranchquota_get_dep((IrInstructionSetEvalBranchQuota *) instruction, index);
3078 }3102 }
3079 zig_unreachable();3103 zig_unreachable();
3080}3104}
...@@ -4481,6 +4505,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4481,6 +4505,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44814505
4482 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);4506 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4483 }4507 }
4508 case BuiltinFnIdSetEvalBranchQuota:
4509 {
4510 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4511 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4512 if (arg0_value == irb->codegen->invalid_instruction)
4513 return arg0_value;
4514
4515 return ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4516 }
4484 }4517 }
4485 zig_unreachable();4518 zig_unreachable();
4486}4519}
...@@ -12432,6 +12465,21 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,...@@ -12432,6 +12465,21 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
12432 return result_type;12465 return result_type;
12433}12466}
1243412467
12468static TypeTableEntry *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
12469 IrInstructionSetEvalBranchQuota *instruction)
12470{
12471 uint64_t new_quota;
12472 if (!ir_resolve_usize(ira, instruction->new_quota->other, &new_quota))
12473 return ira->codegen->builtin_types.entry_invalid;
12474
12475 if (new_quota > ira->new_irb.exec->backward_branch_quota) {
12476 ira->new_irb.exec->backward_branch_quota = new_quota;
12477 }
12478
12479 ir_build_const_from(ira, &instruction->base);
12480 return ira->codegen->builtin_types.entry_void;
12481}
12482
12435static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {12483static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {
12436 IrInstruction *type_value = instruction->type_value->other;12484 IrInstruction *type_value = instruction->type_value->other;
12437 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);12485 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
...@@ -14249,6 +14297,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -14249,6 +14297,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
14249 return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);14297 return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);
14250 case IrInstructionIdTypeId:14298 case IrInstructionIdTypeId:
14251 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);14299 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
14300 case IrInstructionIdSetEvalBranchQuota:
14301 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction);
14252 case IrInstructionIdMaybeWrap:14302 case IrInstructionIdMaybeWrap:
14253 case IrInstructionIdErrWrapCode:14303 case IrInstructionIdErrWrapCode:
14254 case IrInstructionIdErrWrapPayload:14304 case IrInstructionIdErrWrapPayload:
...@@ -14365,6 +14415,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -14365,6 +14415,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
14365 case IrInstructionIdSetGlobalSection:14415 case IrInstructionIdSetGlobalSection:
14366 case IrInstructionIdSetGlobalLinkage:14416 case IrInstructionIdSetGlobalLinkage:
14367 case IrInstructionIdPanic:14417 case IrInstructionIdPanic:
14418 case IrInstructionIdSetEvalBranchQuota:
14368 return true;14419 return true;
14369 case IrInstructionIdPhi:14420 case IrInstructionIdPhi:
14370 case IrInstructionIdUnOp:14421 case IrInstructionIdUnOp:
src/ir_print.cpp+9
...@@ -910,6 +910,12 @@ static void ir_print_type_id(IrPrint *irp, IrInstructionTypeId *instruction) {...@@ -910,6 +910,12 @@ static void ir_print_type_id(IrPrint *irp, IrInstructionTypeId *instruction) {
910 fprintf(irp->f, ")");910 fprintf(irp->f, ")");
911}911}
912912
913static void ir_print_set_eval_branch_quota(IrPrint *irp, IrInstructionSetEvalBranchQuota *instruction) {
914 fprintf(irp->f, "@setEvalBranchQuota(");
915 ir_print_other_instruction(irp, instruction->new_quota);
916 fprintf(irp->f, ")");
917}
918
913static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {919static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
914 ir_print_prefix(irp, instruction);920 ir_print_prefix(irp, instruction);
915 switch (instruction->id) {921 switch (instruction->id) {
...@@ -1200,6 +1206,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1200,6 +1206,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1200 case IrInstructionIdTypeId:1206 case IrInstructionIdTypeId:
1201 ir_print_type_id(irp, (IrInstructionTypeId *)instruction);1207 ir_print_type_id(irp, (IrInstructionTypeId *)instruction);
1202 break;1208 break;
1209 case IrInstructionIdSetEvalBranchQuota:
1210 ir_print_set_eval_branch_quota(irp, (IrInstructionSetEvalBranchQuota *)instruction);
1211 break;
1203 }1212 }
1204 fprintf(irp->f, "\n");1213 fprintf(irp->f, "\n");
1205}1214}
test/cases/eval.zig+13
...@@ -342,3 +342,16 @@ test "const global shares pointer with other same one" {...@@ -342,3 +342,16 @@ test "const global shares pointer with other same one" {
342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {
343 assert(ptr1 == ptr2);343 assert(ptr1 == ptr2);
344}344}
345
346test "@setEvalBranchQuota" {
347 comptime {
348 // 1001 for the loop and then 1 more for the assert fn call
349 @setEvalBranchQuota(1002);
350 var i = 0;
351 var sum = 0;
352 while (i < 1001) : (i += 1) {
353 sum += i;
354 }
355 assert(sum == 500500);
356 }
357}