zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob b4eef13c (32576B) - Raw


      1 /*
      2  * Copyright (c) 2015 Andrew Kelley
      3  *
      4  * This file is part of zig, which is MIT licensed.
      5  * See http://opensource.org/licenses/MIT
      6  */
      7 
      8 
      9 /*
     10  * The point of this file is to contain all the LLVM C++ API interaction so that:
     11  * 1. The compile time of other files is kept under control.
     12  * 2. Provide a C interface to the LLVM functions we need for self-hosting purposes.
     13  * 3. Prevent C++ from infecting the rest of the project.
     14  */
     15 
     16 #include "zig_llvm.h"
     17 
     18 #include <llvm/Analysis/TargetLibraryInfo.h>
     19 #include <llvm/Analysis/TargetTransformInfo.h>
     20 #include <llvm/IR/DIBuilder.h>
     21 #include <llvm/IR/DiagnosticInfo.h>
     22 #include <llvm/IR/IRBuilder.h>
     23 #include <llvm/IR/InlineAsm.h>
     24 #include <llvm/IR/Instructions.h>
     25 #include <llvm/IR/LegacyPassManager.h>
     26 #include <llvm/IR/Module.h>
     27 #include <llvm/IR/Verifier.h>
     28 #include <llvm/InitializePasses.h>
     29 #include <llvm/MC/SubtargetFeature.h>
     30 #include <llvm/PassRegistry.h>
     31 #include <llvm/Support/FileSystem.h>
     32 #include <llvm/Support/TargetParser.h>
     33 #include <llvm/Support/raw_ostream.h>
     34 #include <llvm/Target/TargetMachine.h>
     35 #include <llvm/Transforms/Coroutines.h>
     36 #include <llvm/Transforms/IPO.h>
     37 #include <llvm/Transforms/IPO/PassManagerBuilder.h>
     38 #include <llvm/Transforms/IPO/AlwaysInliner.h>
     39 #include <llvm/Transforms/Scalar.h>
     40 
     41 #include <lld/Common/Driver.h>
     42 
     43 #include <new>
     44 
     45 #include <stdlib.h>
     46 
     47 using namespace llvm;
     48 
     49 void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
     50     initializeLoopStrengthReducePass(*unwrap(R));
     51 }
     52 
     53 void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
     54     initializeLowerIntrinsicsPass(*unwrap(R));
     55 }
     56 
     57 char *ZigLLVMGetHostCPUName(void) {
     58     return strdup((const char *)sys::getHostCPUName().bytes_begin());
     59 }
     60 
     61 char *ZigLLVMGetNativeFeatures(void) {
     62     SubtargetFeatures features;
     63 
     64     StringMap<bool> host_features;
     65     if (sys::getHostCPUFeatures(host_features)) {
     66         for (auto &F : host_features)
     67             features.AddFeature(F.first(), F.second);
     68     }
     69 
     70     return strdup((const char *)StringRef(features.getString()).bytes_begin());
     71 }
     72 
     73 static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
     74     PM.add(createAddDiscriminatorsPass());
     75 }
     76 
     77 #ifndef NDEBUG
     78 static const bool assertions_on = true;
     79 #else
     80 static const bool assertions_on = false;
     81 #endif
     82 
     83 bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
     84         const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug)
     85 {
     86     std::error_code EC;
     87     raw_fd_ostream dest(filename, EC, sys::fs::F_None);
     88     if (EC) {
     89         *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
     90         return true;
     91     }
     92     TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
     93     target_machine->setO0WantsFastISel(true);
     94 
     95     Module* module = unwrap(module_ref);
     96 
     97     PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder();
     98     if (PMBuilder == nullptr) {
     99         *error_message = strdup("memory allocation failure");
    100         return true;
    101     }
    102     PMBuilder->OptLevel = target_machine->getOptLevel();
    103     PMBuilder->SizeLevel = 0;
    104 
    105     PMBuilder->DisableTailCalls = is_debug;
    106     PMBuilder->DisableUnitAtATime = is_debug;
    107     PMBuilder->DisableUnrollLoops = is_debug;
    108     PMBuilder->SLPVectorize = !is_debug;
    109     PMBuilder->LoopVectorize = !is_debug;
    110     PMBuilder->RerollLoops = !is_debug;
    111     // Leaving NewGVN as default (off) because when on it caused issue #673
    112     //PMBuilder->NewGVN = !is_debug;
    113     PMBuilder->DisableGVNLoadPRE = is_debug;
    114     PMBuilder->VerifyInput = assertions_on;
    115     PMBuilder->VerifyOutput = assertions_on;
    116     PMBuilder->MergeFunctions = !is_debug;
    117     PMBuilder->PrepareForLTO = false;
    118     PMBuilder->PrepareForThinLTO = false;
    119     PMBuilder->PerformThinLTO = false;
    120 
    121     TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple()));
    122     PMBuilder->LibraryInfo = &tlii;
    123 
    124     if (is_debug) {
    125         PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false);
    126     } else {
    127         target_machine->adjustPassManager(*PMBuilder);
    128 
    129         PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass);
    130         PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false);
    131     }
    132 
    133     addCoroutinePassesToExtensionPoints(*PMBuilder);
    134 
    135     // Set up the per-function pass manager.
    136     legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);
    137     auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii);
    138     FPM.add(tliwp);
    139     FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
    140     if (assertions_on) {
    141         FPM.add(createVerifierPass());
    142     }
    143     PMBuilder->populateFunctionPassManager(FPM);
    144 
    145     // Set up the per-module pass manager.
    146     legacy::PassManager MPM;
    147     MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
    148     PMBuilder->populateModulePassManager(MPM);
    149 
    150     // Set output pass.
    151     TargetMachine::CodeGenFileType ft;
    152     if (output_type != ZigLLVM_EmitLLVMIr) {
    153         switch (output_type) {
    154             case ZigLLVM_EmitAssembly:
    155                 ft = TargetMachine::CGFT_AssemblyFile;
    156                 break;
    157             case ZigLLVM_EmitBinary:
    158                 ft = TargetMachine::CGFT_ObjectFile;
    159                 break;
    160             default:
    161                 abort();
    162         }
    163 
    164         if (target_machine->addPassesToEmitFile(MPM, dest, ft)) {
    165             *error_message = strdup("TargetMachine can't emit a file of this type");
    166             return true;
    167         }
    168     }
    169 
    170     // run per function optimization passes
    171     FPM.doInitialization();
    172     for (Function &F : *module)
    173       if (!F.isDeclaration())
    174         FPM.run(F);
    175     FPM.doFinalization();
    176 
    177     MPM.run(*module);
    178 
    179     if (output_type == ZigLLVM_EmitLLVMIr) {
    180         if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {
    181             return true;
    182         }
    183     }
    184 
    185     return false;
    186 }
    187 
    188 ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) {
    189   return wrap(Type::getTokenTy(*unwrap(context_ref)));
    190 }
    191 
    192 LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
    193         unsigned NumArgs, unsigned CC, ZigLLVM_FnInline fn_inline, const char *Name)
    194 {
    195     CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name);
    196     call_inst->setCallingConv(CC);
    197     switch (fn_inline) {
    198         case ZigLLVM_FnInlineAuto:
    199             break;
    200         case ZigLLVM_FnInlineAlways:
    201             call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::AlwaysInline);
    202             break;
    203         case ZigLLVM_FnInlineNever:
    204             call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::NoInline);
    205             break;
    206     }
    207     return wrap(unwrap(B)->Insert(call_inst));
    208 }
    209 
    210 void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
    211     assert( isa<Function>(unwrap(fn)) );
    212     Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
    213     unwrapped_function->setSubprogram(reinterpret_cast<DISubprogram*>(subprogram));
    214 }
    215 
    216 
    217 ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *pointee_type,
    218         uint64_t size_in_bits, uint64_t align_in_bits, const char *name)
    219 {
    220     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createPointerType(
    221             reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, Optional<unsigned>(), name);
    222     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    223 }
    224 
    225 ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const char *name,
    226         uint64_t size_in_bits, unsigned encoding)
    227 {
    228     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createBasicType(
    229             name, size_in_bits, encoding);
    230     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    231 }
    232 
    233 ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,
    234         uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count)
    235 {
    236     SmallVector<Metadata *, 1> subrange;
    237     subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, elem_count));
    238     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createArrayType(
    239             size_in_bits, align_in_bits,
    240             reinterpret_cast<DIType*>(elem_type),
    241             reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange));
    242     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    243 }
    244 
    245 ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) {
    246     DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);
    247     return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
    248 }
    249 
    250 ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    251         const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    252         uint64_t align_in_bits, ZigLLVMDIEnumerator **enumerator_array, int enumerator_array_len,
    253         ZigLLVMDIType *underlying_type, const char *unique_id)
    254 {
    255     SmallVector<Metadata *, 8> fields;
    256     for (int i = 0; i < enumerator_array_len; i += 1) {
    257         DIEnumerator *dienumerator = reinterpret_cast<DIEnumerator*>(enumerator_array[i]);
    258         fields.push_back(dienumerator);
    259     }
    260     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerationType(
    261             reinterpret_cast<DIScope*>(scope),
    262             name,
    263             reinterpret_cast<DIFile*>(file),
    264             line_number, size_in_bits, align_in_bits,
    265             reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
    266             reinterpret_cast<DIType*>(underlying_type),
    267             unique_id);
    268     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    269 }
    270 
    271 ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    272         const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
    273         uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)
    274 {
    275     assert(flags == 0);
    276     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
    277             reinterpret_cast<DIScope*>(scope),
    278             name,
    279             reinterpret_cast<DIFile*>(file),
    280             line, size_in_bits, align_in_bits, offset_in_bits, DINode::FlagZero,
    281             reinterpret_cast<DIType*>(type));
    282     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    283 }
    284 
    285 ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    286         const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    287         uint64_t align_in_bits, unsigned flags, ZigLLVMDIType **types_array, int types_array_len,
    288         unsigned run_time_lang, const char *unique_id)
    289 {
    290     SmallVector<Metadata *, 8> fields;
    291     for (int i = 0; i < types_array_len; i += 1) {
    292         DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
    293         fields.push_back(ditype);
    294     }
    295     assert(flags == 0);
    296     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
    297             reinterpret_cast<DIScope*>(scope),
    298             name,
    299             reinterpret_cast<DIFile*>(file),
    300             line_number, size_in_bits, align_in_bits, DINode::FlagZero,
    301             reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
    302             run_time_lang, unique_id);
    303     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    304 }
    305 
    306 ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    307         const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    308         uint64_t align_in_bits, unsigned flags, ZigLLVMDIType *derived_from,
    309         ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang, ZigLLVMDIType *vtable_holder,
    310         const char *unique_id)
    311 {
    312     SmallVector<Metadata *, 8> fields;
    313     for (int i = 0; i < types_array_len; i += 1) {
    314         DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
    315         fields.push_back(ditype);
    316     }
    317     assert(flags == 0);
    318     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(
    319             reinterpret_cast<DIScope*>(scope),
    320             name,
    321             reinterpret_cast<DIFile*>(file),
    322             line_number, size_in_bits, align_in_bits, DINode::FlagZero,
    323             reinterpret_cast<DIType*>(derived_from),
    324             reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
    325             run_time_lang,
    326             reinterpret_cast<DIType*>(vtable_holder),
    327             unique_id);
    328     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    329 }
    330 
    331 ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
    332         const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
    333 {
    334     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createReplaceableCompositeType(
    335             tag, name,
    336             reinterpret_cast<DIScope*>(scope),
    337             reinterpret_cast<DIFile*>(file),
    338             line);
    339     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    340 }
    341 
    342 ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
    343         const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
    344 {
    345     DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createForwardDecl(
    346             tag, name,
    347             reinterpret_cast<DIScope*>(scope),
    348             reinterpret_cast<DIFile*>(file),
    349             line);
    350     return reinterpret_cast<ZigLLVMDIType*>(di_type);
    351 }
    352 
    353 void ZigLLVMReplaceTemporary(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
    354         ZigLLVMDIType *replacement)
    355 {
    356     reinterpret_cast<DIBuilder*>(dibuilder)->replaceTemporary(
    357             TempDIType(reinterpret_cast<DIType*>(type)),
    358             reinterpret_cast<DIType*>(replacement));
    359 }
    360 
    361 void ZigLLVMReplaceDebugArrays(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
    362         ZigLLVMDIType **types_array, int types_array_len)
    363 {
    364     SmallVector<Metadata *, 8> fields;
    365     for (int i = 0; i < types_array_len; i += 1) {
    366         DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
    367         fields.push_back(ditype);
    368     }
    369     DICompositeType *composite_type = (DICompositeType*)reinterpret_cast<DIType*>(type);
    370     reinterpret_cast<DIBuilder*>(dibuilder)->replaceArrays(
    371             composite_type,
    372             reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields));
    373 }
    374 
    375 ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
    376         ZigLLVMDIType **types_array, int types_array_len, unsigned flags)
    377 {
    378     SmallVector<Metadata *, 8> types;
    379     for (int i = 0; i < types_array_len; i += 1) {
    380         DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
    381         types.push_back(ditype);
    382     }
    383     assert(flags == 0);
    384     DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
    385     DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
    386             dibuilder->getOrCreateTypeArray(types),
    387             DINode::FlagZero);
    388     DIType *ditype = subroutine_type;
    389     return reinterpret_cast<ZigLLVMDIType*>(ditype);
    390 }
    391 
    392 unsigned ZigLLVMEncoding_DW_ATE_unsigned(void) {
    393     return dwarf::DW_ATE_unsigned;
    394 }
    395 
    396 unsigned ZigLLVMEncoding_DW_ATE_signed(void) {
    397     return dwarf::DW_ATE_signed;
    398 }
    399 
    400 unsigned ZigLLVMEncoding_DW_ATE_float(void) {
    401     return dwarf::DW_ATE_float;
    402 }
    403 
    404 unsigned ZigLLVMEncoding_DW_ATE_boolean(void) {
    405     return dwarf::DW_ATE_boolean;
    406 }
    407 
    408 unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void) {
    409     return dwarf::DW_ATE_unsigned_char;
    410 }
    411 
    412 unsigned ZigLLVMEncoding_DW_ATE_signed_char(void) {
    413     return dwarf::DW_ATE_signed_char;
    414 }
    415 
    416 unsigned ZigLLVMLang_DW_LANG_C99(void) {
    417     return dwarf::DW_LANG_C99;
    418 }
    419 
    420 unsigned ZigLLVMTag_DW_variable(void) {
    421     return dwarf::DW_TAG_variable;
    422 }
    423 
    424 unsigned ZigLLVMTag_DW_structure_type(void) {
    425     return dwarf::DW_TAG_structure_type;
    426 }
    427 
    428 unsigned ZigLLVMTag_DW_enumeration_type(void) {
    429     return dwarf::DW_TAG_enumeration_type;
    430 }
    431 
    432 unsigned ZigLLVMTag_DW_union_type(void) {
    433     return dwarf::DW_TAG_union_type;
    434 }
    435 
    436 ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
    437     DIBuilder *di_builder = new(std::nothrow) DIBuilder(*unwrap(module), allow_unresolved);
    438     if (di_builder == nullptr)
    439         return nullptr;
    440     return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);
    441 }
    442 
    443 void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, ZigLLVMDIScope *scope) {
    444     unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get(
    445                 line, column, reinterpret_cast<DIScope*>(scope)));
    446 }
    447 
    448 void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {
    449     unwrap(builder)->SetCurrentDebugLocation(DebugLoc());
    450 }
    451 
    452 
    453 ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope,
    454         ZigLLVMDIFile *file, unsigned line, unsigned col)
    455 {
    456     DILexicalBlock *result = reinterpret_cast<DIBuilder*>(dbuilder)->createLexicalBlock(
    457             reinterpret_cast<DIScope*>(scope),
    458             reinterpret_cast<DIFile*>(file),
    459             line,
    460             col);
    461     return reinterpret_cast<ZigLLVMDILexicalBlock*>(result);
    462 }
    463 
    464 ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
    465         ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
    466         ZigLLVMDIType *type, bool always_preserve, unsigned flags)
    467 {
    468     assert(flags == 0);
    469     DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(
    470             reinterpret_cast<DIScope*>(scope),
    471             name,
    472             reinterpret_cast<DIFile*>(file),
    473             line_no,
    474             reinterpret_cast<DIType*>(type),
    475             always_preserve,
    476             DINode::FlagZero);
    477     return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
    478 }
    479 
    480 ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder,
    481     ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file,
    482     unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit)
    483 {
    484     DIGlobalVariableExpression *result = reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariableExpression(
    485         reinterpret_cast<DIScope*>(scope),
    486         name,
    487         linkage_name,
    488         reinterpret_cast<DIFile*>(file),
    489         line_no,
    490         reinterpret_cast<DIType*>(di_type),
    491         is_local_to_unit);
    492     return reinterpret_cast<ZigLLVMDIGlobalVariable*>(result);
    493 }
    494 
    495 ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder,
    496         ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
    497         ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
    498 {
    499     assert(flags == 0);
    500     DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(
    501             reinterpret_cast<DIScope*>(scope),
    502             name,
    503             arg_no,
    504             reinterpret_cast<DIFile*>(file),
    505             line_no,
    506             reinterpret_cast<DIType*>(type),
    507             always_preserve,
    508             DINode::FlagZero);
    509     return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
    510 }
    511 
    512 ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(ZigLLVMDILexicalBlock *lexical_block) {
    513     DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block);
    514     return reinterpret_cast<ZigLLVMDIScope*>(scope);
    515 }
    516 
    517 ZigLLVMDIScope *ZigLLVMCompileUnitToScope(ZigLLVMDICompileUnit *compile_unit) {
    518     DIScope *scope = reinterpret_cast<DICompileUnit*>(compile_unit);
    519     return reinterpret_cast<ZigLLVMDIScope*>(scope);
    520 }
    521 
    522 ZigLLVMDIScope *ZigLLVMFileToScope(ZigLLVMDIFile *difile) {
    523     DIScope *scope = reinterpret_cast<DIFile*>(difile);
    524     return reinterpret_cast<ZigLLVMDIScope*>(scope);
    525 }
    526 
    527 ZigLLVMDIScope *ZigLLVMSubprogramToScope(ZigLLVMDISubprogram *subprogram) {
    528     DIScope *scope = reinterpret_cast<DISubprogram*>(subprogram);
    529     return reinterpret_cast<ZigLLVMDIScope*>(scope);
    530 }
    531 
    532 ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type) {
    533     DIScope *scope = reinterpret_cast<DIType*>(type);
    534     return reinterpret_cast<ZigLLVMDIScope*>(scope);
    535 }
    536 
    537 ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder,
    538         unsigned lang, ZigLLVMDIFile *difile, const char *producer,
    539         bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
    540         uint64_t dwo_id, bool emit_debug_info)
    541 {
    542     DICompileUnit *result = reinterpret_cast<DIBuilder*>(dibuilder)->createCompileUnit(
    543             lang,
    544             reinterpret_cast<DIFile*>(difile),
    545             producer, is_optimized, flags, runtime_version, split_name,
    546             (emit_debug_info ? DICompileUnit::DebugEmissionKind::FullDebug : DICompileUnit::DebugEmissionKind::NoDebug),
    547             dwo_id);
    548     return reinterpret_cast<ZigLLVMDICompileUnit*>(result);
    549 }
    550 
    551 
    552 ZigLLVMDIFile *ZigLLVMCreateFile(ZigLLVMDIBuilder *dibuilder, const char *filename, const char *directory) {
    553     DIFile *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFile(filename, directory);
    554     return reinterpret_cast<ZigLLVMDIFile*>(result);
    555 }
    556 
    557 ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    558         const char *name, const char *linkage_name, ZigLLVMDIFile *file, unsigned lineno,
    559         ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, unsigned scope_line,
    560         unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)
    561 {
    562     DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));
    563     assert(flags == 0);
    564     DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
    565             reinterpret_cast<DIScope*>(scope),
    566             name, linkage_name,
    567             reinterpret_cast<DIFile*>(file),
    568             lineno,
    569             di_sub_type,
    570             is_local_to_unit, is_definition, scope_line, DINode::FlagZero, is_optimized,
    571             nullptr,
    572             reinterpret_cast<DISubprogram *>(decl_subprogram));
    573     return reinterpret_cast<ZigLLVMDISubprogram*>(result);
    574 }
    575 
    576 void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder) {
    577     reinterpret_cast<DIBuilder*>(dibuilder)->finalize();
    578 }
    579 
    580 LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    581         ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref)
    582 {
    583     Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
    584             unwrap(storage),
    585             reinterpret_cast<DILocalVariable *>(var_info),
    586             reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
    587             reinterpret_cast<DILocation*>(debug_loc),
    588             static_cast<BasicBlock*>(unwrap(basic_block_ref)));
    589     return wrap(result);
    590 }
    591 
    592 LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    593         ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr)
    594 {
    595     Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
    596             unwrap(storage),
    597             reinterpret_cast<DILocalVariable *>(var_info),
    598             reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
    599             reinterpret_cast<DILocation*>(debug_loc),
    600             static_cast<Instruction*>(unwrap(insert_before_instr)));
    601     return wrap(result);
    602 }
    603 
    604 ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope) {
    605     DebugLoc debug_loc = DebugLoc::get(line, col, reinterpret_cast<DIScope*>(scope), nullptr);
    606     return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
    607 }
    608 
    609 void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
    610     if (on_state) {
    611         FastMathFlags fmf;
    612         fmf.setFast();
    613         unwrap(builder_wrapped)->setFastMathFlags(fmf);
    614     } else {
    615         unwrap(builder_wrapped)->clearFastMathFlags();
    616     }
    617 }
    618 
    619 void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) {
    620     Function *func = unwrap<Function>(fn_ref);
    621     const AttributeList attr_set = func->getAttributes();
    622     AttrBuilder attr_builder;
    623     if (attr_value) {
    624         attr_builder.addAttribute(attr_name, attr_value);
    625     } else {
    626         attr_builder.addAttribute(attr_name);
    627     }
    628     const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(),
    629             AttributeList::FunctionIndex, attr_builder);
    630     func->setAttributes(new_attr_set);
    631 }
    632 
    633 void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
    634     Function *func = unwrap<Function>(fn_ref);
    635     const AttributeList attr_set = func->getAttributes();
    636     const AttributeList new_attr_set = attr_set.addAttribute(func->getContext(), AttributeList::FunctionIndex,
    637             Attribute::Cold);
    638     func->setAttributes(new_attr_set);
    639 }
    640 
    641 void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
    642     llvm::cl::ParseCommandLineOptions(argc, argv);
    643 }
    644 
    645 
    646 static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
    647 static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, "");
    648 static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, "");
    649 static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, "");
    650 static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
    651 
    652 static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, "");
    653 static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, "");
    654 static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, "");
    655 static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, "");
    656 static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");
    657 
    658 const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) {
    659     return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin();
    660 }
    661 
    662 const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) {
    663     return (const char*)Triple::getVendorTypeName((Triple::VendorType)vendor).bytes_begin();
    664 }
    665 
    666 const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) {
    667     return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin();
    668 }
    669 
    670 const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
    671     return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();
    672 }
    673 
    674 void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
    675         ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
    676         ZigLLVM_ObjectFormatType *oformat)
    677 {
    678     char *native_triple = LLVMGetDefaultTargetTriple();
    679     Triple triple(native_triple);
    680 
    681     *arch_type = (ZigLLVM_ArchType)triple.getArch();
    682     *sub_arch_type = (ZigLLVM_SubArchType)triple.getSubArch();
    683     *vendor_type = (ZigLLVM_VendorType)triple.getVendor();
    684     *os_type = (ZigLLVM_OSType)triple.getOS();
    685     *environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();
    686     *oformat = (ZigLLVM_ObjectFormatType)triple.getObjectFormat();
    687 
    688     free(native_triple);
    689 }
    690 
    691 const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
    692     switch (sub_arch) {
    693         case ZigLLVM_NoSubArch:
    694             return "(none)";
    695         case ZigLLVM_ARMSubArch_v8_3a:
    696             return "v8_3a";
    697         case ZigLLVM_ARMSubArch_v8_2a:
    698             return "v8_2a";
    699         case ZigLLVM_ARMSubArch_v8_1a:
    700             return "v8_1a";
    701         case ZigLLVM_ARMSubArch_v8:
    702             return "v8";
    703         case ZigLLVM_ARMSubArch_v8r:
    704             return "v8r";
    705         case ZigLLVM_ARMSubArch_v8m_baseline:
    706             return "v8m_baseline";
    707         case ZigLLVM_ARMSubArch_v8m_mainline:
    708             return "v8m_mainline";
    709         case ZigLLVM_ARMSubArch_v7:
    710             return "v7";
    711         case ZigLLVM_ARMSubArch_v7em:
    712             return "v7em";
    713         case ZigLLVM_ARMSubArch_v7m:
    714             return "v7m";
    715         case ZigLLVM_ARMSubArch_v7s:
    716             return "v7s";
    717         case ZigLLVM_ARMSubArch_v7k:
    718             return "v7k";
    719         case ZigLLVM_ARMSubArch_v7ve:
    720             return "v7ve";
    721         case ZigLLVM_ARMSubArch_v6:
    722             return "v6";
    723         case ZigLLVM_ARMSubArch_v6m:
    724             return "v6m";
    725         case ZigLLVM_ARMSubArch_v6k:
    726             return "v6k";
    727         case ZigLLVM_ARMSubArch_v6t2:
    728             return "v6t2";
    729         case ZigLLVM_ARMSubArch_v5:
    730             return "v5";
    731         case ZigLLVM_ARMSubArch_v5te:
    732             return "v5te";
    733         case ZigLLVM_ARMSubArch_v4t:
    734             return "v4t";
    735         case ZigLLVM_KalimbaSubArch_v3:
    736             return "v3";
    737         case ZigLLVM_KalimbaSubArch_v4:
    738             return "v4";
    739         case ZigLLVM_KalimbaSubArch_v5:
    740             return "v5";
    741     }
    742     abort();
    743 }
    744 
    745 void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
    746     unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
    747 }
    748 
    749 void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
    750     unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
    751 }
    752 
    753 static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
    754     switch (Ordering) {
    755         case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
    756         case LLVMAtomicOrderingUnordered: return AtomicOrdering::Unordered;
    757         case LLVMAtomicOrderingMonotonic: return AtomicOrdering::Monotonic;
    758         case LLVMAtomicOrderingAcquire: return AtomicOrdering::Acquire;
    759         case LLVMAtomicOrderingRelease: return AtomicOrdering::Release;
    760         case LLVMAtomicOrderingAcquireRelease: return AtomicOrdering::AcquireRelease;
    761         case LLVMAtomicOrderingSequentiallyConsistent: return AtomicOrdering::SequentiallyConsistent;
    762     }
    763     abort();
    764 }
    765 
    766 LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp,
    767         LLVMValueRef new_val, LLVMAtomicOrdering success_ordering,
    768         LLVMAtomicOrdering failure_ordering)
    769 {
    770     return wrap(unwrap(builder)->CreateAtomicCmpXchg(unwrap(ptr), unwrap(cmp), unwrap(new_val),
    771                 mapFromLLVMOrdering(success_ordering), mapFromLLVMOrdering(failure_ordering)));
    772 }
    773 
    774 LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    775         const char *name)
    776 {
    777     return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, false, true));
    778 }
    779 
    780 LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    781         const char *name)
    782 {
    783     return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, true, false));
    784 }
    785 
    786 LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    787         const char *name)
    788 {
    789     return wrap(unwrap(builder)->CreateLShr(unwrap(LHS), unwrap(RHS), name, true));
    790 }
    791 
    792 LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    793         const char *name)
    794 {
    795     return wrap(unwrap(builder)->CreateAShr(unwrap(LHS), unwrap(RHS), name, true));
    796 }
    797 
    798 
    799 class MyOStream: public raw_ostream {
    800     public:
    801         MyOStream(void (*_append_diagnostic)(void *, const char *, size_t), void *_context) :
    802             raw_ostream(true), append_diagnostic(_append_diagnostic), context(_context), pos(0) {
    803 
    804         }
    805         void write_impl(const char *ptr, size_t len) override {
    806             append_diagnostic(context, ptr, len);
    807             pos += len;
    808         }
    809         uint64_t current_pos() const override {
    810             return pos;
    811         }
    812         void (*append_diagnostic)(void *, const char *, size_t);
    813         void *context;
    814         size_t pos;
    815 };
    816 
    817 
    818 bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
    819         void (*append_diagnostic)(void *, const char *, size_t), void *context)
    820 {
    821     ArrayRef<const char *> array_ref_args(args, arg_count);
    822 
    823     MyOStream diag(append_diagnostic, context);
    824 
    825     switch (oformat) {
    826         case ZigLLVM_UnknownObjectFormat:
    827             assert(false); // unreachable
    828 
    829         case ZigLLVM_COFF:
    830             return lld::coff::link(array_ref_args, false, diag);
    831 
    832         case ZigLLVM_ELF:
    833             return lld::elf::link(array_ref_args, false, diag);
    834 
    835         case ZigLLVM_MachO:
    836             return lld::mach_o::link(array_ref_args, diag);
    837 
    838         case ZigLLVM_Wasm:
    839             assert(false); // TODO ZigLLDLink for Wasm
    840     }
    841     assert(false); // unreachable
    842     abort();
    843 }