From 96ed94859015b4bbb5844f0da62786c6aaf3b18f Mon Sep 17 00:00:00 2001 From: Tetralux Date: Sat, 16 May 2020 15:04:08 +0000 Subject: LLVM C backend: Obey directives on blocks, procedures, and expressions e.g: #no_bounds_check / #bounds_check --- src/llvm_backend.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f38a07740..0b1431472 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -149,6 +149,9 @@ void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue le if (build_context.no_bounds_check) { return; } + if ((p->module->state_flags & StateFlag_no_bounds_check) != 0) { + return; + } index = lb_emit_conv(p, index, t_int); len = lb_emit_conv(p, len, t_int); @@ -171,6 +174,9 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu if (build_context.no_bounds_check) { return; } + if ((p->module->state_flags & StateFlag_no_bounds_check) != 0) { + return; + } lbValue file = lb_find_or_add_entity_string(p->module, token.pos.file); lbValue line = lb_const_int(p->module, t_int, token.pos.line); @@ -2294,6 +2300,19 @@ void lb_begin_procedure_body(lbProcedure *p) { } } + if (p->tags != 0) { + u64 in = p->tags; + u64 out = p->module->state_flags; + if (in & ProcTag_bounds_check) { + out |= StateFlag_bounds_check; + out &= ~StateFlag_no_bounds_check; + } else if (in & ProcTag_no_bounds_check) { + out |= StateFlag_no_bounds_check; + out &= ~StateFlag_bounds_check; + } + p->module->state_flags = out; + } + p->builder = LLVMCreateBuilder(); p->decl_block = lb_create_block(p, "decls", true); @@ -2457,7 +2476,7 @@ void lb_end_procedure_body(lbProcedure *p) { } p->curr_block = nullptr; - + p->module->state_flags = 0; } void lb_end_procedure(lbProcedure *p) { LLVMDisposeBuilder(p->builder); @@ -3829,6 +3848,24 @@ lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast void lb_build_stmt(lbProcedure *p, Ast *node) { + u64 prev_state_flags = p->module->state_flags; + defer (p->module->state_flags = prev_state_flags); + + if (node->state_flags != 0) { + u64 in = node->state_flags; + u64 out = p->module->state_flags; + + if (in & StateFlag_bounds_check) { + out |= StateFlag_bounds_check; + out &= ~StateFlag_no_bounds_check; + } else if (in & StateFlag_no_bounds_check) { + out |= StateFlag_no_bounds_check; + out &= ~StateFlag_bounds_check; + } + + p->module->state_flags = out; + } + switch (node->kind) { case_ast_node(bs, EmptyStmt, node); case_end; @@ -8849,6 +8886,24 @@ lbValue lb_emit_any_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbModule *m = p->module; + u64 prev_state_flags = p->module->state_flags; + defer (p->module->state_flags = prev_state_flags); + + if (expr->state_flags != 0) { + u64 in = expr->state_flags; + u64 out = p->module->state_flags; + + if (in & StateFlag_bounds_check) { + out |= StateFlag_bounds_check; + out &= ~StateFlag_no_bounds_check; + } else if (in & StateFlag_no_bounds_check) { + out |= StateFlag_no_bounds_check; + out &= ~StateFlag_bounds_check; + } + + p->module->state_flags = out; + } + expr = unparen_expr(expr); TypeAndValue tv = type_and_value_of_expr(expr); @@ -10538,6 +10593,9 @@ void lb_init_module(lbModule *m, Checker *c) { m->mod = LLVMModuleCreateWithNameInContext("odin_module", m->ctx); m->debug_builder = LLVMCreateDIBuilder(m->mod); + m->state_flags = 0; + m->state_flags |= StateFlag_bounds_check; + gb_mutex_init(&m->mutex); gbAllocator a = heap_allocator(); map_init(&m->types, a); -- cgit v1.2.3