Commit 7b3686861f

Andrew Kelley <andrew@ziglang.org>
2019-07-26 04:24:01
`@frameSize` works via PrefixData
1 parent 538c0cd
src/all_types.hpp
@@ -3063,7 +3063,6 @@ struct IrInstructionFrameSizeGen {
     IrInstruction base;
 
     IrInstruction *fn;
-    IrInstruction *frame_ptr;
 };
 
 enum IrOverflowOp {
src/codegen.cpp
@@ -4914,13 +4914,16 @@ static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable,
     return nullptr;
 }
 
-static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutable *executable, IrInstructionFrameSizeGen *instruction) {
+static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutable *executable,
+        IrInstructionFrameSizeGen *instruction)
+{
+    LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type;
+    LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0);
     LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);
-    LLVMValueRef frame_ptr = ir_llvm_value(g, instruction->frame_ptr);
-    LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, frame_ptr, coro_resume_index_index, "");
-    LLVMValueRef one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false);
-    LLVMBuildStore(g->builder, one, resume_index_ptr);
-    return ZigLLVMBuildCall(g->builder, fn_val, &frame_ptr, 1, LLVMFastCallConv, ZigLLVM_FnInlineAuto, "");
+    LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, "");
+    LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true);
+    LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP(g->builder, casted_fn_val, &negative_one, 1, "");
+    return LLVMBuildLoad(g->builder, prefix_ptr, "");
 }
 
 static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
@@ -6409,13 +6412,16 @@ static void do_code_gen(CodeGen *g) {
         }
 
         if (is_async) {
+            LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+            LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
+            ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val);
+
             if (!g->strip_debug_symbols) {
                 AstNode *source_node = fn_table_entry->proto_node;
                 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
                         (int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));
             }
             IrExecutable *executable = &fn_table_entry->analyzed_executable;
-            LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
             LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
             LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
             gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope);
@@ -6424,7 +6430,6 @@ static void do_code_gen(CodeGen *g) {
             LLVMPositionBuilderAtEnd(g->builder, get_size_block);
             assert(fn_table_entry->frame_type->abi_size != 0);
             assert(fn_table_entry->frame_type->abi_size != SIZE_MAX);
-            LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
             LLVMBuildRet(g->builder, size_val);
 
             LLVMPositionBuilderAtEnd(g->builder, fn_table_entry->preamble_llvm_block);
src/ir.cpp
@@ -2396,15 +2396,12 @@ static IrInstruction *ir_build_frame_size_src(IrBuilder *irb, Scope *scope, AstN
     return &instruction->base;
 }
 
-static IrInstruction *ir_build_frame_size_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn,
-        IrInstruction *frame_ptr)
+static IrInstruction *ir_build_frame_size_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn)
 {
     IrInstructionFrameSizeGen *instruction = ir_build_instruction<IrInstructionFrameSizeGen>(irb, scope, source_node);
     instruction->fn = fn;
-    instruction->frame_ptr = frame_ptr;
 
     ir_ref_instruction(fn, irb->current_basic_block);
-    ir_ref_instruction(frame_ptr, irb->current_basic_block);
 
     return &instruction->base;
 }
@@ -21808,13 +21805,8 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru
         return ira->codegen->invalid_instruction;
     }
 
-    IrInstruction *frame_ptr = ir_resolve_result(ira, &instruction->base, no_result_loc(),
-            ira->codegen->builtin_types.entry_frame_header, nullptr, true, false);
-    if (frame_ptr != nullptr && (type_is_invalid(frame_ptr->value.type) || instr_is_unreachable(frame_ptr)))
-        return frame_ptr;
-
     IrInstruction *result = ir_build_frame_size_gen(&ira->new_irb, instruction->base.scope,
-            instruction->base.source_node, fn, frame_ptr);
+            instruction->base.source_node, fn);
     result->value.type = ira->codegen->builtin_types.entry_usize;
     return result;
 }
src/ir_print.cpp
@@ -925,8 +925,6 @@ static void ir_print_frame_size_src(IrPrint *irp, IrInstructionFrameSizeSrc *ins
 static void ir_print_frame_size_gen(IrPrint *irp, IrInstructionFrameSizeGen *instruction) {
     fprintf(irp->f, "@frameSize(");
     ir_print_other_instruction(irp, instruction->fn);
-    fprintf(irp->f, ",");
-    ir_print_other_instruction(irp, instruction->frame_ptr);
     fprintf(irp->f, ")");
 }
 
src/zig_llvm.cpp
@@ -899,9 +899,13 @@ LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLV
 }
 
 void ZigLLVMSetTailCall(LLVMValueRef Call) {
-  unwrap<CallInst>(Call)->setTailCallKind(CallInst::TCK_MustTail);
+    unwrap<CallInst>(Call)->setTailCallKind(CallInst::TCK_MustTail);
 } 
 
+void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) {
+    unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data));
+}
+
 
 class MyOStream: public raw_ostream {
     public:
src/zig_llvm.h
@@ -212,6 +212,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne
 
 ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
 ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call);
+ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data);
 
 ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
 ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
BRANCH_TODO
@@ -1,5 +1,14 @@
+ * reimplement @frameSize with Prefix Data
+ * reimplement with function splitting rather than switch
+ * add the `anyframe` type and `anyframe->T`
  * await
  * await of a non async function
+ * await in single-threaded mode
  * async call on a non async function
+ * @asyncCall with an async function pointer
+ * cancel
+ * defer and errdefer
  * safety for resuming when it is awaiting
  * implicit cast of normal function to async function should be allowed when it is inferred to be async
+ * go over the commented out tests
+ * revive std.event.Loop