2377 lines · cpp
1//===- DebugInfo.cpp - Debug Information Helper Classes -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the helper classes used to build and interpret debug10// information in LLVM IR form.11//12//===----------------------------------------------------------------------===//13 14#include "llvm-c/DebugInfo.h"15#include "LLVMContextImpl.h"16#include "llvm/ADT/APSInt.h"17#include "llvm/ADT/DenseMap.h"18#include "llvm/ADT/DenseSet.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/ADT/SmallPtrSet.h"21#include "llvm/ADT/SmallVector.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/IR/BasicBlock.h"24#include "llvm/IR/Constants.h"25#include "llvm/IR/DIBuilder.h"26#include "llvm/IR/DebugInfo.h"27#include "llvm/IR/DebugInfoMetadata.h"28#include "llvm/IR/DebugLoc.h"29#include "llvm/IR/DebugProgramInstruction.h"30#include "llvm/IR/Function.h"31#include "llvm/IR/GVMaterializer.h"32#include "llvm/IR/Instruction.h"33#include "llvm/IR/IntrinsicInst.h"34#include "llvm/IR/LLVMContext.h"35#include "llvm/IR/Metadata.h"36#include "llvm/IR/Module.h"37#include "llvm/IR/PassManager.h"38#include "llvm/Support/Casting.h"39#include "llvm/Support/TimeProfiler.h"40#include <algorithm>41#include <cassert>42#include <optional>43 44using namespace llvm;45using namespace llvm::at;46using namespace llvm::dwarf;47 48TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) {49 // This function is hot. Check whether the value has any metadata to avoid a50 // DenseMap lookup. This check is a bitfield datamember lookup.51 if (!V->isUsedByMetadata())52 return {};53 auto *L = ValueAsMetadata::getIfExists(V);54 if (!L)55 return {};56 57 TinyPtrVector<DbgVariableRecord *> Declares;58 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())59 if (DVR->getType() == DbgVariableRecord::LocationType::Declare)60 Declares.push_back(DVR);61 62 return Declares;63}64 65TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclareValues(Value *V) {66 // This function is hot. Check whether the value has any metadata to avoid a67 // DenseMap lookup. This check is a bitfield datamember lookup.68 if (!V->isUsedByMetadata())69 return {};70 auto *L = ValueAsMetadata::getIfExists(V);71 if (!L)72 return {};73 74 TinyPtrVector<DbgVariableRecord *> DEclareValues;75 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())76 if (DVR->getType() == DbgVariableRecord::LocationType::DeclareValue)77 DEclareValues.push_back(DVR);78 79 return DEclareValues;80}81 82TinyPtrVector<DbgVariableRecord *> llvm::findDVRValues(Value *V) {83 // This function is hot. Check whether the value has any metadata to avoid a84 // DenseMap lookup. This check is a bitfield datamember lookup.85 if (!V->isUsedByMetadata())86 return {};87 auto *L = ValueAsMetadata::getIfExists(V);88 if (!L)89 return {};90 91 TinyPtrVector<DbgVariableRecord *> Values;92 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())93 if (DVR->isValueOfVariable())94 Values.push_back(DVR);95 96 return Values;97}98 99template <bool DbgAssignAndValuesOnly>100static void101findDbgIntrinsics(Value *V,102 SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {103 // This function is hot. Check whether the value has any metadata to avoid a104 // DenseMap lookup.105 if (!V->isUsedByMetadata())106 return;107 108 // TODO: If this value appears multiple times in a DIArgList, we should still109 // only add the owning dbg.value once; use this set to track ArgListUsers.110 // This behaviour can be removed when we can automatically remove duplicates.111 // V will also appear twice in a dbg.assign if its used in the both the value112 // and address components.113 SmallPtrSet<DbgVariableRecord *, 4> EncounteredDbgVariableRecords;114 115 /// Append users of MetadataAsValue(MD).116 auto AppendUsers = [&EncounteredDbgVariableRecords,117 &DbgVariableRecords](Metadata *MD) {118 // Get DbgVariableRecords that use this as a single value.119 if (LocalAsMetadata *L = dyn_cast<LocalAsMetadata>(MD)) {120 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) {121 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())122 if (EncounteredDbgVariableRecords.insert(DVR).second)123 DbgVariableRecords.push_back(DVR);124 }125 }126 };127 128 if (auto *L = LocalAsMetadata::getIfExists(V)) {129 AppendUsers(L);130 for (Metadata *AL : L->getAllArgListUsers()) {131 AppendUsers(AL);132 DIArgList *DI = cast<DIArgList>(AL);133 for (DbgVariableRecord *DVR : DI->getAllDbgVariableRecordUsers())134 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())135 if (EncounteredDbgVariableRecords.insert(DVR).second)136 DbgVariableRecords.push_back(DVR);137 }138 }139}140 141void llvm::findDbgValues(142 Value *V, SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {143 findDbgIntrinsics</*DbgAssignAndValuesOnly=*/true>(V, DbgVariableRecords);144}145 146void llvm::findDbgUsers(147 Value *V, SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {148 findDbgIntrinsics</*DbgAssignAndValuesOnly=*/false>(V, DbgVariableRecords);149}150 151DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {152 if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope))153 return LocalScope->getSubprogram();154 return nullptr;155}156 157DebugLoc llvm::getDebugValueLoc(DbgVariableRecord *DVR) {158 // Original dbg.declare must have a location.159 const DebugLoc &DeclareLoc = DVR->getDebugLoc();160 MDNode *Scope = DeclareLoc.getScope();161 DILocation *InlinedAt = DeclareLoc.getInlinedAt();162 // Because no machine insts can come from debug intrinsics, only the scope163 // and inlinedAt is significant. Zero line numbers are used in case this164 // DebugLoc leaks into any adjacent instructions. Produce an unknown location165 // with the correct scope / inlinedAt fields.166 return DILocation::get(DVR->getContext(), 0, 0, Scope, InlinedAt);167}168 169//===----------------------------------------------------------------------===//170// DebugInfoFinder implementations.171//===----------------------------------------------------------------------===//172 173void DebugInfoFinder::reset() {174 CUs.clear();175 SPs.clear();176 GVs.clear();177 TYs.clear();178 Scopes.clear();179 NodesSeen.clear();180}181 182void DebugInfoFinder::processModule(const Module &M) {183 for (auto *CU : M.debug_compile_units())184 processCompileUnit(CU);185 for (auto &F : M.functions()) {186 if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))187 processSubprogram(SP);188 // There could be subprograms from inlined functions referenced from189 // instructions only. Walk the function to find them.190 for (const BasicBlock &BB : F)191 for (const Instruction &I : BB)192 processInstruction(M, I);193 }194}195 196void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {197 if (!addCompileUnit(CU))198 return;199 for (auto *DIG : CU->getGlobalVariables()) {200 if (!addGlobalVariable(DIG))201 continue;202 auto *GV = DIG->getVariable();203 processScope(GV->getScope());204 processType(GV->getType());205 }206 for (auto *ET : CU->getEnumTypes())207 processType(ET);208 for (auto *RT : CU->getRetainedTypes())209 if (auto *T = dyn_cast<DIType>(RT))210 processType(T);211 else212 processSubprogram(cast<DISubprogram>(RT));213 for (auto *Import : CU->getImportedEntities())214 processImportedEntity(Import);215}216 217void DebugInfoFinder::processInstruction(const Module &M,218 const Instruction &I) {219 if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))220 processVariable(DVI->getVariable());221 222 if (auto DbgLoc = I.getDebugLoc())223 processLocation(M, DbgLoc.get());224 225 for (const DbgRecord &DPR : I.getDbgRecordRange())226 processDbgRecord(M, DPR);227}228 229void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {230 if (!Loc)231 return;232 processScope(Loc->getScope());233 processLocation(M, Loc->getInlinedAt());234}235 236void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DR) {237 if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR))238 processVariable(DVR->getVariable());239 processLocation(M, DR.getDebugLoc().get());240}241 242void DebugInfoFinder::processType(DIType *DT) {243 if (!addType(DT))244 return;245 processScope(DT->getScope());246 if (auto *ST = dyn_cast<DISubroutineType>(DT)) {247 for (DIType *Ref : ST->getTypeArray())248 processType(Ref);249 return;250 }251 if (auto *DCT = dyn_cast<DICompositeType>(DT)) {252 processType(DCT->getBaseType());253 for (Metadata *D : DCT->getElements()) {254 if (auto *T = dyn_cast<DIType>(D))255 processType(T);256 else if (auto *SP = dyn_cast<DISubprogram>(D))257 processSubprogram(SP);258 }259 return;260 }261 if (auto *DDT = dyn_cast<DIDerivedType>(DT)) {262 processType(DDT->getBaseType());263 }264}265 266void DebugInfoFinder::processImportedEntity(const DIImportedEntity *Import) {267 auto *Entity = Import->getEntity();268 if (auto *T = dyn_cast<DIType>(Entity))269 processType(T);270 else if (auto *SP = dyn_cast<DISubprogram>(Entity))271 processSubprogram(SP);272 else if (auto *NS = dyn_cast<DINamespace>(Entity))273 processScope(NS->getScope());274 else if (auto *M = dyn_cast<DIModule>(Entity))275 processScope(M->getScope());276}277 278void DebugInfoFinder::processScope(DIScope *Scope) {279 if (!Scope)280 return;281 if (auto *Ty = dyn_cast<DIType>(Scope)) {282 processType(Ty);283 return;284 }285 if (auto *CU = dyn_cast<DICompileUnit>(Scope)) {286 addCompileUnit(CU);287 return;288 }289 if (auto *SP = dyn_cast<DISubprogram>(Scope)) {290 processSubprogram(SP);291 return;292 }293 if (!addScope(Scope))294 return;295 if (auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) {296 processScope(LB->getScope());297 } else if (auto *NS = dyn_cast<DINamespace>(Scope)) {298 processScope(NS->getScope());299 } else if (auto *M = dyn_cast<DIModule>(Scope)) {300 processScope(M->getScope());301 }302}303 304void DebugInfoFinder::processSubprogram(DISubprogram *SP) {305 if (!addSubprogram(SP))306 return;307 processScope(SP->getScope());308 // Some of the users, e.g. CloneFunctionInto / CloneModule, need to set up a309 // ValueMap containing identity mappings for all of the DICompileUnit's, not310 // just DISubprogram's, referenced from anywhere within the Function being311 // cloned prior to calling MapMetadata / RemapInstruction to avoid their312 // duplication later as DICompileUnit's are also directly referenced by313 // llvm.dbg.cu list. Therefore we need to collect DICompileUnit's here as314 // well. Also, DICompileUnit's may reference DISubprogram's too and therefore315 // need to be at least looked through.316 processCompileUnit(SP->getUnit());317 processType(SP->getType());318 for (auto *Element : SP->getTemplateParams()) {319 if (auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) {320 processType(TType->getType());321 } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) {322 processType(TVal->getType());323 }324 }325 326 SP->forEachRetainedNode(327 [this](const DILocalVariable *LV) { processVariable(LV); },328 [](const DILabel *L) {},329 [this](const DIImportedEntity *IE) { processImportedEntity(IE); });330}331 332void DebugInfoFinder::processVariable(const DILocalVariable *DV) {333 if (!NodesSeen.insert(DV).second)334 return;335 processScope(DV->getScope());336 processType(DV->getType());337}338 339bool DebugInfoFinder::addType(DIType *DT) {340 if (!DT)341 return false;342 343 if (!NodesSeen.insert(DT).second)344 return false;345 346 TYs.push_back(DT);347 return true;348}349 350bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) {351 if (!CU)352 return false;353 if (!NodesSeen.insert(CU).second)354 return false;355 356 CUs.push_back(CU);357 return true;358}359 360bool DebugInfoFinder::addGlobalVariable(DIGlobalVariableExpression *DIG) {361 if (!NodesSeen.insert(DIG).second)362 return false;363 364 GVs.push_back(DIG);365 return true;366}367 368bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {369 if (!SP)370 return false;371 372 if (!NodesSeen.insert(SP).second)373 return false;374 375 SPs.push_back(SP);376 return true;377}378 379bool DebugInfoFinder::addScope(DIScope *Scope) {380 if (!Scope)381 return false;382 // FIXME: Ocaml binding generates a scope with no content, we treat it383 // as null for now.384 if (Scope->getNumOperands() == 0)385 return false;386 if (!NodesSeen.insert(Scope).second)387 return false;388 Scopes.push_back(Scope);389 return true;390}391 392/// Recursively handle DILocations in followup metadata etc.393///394/// TODO: If for example a followup loop metadata would reference itself this395/// function would go into infinite recursion. We do not expect such cycles in396/// the loop metadata (except for the self-referencing first element397/// "LoopID"). However, we could at least handle such situations more gracefully398/// somehow (e.g. by keeping track of visited nodes and dropping metadata).399static Metadata *updateLoopMetadataDebugLocationsRecursive(400 Metadata *MetadataIn, function_ref<Metadata *(Metadata *)> Updater) {401 const MDTuple *M = dyn_cast_or_null<MDTuple>(MetadataIn);402 // The loop metadata options should start with a MDString.403 if (!M || M->getNumOperands() < 1 || !isa<MDString>(M->getOperand(0)))404 return MetadataIn;405 406 bool Updated = false;407 SmallVector<Metadata *, 4> MDs{M->getOperand(0)};408 for (Metadata *MD : llvm::drop_begin(M->operands())) {409 if (!MD) {410 MDs.push_back(nullptr);411 continue;412 }413 Metadata *NewMD =414 Updater(updateLoopMetadataDebugLocationsRecursive(MD, Updater));415 if (NewMD)416 MDs.push_back(NewMD);417 Updated |= NewMD != MD;418 }419 420 assert(!M->isDistinct() && "M should not be distinct.");421 return Updated ? MDNode::get(M->getContext(), MDs) : MetadataIn;422}423 424static MDNode *updateLoopMetadataDebugLocationsImpl(425 MDNode *OrigLoopID, function_ref<Metadata *(Metadata *)> Updater) {426 assert(OrigLoopID && OrigLoopID->getNumOperands() > 0 &&427 "Loop ID needs at least one operand");428 assert(OrigLoopID && OrigLoopID->getOperand(0).get() == OrigLoopID &&429 "Loop ID should refer to itself");430 431 // Save space for the self-referential LoopID.432 SmallVector<Metadata *, 4> MDs = {nullptr};433 434 for (Metadata *MD : llvm::drop_begin(OrigLoopID->operands())) {435 if (!MD)436 MDs.push_back(nullptr);437 else if (Metadata *NewMD = Updater(438 updateLoopMetadataDebugLocationsRecursive(MD, Updater)))439 MDs.push_back(NewMD);440 }441 442 MDNode *NewLoopID = MDNode::getDistinct(OrigLoopID->getContext(), MDs);443 // Insert the self-referential LoopID.444 NewLoopID->replaceOperandWith(0, NewLoopID);445 return NewLoopID;446}447 448void llvm::updateLoopMetadataDebugLocations(449 Instruction &I, function_ref<Metadata *(Metadata *)> Updater) {450 MDNode *OrigLoopID = I.getMetadata(LLVMContext::MD_loop);451 if (!OrigLoopID)452 return;453 MDNode *NewLoopID = updateLoopMetadataDebugLocationsImpl(OrigLoopID, Updater);454 I.setMetadata(LLVMContext::MD_loop, NewLoopID);455}456 457/// Return true if a node is a DILocation or if a DILocation is458/// indirectly referenced by one of the node's children.459static bool isDILocationReachable(SmallPtrSetImpl<Metadata *> &Visited,460 SmallPtrSetImpl<Metadata *> &Reachable,461 Metadata *MD) {462 MDNode *N = dyn_cast_or_null<MDNode>(MD);463 if (!N)464 return false;465 if (isa<DILocation>(N) || Reachable.count(N))466 return true;467 if (!Visited.insert(N).second)468 return false;469 for (auto &OpIt : N->operands()) {470 Metadata *Op = OpIt.get();471 if (isDILocationReachable(Visited, Reachable, Op)) {472 // Don't return just yet as we want to visit all MD's children to473 // initialize DILocationReachable in stripDebugLocFromLoopID474 Reachable.insert(N);475 }476 }477 return Reachable.count(N);478}479 480static bool isAllDILocation(SmallPtrSetImpl<Metadata *> &Visited,481 SmallPtrSetImpl<Metadata *> &AllDILocation,482 const SmallPtrSetImpl<Metadata *> &DIReachable,483 Metadata *MD) {484 MDNode *N = dyn_cast_or_null<MDNode>(MD);485 if (!N)486 return false;487 if (isa<DILocation>(N) || AllDILocation.count(N))488 return true;489 if (!DIReachable.count(N))490 return false;491 if (!Visited.insert(N).second)492 return false;493 for (auto &OpIt : N->operands()) {494 Metadata *Op = OpIt.get();495 if (Op == MD)496 continue;497 if (!isAllDILocation(Visited, AllDILocation, DIReachable, Op)) {498 return false;499 }500 }501 AllDILocation.insert(N);502 return true;503}504 505static Metadata *506stripLoopMDLoc(const SmallPtrSetImpl<Metadata *> &AllDILocation,507 const SmallPtrSetImpl<Metadata *> &DIReachable, Metadata *MD) {508 if (isa<DILocation>(MD) || AllDILocation.count(MD))509 return nullptr;510 511 if (!DIReachable.count(MD))512 return MD;513 514 MDNode *N = dyn_cast_or_null<MDNode>(MD);515 if (!N)516 return MD;517 518 SmallVector<Metadata *, 4> Args;519 bool HasSelfRef = false;520 for (unsigned i = 0; i < N->getNumOperands(); ++i) {521 Metadata *A = N->getOperand(i);522 if (!A) {523 Args.push_back(nullptr);524 } else if (A == MD) {525 assert(i == 0 && "expected i==0 for self-reference");526 HasSelfRef = true;527 Args.push_back(nullptr);528 } else if (Metadata *NewArg =529 stripLoopMDLoc(AllDILocation, DIReachable, A)) {530 Args.push_back(NewArg);531 }532 }533 if (Args.empty() || (HasSelfRef && Args.size() == 1))534 return nullptr;535 536 MDNode *NewMD = N->isDistinct() ? MDNode::getDistinct(N->getContext(), Args)537 : MDNode::get(N->getContext(), Args);538 if (HasSelfRef)539 NewMD->replaceOperandWith(0, NewMD);540 return NewMD;541}542 543static MDNode *stripDebugLocFromLoopID(MDNode *N) {544 assert(!N->operands().empty() && "Missing self reference?");545 SmallPtrSet<Metadata *, 8> Visited, DILocationReachable, AllDILocation;546 // If we already visited N, there is nothing to do.547 if (!Visited.insert(N).second)548 return N;549 550 // If there is no debug location, we do not have to rewrite this551 // MDNode. This loop also initializes DILocationReachable, later552 // needed by updateLoopMetadataDebugLocationsImpl; the use of553 // count_if avoids an early exit.554 if (!llvm::count_if(llvm::drop_begin(N->operands()),555 [&Visited, &DILocationReachable](const MDOperand &Op) {556 return isDILocationReachable(557 Visited, DILocationReachable, Op.get());558 }))559 return N;560 561 Visited.clear();562 // If there is only the debug location without any actual loop metadata, we563 // can remove the metadata.564 if (llvm::all_of(llvm::drop_begin(N->operands()),565 [&Visited, &AllDILocation,566 &DILocationReachable](const MDOperand &Op) {567 return isAllDILocation(Visited, AllDILocation,568 DILocationReachable, Op.get());569 }))570 return nullptr;571 572 return updateLoopMetadataDebugLocationsImpl(573 N, [&AllDILocation, &DILocationReachable](Metadata *MD) -> Metadata * {574 return stripLoopMDLoc(AllDILocation, DILocationReachable, MD);575 });576}577 578bool llvm::stripDebugInfo(Function &F) {579 bool Changed = false;580 if (F.hasMetadata(LLVMContext::MD_dbg)) {581 Changed = true;582 F.setSubprogram(nullptr);583 }584 585 DenseMap<MDNode *, MDNode *> LoopIDsMap;586 for (BasicBlock &BB : F) {587 for (Instruction &I : llvm::make_early_inc_range(BB)) {588 if (I.getDebugLoc()) {589 Changed = true;590 I.setDebugLoc(DebugLoc());591 }592 if (auto *LoopID = I.getMetadata(LLVMContext::MD_loop)) {593 auto *NewLoopID = LoopIDsMap.lookup(LoopID);594 if (!NewLoopID)595 NewLoopID = LoopIDsMap[LoopID] = stripDebugLocFromLoopID(LoopID);596 if (NewLoopID != LoopID)597 I.setMetadata(LLVMContext::MD_loop, NewLoopID);598 }599 // Strip other attachments that are or use debug info.600 if (I.hasMetadataOtherThanDebugLoc()) {601 // Heapallocsites point into the DIType system.602 I.setMetadata("heapallocsite", nullptr);603 // DIAssignID are debug info metadata primitives.604 I.setMetadata(LLVMContext::MD_DIAssignID, nullptr);605 }606 I.dropDbgRecords();607 }608 }609 return Changed;610}611 612bool llvm::StripDebugInfo(Module &M) {613 llvm::TimeTraceScope timeScope("Strip debug info");614 bool Changed = false;615 616 for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata())) {617 // We're stripping debug info, and without them, coverage information618 // doesn't quite make sense.619 if (NMD.getName().starts_with("llvm.dbg.") ||620 NMD.getName() == "llvm.gcov") {621 NMD.eraseFromParent();622 Changed = true;623 }624 }625 626 for (Function &F : M)627 Changed |= stripDebugInfo(F);628 629 for (auto &GV : M.globals()) {630 Changed |= GV.eraseMetadata(LLVMContext::MD_dbg);631 }632 633 if (GVMaterializer *Materializer = M.getMaterializer())634 Materializer->setStripDebugInfo();635 636 return Changed;637}638 639namespace {640 641/// Helper class to downgrade -g metadata to -gline-tables-only metadata.642class DebugTypeInfoRemoval {643 DenseMap<Metadata *, Metadata *> Replacements;644 645public:646 /// The (void)() type.647 MDNode *EmptySubroutineType;648 649private:650 /// Remember what linkage name we originally had before stripping. If we end651 /// up making two subprograms identical who originally had different linkage652 /// names, then we need to make one of them distinct, to avoid them getting653 /// uniqued. Maps the new node to the old linkage name.654 DenseMap<DISubprogram *, StringRef> NewToLinkageName;655 656 // TODO: Remember the distinct subprogram we created for a given linkage name,657 // so that we can continue to unique whenever possible. Map <newly created658 // node, old linkage name> to the first (possibly distinct) mdsubprogram659 // created for that combination. This is not strictly needed for correctness,660 // but can cut down on the number of MDNodes and let us diff cleanly with the661 // output of -gline-tables-only.662 663public:664 DebugTypeInfoRemoval(LLVMContext &C)665 : EmptySubroutineType(DISubroutineType::get(C, DINode::FlagZero, 0,666 MDNode::get(C, {}))) {}667 668 Metadata *map(Metadata *M) {669 if (!M)670 return nullptr;671 auto Replacement = Replacements.find(M);672 if (Replacement != Replacements.end())673 return Replacement->second;674 675 return M;676 }677 MDNode *mapNode(Metadata *N) { return dyn_cast_or_null<MDNode>(map(N)); }678 679 /// Recursively remap N and all its referenced children. Does a DF post-order680 /// traversal, so as to remap bottoms up.681 void traverseAndRemap(MDNode *N) { traverse(N); }682 683private:684 // Create a new DISubprogram, to replace the one given.685 DISubprogram *getReplacementSubprogram(DISubprogram *MDS) {686 auto *FileAndScope = cast_or_null<DIFile>(map(MDS->getFile()));687 StringRef LinkageName = MDS->getName().empty() ? MDS->getLinkageName() : "";688 DISubprogram *Declaration = nullptr;689 auto *Type = cast_or_null<DISubroutineType>(map(MDS->getType()));690 DIType *ContainingType =691 cast_or_null<DIType>(map(MDS->getContainingType()));692 auto *Unit = cast_or_null<DICompileUnit>(map(MDS->getUnit()));693 auto Variables = nullptr;694 auto TemplateParams = nullptr;695 696 // Make a distinct DISubprogram, for situations that warrant it.697 auto distinctMDSubprogram = [&]() {698 return DISubprogram::getDistinct(699 MDS->getContext(), FileAndScope, MDS->getName(), LinkageName,700 FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(),701 ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(),702 MDS->getFlags(), MDS->getSPFlags(), Unit, TemplateParams, Declaration,703 Variables);704 };705 706 if (MDS->isDistinct())707 return distinctMDSubprogram();708 709 auto *NewMDS = DISubprogram::get(710 MDS->getContext(), FileAndScope, MDS->getName(), LinkageName,711 FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType,712 MDS->getVirtualIndex(), MDS->getThisAdjustment(), MDS->getFlags(),713 MDS->getSPFlags(), Unit, TemplateParams, Declaration, Variables);714 715 StringRef OldLinkageName = MDS->getLinkageName();716 717 // See if we need to make a distinct one.718 auto OrigLinkage = NewToLinkageName.find(NewMDS);719 if (OrigLinkage != NewToLinkageName.end()) {720 if (OrigLinkage->second == OldLinkageName)721 // We're good.722 return NewMDS;723 724 // Otherwise, need to make a distinct one.725 // TODO: Query the map to see if we already have one.726 return distinctMDSubprogram();727 }728 729 NewToLinkageName.insert({NewMDS, MDS->getLinkageName()});730 return NewMDS;731 }732 733 /// Create a new compile unit, to replace the one given734 DICompileUnit *getReplacementCU(DICompileUnit *CU) {735 // Drop skeleton CUs.736 if (CU->getDWOId())737 return nullptr;738 739 auto *File = cast_or_null<DIFile>(map(CU->getFile()));740 MDTuple *EnumTypes = nullptr;741 MDTuple *RetainedTypes = nullptr;742 MDTuple *GlobalVariables = nullptr;743 MDTuple *ImportedEntities = nullptr;744 return DICompileUnit::getDistinct(745 CU->getContext(), CU->getSourceLanguage(), File, CU->getProducer(),746 CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(),747 CU->getSplitDebugFilename(), DICompileUnit::LineTablesOnly, EnumTypes,748 RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(),749 CU->getDWOId(), CU->getSplitDebugInlining(),750 CU->getDebugInfoForProfiling(), CU->getNameTableKind(),751 CU->getRangesBaseAddress(), CU->getSysRoot(), CU->getSDK());752 }753 754 DILocation *getReplacementMDLocation(DILocation *MLD) {755 auto *Scope = map(MLD->getScope());756 auto *InlinedAt = map(MLD->getInlinedAt());757 if (MLD->isDistinct())758 return DILocation::getDistinct(MLD->getContext(), MLD->getLine(),759 MLD->getColumn(), Scope, InlinedAt);760 return DILocation::get(MLD->getContext(), MLD->getLine(), MLD->getColumn(),761 Scope, InlinedAt);762 }763 764 /// Create a new generic MDNode, to replace the one given765 MDNode *getReplacementMDNode(MDNode *N) {766 SmallVector<Metadata *, 8> Ops;767 Ops.reserve(N->getNumOperands());768 for (auto &I : N->operands())769 if (I)770 Ops.push_back(map(I));771 auto *Ret = MDNode::get(N->getContext(), Ops);772 return Ret;773 }774 775 /// Attempt to re-map N to a newly created node.776 void remap(MDNode *N) {777 if (Replacements.count(N))778 return;779 780 auto doRemap = [&](MDNode *N) -> MDNode * {781 if (!N)782 return nullptr;783 if (auto *MDSub = dyn_cast<DISubprogram>(N)) {784 remap(MDSub->getUnit());785 return getReplacementSubprogram(MDSub);786 }787 if (isa<DISubroutineType>(N))788 return EmptySubroutineType;789 if (auto *CU = dyn_cast<DICompileUnit>(N))790 return getReplacementCU(CU);791 if (isa<DIFile>(N))792 return N;793 if (auto *MDLB = dyn_cast<DILexicalBlockBase>(N))794 // Remap to our referenced scope (recursively).795 return mapNode(MDLB->getScope());796 if (auto *MLD = dyn_cast<DILocation>(N))797 return getReplacementMDLocation(MLD);798 799 // Otherwise, if we see these, just drop them now. Not strictly necessary,800 // but this speeds things up a little.801 if (isa<DINode>(N))802 return nullptr;803 804 return getReplacementMDNode(N);805 };806 // Separate recursive doRemap and operator [] into 2 lines to avoid807 // out-of-order evaluations since both of them can access the same memory808 // location in map Replacements.809 auto Value = doRemap(N);810 Replacements[N] = Value;811 }812 813 /// Do the remapping traversal.814 void traverse(MDNode *);815};816 817} // end anonymous namespace818 819void DebugTypeInfoRemoval::traverse(MDNode *N) {820 if (!N || Replacements.count(N))821 return;822 823 // To avoid cycles, as well as for efficiency sake, we will sometimes prune824 // parts of the graph.825 auto prune = [](MDNode *Parent, MDNode *Child) {826 if (auto *MDS = dyn_cast<DISubprogram>(Parent))827 return Child == MDS->getRetainedNodes().get();828 return false;829 };830 831 SmallVector<MDNode *, 16> ToVisit;832 DenseSet<MDNode *> Opened;833 834 // Visit each node starting at N in post order, and map them.835 ToVisit.push_back(N);836 while (!ToVisit.empty()) {837 auto *N = ToVisit.back();838 if (!Opened.insert(N).second) {839 // Close it.840 remap(N);841 ToVisit.pop_back();842 continue;843 }844 for (auto &I : N->operands())845 if (auto *MDN = dyn_cast_or_null<MDNode>(I))846 if (!Opened.count(MDN) && !Replacements.count(MDN) && !prune(N, MDN) &&847 !isa<DICompileUnit>(MDN))848 ToVisit.push_back(MDN);849 }850}851 852bool llvm::stripNonLineTableDebugInfo(Module &M) {853 bool Changed = false;854 855 // Delete non-CU debug info named metadata nodes.856 for (auto NMI = M.named_metadata_begin(), NME = M.named_metadata_end();857 NMI != NME;) {858 NamedMDNode *NMD = &*NMI;859 ++NMI;860 // Specifically keep dbg.cu around.861 if (NMD->getName() == "llvm.dbg.cu")862 continue;863 }864 865 // Drop all dbg attachments from global variables.866 for (auto &GV : M.globals())867 GV.eraseMetadata(LLVMContext::MD_dbg);868 869 DebugTypeInfoRemoval Mapper(M.getContext());870 auto remap = [&](MDNode *Node) -> MDNode * {871 if (!Node)872 return nullptr;873 Mapper.traverseAndRemap(Node);874 auto *NewNode = Mapper.mapNode(Node);875 Changed |= Node != NewNode;876 Node = NewNode;877 return NewNode;878 };879 880 // Rewrite the DebugLocs to be equivalent to what881 // -gline-tables-only would have created.882 for (auto &F : M) {883 if (auto *SP = F.getSubprogram()) {884 Mapper.traverseAndRemap(SP);885 auto *NewSP = cast<DISubprogram>(Mapper.mapNode(SP));886 Changed |= SP != NewSP;887 F.setSubprogram(NewSP);888 }889 for (auto &BB : F) {890 for (auto &I : BB) {891 auto remapDebugLoc = [&](const DebugLoc &DL) -> DebugLoc {892 auto *Scope = DL.getScope();893 MDNode *InlinedAt = DL.getInlinedAt();894 Scope = remap(Scope);895 InlinedAt = remap(InlinedAt);896 return DILocation::get(M.getContext(), DL.getLine(), DL.getCol(),897 Scope, InlinedAt);898 };899 900 if (I.getDebugLoc() != DebugLoc())901 I.setDebugLoc(remapDebugLoc(I.getDebugLoc()));902 903 // Remap DILocations in llvm.loop attachments.904 updateLoopMetadataDebugLocations(I, [&](Metadata *MD) -> Metadata * {905 if (auto *Loc = dyn_cast_or_null<DILocation>(MD))906 return remapDebugLoc(Loc).get();907 return MD;908 });909 910 // Strip heapallocsite attachments, they point into the DIType system.911 if (I.hasMetadataOtherThanDebugLoc())912 I.setMetadata("heapallocsite", nullptr);913 914 // Strip any DbgRecords attached.915 I.dropDbgRecords();916 }917 }918 }919 920 // Create a new llvm.dbg.cu, which is equivalent to the one921 // -gline-tables-only would have created.922 for (auto &NMD : M.named_metadata()) {923 SmallVector<MDNode *, 8> Ops;924 for (MDNode *Op : NMD.operands())925 Ops.push_back(remap(Op));926 927 if (!Changed)928 continue;929 930 NMD.clearOperands();931 for (auto *Op : Ops)932 if (Op)933 NMD.addOperand(Op);934 }935 return Changed;936}937 938unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {939 if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(940 M.getModuleFlag("Debug Info Version")))941 return Val->getZExtValue();942 return 0;943}944 945void Instruction::applyMergedLocation(DebugLoc LocA, DebugLoc LocB) {946 setDebugLoc(DebugLoc::getMergedLocation(LocA, LocB));947}948 949void Instruction::mergeDIAssignID(950 ArrayRef<const Instruction *> SourceInstructions) {951 // Replace all uses (and attachments) of all the DIAssignIDs952 // on SourceInstructions with a single merged value.953 assert(getFunction() && "Uninserted instruction merged");954 // Collect up the DIAssignID tags.955 SmallVector<DIAssignID *, 4> IDs;956 for (const Instruction *I : SourceInstructions) {957 if (auto *MD = I->getMetadata(LLVMContext::MD_DIAssignID))958 IDs.push_back(cast<DIAssignID>(MD));959 assert(getFunction() == I->getFunction() &&960 "Merging with instruction from another function not allowed");961 }962 963 // Add this instruction's DIAssignID too, if it has one.964 if (auto *MD = getMetadata(LLVMContext::MD_DIAssignID))965 IDs.push_back(cast<DIAssignID>(MD));966 967 if (IDs.empty())968 return; // No DIAssignID tags to process.969 970 DIAssignID *MergeID = IDs[0];971 for (DIAssignID *AssignID : drop_begin(IDs)) {972 if (AssignID != MergeID)973 at::RAUW(AssignID, MergeID);974 }975 setMetadata(LLVMContext::MD_DIAssignID, MergeID);976}977 978void Instruction::updateLocationAfterHoist() { dropLocation(); }979 980void Instruction::dropLocation() {981 const DebugLoc &DL = getDebugLoc();982 if (!DL) {983 setDebugLoc(DebugLoc::getDropped());984 return;985 }986 987 // If this isn't a call, drop the location to allow a location from a988 // preceding instruction to propagate.989 bool MayLowerToCall = false;990 if (isa<CallBase>(this)) {991 auto *II = dyn_cast<IntrinsicInst>(this);992 MayLowerToCall =993 !II || IntrinsicInst::mayLowerToFunctionCall(II->getIntrinsicID());994 }995 996 if (!MayLowerToCall) {997 setDebugLoc(DebugLoc::getDropped());998 return;999 }1000 1001 // Set a line 0 location for calls to preserve scope information in case1002 // inlining occurs.1003 DISubprogram *SP = getFunction()->getSubprogram();1004 if (SP)1005 // If a function scope is available, set it on the line 0 location. When1006 // hoisting a call to a predecessor block, using the function scope avoids1007 // making it look like the callee was reached earlier than it should be.1008 setDebugLoc(DILocation::get(getContext(), 0, 0, SP));1009 else1010 // The parent function has no scope. Go ahead and drop the location. If1011 // the parent function is inlined, and the callee has a subprogram, the1012 // inliner will attach a location to the call.1013 //1014 // One alternative is to set a line 0 location with the existing scope and1015 // inlinedAt info. The location might be sensitive to when inlining occurs.1016 setDebugLoc(DebugLoc::getDropped());1017}1018 1019//===----------------------------------------------------------------------===//1020// LLVM C API implementations.1021//===----------------------------------------------------------------------===//1022 1023static unsigned map_from_llvmDWARFsourcelanguage(LLVMDWARFSourceLanguage lang) {1024 switch (lang) {1025#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \1026 case LLVMDWARFSourceLanguage##NAME: \1027 return ID;1028#include "llvm/BinaryFormat/Dwarf.def"1029#undef HANDLE_DW_LANG1030 }1031 llvm_unreachable("Unhandled Tag");1032}1033 1034template <typename DIT> DIT *unwrapDI(LLVMMetadataRef Ref) {1035 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);1036}1037 1038static DINode::DIFlags map_from_llvmDIFlags(LLVMDIFlags Flags) {1039 return static_cast<DINode::DIFlags>(Flags);1040}1041 1042static LLVMDIFlags map_to_llvmDIFlags(DINode::DIFlags Flags) {1043 return static_cast<LLVMDIFlags>(Flags);1044}1045 1046static DISubprogram::DISPFlags1047pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) {1048 return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized);1049}1050 1051unsigned LLVMDebugMetadataVersion() {1052 return DEBUG_METADATA_VERSION;1053}1054 1055LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M) {1056 return wrap(new DIBuilder(*unwrap(M), false));1057}1058 1059LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M) {1060 return wrap(new DIBuilder(*unwrap(M)));1061}1062 1063unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef M) {1064 return getDebugMetadataVersionFromModule(*unwrap(M));1065}1066 1067LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef M) {1068 return StripDebugInfo(*unwrap(M));1069}1070 1071void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder) {1072 delete unwrap(Builder);1073}1074 1075void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder) {1076 unwrap(Builder)->finalize();1077}1078 1079void LLVMDIBuilderFinalizeSubprogram(LLVMDIBuilderRef Builder,1080 LLVMMetadataRef subprogram) {1081 unwrap(Builder)->finalizeSubprogram(unwrapDI<DISubprogram>(subprogram));1082}1083 1084LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(1085 LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,1086 LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,1087 LLVMBool isOptimized, const char *Flags, size_t FlagsLen,1088 unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,1089 LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,1090 LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen,1091 const char *SDK, size_t SDKLen) {1092 auto File = unwrapDI<DIFile>(FileRef);1093 1094 return wrap(unwrap(Builder)->createCompileUnit(1095 DISourceLanguageName(map_from_llvmDWARFsourcelanguage(Lang)), File,1096 StringRef(Producer, ProducerLen), isOptimized, StringRef(Flags, FlagsLen),1097 RuntimeVer, StringRef(SplitName, SplitNameLen),1098 static_cast<DICompileUnit::DebugEmissionKind>(Kind), DWOId,1099 SplitDebugInlining, DebugInfoForProfiling,1100 DICompileUnit::DebugNameTableKind::Default, false,1101 StringRef(SysRoot, SysRootLen), StringRef(SDK, SDKLen)));1102}1103 1104LLVMMetadataRef1105LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,1106 size_t FilenameLen, const char *Directory,1107 size_t DirectoryLen) {1108 return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),1109 StringRef(Directory, DirectoryLen)));1110}1111 1112static llvm::DIFile::ChecksumKind1113map_from_llvmChecksumKind(LLVMChecksumKind CSKind) {1114 switch (CSKind) {1115 case LLVMChecksumKind::CSK_MD5:1116 return llvm::DIFile::CSK_MD5;1117 case LLVMChecksumKind::CSK_SHA1:1118 return llvm::DIFile::CSK_SHA1;1119 case LLVMChecksumKind::CSK_SHA256:1120 return llvm::DIFile::CSK_SHA256;1121 }1122 llvm_unreachable("Unhandled Checksum Kind");1123}1124 1125LLVMMetadataRef LLVMDIBuilderCreateFileWithChecksum(1126 LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen,1127 const char *Directory, size_t DirectoryLen, LLVMChecksumKind ChecksumKind,1128 const char *Checksum, size_t ChecksumLen, const char *Source,1129 size_t SourceLen) {1130 StringRef ChkSum = StringRef(Checksum, ChecksumLen);1131 auto CSK = map_from_llvmChecksumKind(ChecksumKind);1132 llvm::DIFile::ChecksumInfo<StringRef> CSInfo(CSK, ChkSum);1133 std::optional<StringRef> Src;1134 if (SourceLen > 0)1135 Src = StringRef(Source, SourceLen);1136 return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),1137 StringRef(Directory, DirectoryLen),1138 CSInfo, Src));1139}1140 1141LLVMMetadataRef1142LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope,1143 const char *Name, size_t NameLen,1144 const char *ConfigMacros, size_t ConfigMacrosLen,1145 const char *IncludePath, size_t IncludePathLen,1146 const char *APINotesFile, size_t APINotesFileLen) {1147 return wrap(unwrap(Builder)->createModule(1148 unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen),1149 StringRef(ConfigMacros, ConfigMacrosLen),1150 StringRef(IncludePath, IncludePathLen),1151 StringRef(APINotesFile, APINotesFileLen)));1152}1153 1154LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder,1155 LLVMMetadataRef ParentScope,1156 const char *Name, size_t NameLen,1157 LLVMBool ExportSymbols) {1158 return wrap(unwrap(Builder)->createNameSpace(1159 unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen), ExportSymbols));1160}1161 1162LLVMMetadataRef LLVMDIBuilderCreateFunction(1163 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1164 size_t NameLen, const char *LinkageName, size_t LinkageNameLen,1165 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,1166 LLVMBool IsLocalToUnit, LLVMBool IsDefinition,1167 unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) {1168 return wrap(unwrap(Builder)->createFunction(1169 unwrapDI<DIScope>(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen},1170 unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine,1171 map_from_llvmDIFlags(Flags),1172 pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr,1173 nullptr, nullptr));1174}1175 1176 1177LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(1178 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,1179 LLVMMetadataRef File, unsigned Line, unsigned Col) {1180 return wrap(unwrap(Builder)->createLexicalBlock(unwrapDI<DIScope>(Scope),1181 unwrapDI<DIFile>(File),1182 Line, Col));1183}1184 1185LLVMMetadataRef1186LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Builder,1187 LLVMMetadataRef Scope,1188 LLVMMetadataRef File,1189 unsigned Discriminator) {1190 return wrap(unwrap(Builder)->createLexicalBlockFile(unwrapDI<DIScope>(Scope),1191 unwrapDI<DIFile>(File),1192 Discriminator));1193}1194 1195LLVMMetadataRef1196LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder,1197 LLVMMetadataRef Scope,1198 LLVMMetadataRef NS,1199 LLVMMetadataRef File,1200 unsigned Line) {1201 return wrap(unwrap(Builder)->createImportedModule(unwrapDI<DIScope>(Scope),1202 unwrapDI<DINamespace>(NS),1203 unwrapDI<DIFile>(File),1204 Line));1205}1206 1207LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias(1208 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,1209 LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line,1210 LLVMMetadataRef *Elements, unsigned NumElements) {1211 auto Elts =1212 (NumElements > 0)1213 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})1214 : nullptr;1215 return wrap(unwrap(Builder)->createImportedModule(1216 unwrapDI<DIScope>(Scope), unwrapDI<DIImportedEntity>(ImportedEntity),1217 unwrapDI<DIFile>(File), Line, Elts));1218}1219 1220LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule(1221 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M,1222 LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements,1223 unsigned NumElements) {1224 auto Elts =1225 (NumElements > 0)1226 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})1227 : nullptr;1228 return wrap(unwrap(Builder)->createImportedModule(1229 unwrapDI<DIScope>(Scope), unwrapDI<DIModule>(M), unwrapDI<DIFile>(File),1230 Line, Elts));1231}1232 1233LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration(1234 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl,1235 LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen,1236 LLVMMetadataRef *Elements, unsigned NumElements) {1237 auto Elts =1238 (NumElements > 0)1239 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})1240 : nullptr;1241 return wrap(unwrap(Builder)->createImportedDeclaration(1242 unwrapDI<DIScope>(Scope), unwrapDI<DINode>(Decl), unwrapDI<DIFile>(File),1243 Line, {Name, NameLen}, Elts));1244}1245 1246LLVMMetadataRef1247LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,1248 unsigned Column, LLVMMetadataRef Scope,1249 LLVMMetadataRef InlinedAt) {1250 return wrap(DILocation::get(*unwrap(Ctx), Line, Column, unwrap(Scope),1251 unwrap(InlinedAt)));1252}1253 1254unsigned LLVMDILocationGetLine(LLVMMetadataRef Location) {1255 return unwrapDI<DILocation>(Location)->getLine();1256}1257 1258unsigned LLVMDILocationGetColumn(LLVMMetadataRef Location) {1259 return unwrapDI<DILocation>(Location)->getColumn();1260}1261 1262LLVMMetadataRef LLVMDILocationGetScope(LLVMMetadataRef Location) {1263 return wrap(unwrapDI<DILocation>(Location)->getScope());1264}1265 1266LLVMMetadataRef LLVMDILocationGetInlinedAt(LLVMMetadataRef Location) {1267 return wrap(unwrapDI<DILocation>(Location)->getInlinedAt());1268}1269 1270LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope) {1271 return wrap(unwrapDI<DIScope>(Scope)->getFile());1272}1273 1274const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len) {1275 auto Dir = unwrapDI<DIFile>(File)->getDirectory();1276 *Len = Dir.size();1277 return Dir.data();1278}1279 1280const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len) {1281 auto Name = unwrapDI<DIFile>(File)->getFilename();1282 *Len = Name.size();1283 return Name.data();1284}1285 1286const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len) {1287 if (auto Src = unwrapDI<DIFile>(File)->getSource()) {1288 *Len = Src->size();1289 return Src->data();1290 }1291 *Len = 0;1292 return "";1293}1294 1295LLVMMetadataRef LLVMDIBuilderCreateMacro(LLVMDIBuilderRef Builder,1296 LLVMMetadataRef ParentMacroFile,1297 unsigned Line,1298 LLVMDWARFMacinfoRecordType RecordType,1299 const char *Name, size_t NameLen,1300 const char *Value, size_t ValueLen) {1301 return wrap(1302 unwrap(Builder)->createMacro(unwrapDI<DIMacroFile>(ParentMacroFile), Line,1303 static_cast<MacinfoRecordType>(RecordType),1304 {Name, NameLen}, {Value, ValueLen}));1305}1306 1307LLVMMetadataRef1308LLVMDIBuilderCreateTempMacroFile(LLVMDIBuilderRef Builder,1309 LLVMMetadataRef ParentMacroFile, unsigned Line,1310 LLVMMetadataRef File) {1311 return wrap(unwrap(Builder)->createTempMacroFile(1312 unwrapDI<DIMacroFile>(ParentMacroFile), Line, unwrapDI<DIFile>(File)));1313}1314 1315LLVMMetadataRef LLVMDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder,1316 const char *Name, size_t NameLen,1317 int64_t Value,1318 LLVMBool IsUnsigned) {1319 return wrap(unwrap(Builder)->createEnumerator({Name, NameLen}, Value,1320 IsUnsigned != 0));1321}1322 1323LLVMMetadataRef LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(1324 LLVMDIBuilderRef Builder, const char *Name, size_t NameLen,1325 uint64_t SizeInBits, const uint64_t Words[], LLVMBool IsUnsigned) {1326 uint64_t NumWords = (SizeInBits + 63) / 64;1327 return wrap(unwrap(Builder)->createEnumerator(1328 {Name, NameLen},1329 APSInt(APInt(SizeInBits, ArrayRef(Words, NumWords)), IsUnsigned != 0)));1330}1331 1332LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(1333 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1334 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,1335 uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef *Elements,1336 unsigned NumElements, LLVMMetadataRef ClassTy) {1337auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),1338 NumElements});1339return wrap(unwrap(Builder)->createEnumerationType(1340 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1341 LineNumber, SizeInBits, AlignInBits, Elts, unwrapDI<DIType>(ClassTy)));1342}1343 1344LLVMMetadataRef LLVMDIBuilderCreateSetType(1345 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1346 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,1347 uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef BaseTy) {1348 return wrap(unwrap(Builder)->createSetType(1349 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1350 LineNumber, SizeInBits, AlignInBits, unwrapDI<DIType>(BaseTy)));1351}1352 1353LLVMMetadataRef LLVMDIBuilderCreateSubrangeType(1354 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1355 size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t SizeInBits,1356 uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef BaseTy,1357 LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound,1358 LLVMMetadataRef Stride, LLVMMetadataRef Bias) {1359 return wrap(unwrap(Builder)->createSubrangeType(1360 {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, unwrapDI<DIScope>(Scope),1361 SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),1362 unwrapDI<DIType>(BaseTy), unwrap(LowerBound), unwrap(UpperBound),1363 unwrap(Stride), unwrap(Bias)));1364}1365 1366/// MD may be nullptr, a DIExpression or DIVariable.1367PointerUnion<DIExpression *, DIVariable *> unwrapExprVar(LLVMMetadataRef MD) {1368 if (!MD)1369 return nullptr;1370 MDNode *MDN = unwrapDI<MDNode>(MD);1371 if (auto *E = dyn_cast<DIExpression>(MDN))1372 return E;1373 assert(isa<DIVariable>(MDN) && "Expected DIExpression or DIVariable");1374 return cast<DIVariable>(MDN);1375}1376 1377LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType(1378 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1379 size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t Size,1380 uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts,1381 unsigned NumSubscripts, LLVMMetadataRef DataLocation,1382 LLVMMetadataRef Associated, LLVMMetadataRef Allocated, LLVMMetadataRef Rank,1383 LLVMMetadataRef BitStride) {1384 auto Subs =1385 unwrap(Builder)->getOrCreateArray({unwrap(Subscripts), NumSubscripts});1386 return wrap(unwrap(Builder)->createArrayType(1387 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,1388 Size, AlignInBits, unwrapDI<DIType>(Ty), Subs,1389 unwrapExprVar(DataLocation), unwrapExprVar(Associated),1390 unwrapExprVar(Allocated), unwrapExprVar(Rank), unwrap(BitStride)));1391}1392 1393void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T,1394 LLVMMetadataRef *Elements, unsigned NumElements) {1395 auto CT = unwrap<DICompositeType>(*T);1396 auto Elts =1397 unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements});1398 unwrap(Builder)->replaceArrays(CT, Elts);1399}1400 1401LLVMMetadataRef LLVMDIBuilderCreateUnionType(1402 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1403 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,1404 uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,1405 LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang,1406 const char *UniqueId, size_t UniqueIdLen) {1407 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),1408 NumElements});1409 return wrap(unwrap(Builder)->createUnionType(1410 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1411 LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),1412 Elts, RunTimeLang, {UniqueId, UniqueIdLen}));1413}1414 1415 1416LLVMMetadataRef1417LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size,1418 uint32_t AlignInBits, LLVMMetadataRef Ty,1419 LLVMMetadataRef *Subscripts,1420 unsigned NumSubscripts) {1421 auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),1422 NumSubscripts});1423 return wrap(unwrap(Builder)->createArrayType(Size, AlignInBits,1424 unwrapDI<DIType>(Ty), Subs));1425}1426 1427LLVMMetadataRef1428LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size,1429 uint32_t AlignInBits, LLVMMetadataRef Ty,1430 LLVMMetadataRef *Subscripts,1431 unsigned NumSubscripts) {1432 auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),1433 NumSubscripts});1434 return wrap(unwrap(Builder)->createVectorType(Size, AlignInBits,1435 unwrapDI<DIType>(Ty), Subs));1436}1437 1438LLVMMetadataRef1439LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,1440 size_t NameLen, uint64_t SizeInBits,1441 LLVMDWARFTypeEncoding Encoding,1442 LLVMDIFlags Flags) {1443 return wrap(unwrap(Builder)->createBasicType({Name, NameLen},1444 SizeInBits, Encoding,1445 map_from_llvmDIFlags(Flags)));1446}1447 1448LLVMMetadataRef LLVMDIBuilderCreatePointerType(1449 LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy,1450 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,1451 const char *Name, size_t NameLen) {1452 return wrap(unwrap(Builder)->createPointerType(1453 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace,1454 {Name, NameLen}));1455}1456 1457LLVMMetadataRef LLVMDIBuilderCreateStructType(1458 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1459 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,1460 uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,1461 LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements,1462 unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder,1463 const char *UniqueId, size_t UniqueIdLen) {1464 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),1465 NumElements});1466 return wrap(unwrap(Builder)->createStructType(1467 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1468 LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),1469 unwrapDI<DIType>(DerivedFrom), Elts, RunTimeLang,1470 unwrapDI<DIType>(VTableHolder), {UniqueId, UniqueIdLen}));1471}1472 1473LLVMMetadataRef LLVMDIBuilderCreateMemberType(1474 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1475 size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,1476 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,1477 LLVMMetadataRef Ty) {1478 return wrap(unwrap(Builder)->createMemberType(unwrapDI<DIScope>(Scope),1479 {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits,1480 OffsetInBits, map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Ty)));1481}1482 1483LLVMMetadataRef1484LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name,1485 size_t NameLen) {1486 return wrap(unwrap(Builder)->createUnspecifiedType({Name, NameLen}));1487}1488 1489LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType(1490 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1491 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,1492 LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal,1493 uint32_t AlignInBits) {1494 return wrap(unwrap(Builder)->createStaticMemberType(1495 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1496 LineNumber, unwrapDI<DIType>(Type), map_from_llvmDIFlags(Flags),1497 unwrap<Constant>(ConstantVal), DW_TAG_member, AlignInBits));1498}1499 1500LLVMMetadataRef1501LLVMDIBuilderCreateObjCIVar(LLVMDIBuilderRef Builder,1502 const char *Name, size_t NameLen,1503 LLVMMetadataRef File, unsigned LineNo,1504 uint64_t SizeInBits, uint32_t AlignInBits,1505 uint64_t OffsetInBits, LLVMDIFlags Flags,1506 LLVMMetadataRef Ty, LLVMMetadataRef PropertyNode) {1507 return wrap(unwrap(Builder)->createObjCIVar(1508 {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,1509 SizeInBits, AlignInBits, OffsetInBits,1510 map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Ty),1511 unwrapDI<MDNode>(PropertyNode)));1512}1513 1514LLVMMetadataRef1515LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,1516 const char *Name, size_t NameLen,1517 LLVMMetadataRef File, unsigned LineNo,1518 const char *GetterName, size_t GetterNameLen,1519 const char *SetterName, size_t SetterNameLen,1520 unsigned PropertyAttributes,1521 LLVMMetadataRef Ty) {1522 return wrap(unwrap(Builder)->createObjCProperty(1523 {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,1524 {GetterName, GetterNameLen}, {SetterName, SetterNameLen},1525 PropertyAttributes, unwrapDI<DIType>(Ty)));1526}1527 1528LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,1529 LLVMMetadataRef Type,1530 LLVMBool Implicit) {1531 return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI<DIType>(Type),1532 Implicit));1533}1534 1535LLVMMetadataRef1536LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type,1537 const char *Name, size_t NameLen,1538 LLVMMetadataRef File, unsigned LineNo,1539 LLVMMetadataRef Scope, uint32_t AlignInBits) {1540 return wrap(unwrap(Builder)->createTypedef(1541 unwrapDI<DIType>(Type), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,1542 unwrapDI<DIScope>(Scope), AlignInBits));1543}1544 1545LLVMMetadataRef1546LLVMDIBuilderCreateInheritance(LLVMDIBuilderRef Builder,1547 LLVMMetadataRef Ty, LLVMMetadataRef BaseTy,1548 uint64_t BaseOffset, uint32_t VBPtrOffset,1549 LLVMDIFlags Flags) {1550 return wrap(unwrap(Builder)->createInheritance(1551 unwrapDI<DIType>(Ty), unwrapDI<DIType>(BaseTy),1552 BaseOffset, VBPtrOffset, map_from_llvmDIFlags(Flags)));1553}1554 1555LLVMMetadataRef1556LLVMDIBuilderCreateForwardDecl(1557 LLVMDIBuilderRef Builder, unsigned Tag, const char *Name,1558 size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,1559 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,1560 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {1561 return wrap(unwrap(Builder)->createForwardDecl(1562 Tag, {Name, NameLen}, unwrapDI<DIScope>(Scope),1563 unwrapDI<DIFile>(File), Line, RuntimeLang, SizeInBits,1564 AlignInBits, {UniqueIdentifier, UniqueIdentifierLen}));1565}1566 1567LLVMMetadataRef1568LLVMDIBuilderCreateReplaceableCompositeType(1569 LLVMDIBuilderRef Builder, unsigned Tag, const char *Name,1570 size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,1571 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,1572 LLVMDIFlags Flags, const char *UniqueIdentifier,1573 size_t UniqueIdentifierLen) {1574 return wrap(unwrap(Builder)->createReplaceableCompositeType(1575 Tag, {Name, NameLen}, unwrapDI<DIScope>(Scope),1576 unwrapDI<DIFile>(File), Line, RuntimeLang, SizeInBits,1577 AlignInBits, map_from_llvmDIFlags(Flags),1578 {UniqueIdentifier, UniqueIdentifierLen}));1579}1580 1581LLVMMetadataRef1582LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,1583 LLVMMetadataRef Type) {1584 return wrap(unwrap(Builder)->createQualifiedType(Tag,1585 unwrapDI<DIType>(Type)));1586}1587 1588LLVMMetadataRef1589LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag,1590 LLVMMetadataRef Type) {1591 return wrap(unwrap(Builder)->createReferenceType(Tag,1592 unwrapDI<DIType>(Type)));1593}1594 1595LLVMMetadataRef1596LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder) {1597 return wrap(unwrap(Builder)->createNullPtrType());1598}1599 1600LLVMMetadataRef1601LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder,1602 LLVMMetadataRef PointeeType,1603 LLVMMetadataRef ClassType,1604 uint64_t SizeInBits,1605 uint32_t AlignInBits,1606 LLVMDIFlags Flags) {1607 return wrap(unwrap(Builder)->createMemberPointerType(1608 unwrapDI<DIType>(PointeeType),1609 unwrapDI<DIType>(ClassType), AlignInBits, SizeInBits,1610 map_from_llvmDIFlags(Flags)));1611}1612 1613LLVMMetadataRef1614LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder,1615 LLVMMetadataRef Scope,1616 const char *Name, size_t NameLen,1617 LLVMMetadataRef File, unsigned LineNumber,1618 uint64_t SizeInBits,1619 uint64_t OffsetInBits,1620 uint64_t StorageOffsetInBits,1621 LLVMDIFlags Flags, LLVMMetadataRef Type) {1622 return wrap(unwrap(Builder)->createBitFieldMemberType(1623 unwrapDI<DIScope>(Scope), {Name, NameLen},1624 unwrapDI<DIFile>(File), LineNumber,1625 SizeInBits, OffsetInBits, StorageOffsetInBits,1626 map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Type)));1627}1628 1629LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder,1630 LLVMMetadataRef Scope, const char *Name, size_t NameLen,1631 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,1632 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,1633 LLVMMetadataRef DerivedFrom,1634 LLVMMetadataRef *Elements, unsigned NumElements,1635 LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode,1636 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {1637 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),1638 NumElements});1639 return wrap(unwrap(Builder)->createClassType(1640 unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),1641 LineNumber, SizeInBits, AlignInBits, OffsetInBits,1642 map_from_llvmDIFlags(Flags), unwrapDI<DIType>(DerivedFrom), Elts,1643 /*RunTimeLang=*/0, unwrapDI<DIType>(VTableHolder),1644 unwrapDI<MDNode>(TemplateParamsNode),1645 {UniqueIdentifier, UniqueIdentifierLen}));1646}1647 1648LLVMMetadataRef1649LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder,1650 LLVMMetadataRef Type) {1651 return wrap(unwrap(Builder)->createArtificialType(unwrapDI<DIType>(Type)));1652}1653 1654uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD) {1655 return unwrapDI<DINode>(MD)->getTag();1656}1657 1658const char *LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length) {1659 StringRef Str = unwrapDI<DIType>(DType)->getName();1660 *Length = Str.size();1661 return Str.data();1662}1663 1664uint64_t LLVMDITypeGetSizeInBits(LLVMMetadataRef DType) {1665 return unwrapDI<DIType>(DType)->getSizeInBits();1666}1667 1668uint64_t LLVMDITypeGetOffsetInBits(LLVMMetadataRef DType) {1669 return unwrapDI<DIType>(DType)->getOffsetInBits();1670}1671 1672uint32_t LLVMDITypeGetAlignInBits(LLVMMetadataRef DType) {1673 return unwrapDI<DIType>(DType)->getAlignInBits();1674}1675 1676unsigned LLVMDITypeGetLine(LLVMMetadataRef DType) {1677 return unwrapDI<DIType>(DType)->getLine();1678}1679 1680LLVMDIFlags LLVMDITypeGetFlags(LLVMMetadataRef DType) {1681 return map_to_llvmDIFlags(unwrapDI<DIType>(DType)->getFlags());1682}1683 1684LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder,1685 LLVMMetadataRef *Types,1686 size_t Length) {1687 return wrap(1688 unwrap(Builder)->getOrCreateTypeArray({unwrap(Types), Length}).get());1689}1690 1691LLVMMetadataRef1692LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,1693 LLVMMetadataRef File,1694 LLVMMetadataRef *ParameterTypes,1695 unsigned NumParameterTypes,1696 LLVMDIFlags Flags) {1697 auto Elts = unwrap(Builder)->getOrCreateTypeArray({unwrap(ParameterTypes),1698 NumParameterTypes});1699 return wrap(unwrap(Builder)->createSubroutineType(1700 Elts, map_from_llvmDIFlags(Flags)));1701}1702 1703LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,1704 uint64_t *Addr, size_t Length) {1705 return wrap(1706 unwrap(Builder)->createExpression(ArrayRef<uint64_t>(Addr, Length)));1707}1708 1709LLVMMetadataRef1710LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,1711 uint64_t Value) {1712 return wrap(unwrap(Builder)->createConstantValueExpression(Value));1713}1714 1715LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(1716 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1717 size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,1718 unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,1719 LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) {1720 return wrap(unwrap(Builder)->createGlobalVariableExpression(1721 unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},1722 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,1723 true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),1724 nullptr, AlignInBits));1725}1726 1727LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) {1728 return wrap(unwrapDI<DIGlobalVariableExpression>(GVE)->getVariable());1729}1730 1731LLVMMetadataRef LLVMDIGlobalVariableExpressionGetExpression(1732 LLVMMetadataRef GVE) {1733 return wrap(unwrapDI<DIGlobalVariableExpression>(GVE)->getExpression());1734}1735 1736LLVMMetadataRef LLVMDIVariableGetFile(LLVMMetadataRef Var) {1737 return wrap(unwrapDI<DIVariable>(Var)->getFile());1738}1739 1740LLVMMetadataRef LLVMDIVariableGetScope(LLVMMetadataRef Var) {1741 return wrap(unwrapDI<DIVariable>(Var)->getScope());1742}1743 1744unsigned LLVMDIVariableGetLine(LLVMMetadataRef Var) {1745 return unwrapDI<DIVariable>(Var)->getLine();1746}1747 1748LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data,1749 size_t Count) {1750 return wrap(1751 MDTuple::getTemporary(*unwrap(Ctx), {unwrap(Data), Count}).release());1752}1753 1754void LLVMDisposeTemporaryMDNode(LLVMMetadataRef TempNode) {1755 MDNode::deleteTemporary(unwrapDI<MDNode>(TempNode));1756}1757 1758void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TargetMetadata,1759 LLVMMetadataRef Replacement) {1760 auto *Node = unwrapDI<MDNode>(TargetMetadata);1761 Node->replaceAllUsesWith(unwrap(Replacement));1762 MDNode::deleteTemporary(Node);1763}1764 1765LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(1766 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1767 size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,1768 unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,1769 LLVMMetadataRef Decl, uint32_t AlignInBits) {1770 return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl(1771 unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen},1772 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,1773 unwrapDI<MDNode>(Decl), nullptr, AlignInBits));1774}1775 1776LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore(1777 LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,1778 LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) {1779 DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare(1780 unwrap(Storage), unwrap<DILocalVariable>(VarInfo),1781 unwrap<DIExpression>(Expr), unwrap<DILocation>(DL),1782 Instr ? InsertPosition(unwrap<Instruction>(Instr)->getIterator())1783 : nullptr);1784 // This assert will fail if the module is in the old debug info format.1785 // This function should only be called if the module is in the new1786 // debug info format.1787 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1788 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1789 assert(isa<DbgRecord *>(DbgInst) &&1790 "Function unexpectedly in old debug info format");1791 return wrap(cast<DbgRecord *>(DbgInst));1792}1793 1794LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd(1795 LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,1796 LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) {1797 DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare(1798 unwrap(Storage), unwrap<DILocalVariable>(VarInfo),1799 unwrap<DIExpression>(Expr), unwrap<DILocation>(DL), unwrap(Block));1800 // This assert will fail if the module is in the old debug info format.1801 // This function should only be called if the module is in the new1802 // debug info format.1803 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1804 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1805 assert(isa<DbgRecord *>(DbgInst) &&1806 "Function unexpectedly in old debug info format");1807 return wrap(cast<DbgRecord *>(DbgInst));1808}1809 1810LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore(1811 LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo,1812 LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr) {1813 DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic(1814 unwrap(Val), unwrap<DILocalVariable>(VarInfo), unwrap<DIExpression>(Expr),1815 unwrap<DILocation>(DebugLoc),1816 Instr ? InsertPosition(unwrap<Instruction>(Instr)->getIterator())1817 : nullptr);1818 // This assert will fail if the module is in the old debug info format.1819 // This function should only be called if the module is in the new1820 // debug info format.1821 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1822 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1823 assert(isa<DbgRecord *>(DbgInst) &&1824 "Function unexpectedly in old debug info format");1825 return wrap(cast<DbgRecord *>(DbgInst));1826}1827 1828LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordAtEnd(1829 LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo,1830 LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) {1831 DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic(1832 unwrap(Val), unwrap<DILocalVariable>(VarInfo), unwrap<DIExpression>(Expr),1833 unwrap<DILocation>(DebugLoc),1834 Block ? InsertPosition(unwrap(Block)->end()) : nullptr);1835 // This assert will fail if the module is in the old debug info format.1836 // This function should only be called if the module is in the new1837 // debug info format.1838 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1839 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1840 assert(isa<DbgRecord *>(DbgInst) &&1841 "Function unexpectedly in old debug info format");1842 return wrap(cast<DbgRecord *>(DbgInst));1843}1844 1845LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(1846 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1847 size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,1848 LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits) {1849 return wrap(unwrap(Builder)->createAutoVariable(1850 unwrap<DIScope>(Scope), {Name, NameLen}, unwrap<DIFile>(File),1851 LineNo, unwrap<DIType>(Ty), AlwaysPreserve,1852 map_from_llvmDIFlags(Flags), AlignInBits));1853}1854 1855LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(1856 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,1857 size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo,1858 LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags) {1859 return wrap(unwrap(Builder)->createParameterVariable(1860 unwrap<DIScope>(Scope), {Name, NameLen}, ArgNo, unwrap<DIFile>(File),1861 LineNo, unwrap<DIType>(Ty), AlwaysPreserve,1862 map_from_llvmDIFlags(Flags)));1863}1864 1865LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder,1866 int64_t Lo, int64_t Count) {1867 return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count));1868}1869 1870LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder,1871 LLVMMetadataRef *Data,1872 size_t Length) {1873 Metadata **DataValue = unwrap(Data);1874 return wrap(unwrap(Builder)->getOrCreateArray({DataValue, Length}).get());1875}1876 1877LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func) {1878 return wrap(unwrap<Function>(Func)->getSubprogram());1879}1880 1881void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP) {1882 unwrap<Function>(Func)->setSubprogram(unwrap<DISubprogram>(SP));1883}1884 1885unsigned LLVMDISubprogramGetLine(LLVMMetadataRef Subprogram) {1886 return unwrapDI<DISubprogram>(Subprogram)->getLine();1887}1888 1889void LLVMDISubprogramReplaceType(LLVMMetadataRef Subprogram,1890 LLVMMetadataRef SubroutineType) {1891 unwrapDI<DISubprogram>(Subprogram)1892 ->replaceType(unwrapDI<DISubroutineType>(SubroutineType));1893}1894 1895LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst) {1896 return wrap(unwrap<Instruction>(Inst)->getDebugLoc().getAsMDNode());1897}1898 1899void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc) {1900 if (Loc)1901 unwrap<Instruction>(Inst)->setDebugLoc(DebugLoc(unwrap<MDNode>(Loc)));1902 else1903 unwrap<Instruction>(Inst)->setDebugLoc(DebugLoc());1904}1905 1906LLVMMetadataRef LLVMDIBuilderCreateLabel(LLVMDIBuilderRef Builder,1907 LLVMMetadataRef Context,1908 const char *Name, size_t NameLen,1909 LLVMMetadataRef File, unsigned LineNo,1910 LLVMBool AlwaysPreserve) {1911 return wrap(unwrap(Builder)->createLabel(1912 unwrapDI<DIScope>(Context), StringRef(Name, NameLen),1913 unwrapDI<DIFile>(File), LineNo, /*Column*/ 0, /*IsArtificial*/ false,1914 /*CoroSuspendIdx*/ std::nullopt, AlwaysPreserve));1915}1916 1917LLVMDbgRecordRef LLVMDIBuilderInsertLabelBefore(LLVMDIBuilderRef Builder,1918 LLVMMetadataRef LabelInfo,1919 LLVMMetadataRef Location,1920 LLVMValueRef InsertBefore) {1921 DbgInstPtr DbgInst = unwrap(Builder)->insertLabel(1922 unwrapDI<DILabel>(LabelInfo), unwrapDI<DILocation>(Location),1923 InsertBefore1924 ? InsertPosition(unwrap<Instruction>(InsertBefore)->getIterator())1925 : nullptr);1926 // This assert will fail if the module is in the old debug info format.1927 // This function should only be called if the module is in the new1928 // debug info format.1929 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1930 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1931 assert(isa<DbgRecord *>(DbgInst) &&1932 "Function unexpectedly in old debug info format");1933 return wrap(cast<DbgRecord *>(DbgInst));1934}1935 1936LLVMDbgRecordRef LLVMDIBuilderInsertLabelAtEnd(LLVMDIBuilderRef Builder,1937 LLVMMetadataRef LabelInfo,1938 LLVMMetadataRef Location,1939 LLVMBasicBlockRef InsertAtEnd) {1940 DbgInstPtr DbgInst = unwrap(Builder)->insertLabel(1941 unwrapDI<DILabel>(LabelInfo), unwrapDI<DILocation>(Location),1942 InsertAtEnd ? InsertPosition(unwrap(InsertAtEnd)->end()) : nullptr);1943 // This assert will fail if the module is in the old debug info format.1944 // This function should only be called if the module is in the new1945 // debug info format.1946 // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,1947 // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.1948 assert(isa<DbgRecord *>(DbgInst) &&1949 "Function unexpectedly in old debug info format");1950 return wrap(cast<DbgRecord *>(DbgInst));1951}1952 1953LLVMMetadataKind LLVMGetMetadataKind(LLVMMetadataRef Metadata) {1954 switch(unwrap(Metadata)->getMetadataID()) {1955#define HANDLE_METADATA_LEAF(CLASS) \1956 case Metadata::CLASS##Kind: \1957 return (LLVMMetadataKind)LLVM##CLASS##MetadataKind;1958#include "llvm/IR/Metadata.def"1959 default:1960 return (LLVMMetadataKind)LLVMGenericDINodeMetadataKind;1961 }1962}1963 1964AssignmentInstRange at::getAssignmentInsts(DIAssignID *ID) {1965 assert(ID && "Expected non-null ID");1966 LLVMContext &Ctx = ID->getContext();1967 auto &Map = Ctx.pImpl->AssignmentIDToInstrs;1968 1969 auto MapIt = Map.find(ID);1970 if (MapIt == Map.end())1971 return make_range(nullptr, nullptr);1972 1973 return make_range(MapIt->second.begin(), MapIt->second.end());1974}1975 1976void at::deleteAssignmentMarkers(const Instruction *Inst) {1977 for (auto *DVR : getDVRAssignmentMarkers(Inst))1978 DVR->eraseFromParent();1979}1980 1981void at::RAUW(DIAssignID *Old, DIAssignID *New) {1982 // Replace attachments.1983 AssignmentInstRange InstRange = getAssignmentInsts(Old);1984 // Use intermediate storage for the instruction ptrs because the1985 // getAssignmentInsts range iterators will be invalidated by adding and1986 // removing DIAssignID attachments.1987 SmallVector<Instruction *> InstVec(InstRange.begin(), InstRange.end());1988 for (auto *I : InstVec)1989 I->setMetadata(LLVMContext::MD_DIAssignID, New);1990 1991 Old->replaceAllUsesWith(New);1992}1993 1994void at::deleteAll(Function *F) {1995 for (BasicBlock &BB : *F) {1996 for (Instruction &I : BB) {1997 for (DbgVariableRecord &DVR :1998 make_early_inc_range(filterDbgVars(I.getDbgRecordRange())))1999 if (DVR.isDbgAssign())2000 DVR.eraseFromParent();2001 2002 I.setMetadata(LLVMContext::MD_DIAssignID, nullptr);2003 }2004 }2005}2006 2007bool at::calculateFragmentIntersect(2008 const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,2009 uint64_t SliceSizeInBits, const DbgVariableRecord *AssignRecord,2010 std::optional<DIExpression::FragmentInfo> &Result) {2011 // No overlap if this DbgRecord describes a killed location.2012 if (AssignRecord->isKillAddress())2013 return false;2014 2015 int64_t AddrOffsetInBits;2016 {2017 int64_t AddrOffsetInBytes;2018 SmallVector<uint64_t> PostOffsetOps; //< Unused.2019 // Bail if we can't find a constant offset (or none) in the expression.2020 if (!AssignRecord->getAddressExpression()->extractLeadingOffset(2021 AddrOffsetInBytes, PostOffsetOps))2022 return false;2023 AddrOffsetInBits = AddrOffsetInBytes * 8;2024 }2025 2026 Value *Addr = AssignRecord->getAddress();2027 // FIXME: It may not always be zero.2028 int64_t BitExtractOffsetInBits = 0;2029 DIExpression::FragmentInfo VarFrag =2030 AssignRecord->getFragmentOrEntireVariable();2031 2032 int64_t OffsetFromLocationInBits; //< Unused.2033 return DIExpression::calculateFragmentIntersect(2034 DL, Dest, SliceOffsetInBits, SliceSizeInBits, Addr, AddrOffsetInBits,2035 BitExtractOffsetInBits, VarFrag, Result, OffsetFromLocationInBits);2036}2037 2038/// Update inlined instructions' DIAssignID metadata. We need to do this2039/// otherwise a function inlined more than once into the same function2040/// will cause DIAssignID to be shared by many instructions.2041void at::remapAssignID(DenseMap<DIAssignID *, DIAssignID *> &Map,2042 Instruction &I) {2043 auto GetNewID = [&Map](Metadata *Old) {2044 DIAssignID *OldID = cast<DIAssignID>(Old);2045 if (DIAssignID *NewID = Map.lookup(OldID))2046 return NewID;2047 DIAssignID *NewID = DIAssignID::getDistinct(OldID->getContext());2048 Map[OldID] = NewID;2049 return NewID;2050 };2051 // If we find a DIAssignID attachment or use, replace it with a new version.2052 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {2053 if (DVR.isDbgAssign())2054 DVR.setAssignId(GetNewID(DVR.getAssignID()));2055 }2056 if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID))2057 I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID));2058}2059 2060/// Collect constant properties (base, size, offset) of \p StoreDest.2061/// Return std::nullopt if any properties are not constants or the2062/// offset from the base pointer is negative.2063static std::optional<AssignmentInfo>2064getAssignmentInfoImpl(const DataLayout &DL, const Value *StoreDest,2065 TypeSize SizeInBits) {2066 if (SizeInBits.isScalable())2067 return std::nullopt;2068 APInt GEPOffset(DL.getIndexTypeSizeInBits(StoreDest->getType()), 0);2069 const Value *Base = StoreDest->stripAndAccumulateConstantOffsets(2070 DL, GEPOffset, /*AllowNonInbounds*/ true);2071 2072 if (GEPOffset.isNegative())2073 return std::nullopt;2074 2075 uint64_t OffsetInBytes = GEPOffset.getLimitedValue();2076 // Check for overflow.2077 if (OffsetInBytes == UINT64_MAX)2078 return std::nullopt;2079 if (const auto *Alloca = dyn_cast<AllocaInst>(Base))2080 return AssignmentInfo(DL, Alloca, OffsetInBytes * 8, SizeInBits);2081 return std::nullopt;2082}2083 2084std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,2085 const MemIntrinsic *I) {2086 const Value *StoreDest = I->getRawDest();2087 // Assume 8 bit bytes.2088 auto *ConstLengthInBytes = dyn_cast<ConstantInt>(I->getLength());2089 if (!ConstLengthInBytes)2090 // We can't use a non-const size, bail.2091 return std::nullopt;2092 uint64_t SizeInBits = 8 * ConstLengthInBytes->getZExtValue();2093 return getAssignmentInfoImpl(DL, StoreDest, TypeSize::getFixed(SizeInBits));2094}2095 2096std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,2097 const StoreInst *SI) {2098 TypeSize SizeInBits = DL.getTypeSizeInBits(SI->getValueOperand()->getType());2099 return getAssignmentInfoImpl(DL, SI->getPointerOperand(), SizeInBits);2100}2101 2102std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,2103 const AllocaInst *AI) {2104 TypeSize SizeInBits = DL.getTypeSizeInBits(AI->getAllocatedType());2105 return getAssignmentInfoImpl(DL, AI, SizeInBits);2106}2107 2108/// Returns nullptr if the assignment shouldn't be attributed to this variable.2109static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,2110 Instruction &StoreLikeInst, const VarRecord &VarRec,2111 DIBuilder &DIB) {2112 auto *ID = StoreLikeInst.getMetadata(LLVMContext::MD_DIAssignID);2113 assert(ID && "Store instruction must have DIAssignID metadata");2114 (void)ID;2115 2116 const uint64_t StoreStartBit = Info.OffsetInBits;2117 const uint64_t StoreEndBit = Info.OffsetInBits + Info.SizeInBits;2118 2119 uint64_t FragStartBit = StoreStartBit;2120 uint64_t FragEndBit = StoreEndBit;2121 2122 bool StoreToWholeVariable = Info.StoreToWholeAlloca;2123 if (auto Size = VarRec.Var->getSizeInBits()) {2124 // NOTE: trackAssignments doesn't understand base expressions yet, so all2125 // variables that reach here are guaranteed to start at offset 0 in the2126 // alloca.2127 const uint64_t VarStartBit = 0;2128 const uint64_t VarEndBit = *Size;2129 2130 // FIXME: trim FragStartBit when nonzero VarStartBit is supported.2131 FragEndBit = std::min(FragEndBit, VarEndBit);2132 2133 // Discard stores to bits outside this variable.2134 if (FragStartBit >= FragEndBit)2135 return;2136 2137 StoreToWholeVariable = FragStartBit <= VarStartBit && FragEndBit >= *Size;2138 }2139 2140 DIExpression *Expr = DIExpression::get(StoreLikeInst.getContext(), {});2141 if (!StoreToWholeVariable) {2142 auto R = DIExpression::createFragmentExpression(Expr, FragStartBit,2143 FragEndBit - FragStartBit);2144 assert(R.has_value() && "failed to create fragment expression");2145 Expr = *R;2146 }2147 DIExpression *AddrExpr = DIExpression::get(StoreLikeInst.getContext(), {});2148 auto *Assign = DbgVariableRecord::createLinkedDVRAssign(2149 &StoreLikeInst, Val, VarRec.Var, Expr, Dest, AddrExpr, VarRec.DL);2150 (void)Assign;2151 LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");2152}2153 2154#undef DEBUG_TYPE // Silence redefinition warning (from ConstantsContext.h).2155#define DEBUG_TYPE "assignment-tracking"2156 2157void at::trackAssignments(Function::iterator Start, Function::iterator End,2158 const StorageToVarsMap &Vars, const DataLayout &DL,2159 bool DebugPrints) {2160 // Early-exit if there are no interesting variables.2161 if (Vars.empty())2162 return;2163 2164 auto &Ctx = Start->getContext();2165 auto &Module = *Start->getModule();2166 2167 // Poison type doesn't matter, so long as it isn't void. Let's just use i1.2168 auto *Poison = PoisonValue::get(Type::getInt1Ty(Ctx));2169 DIBuilder DIB(Module, /*AllowUnresolved*/ false);2170 2171 // Scan the instructions looking for stores to local variables' storage.2172 LLVM_DEBUG(errs() << "# Scanning instructions\n");2173 for (auto BBI = Start; BBI != End; ++BBI) {2174 for (Instruction &I : *BBI) {2175 2176 std::optional<AssignmentInfo> Info;2177 Value *ValueComponent = nullptr;2178 Value *DestComponent = nullptr;2179 if (auto *AI = dyn_cast<AllocaInst>(&I)) {2180 // We want to track the variable's stack home from its alloca's2181 // position onwards so we treat it as an assignment (where the stored2182 // value is poison).2183 Info = getAssignmentInfo(DL, AI);2184 ValueComponent = Poison;2185 DestComponent = AI;2186 } else if (auto *SI = dyn_cast<StoreInst>(&I)) {2187 Info = getAssignmentInfo(DL, SI);2188 ValueComponent = SI->getValueOperand();2189 DestComponent = SI->getPointerOperand();2190 } else if (auto *MI = dyn_cast<MemTransferInst>(&I)) {2191 Info = getAssignmentInfo(DL, MI);2192 // May not be able to represent this value easily.2193 ValueComponent = Poison;2194 DestComponent = MI->getOperand(0);2195 } else if (auto *MI = dyn_cast<MemSetInst>(&I)) {2196 Info = getAssignmentInfo(DL, MI);2197 // If we're zero-initing we can state the assigned value is zero,2198 // otherwise use undef.2199 auto *ConstValue = dyn_cast<ConstantInt>(MI->getOperand(1));2200 if (ConstValue && ConstValue->isZero())2201 ValueComponent = ConstValue;2202 else2203 ValueComponent = Poison;2204 DestComponent = MI->getOperand(0);2205 } else {2206 // Not a store-like instruction.2207 continue;2208 }2209 2210 assert(ValueComponent && DestComponent);2211 LLVM_DEBUG(errs() << "SCAN: Found store-like: " << I << "\n");2212 2213 // Check if getAssignmentInfo failed to understand this store.2214 if (!Info.has_value()) {2215 LLVM_DEBUG(2216 errs()2217 << " | SKIP: Untrackable store (e.g. through non-const gep)\n");2218 continue;2219 }2220 LLVM_DEBUG(errs() << " | BASE: " << *Info->Base << "\n");2221 2222 // Check if the store destination is a local variable with debug info.2223 auto LocalIt = Vars.find(Info->Base);2224 if (LocalIt == Vars.end()) {2225 LLVM_DEBUG(2226 errs()2227 << " | SKIP: Base address not associated with local variable\n");2228 continue;2229 }2230 2231 DIAssignID *ID =2232 cast_or_null<DIAssignID>(I.getMetadata(LLVMContext::MD_DIAssignID));2233 if (!ID) {2234 ID = DIAssignID::getDistinct(Ctx);2235 I.setMetadata(LLVMContext::MD_DIAssignID, ID);2236 }2237 2238 for (const VarRecord &R : LocalIt->second)2239 emitDbgAssign(*Info, ValueComponent, DestComponent, I, R, DIB);2240 }2241 }2242}2243 2244bool AssignmentTrackingPass::runOnFunction(Function &F) {2245 // No value in assignment tracking without optimisations.2246 if (F.hasFnAttribute(Attribute::OptimizeNone))2247 return /*Changed*/ false;2248 2249 bool Changed = false;2250 auto *DL = &F.getDataLayout();2251 // Collect a map of {backing storage : dbg.declares} (currently "backing2252 // storage" is limited to Allocas). We'll use this to find dbg.declares to2253 // delete after running `trackAssignments`.2254 DenseMap<const AllocaInst *, SmallPtrSet<DbgVariableRecord *, 2>> DVRDeclares;2255 // Create another similar map of {storage : variables} that we'll pass to2256 // trackAssignments.2257 StorageToVarsMap Vars;2258 auto ProcessDeclare = [&](DbgVariableRecord &Declare) {2259 // FIXME: trackAssignments doesn't let you specify any modifiers to the2260 // variable (e.g. fragment) or location (e.g. offset), so we have to2261 // leave dbg.declares with non-empty expressions in place.2262 if (Declare.getExpression()->getNumElements() != 0)2263 return;2264 if (!Declare.getAddress())2265 return;2266 if (AllocaInst *Alloca =2267 dyn_cast<AllocaInst>(Declare.getAddress()->stripPointerCasts())) {2268 // FIXME: Skip VLAs for now (let these variables use dbg.declares).2269 if (!Alloca->isStaticAlloca())2270 return;2271 // Similarly, skip scalable vectors (use dbg.declares instead).2272 if (auto Sz = Alloca->getAllocationSize(*DL); Sz && Sz->isScalable())2273 return;2274 DVRDeclares[Alloca].insert(&Declare);2275 Vars[Alloca].insert(VarRecord(&Declare));2276 }2277 };2278 for (auto &BB : F) {2279 for (auto &I : BB) {2280 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {2281 if (DVR.isDbgDeclare())2282 ProcessDeclare(DVR);2283 }2284 }2285 }2286 2287 // FIXME: Locals can be backed by caller allocas (sret, byval).2288 // Note: trackAssignments doesn't respect dbg.declare's IR positions (as it2289 // doesn't "understand" dbg.declares). However, this doesn't appear to break2290 // any rules given this description of dbg.declare from2291 // llvm/docs/SourceLevelDebugging.rst:2292 //2293 // It is not control-dependent, meaning that if a call to llvm.dbg.declare2294 // exists and has a valid location argument, that address is considered to2295 // be the true home of the variable across its entire lifetime.2296 trackAssignments(F.begin(), F.end(), Vars, *DL);2297 2298 // Delete dbg.declares for variables now tracked with assignment tracking.2299 for (auto &[Insts, Declares] : DVRDeclares) {2300 auto Markers = at::getDVRAssignmentMarkers(Insts);2301 for (auto *Declare : Declares) {2302 // Assert that the alloca that Declare uses is now linked to a dbg.assign2303 // describing the same variable (i.e. check that this dbg.declare has2304 // been replaced by a dbg.assign). Use DebugVariableAggregate to Discard2305 // the fragment part because trackAssignments may alter the2306 // fragment. e.g. if the alloca is smaller than the variable, then2307 // trackAssignments will create an alloca-sized fragment for the2308 // dbg.assign.2309 assert(llvm::any_of(Markers, [Declare](auto *Assign) {2310 return DebugVariableAggregate(Assign) ==2311 DebugVariableAggregate(Declare);2312 }));2313 // Delete Declare because the variable location is now tracked using2314 // assignment tracking.2315 Declare->eraseFromParent();2316 Changed = true;2317 }2318 };2319 return Changed;2320}2321 2322static const char *AssignmentTrackingModuleFlag =2323 "debug-info-assignment-tracking";2324 2325static void setAssignmentTrackingModuleFlag(Module &M) {2326 M.setModuleFlag(Module::ModFlagBehavior::Max, AssignmentTrackingModuleFlag,2327 ConstantAsMetadata::get(2328 ConstantInt::get(Type::getInt1Ty(M.getContext()), 1)));2329}2330 2331static bool getAssignmentTrackingModuleFlag(const Module &M) {2332 Metadata *Value = M.getModuleFlag(AssignmentTrackingModuleFlag);2333 return Value && !cast<ConstantAsMetadata>(Value)->getValue()->isZeroValue();2334}2335 2336bool llvm::isAssignmentTrackingEnabled(const Module &M) {2337 return getAssignmentTrackingModuleFlag(M);2338}2339 2340PreservedAnalyses AssignmentTrackingPass::run(Function &F,2341 FunctionAnalysisManager &AM) {2342 if (!runOnFunction(F))2343 return PreservedAnalyses::all();2344 2345 // Record that this module uses assignment tracking. It doesn't matter that2346 // some functions in the module may not use it - the debug info in those2347 // functions will still be handled properly.2348 setAssignmentTrackingModuleFlag(*F.getParent());2349 2350 // Q: Can we return a less conservative set than just CFGAnalyses? Can we2351 // return PreservedAnalyses::all()?2352 PreservedAnalyses PA;2353 PA.preserveSet<CFGAnalyses>();2354 return PA;2355}2356 2357PreservedAnalyses AssignmentTrackingPass::run(Module &M,2358 ModuleAnalysisManager &AM) {2359 bool Changed = false;2360 for (auto &F : M)2361 Changed |= runOnFunction(F);2362 2363 if (!Changed)2364 return PreservedAnalyses::all();2365 2366 // Record that this module uses assignment tracking.2367 setAssignmentTrackingModuleFlag(M);2368 2369 // Q: Can we return a less conservative set than just CFGAnalyses? Can we2370 // return PreservedAnalyses::all()?2371 PreservedAnalyses PA;2372 PA.preserveSet<CFGAnalyses>();2373 return PA;2374}2375 2376#undef DEBUG_TYPE2377