diff options
Diffstat (limited to 'src/llvm_backend_general.cpp')
| -rw-r--r-- | src/llvm_backend_general.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 5dfc7aff9..ccc0f2a54 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -90,6 +90,8 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { map_init(&m->map_cell_info_map, 0); map_init(&m->exact_value_compound_literal_addr_map, 1024); + m->const_dummy_builder = LLVMCreateBuilderInContext(m->ctx); + } gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { @@ -277,10 +279,39 @@ gb_internal lbValue lb_zero(lbModule *m, Type *t) { return v; } +gb_internal LLVMValueRef llvm_const_extract_value(lbModule *m, LLVMValueRef agg, unsigned *indices, isize count) { + // return LLVMConstExtractValue(value, indices, count); + LLVMValueRef res = agg; + GB_ASSERT(LLVMIsConstant(res)); + for (isize i = 0; i < count; i++) { + res = LLVMBuildExtractValue(m->const_dummy_builder, res, indices[i], ""); + GB_ASSERT(LLVMIsConstant(res)); + } + return res; +} + +gb_internal LLVMValueRef llvm_const_insert_value(lbModule *m, LLVMValueRef agg, LLVMValueRef val, unsigned *indices, isize count) { + GB_ASSERT(LLVMIsConstant(agg)); + GB_ASSERT(LLVMIsConstant(val)); + GB_ASSERT(count > 0); + + LLVMValueRef extracted_value = val; + for (isize i = count-1; i >= 0; i--) { + LLVMValueRef nested = llvm_const_extract_value(m, agg, indices, i); + GB_ASSERT(LLVMIsConstant(nested)); + extracted_value = LLVMBuildInsertValue(m->const_dummy_builder, nested, extracted_value, indices[i], ""); + } + GB_ASSERT(LLVMIsConstant(extracted_value)); + return extracted_value; +} + + + + gb_internal LLVMValueRef llvm_cstring(lbModule *m, String const &str) { lbValue v = lb_find_or_add_entity_string(m, str); unsigned indices[1] = {0}; - return LLVMConstExtractValue(v.value, indices, gb_count_of(indices)); + return llvm_const_extract_value(m, v.value, indices, gb_count_of(indices)); } gb_internal bool lb_is_instr_terminating(LLVMValueRef instr) { |