diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-02-05 12:50:19 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-02-05 12:50:19 -0500 |
| commit | 6f316d8ebd1d7e594b957bac16a5458b5d173481 (patch) | |
| tree | 3aa2abd7789deea716e700ffeeff395d624d35e9 | |
| parent | d2f1f57fa410b781f17ab7b04311af50ff775070 (diff) | |
| download | zig-6f316d8ebd1d7e594b957bac16a5458b5d173481.tar.gz zig-6f316d8ebd1d7e594b957bac16a5458b5d173481.zip | |
setGlobalSection and setGlobalAlign work for functions
| -rw-r--r-- | src/all_types.hpp | 9 | ||||
| -rw-r--r-- | src/codegen.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 70 | ||||
| -rw-r--r-- | src/ir_print.cpp | 4 |
4 files changed, 65 insertions, 24 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 169e2266b6..dc4b40ba2d 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1067,6 +1067,11 @@ struct FnTableEntry { ZigList<IrInstruction *> alloca_list; ZigList<VariableTableEntry *> variable_list; + + AstNode *set_global_align_node; + uint64_t alignment; + AstNode *set_global_section_node; + Buf *section_name; }; uint32_t fn_table_entry_hash(FnTableEntry*); @@ -2261,14 +2266,14 @@ struct IrInstructionCanImplicitCast { struct IrInstructionSetGlobalAlign { IrInstruction base; - TldVar *tld_var; + Tld *tld; IrInstruction *value; }; struct IrInstructionSetGlobalSection { IrInstruction base; - TldVar *tld_var; + Tld *tld; IrInstruction *value; }; diff --git a/src/codegen.cpp b/src/codegen.cpp index f19f6bb8bf..a34312c5de 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -275,6 +275,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim-non-leaf", nullptr); } + if (fn_table_entry->section_name) { + LLVMSetSection(fn_table_entry->llvm_value, buf_ptr(fn_table_entry->section_name)); + } + if (fn_table_entry->alignment) { + LLVMSetAlignment(fn_table_entry->llvm_value, fn_table_entry->alignment); + } return fn_table_entry->llvm_value; } diff --git a/src/ir.cpp b/src/ir.cpp index 62cc904ce7..629c4149eb 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2074,11 +2074,11 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A } static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, AstNode *source_node, - TldVar *tld_var, IrInstruction *value) + Tld *tld, IrInstruction *value) { IrInstructionSetGlobalAlign *instruction = ir_build_instruction<IrInstructionSetGlobalAlign>( irb, scope, source_node); - instruction->tld_var = tld_var; + instruction->tld = tld; instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -2087,11 +2087,11 @@ static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, As } static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node, - TldVar *tld_var, IrInstruction *value) + Tld *tld, IrInstruction *value) { IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>( irb, scope, source_node); - instruction->tld_var = tld_var; + instruction->tld = tld; instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -4192,22 +4192,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo buf_ptr(variable_name))); return irb->codegen->invalid_instruction; } - if (tld->id != TldIdVar) { - add_node_error(irb->codegen, node, buf_sprintf("'%s' is not a global variable", + if (tld->id != TldIdVar && tld->id != TldIdFn) { + add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function", buf_ptr(variable_name))); return irb->codegen->invalid_instruction; } - TldVar *tld_var = (TldVar *)tld; - AstNode *arg1_node = node->data.fn_call_expr.params.at(1); IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); if (arg1_value == irb->codegen->invalid_instruction) return arg1_value; if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) { - return ir_build_set_global_align(irb, scope, node, tld_var, arg1_value); + return ir_build_set_global_align(irb, scope, node, tld, arg1_value); } else { - return ir_build_set_global_section(irb, scope, node, tld_var, arg1_value); + return ir_build_set_global_section(irb, scope, node, tld, arg1_value); } } } @@ -9472,7 +9470,7 @@ static bool is_power_of_2(uint64_t x) { static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, IrInstructionSetGlobalAlign *instruction) { - TldVar *tld_var = instruction->tld_var; + Tld *tld = instruction->tld; IrInstruction *align_value = instruction->value->other; uint64_t scalar_align; @@ -9484,15 +9482,31 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, return ira->codegen->builtin_types.entry_invalid; } + AstNode **set_global_align_node; + uint64_t *alignment_ptr; + if (tld->id == TldIdVar) { + TldVar *tld_var = (TldVar *)tld; + set_global_align_node = &tld_var->set_global_align_node; + alignment_ptr = &tld_var->alignment; + } else if (tld->id == TldIdFn) { + TldFn *tld_fn = (TldFn *)tld; + FnTableEntry *fn_entry = tld_fn->fn_entry; + set_global_align_node = &fn_entry->set_global_align_node; + alignment_ptr = &fn_entry->alignment; + } else { + // error is caught in pass1 IR gen + zig_unreachable(); + } + AstNode *source_node = instruction->base.source_node; - if (tld_var->set_global_align_node) { + if (*set_global_align_node) { ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("alignment set twice")); - add_error_note(ira->codegen, msg, tld_var->set_global_align_node, buf_sprintf("first set here")); + add_error_note(ira->codegen, msg, *set_global_align_node, buf_sprintf("first set here")); return ira->codegen->builtin_types.entry_invalid; } - tld_var->set_global_align_node = source_node; - tld_var->alignment = scalar_align; + *set_global_align_node = source_node; + *alignment_ptr = scalar_align; ir_build_const_from(ira, &instruction->base, false); return ira->codegen->builtin_types.entry_void; @@ -9501,21 +9515,37 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira, IrInstructionSetGlobalSection *instruction) { - TldVar *tld_var = instruction->tld_var; + Tld *tld = instruction->tld; IrInstruction *section_value = instruction->value->other; Buf *section_name = ir_resolve_str(ira, section_value); if (!section_name) return ira->codegen->builtin_types.entry_invalid; + AstNode **set_global_section_node; + Buf **section_name_ptr; + if (tld->id == TldIdVar) { + TldVar *tld_var = (TldVar *)tld; + set_global_section_node = &tld_var->set_global_section_node; + section_name_ptr = &tld_var->section_name; + } else if (tld->id == TldIdFn) { + TldFn *tld_fn = (TldFn *)tld; + FnTableEntry *fn_entry = tld_fn->fn_entry; + set_global_section_node = &fn_entry->set_global_section_node; + section_name_ptr = &fn_entry->section_name; + } else { + // error is caught in pass1 IR gen + zig_unreachable(); + } + AstNode *source_node = instruction->base.source_node; - if (tld_var->set_global_section_node) { + if (*set_global_section_node) { ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice")); - add_error_note(ira->codegen, msg, tld_var->set_global_section_node, buf_sprintf("first set here")); + add_error_note(ira->codegen, msg, *set_global_section_node, buf_sprintf("first set here")); return ira->codegen->builtin_types.entry_invalid; } - tld_var->set_global_section_node = source_node; - tld_var->section_name = section_name; + *set_global_section_node = source_node; + *section_name_ptr = section_name; ir_build_const_from(ira, &instruction->base, false); return ira->codegen->builtin_types.entry_void; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index f7abbc9ae0..a378df04b5 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -833,13 +833,13 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas } static void ir_print_set_global_align(IrPrint *irp, IrInstructionSetGlobalAlign *instruction) { - fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld_var->base.name)); + fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld->name)); ir_print_other_instruction(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) { - fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld_var->base.name)); + fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld->name)); ir_print_other_instruction(irp, instruction->value); fprintf(irp->f, ")"); } |
