1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 6bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 7bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 8bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 9bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 10bf215546Sopenharmony_ci * the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 15bf215546Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 16bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 17bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 18bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 19bf215546Sopenharmony_ci * 20bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 21bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 22bf215546Sopenharmony_ci * of the Software. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci/* based on pieces from si_pipe.c and radeon_llvm_emit.c */ 26bf215546Sopenharmony_ci#include "ac_llvm_util.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "ac_llvm_build.h" 29bf215546Sopenharmony_ci#include "c11/threads.h" 30bf215546Sopenharmony_ci#include "util/bitscan.h" 31bf215546Sopenharmony_ci#include "util/u_math.h" 32bf215546Sopenharmony_ci#include <llvm-c/Core.h> 33bf215546Sopenharmony_ci#include <llvm-c/Support.h> 34bf215546Sopenharmony_ci#include <llvm-c/Transforms/IPO.h> 35bf215546Sopenharmony_ci#include <llvm-c/Transforms/Scalar.h> 36bf215546Sopenharmony_ci#include <llvm-c/Transforms/Utils.h> 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include <assert.h> 39bf215546Sopenharmony_ci#include <stdio.h> 40bf215546Sopenharmony_ci#include <string.h> 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic void ac_init_llvm_target(void) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci LLVMInitializeAMDGPUTargetInfo(); 45bf215546Sopenharmony_ci LLVMInitializeAMDGPUTarget(); 46bf215546Sopenharmony_ci LLVMInitializeAMDGPUTargetMC(); 47bf215546Sopenharmony_ci LLVMInitializeAMDGPUAsmPrinter(); 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci /* For inline assembly. */ 50bf215546Sopenharmony_ci LLVMInitializeAMDGPUAsmParser(); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci /* For ACO disassembly. */ 53bf215546Sopenharmony_ci LLVMInitializeAMDGPUDisassembler(); 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci const char *argv[] = { 56bf215546Sopenharmony_ci /* error messages prefix */ 57bf215546Sopenharmony_ci "mesa", 58bf215546Sopenharmony_ci "-amdgpu-atomic-optimizations=true", 59bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR == 11 60bf215546Sopenharmony_ci /* This fixes variable indexing on LLVM 11. It also breaks atomic.cmpswap on LLVM >= 12. */ 61bf215546Sopenharmony_ci "-structurizecfg-skip-uniform-regions", 62bf215546Sopenharmony_ci#endif 63bf215546Sopenharmony_ci }; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci ac_reset_llvm_all_options_occurences(); 66bf215546Sopenharmony_ci LLVMParseCommandLineOptions(ARRAY_SIZE(argv), argv, NULL); 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ciPUBLIC void ac_init_shared_llvm_once(void) 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci static once_flag ac_init_llvm_target_once_flag = ONCE_FLAG_INIT; 72bf215546Sopenharmony_ci call_once(&ac_init_llvm_target_once_flag, ac_init_llvm_target); 73bf215546Sopenharmony_ci} 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci#if !LLVM_IS_SHARED 76bf215546Sopenharmony_cistatic once_flag ac_init_static_llvm_target_once_flag = ONCE_FLAG_INIT; 77bf215546Sopenharmony_cistatic void ac_init_static_llvm_once(void) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci call_once(&ac_init_static_llvm_target_once_flag, ac_init_llvm_target); 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci#endif 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_civoid ac_init_llvm_once(void) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci#if LLVM_IS_SHARED 86bf215546Sopenharmony_ci ac_init_shared_llvm_once(); 87bf215546Sopenharmony_ci#else 88bf215546Sopenharmony_ci ac_init_static_llvm_once(); 89bf215546Sopenharmony_ci#endif 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ciLLVMTargetRef ac_get_llvm_target(const char *triple) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci LLVMTargetRef target = NULL; 95bf215546Sopenharmony_ci char *err_message = NULL; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci if (LLVMGetTargetFromTriple(triple, &target, &err_message)) { 98bf215546Sopenharmony_ci fprintf(stderr, "Cannot find target for triple %s ", triple); 99bf215546Sopenharmony_ci if (err_message) { 100bf215546Sopenharmony_ci fprintf(stderr, "%s\n", err_message); 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci LLVMDisposeMessage(err_message); 103bf215546Sopenharmony_ci return NULL; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci return target; 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ciconst char *ac_get_llvm_processor_name(enum radeon_family family) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci switch (family) { 111bf215546Sopenharmony_ci case CHIP_TAHITI: 112bf215546Sopenharmony_ci return "tahiti"; 113bf215546Sopenharmony_ci case CHIP_PITCAIRN: 114bf215546Sopenharmony_ci return "pitcairn"; 115bf215546Sopenharmony_ci case CHIP_VERDE: 116bf215546Sopenharmony_ci return "verde"; 117bf215546Sopenharmony_ci case CHIP_OLAND: 118bf215546Sopenharmony_ci return "oland"; 119bf215546Sopenharmony_ci case CHIP_HAINAN: 120bf215546Sopenharmony_ci return "hainan"; 121bf215546Sopenharmony_ci case CHIP_BONAIRE: 122bf215546Sopenharmony_ci return "bonaire"; 123bf215546Sopenharmony_ci case CHIP_KABINI: 124bf215546Sopenharmony_ci return "kabini"; 125bf215546Sopenharmony_ci case CHIP_KAVERI: 126bf215546Sopenharmony_ci return "kaveri"; 127bf215546Sopenharmony_ci case CHIP_HAWAII: 128bf215546Sopenharmony_ci return "hawaii"; 129bf215546Sopenharmony_ci case CHIP_TONGA: 130bf215546Sopenharmony_ci return "tonga"; 131bf215546Sopenharmony_ci case CHIP_ICELAND: 132bf215546Sopenharmony_ci return "iceland"; 133bf215546Sopenharmony_ci case CHIP_CARRIZO: 134bf215546Sopenharmony_ci return "carrizo"; 135bf215546Sopenharmony_ci case CHIP_FIJI: 136bf215546Sopenharmony_ci return "fiji"; 137bf215546Sopenharmony_ci case CHIP_STONEY: 138bf215546Sopenharmony_ci return "stoney"; 139bf215546Sopenharmony_ci case CHIP_POLARIS10: 140bf215546Sopenharmony_ci return "polaris10"; 141bf215546Sopenharmony_ci case CHIP_POLARIS11: 142bf215546Sopenharmony_ci case CHIP_POLARIS12: 143bf215546Sopenharmony_ci case CHIP_VEGAM: 144bf215546Sopenharmony_ci return "polaris11"; 145bf215546Sopenharmony_ci case CHIP_VEGA10: 146bf215546Sopenharmony_ci return "gfx900"; 147bf215546Sopenharmony_ci case CHIP_RAVEN: 148bf215546Sopenharmony_ci return "gfx902"; 149bf215546Sopenharmony_ci case CHIP_VEGA12: 150bf215546Sopenharmony_ci return "gfx904"; 151bf215546Sopenharmony_ci case CHIP_VEGA20: 152bf215546Sopenharmony_ci return "gfx906"; 153bf215546Sopenharmony_ci case CHIP_RAVEN2: 154bf215546Sopenharmony_ci case CHIP_RENOIR: 155bf215546Sopenharmony_ci return "gfx909"; 156bf215546Sopenharmony_ci case CHIP_ARCTURUS: 157bf215546Sopenharmony_ci return "gfx908"; 158bf215546Sopenharmony_ci case CHIP_ALDEBARAN: 159bf215546Sopenharmony_ci return "gfx90a"; 160bf215546Sopenharmony_ci case CHIP_NAVI10: 161bf215546Sopenharmony_ci return "gfx1010"; 162bf215546Sopenharmony_ci case CHIP_NAVI12: 163bf215546Sopenharmony_ci return "gfx1011"; 164bf215546Sopenharmony_ci case CHIP_NAVI14: 165bf215546Sopenharmony_ci return "gfx1012"; 166bf215546Sopenharmony_ci case CHIP_NAVI21: 167bf215546Sopenharmony_ci return "gfx1030"; 168bf215546Sopenharmony_ci case CHIP_NAVI22: 169bf215546Sopenharmony_ci return LLVM_VERSION_MAJOR >= 12 ? "gfx1031" : "gfx1030"; 170bf215546Sopenharmony_ci case CHIP_NAVI23: 171bf215546Sopenharmony_ci return LLVM_VERSION_MAJOR >= 12 ? "gfx1032" : "gfx1030"; 172bf215546Sopenharmony_ci case CHIP_VANGOGH: 173bf215546Sopenharmony_ci return LLVM_VERSION_MAJOR >= 12 ? "gfx1033" : "gfx1030"; 174bf215546Sopenharmony_ci case CHIP_NAVI24: 175bf215546Sopenharmony_ci return LLVM_VERSION_MAJOR >= 13 ? "gfx1034" : "gfx1030"; 176bf215546Sopenharmony_ci case CHIP_REMBRANDT: 177bf215546Sopenharmony_ci return LLVM_VERSION_MAJOR >= 13 ? "gfx1035" : "gfx1030"; 178bf215546Sopenharmony_ci case CHIP_GFX1036: /* TODO: LLVM 15 doesn't support this yet */ 179bf215546Sopenharmony_ci return "gfx1030"; 180bf215546Sopenharmony_ci case CHIP_GFX1100: 181bf215546Sopenharmony_ci return "gfx1100"; 182bf215546Sopenharmony_ci case CHIP_GFX1101: 183bf215546Sopenharmony_ci return "gfx1101"; 184bf215546Sopenharmony_ci case CHIP_GFX1102: 185bf215546Sopenharmony_ci return "gfx1102"; 186bf215546Sopenharmony_ci case CHIP_GFX1103: 187bf215546Sopenharmony_ci return "gfx1103"; 188bf215546Sopenharmony_ci default: 189bf215546Sopenharmony_ci return ""; 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci} 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_cistatic LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family, 194bf215546Sopenharmony_ci enum ac_target_machine_options tm_options, 195bf215546Sopenharmony_ci LLVMCodeGenOptLevel level, 196bf215546Sopenharmony_ci const char **out_triple) 197bf215546Sopenharmony_ci{ 198bf215546Sopenharmony_ci assert(family >= CHIP_TAHITI); 199bf215546Sopenharmony_ci const char *triple = (tm_options & AC_TM_SUPPORTS_SPILL) ? "amdgcn-mesa-mesa3d" : "amdgcn--"; 200bf215546Sopenharmony_ci LLVMTargetRef target = ac_get_llvm_target(triple); 201bf215546Sopenharmony_ci const char *name = ac_get_llvm_processor_name(family); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci LLVMTargetMachineRef tm = 204bf215546Sopenharmony_ci LLVMCreateTargetMachine(target, triple, name, "", level, 205bf215546Sopenharmony_ci LLVMRelocDefault, LLVMCodeModelDefault); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci if (!ac_is_llvm_processor_supported(tm, name)) { 208bf215546Sopenharmony_ci LLVMDisposeTargetMachine(tm); 209bf215546Sopenharmony_ci fprintf(stderr, "amd: LLVM doesn't support %s, bailing out...\n", name); 210bf215546Sopenharmony_ci return NULL; 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (out_triple) 214bf215546Sopenharmony_ci *out_triple = triple; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci return tm; 217bf215546Sopenharmony_ci} 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_cistatic LLVMPassManagerRef ac_create_passmgr(LLVMTargetLibraryInfoRef target_library_info, 220bf215546Sopenharmony_ci bool check_ir) 221bf215546Sopenharmony_ci{ 222bf215546Sopenharmony_ci LLVMPassManagerRef passmgr = LLVMCreatePassManager(); 223bf215546Sopenharmony_ci if (!passmgr) 224bf215546Sopenharmony_ci return NULL; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci if (target_library_info) 227bf215546Sopenharmony_ci LLVMAddTargetLibraryInfo(target_library_info, passmgr); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci if (check_ir) 230bf215546Sopenharmony_ci LLVMAddVerifierPass(passmgr); 231bf215546Sopenharmony_ci LLVMAddAlwaysInlinerPass(passmgr); 232bf215546Sopenharmony_ci /* Normally, the pass manager runs all passes on one function before 233bf215546Sopenharmony_ci * moving onto another. Adding a barrier no-op pass forces the pass 234bf215546Sopenharmony_ci * manager to run the inliner on all functions first, which makes sure 235bf215546Sopenharmony_ci * that the following passes are only run on the remaining non-inline 236bf215546Sopenharmony_ci * function, so it removes useless work done on dead inline functions. 237bf215546Sopenharmony_ci */ 238bf215546Sopenharmony_ci ac_llvm_add_barrier_noop_pass(passmgr); 239bf215546Sopenharmony_ci /* This pass should eliminate all the load and store instructions. */ 240bf215546Sopenharmony_ci LLVMAddPromoteMemoryToRegisterPass(passmgr); 241bf215546Sopenharmony_ci LLVMAddScalarReplAggregatesPass(passmgr); 242bf215546Sopenharmony_ci LLVMAddLICMPass(passmgr); 243bf215546Sopenharmony_ci LLVMAddAggressiveDCEPass(passmgr); 244bf215546Sopenharmony_ci LLVMAddCFGSimplificationPass(passmgr); 245bf215546Sopenharmony_ci /* This is recommended by the instruction combining pass. */ 246bf215546Sopenharmony_ci LLVMAddEarlyCSEMemSSAPass(passmgr); 247bf215546Sopenharmony_ci LLVMAddInstructionCombiningPass(passmgr); 248bf215546Sopenharmony_ci return passmgr; 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_cistatic const char *attr_to_str(enum ac_func_attr attr) 252bf215546Sopenharmony_ci{ 253bf215546Sopenharmony_ci switch (attr) { 254bf215546Sopenharmony_ci case AC_FUNC_ATTR_ALWAYSINLINE: 255bf215546Sopenharmony_ci return "alwaysinline"; 256bf215546Sopenharmony_ci case AC_FUNC_ATTR_INREG: 257bf215546Sopenharmony_ci return "inreg"; 258bf215546Sopenharmony_ci case AC_FUNC_ATTR_NOALIAS: 259bf215546Sopenharmony_ci return "noalias"; 260bf215546Sopenharmony_ci case AC_FUNC_ATTR_NOUNWIND: 261bf215546Sopenharmony_ci return "nounwind"; 262bf215546Sopenharmony_ci case AC_FUNC_ATTR_READNONE: 263bf215546Sopenharmony_ci return "readnone"; 264bf215546Sopenharmony_ci case AC_FUNC_ATTR_READONLY: 265bf215546Sopenharmony_ci return "readonly"; 266bf215546Sopenharmony_ci case AC_FUNC_ATTR_WRITEONLY: 267bf215546Sopenharmony_ci return "writeonly"; 268bf215546Sopenharmony_ci case AC_FUNC_ATTR_INACCESSIBLE_MEM_ONLY: 269bf215546Sopenharmony_ci return "inaccessiblememonly"; 270bf215546Sopenharmony_ci case AC_FUNC_ATTR_CONVERGENT: 271bf215546Sopenharmony_ci return "convergent"; 272bf215546Sopenharmony_ci default: 273bf215546Sopenharmony_ci fprintf(stderr, "Unhandled function attribute: %x\n", attr); 274bf215546Sopenharmony_ci return 0; 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci} 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_civoid ac_add_function_attr(LLVMContextRef ctx, LLVMValueRef function, int attr_idx, 279bf215546Sopenharmony_ci enum ac_func_attr attr) 280bf215546Sopenharmony_ci{ 281bf215546Sopenharmony_ci const char *attr_name = attr_to_str(attr); 282bf215546Sopenharmony_ci unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); 283bf215546Sopenharmony_ci LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(ctx, kind_id, 0); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci if (LLVMIsAFunction(function)) 286bf215546Sopenharmony_ci LLVMAddAttributeAtIndex(function, attr_idx, llvm_attr); 287bf215546Sopenharmony_ci else 288bf215546Sopenharmony_ci LLVMAddCallSiteAttribute(function, attr_idx, llvm_attr); 289bf215546Sopenharmony_ci} 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_civoid ac_add_func_attributes(LLVMContextRef ctx, LLVMValueRef function, unsigned attrib_mask) 292bf215546Sopenharmony_ci{ 293bf215546Sopenharmony_ci attrib_mask |= AC_FUNC_ATTR_NOUNWIND; 294bf215546Sopenharmony_ci attrib_mask &= ~AC_FUNC_ATTR_LEGACY; 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci while (attrib_mask) { 297bf215546Sopenharmony_ci enum ac_func_attr attr = 1u << u_bit_scan(&attrib_mask); 298bf215546Sopenharmony_ci ac_add_function_attr(ctx, function, -1, attr); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci} 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_civoid ac_dump_module(LLVMModuleRef module) 303bf215546Sopenharmony_ci{ 304bf215546Sopenharmony_ci char *str = LLVMPrintModuleToString(module); 305bf215546Sopenharmony_ci fprintf(stderr, "%s", str); 306bf215546Sopenharmony_ci LLVMDisposeMessage(str); 307bf215546Sopenharmony_ci} 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_civoid ac_llvm_add_target_dep_function_attr(LLVMValueRef F, const char *name, unsigned value) 310bf215546Sopenharmony_ci{ 311bf215546Sopenharmony_ci char str[16]; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci snprintf(str, sizeof(str), "0x%x", value); 314bf215546Sopenharmony_ci LLVMAddTargetDependentFunctionAttr(F, name, str); 315bf215546Sopenharmony_ci} 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_civoid ac_llvm_set_workgroup_size(LLVMValueRef F, unsigned size) 318bf215546Sopenharmony_ci{ 319bf215546Sopenharmony_ci if (!size) 320bf215546Sopenharmony_ci return; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci char str[32]; 323bf215546Sopenharmony_ci snprintf(str, sizeof(str), "%u,%u", size, size); 324bf215546Sopenharmony_ci LLVMAddTargetDependentFunctionAttr(F, "amdgpu-flat-work-group-size", str); 325bf215546Sopenharmony_ci} 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_civoid ac_llvm_set_target_features(LLVMValueRef F, struct ac_llvm_context *ctx) 328bf215546Sopenharmony_ci{ 329bf215546Sopenharmony_ci char features[2048]; 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci snprintf(features, sizeof(features), "+DumpCode%s%s", 332bf215546Sopenharmony_ci /* GFX9 has broken VGPR indexing, so always promote alloca to scratch. */ 333bf215546Sopenharmony_ci ctx->gfx_level == GFX9 ? ",-promote-alloca" : "", 334bf215546Sopenharmony_ci /* Wave32 is the default. */ 335bf215546Sopenharmony_ci ctx->gfx_level >= GFX10 && ctx->wave_size == 64 ? 336bf215546Sopenharmony_ci ",+wavefrontsize64,-wavefrontsize32" : ""); 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci LLVMAddTargetDependentFunctionAttr(F, "target-features", features); 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_cibool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler, enum radeon_family family, 342bf215546Sopenharmony_ci enum ac_target_machine_options tm_options) 343bf215546Sopenharmony_ci{ 344bf215546Sopenharmony_ci const char *triple; 345bf215546Sopenharmony_ci memset(compiler, 0, sizeof(*compiler)); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci compiler->tm = ac_create_target_machine(family, tm_options, LLVMCodeGenLevelDefault, &triple); 348bf215546Sopenharmony_ci if (!compiler->tm) 349bf215546Sopenharmony_ci return false; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (tm_options & AC_TM_CREATE_LOW_OPT) { 352bf215546Sopenharmony_ci compiler->low_opt_tm = 353bf215546Sopenharmony_ci ac_create_target_machine(family, tm_options, LLVMCodeGenLevelLess, NULL); 354bf215546Sopenharmony_ci if (!compiler->low_opt_tm) 355bf215546Sopenharmony_ci goto fail; 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci compiler->target_library_info = ac_create_target_library_info(triple); 359bf215546Sopenharmony_ci if (!compiler->target_library_info) 360bf215546Sopenharmony_ci goto fail; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci compiler->passmgr = 363bf215546Sopenharmony_ci ac_create_passmgr(compiler->target_library_info, tm_options & AC_TM_CHECK_IR); 364bf215546Sopenharmony_ci if (!compiler->passmgr) 365bf215546Sopenharmony_ci goto fail; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci return true; 368bf215546Sopenharmony_cifail: 369bf215546Sopenharmony_ci ac_destroy_llvm_compiler(compiler); 370bf215546Sopenharmony_ci return false; 371bf215546Sopenharmony_ci} 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_civoid ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci ac_destroy_llvm_passes(compiler->passes); 376bf215546Sopenharmony_ci ac_destroy_llvm_passes(compiler->low_opt_passes); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (compiler->passmgr) 379bf215546Sopenharmony_ci LLVMDisposePassManager(compiler->passmgr); 380bf215546Sopenharmony_ci if (compiler->target_library_info) 381bf215546Sopenharmony_ci ac_dispose_target_library_info(compiler->target_library_info); 382bf215546Sopenharmony_ci if (compiler->low_opt_tm) 383bf215546Sopenharmony_ci LLVMDisposeTargetMachine(compiler->low_opt_tm); 384bf215546Sopenharmony_ci if (compiler->tm) 385bf215546Sopenharmony_ci LLVMDisposeTargetMachine(compiler->tm); 386bf215546Sopenharmony_ci} 387