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 }