authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 12:50:19-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 12:50:19-05:00
log6f316d8ebd1d7e594b957bac16a5458b5d173481
tree3aa2abd7789deea716e700ffeeff395d624d35e9
parentd2f1f57fa410b781f17ab7b04311af50ff775070

setGlobalSection and setGlobalAlign work for functions


4 files changed, 65 insertions(+), 24 deletions(-)

src/all_types.hpp+7-2
......@@ -1067,6 +1067,11 @@ struct FnTableEntry {
10671067
10681068 ZigList<IrInstruction *> alloca_list;
10691069 ZigList<VariableTableEntry *> variable_list;
1070
1071 AstNode *set_global_align_node;
1072 uint64_t alignment;
1073 AstNode *set_global_section_node;
1074 Buf *section_name;
10701075};
10711076
10721077uint32_t fn_table_entry_hash(FnTableEntry*);
......@@ -2261,14 +2266,14 @@ struct IrInstructionCanImplicitCast {
22612266struct IrInstructionSetGlobalAlign {
22622267 IrInstruction base;
22632268
2264 TldVar *tld_var;
2269 Tld *tld;
22652270 IrInstruction *value;
22662271};
22672272
22682273struct IrInstructionSetGlobalSection {
22692274 IrInstruction base;
22702275
2271 TldVar *tld_var;
2276 Tld *tld;
22722277 IrInstruction *value;
22732278};
22742279
src/codegen.cpp+6
......@@ -275,6 +275,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
275275 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true");
276276 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim-non-leaf", nullptr);
277277 }
278 if (fn_table_entry->section_name) {
279 LLVMSetSection(fn_table_entry->llvm_value, buf_ptr(fn_table_entry->section_name));
280 }
281 if (fn_table_entry->alignment) {
282 LLVMSetAlignment(fn_table_entry->llvm_value, fn_table_entry->alignment);
283 }
278284
279285 return fn_table_entry->llvm_value;
280286}
src/ir.cpp+50-20
......@@ -2074,11 +2074,11 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A
20742074}
20752075
20762076static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, AstNode *source_node,
2077 TldVar *tld_var, IrInstruction *value)
2077 Tld *tld, IrInstruction *value)
20782078{
20792079 IrInstructionSetGlobalAlign *instruction = ir_build_instruction<IrInstructionSetGlobalAlign>(
20802080 irb, scope, source_node);
2081 instruction->tld_var = tld_var;
2081 instruction->tld = tld;
20822082 instruction->value = value;
20832083
20842084 ir_ref_instruction(value, irb->current_basic_block);
......@@ -2087,11 +2087,11 @@ static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, As
20872087}
20882088
20892089static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node,
2090 TldVar *tld_var, IrInstruction *value)
2090 Tld *tld, IrInstruction *value)
20912091{
20922092 IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>(
20932093 irb, scope, source_node);
2094 instruction->tld_var = tld_var;
2094 instruction->tld = tld;
20952095 instruction->value = value;
20962096
20972097 ir_ref_instruction(value, irb->current_basic_block);
......@@ -4192,22 +4192,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41924192 buf_ptr(variable_name)));
41934193 return irb->codegen->invalid_instruction;
41944194 }
4195 if (tld->id != TldIdVar) {
4196 add_node_error(irb->codegen, node, buf_sprintf("'%s' is not a global variable",
4195 if (tld->id != TldIdVar && tld->id != TldIdFn) {
4196 add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function",
41974197 buf_ptr(variable_name)));
41984198 return irb->codegen->invalid_instruction;
41994199 }
4200 TldVar *tld_var = (TldVar *)tld;
4201
42024200 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
42034201 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
42044202 if (arg1_value == irb->codegen->invalid_instruction)
42054203 return arg1_value;
42064204
42074205 if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) {
4208 return ir_build_set_global_align(irb, scope, node, tld_var, arg1_value);
4206 return ir_build_set_global_align(irb, scope, node, tld, arg1_value);
42094207 } else {
4210 return ir_build_set_global_section(irb, scope, node, tld_var, arg1_value);
4208 return ir_build_set_global_section(irb, scope, node, tld, arg1_value);
42114209 }
42124210 }
42134211 }
......@@ -9472,7 +9470,7 @@ static bool is_power_of_2(uint64_t x) {
94729470static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
94739471 IrInstructionSetGlobalAlign *instruction)
94749472{
9475 TldVar *tld_var = instruction->tld_var;
9473 Tld *tld = instruction->tld;
94769474 IrInstruction *align_value = instruction->value->other;
94779475
94789476 uint64_t scalar_align;
......@@ -9484,15 +9482,31 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
94849482 return ira->codegen->builtin_types.entry_invalid;
94859483 }
94869484
9485 AstNode **set_global_align_node;
9486 uint64_t *alignment_ptr;
9487 if (tld->id == TldIdVar) {
9488 TldVar *tld_var = (TldVar *)tld;
9489 set_global_align_node = &tld_var->set_global_align_node;
9490 alignment_ptr = &tld_var->alignment;
9491 } else if (tld->id == TldIdFn) {
9492 TldFn *tld_fn = (TldFn *)tld;
9493 FnTableEntry *fn_entry = tld_fn->fn_entry;
9494 set_global_align_node = &fn_entry->set_global_align_node;
9495 alignment_ptr = &fn_entry->alignment;
9496 } else {
9497 // error is caught in pass1 IR gen
9498 zig_unreachable();
9499 }
9500
94879501 AstNode *source_node = instruction->base.source_node;
9488 if (tld_var->set_global_align_node) {
9502 if (*set_global_align_node) {
94899503 ErrorMsg *msg = ir_add_error_node(ira, source_node,
94909504 buf_sprintf("alignment set twice"));
9491 add_error_note(ira->codegen, msg, tld_var->set_global_align_node, buf_sprintf("first set here"));
9505 add_error_note(ira->codegen, msg, *set_global_align_node, buf_sprintf("first set here"));
94929506 return ira->codegen->builtin_types.entry_invalid;
94939507 }
9494 tld_var->set_global_align_node = source_node;
9495 tld_var->alignment = scalar_align;
9508 *set_global_align_node = source_node;
9509 *alignment_ptr = scalar_align;
94969510
94979511 ir_build_const_from(ira, &instruction->base, false);
94989512 return ira->codegen->builtin_types.entry_void;
......@@ -9501,21 +9515,37 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
95019515static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
95029516 IrInstructionSetGlobalSection *instruction)
95039517{
9504 TldVar *tld_var = instruction->tld_var;
9518 Tld *tld = instruction->tld;
95059519 IrInstruction *section_value = instruction->value->other;
95069520
95079521 Buf *section_name = ir_resolve_str(ira, section_value);
95089522 if (!section_name)
95099523 return ira->codegen->builtin_types.entry_invalid;
95109524
9525 AstNode **set_global_section_node;
9526 Buf **section_name_ptr;
9527 if (tld->id == TldIdVar) {
9528 TldVar *tld_var = (TldVar *)tld;
9529 set_global_section_node = &tld_var->set_global_section_node;
9530 section_name_ptr = &tld_var->section_name;
9531 } else if (tld->id == TldIdFn) {
9532 TldFn *tld_fn = (TldFn *)tld;
9533 FnTableEntry *fn_entry = tld_fn->fn_entry;
9534 set_global_section_node = &fn_entry->set_global_section_node;
9535 section_name_ptr = &fn_entry->section_name;
9536 } else {
9537 // error is caught in pass1 IR gen
9538 zig_unreachable();
9539 }
9540
95119541 AstNode *source_node = instruction->base.source_node;
9512 if (tld_var->set_global_section_node) {
9542 if (*set_global_section_node) {
95139543 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice"));
9514 add_error_note(ira->codegen, msg, tld_var->set_global_section_node, buf_sprintf("first set here"));
9544 add_error_note(ira->codegen, msg, *set_global_section_node, buf_sprintf("first set here"));
95159545 return ira->codegen->builtin_types.entry_invalid;
95169546 }
9517 tld_var->set_global_section_node = source_node;
9518 tld_var->section_name = section_name;
9547 *set_global_section_node = source_node;
9548 *section_name_ptr = section_name;
95199549
95209550 ir_build_const_from(ira, &instruction->base, false);
95219551 return ira->codegen->builtin_types.entry_void;
src/ir_print.cpp+2-2
......@@ -833,13 +833,13 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas
833833}
834834
835835static void ir_print_set_global_align(IrPrint *irp, IrInstructionSetGlobalAlign *instruction) {
836 fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld_var->base.name));
836 fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld->name));
837837 ir_print_other_instruction(irp, instruction->value);
838838 fprintf(irp->f, ")");
839839}
840840
841841static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) {
842 fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld_var->base.name));
842 fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld->name));
843843 ir_print_other_instruction(irp, instruction->value);
844844 fprintf(irp->f, ")");
845845}