mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
setGlobalSection and setGlobalAlign work for functions
This commit is contained in:
parent
d2f1f57fa4
commit
6f316d8ebd
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
70
src/ir.cpp
70
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;
|
||||
|
||||
@ -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, ")");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user