Compacted section list. Somewhat more controlled ctarg search.

This commit is contained in:
Christoffer Lerno
2023-07-15 16:31:53 +02:00
parent 34306cbf5d
commit 4325d017c8
10 changed files with 72 additions and 32 deletions

View File

@@ -49,6 +49,7 @@ void compiler_init(const char *std_lib_dir)
global_context.module_list = NULL;
global_context.generic_module_list = NULL;
global_context.method_extensions = NULL;
global_context.section_list = NULL;
vmem_init(&ast_arena, 512);
ast_calloc();
vmem_init(&expr_arena, 512);
@@ -874,6 +875,25 @@ void global_context_add_generic_decl(Decl *decl)
decltable_set(&global_context.generic_symbols, decl);
}
SectionId global_context_register_section(const char *section)
{
scratch_buffer_clear();
scratch_buffer_append("SECTION#");
scratch_buffer_append(section);
TokenType type = TOKEN_INVALID_TOKEN;
const char *result = scratch_buffer_interned();
FOREACH_BEGIN_IDX(i, const char *candidate, global_context.section_list)
if (result == candidate) return i + 1;
FOREACH_END();
unsigned len = vec_size(global_context.section_list);
if (len >= MAX_SECTIONS)
{
error_exit("Too many sections in source, max %d allowed.", MAX_SECTIONS);
}
vec_add(global_context.section_list, result);
return len + 1;
}
void global_context_clear_errors(void)
{
global_context.in_panic_mode = false;

View File

@@ -24,7 +24,10 @@ typedef uint32_t AlignSize;
typedef int32_t ScopeId;
typedef uint32_t ArraySize;
typedef uint64_t BitSize;
typedef uint16_t SectionId;
#define MAX_SECTIONS 0xFFFE
#define SECTION_PREFIX_LEN 8
#define MAX_FIXUPS 0xFFFFF
#define MAX_HASH_SIZE (512 * 1024 * 1024)
#define INVALID_SPAN ((SourceSpan){ .row = 0 })
@@ -678,24 +681,13 @@ typedef struct Decl_
AlignSize alignment;
union
{
const char *section;
ExprId varef_id;
SectionId section_id;
uint16_t va_index;
};
AlignSize offset : 32;
AlignSize padding : 32;
/* bool is_exported : 1;
bool is_used : 1;
bool is_used_public : 1;
bool has_cname : 1;
uint32_t alignment : 5;
union
{
uint32_t offset;
uint32_t counter;
};
uint32_t size;*/
struct CompilationUnit_ *unit;
Attr** attributes;
Attr **attributes;
Type *type;
union
{
@@ -734,7 +726,6 @@ typedef struct Decl_
typedef struct
{
bool start_from_end : 1;
@@ -1725,6 +1716,7 @@ typedef struct
Decl *decl_stack[MAX_GLOBAL_DECL_STACK];
Decl **decl_stack_bottom;
Decl **decl_stack_top;
const char **section_list;
} GlobalContext;
@@ -2106,6 +2098,8 @@ void global_context_clear_errors(void);
void global_context_add_type(Type *type);
void global_context_add_decl(Decl *type_decl);
void global_context_add_generic_decl(Decl *decl);
SectionId global_context_register_section(const char *section);
INLINE const char *section_from_id(SectionId id);
Module *compiler_find_or_create_module(Path *module_name, const char **parameters);
Module *global_context_find_module(const char *name);
@@ -3397,3 +3391,7 @@ INLINE bool expr_is_const_member(Expr *expr)
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_MEMBER;
}
INLINE const char *section_from_id(SectionId id)
{
return id ? global_context.section_list[id - 1] + SECTION_PREFIX_LEN : NULL;
}

View File

@@ -427,9 +427,9 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
LLVMSetUnnamedAddress(decl->backend_ref,
decl_is_local(decl) ? LLVMGlobalUnnamedAddr : LLVMLocalUnnamedAddr);
}
if (decl->section)
if (decl->section_id)
{
LLVMSetSection(global_ref, decl->section);
LLVMSetSection(global_ref, section_from_id(decl->section_id));
}
llvm_set_global_tls(decl);

View File

@@ -716,9 +716,9 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl)
LLVMValueRef function = llvm_get_ref(c, decl);
decl->backend_ref = function;
if (decl->section)
if (decl->section_id)
{
LLVMSetSection(function, decl->section);
LLVMSetSection(function, section_from_id(decl->section_id));
}
if (llvm_use_debug(c))
{

View File

@@ -1830,7 +1830,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
{
case ATTRIBUTE_SECTION:
if (!sema_check_section(context, attr)) return false;
decl->section = expr->const_expr.bytes.ptr;
decl->section_id = global_context_register_section(expr->const_expr.bytes.ptr);
break;
case ATTRIBUTE_EXTERN:
decl->has_extname = true;

View File

@@ -213,7 +213,7 @@ static inline bool sema_constant_fold_ops(Expr *expr)
UNREACHABLE
}
Expr *sema_expr_analyse_ct_arg_index(SemaContext *context, Expr *index_expr)
Expr *sema_expr_analyse_ct_arg_index(SemaContext *context, Expr *index_expr, unsigned *index_ref)
{
unsigned args = vec_size(context->macro_varargs);
uint64_t index;
@@ -241,6 +241,7 @@ Expr *sema_expr_analyse_ct_arg_index(SemaContext *context, Expr *index_expr)
SEMA_ERROR(index_expr, "Only %u vararg%s exist.", args, args == 1 ? "" : "s");
return poisoned_expr;
}
if (index_ref) *index_ref = (unsigned)index_val.i.low;
return context->macro_varargs[(size_t)index_val.i.low];
}
@@ -7292,14 +7293,17 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
return true;
case TOKEN_CT_VAARG:
{
unsigned index;
// A normal argument, this means we only evaluate it once.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg), &index), false);
index++;
assert(index < 0x10000);
Decl *decl = NULL;
// Try to find the original param.
FOREACH_BEGIN(Decl *val, context->macro_params)
if (!val) continue;
if (val->var.init_expr == arg_expr)
if (val->va_index == index && val->var.kind == VARDECL_PARAM)
{
decl = val;
break;
@@ -7310,6 +7314,7 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
{
decl = decl_new_generated_var(arg_expr->type, VARDECL_PARAM, arg_expr->span);
decl->var.init_expr = arg_expr;
decl->va_index = (uint16_t)index;
vec_add(context->macro_params, decl);
}
// Replace with the identifier.
@@ -7320,14 +7325,14 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
case TOKEN_CT_VAEXPR:
{
// An expr argument, this means we copy and evaluate.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg), NULL), false);
expr_replace(expr, copy_expr_single(arg_expr));
return true;
}
case TOKEN_CT_VACONST:
{
// An expr argument, this means we copy and evaluate.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg), NULL), false);
arg_expr = copy_expr_single(arg_expr);
if (!expr_is_constant_eval(arg_expr, CONSTANT_EVAL_CONSTANT_VALUE))
{
@@ -7340,16 +7345,18 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
case TOKEN_CT_VAREF:
{
// A normal argument, this means we only evaluate it once.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
unsigned index;
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg), &index), false);
if (!sema_binary_is_expr_lvalue(arg_expr, arg_expr)) return false;
index++;
assert(index < 0x10000);
ExprId va_ref_id = exprid(arg_expr);
Decl *decl = NULL;
// Try to find the original param.
FOREACH_BEGIN(Decl *val, context->macro_params)
if (!val) continue;
if (val->var.kind == VARDECL_PARAM_REF && val->varef_id == va_ref_id)
if (val->var.kind == VARDECL_PARAM_REF && val->va_index == index)
{
decl = val;
break;
@@ -7362,7 +7369,7 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
expr_insert_addr(arg_expr);
decl = decl_new_generated_var(arg_expr->type, VARDECL_PARAM_REF, arg_expr->span);
decl->var.init_expr = arg_expr;
decl->varef_id = va_ref_id;
decl->va_index = (uint16_t)index;
vec_add(context->macro_params, decl);
}
// Replace with the identifier.

View File

@@ -73,7 +73,7 @@ Decl *sema_find_operator(SemaContext *context, Expr *expr, OperatorOverload oper
bool sema_insert_method_call(SemaContext *context, Expr *method_call, Decl *method_decl, Expr *parent, Expr **arguments);
bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr);
bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *struct_var, Decl *decl, bool optional);
Expr *sema_expr_analyse_ct_arg_index(SemaContext *context, Expr *index_expr);
Expr *sema_expr_analyse_ct_arg_index(SemaContext *context, Expr *index_expr, unsigned *index_ref);
Expr *sema_ct_eval_expr(SemaContext *c, bool is_type, Expr *inner, bool report_missing);
bool sema_analyse_asm(SemaContext *context, AsmInlineBlock *block, Ast *asm_stmt);
bool sema_bit_assignment_check(Expr *right, Decl *member);

View File

@@ -302,7 +302,7 @@ INLINE bool sema_resolve_vatype(SemaContext *context, TypeInfo *type_info)
{
RETURN_SEMA_ERROR(type_info, "'%s' can only be used inside of a macro.", token_type_to_string(TOKEN_CT_VATYPE));
}
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, type_info->unresolved_type_expr),
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, type_info->unresolved_type_expr, NULL),
false);
if (arg_expr->expr_kind != EXPR_TYPEINFO) RETURN_SEMA_ERROR(arg_expr, "The argument was not a type.");

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.567"
#define COMPILER_VERSION "0.4.568"

View File

@@ -0,0 +1,15 @@
// #target: macos-x64
module test;
int z @section("__TEXT,__custoection");
int w @section("__TEXT,__custoection");
fn void main()
{
int a = z + w;
}
/* #expect: test.ll
@test.z = local_unnamed_addr global i32 0, section "__TEXT,__custoection", align 4
@test.w = local_unnamed_addr global i32 0, section "__TEXT,__custoection", align 4