10b57cec5SDimitry Andric //===- DebugInfo.cpp - Debug Information Helper Classes -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the helper classes used to build and interpret debug 100b57cec5SDimitry Andric // information in LLVM IR form. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm-c/DebugInfo.h" 15bdd1243dSDimitry Andric #include "LLVMContextImpl.h" 160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 220b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 230b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 241fd87a68SDimitry Andric #include "llvm/IR/DIBuilder.h" 251fd87a68SDimitry Andric #include "llvm/IR/DebugInfo.h" 260b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 270b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 285f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h" 290b57cec5SDimitry Andric #include "llvm/IR/Function.h" 300b57cec5SDimitry Andric #include "llvm/IR/GVMaterializer.h" 310b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 320b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 330b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 340b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 350b57cec5SDimitry Andric #include "llvm/IR/Module.h" 36bdd1243dSDimitry Andric #include "llvm/IR/PassManager.h" 370b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 380b57cec5SDimitry Andric #include <algorithm> 390b57cec5SDimitry Andric #include <cassert> 40bdd1243dSDimitry Andric #include <optional> 410b57cec5SDimitry Andric #include <utility> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric using namespace llvm; 44bdd1243dSDimitry Andric using namespace llvm::at; 450b57cec5SDimitry Andric using namespace llvm::dwarf; 460b57cec5SDimitry Andric 477a6dacacSDimitry Andric TinyPtrVector<DbgDeclareInst *> llvm::findDbgDeclares(Value *V) { 487a6dacacSDimitry Andric // This function is hot. Check whether the value has any metadata to avoid a 497a6dacacSDimitry Andric // DenseMap lookup. 507a6dacacSDimitry Andric if (!V->isUsedByMetadata()) 517a6dacacSDimitry Andric return {}; 527a6dacacSDimitry Andric auto *L = LocalAsMetadata::getIfExists(V); 537a6dacacSDimitry Andric if (!L) 547a6dacacSDimitry Andric return {}; 557a6dacacSDimitry Andric auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L); 567a6dacacSDimitry Andric if (!MDV) 577a6dacacSDimitry Andric return {}; 587a6dacacSDimitry Andric 597a6dacacSDimitry Andric TinyPtrVector<DbgDeclareInst *> Declares; 607a6dacacSDimitry Andric for (User *U : MDV->users()) 617a6dacacSDimitry Andric if (auto *DDI = dyn_cast<DbgDeclareInst>(U)) 627a6dacacSDimitry Andric Declares.push_back(DDI); 637a6dacacSDimitry Andric 647a6dacacSDimitry Andric return Declares; 657a6dacacSDimitry Andric } 66*0fca6ea1SDimitry Andric TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) { 677a6dacacSDimitry Andric // This function is hot. Check whether the value has any metadata to avoid a 687a6dacacSDimitry Andric // DenseMap lookup. 697a6dacacSDimitry Andric if (!V->isUsedByMetadata()) 707a6dacacSDimitry Andric return {}; 717a6dacacSDimitry Andric auto *L = LocalAsMetadata::getIfExists(V); 727a6dacacSDimitry Andric if (!L) 737a6dacacSDimitry Andric return {}; 747a6dacacSDimitry Andric 75*0fca6ea1SDimitry Andric TinyPtrVector<DbgVariableRecord *> Declares; 76*0fca6ea1SDimitry Andric for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) 77*0fca6ea1SDimitry Andric if (DVR->getType() == DbgVariableRecord::LocationType::Declare) 78*0fca6ea1SDimitry Andric Declares.push_back(DVR); 797a6dacacSDimitry Andric 807a6dacacSDimitry Andric return Declares; 817a6dacacSDimitry Andric } 827a6dacacSDimitry Andric 83*0fca6ea1SDimitry Andric template <typename IntrinsicT, bool DbgAssignAndValuesOnly> 84*0fca6ea1SDimitry Andric static void 85*0fca6ea1SDimitry Andric findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V, 86*0fca6ea1SDimitry Andric SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { 87fe6060f1SDimitry Andric // This function is hot. Check whether the value has any metadata to avoid a 88fe6060f1SDimitry Andric // DenseMap lookup. 89fe6060f1SDimitry Andric if (!V->isUsedByMetadata()) 90fe6060f1SDimitry Andric return; 9106c3fb27SDimitry Andric 9206c3fb27SDimitry Andric LLVMContext &Ctx = V->getContext(); 93fe6060f1SDimitry Andric // TODO: If this value appears multiple times in a DIArgList, we should still 94fe6060f1SDimitry Andric // only add the owning DbgValueInst once; use this set to track ArgListUsers. 95fe6060f1SDimitry Andric // This behaviour can be removed when we can automatically remove duplicates. 9606c3fb27SDimitry Andric // V will also appear twice in a dbg.assign if its used in the both the value 9706c3fb27SDimitry Andric // and address components. 9806c3fb27SDimitry Andric SmallPtrSet<IntrinsicT *, 4> EncounteredIntrinsics; 99*0fca6ea1SDimitry Andric SmallPtrSet<DbgVariableRecord *, 4> EncounteredDbgVariableRecords; 10006c3fb27SDimitry Andric 10106c3fb27SDimitry Andric /// Append IntrinsicT users of MetadataAsValue(MD). 102*0fca6ea1SDimitry Andric auto AppendUsers = [&Ctx, &EncounteredIntrinsics, 103*0fca6ea1SDimitry Andric &EncounteredDbgVariableRecords, &Result, 104*0fca6ea1SDimitry Andric DbgVariableRecords](Metadata *MD) { 10506c3fb27SDimitry Andric if (auto *MDV = MetadataAsValue::getIfExists(Ctx, MD)) { 10606c3fb27SDimitry Andric for (User *U : MDV->users()) 10706c3fb27SDimitry Andric if (IntrinsicT *DVI = dyn_cast<IntrinsicT>(U)) 10806c3fb27SDimitry Andric if (EncounteredIntrinsics.insert(DVI).second) 10906c3fb27SDimitry Andric Result.push_back(DVI); 11006c3fb27SDimitry Andric } 111*0fca6ea1SDimitry Andric if (!DbgVariableRecords) 1125f757f3fSDimitry Andric return; 113*0fca6ea1SDimitry Andric // Get DbgVariableRecords that use this as a single value. 1145f757f3fSDimitry Andric if (LocalAsMetadata *L = dyn_cast<LocalAsMetadata>(MD)) { 115*0fca6ea1SDimitry Andric for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) { 116*0fca6ea1SDimitry Andric if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign()) 117*0fca6ea1SDimitry Andric if (EncounteredDbgVariableRecords.insert(DVR).second) 118*0fca6ea1SDimitry Andric DbgVariableRecords->push_back(DVR); 1195f757f3fSDimitry Andric } 1205f757f3fSDimitry Andric } 12106c3fb27SDimitry Andric }; 12206c3fb27SDimitry Andric 123fe6060f1SDimitry Andric if (auto *L = LocalAsMetadata::getIfExists(V)) { 12406c3fb27SDimitry Andric AppendUsers(L); 1255f757f3fSDimitry Andric for (Metadata *AL : L->getAllArgListUsers()) { 12606c3fb27SDimitry Andric AppendUsers(AL); 127*0fca6ea1SDimitry Andric if (!DbgVariableRecords) 1285f757f3fSDimitry Andric continue; 1295f757f3fSDimitry Andric DIArgList *DI = cast<DIArgList>(AL); 130*0fca6ea1SDimitry Andric for (DbgVariableRecord *DVR : DI->getAllDbgVariableRecordUsers()) 131*0fca6ea1SDimitry Andric if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign()) 132*0fca6ea1SDimitry Andric if (EncounteredDbgVariableRecords.insert(DVR).second) 133*0fca6ea1SDimitry Andric DbgVariableRecords->push_back(DVR); 1345f757f3fSDimitry Andric } 135fe6060f1SDimitry Andric } 136fe6060f1SDimitry Andric } 13706c3fb27SDimitry Andric 138*0fca6ea1SDimitry Andric void llvm::findDbgValues( 139*0fca6ea1SDimitry Andric SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V, 140*0fca6ea1SDimitry Andric SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { 141*0fca6ea1SDimitry Andric findDbgIntrinsics<DbgValueInst, /*DbgAssignAndValuesOnly=*/true>( 142*0fca6ea1SDimitry Andric DbgValues, V, DbgVariableRecords); 143fe6060f1SDimitry Andric } 144fe6060f1SDimitry Andric 145*0fca6ea1SDimitry Andric void llvm::findDbgUsers( 146*0fca6ea1SDimitry Andric SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers, Value *V, 147*0fca6ea1SDimitry Andric SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { 148*0fca6ea1SDimitry Andric findDbgIntrinsics<DbgVariableIntrinsic, /*DbgAssignAndValuesOnly=*/false>( 149*0fca6ea1SDimitry Andric DbgUsers, V, DbgVariableRecords); 150fe6060f1SDimitry Andric } 151fe6060f1SDimitry Andric 1520b57cec5SDimitry Andric DISubprogram *llvm::getDISubprogram(const MDNode *Scope) { 1530b57cec5SDimitry Andric if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope)) 1540b57cec5SDimitry Andric return LocalScope->getSubprogram(); 1550b57cec5SDimitry Andric return nullptr; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 158bdd1243dSDimitry Andric DebugLoc llvm::getDebugValueLoc(DbgVariableIntrinsic *DII) { 159bdd1243dSDimitry Andric // Original dbg.declare must have a location. 160bdd1243dSDimitry Andric const DebugLoc &DeclareLoc = DII->getDebugLoc(); 161bdd1243dSDimitry Andric MDNode *Scope = DeclareLoc.getScope(); 162bdd1243dSDimitry Andric DILocation *InlinedAt = DeclareLoc.getInlinedAt(); 163bdd1243dSDimitry Andric // Because no machine insts can come from debug intrinsics, only the scope 164bdd1243dSDimitry Andric // and inlinedAt is significant. Zero line numbers are used in case this 165bdd1243dSDimitry Andric // DebugLoc leaks into any adjacent instructions. Produce an unknown location 166bdd1243dSDimitry Andric // with the correct scope / inlinedAt fields. 167bdd1243dSDimitry Andric return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt); 168bdd1243dSDimitry Andric } 169bdd1243dSDimitry Andric 170*0fca6ea1SDimitry Andric DebugLoc llvm::getDebugValueLoc(DbgVariableRecord *DVR) { 1717a6dacacSDimitry Andric // Original dbg.declare must have a location. 172*0fca6ea1SDimitry Andric const DebugLoc &DeclareLoc = DVR->getDebugLoc(); 1737a6dacacSDimitry Andric MDNode *Scope = DeclareLoc.getScope(); 1747a6dacacSDimitry Andric DILocation *InlinedAt = DeclareLoc.getInlinedAt(); 1757a6dacacSDimitry Andric // Because no machine insts can come from debug intrinsics, only the scope 1767a6dacacSDimitry Andric // and inlinedAt is significant. Zero line numbers are used in case this 1777a6dacacSDimitry Andric // DebugLoc leaks into any adjacent instructions. Produce an unknown location 1787a6dacacSDimitry Andric // with the correct scope / inlinedAt fields. 179*0fca6ea1SDimitry Andric return DILocation::get(DVR->getContext(), 0, 0, Scope, InlinedAt); 1807a6dacacSDimitry Andric } 1817a6dacacSDimitry Andric 1820b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1830b57cec5SDimitry Andric // DebugInfoFinder implementations. 1840b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void DebugInfoFinder::reset() { 1870b57cec5SDimitry Andric CUs.clear(); 1880b57cec5SDimitry Andric SPs.clear(); 1890b57cec5SDimitry Andric GVs.clear(); 1900b57cec5SDimitry Andric TYs.clear(); 1910b57cec5SDimitry Andric Scopes.clear(); 1920b57cec5SDimitry Andric NodesSeen.clear(); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric void DebugInfoFinder::processModule(const Module &M) { 1960b57cec5SDimitry Andric for (auto *CU : M.debug_compile_units()) 1970b57cec5SDimitry Andric processCompileUnit(CU); 1980b57cec5SDimitry Andric for (auto &F : M.functions()) { 1990b57cec5SDimitry Andric if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram())) 2000b57cec5SDimitry Andric processSubprogram(SP); 2010b57cec5SDimitry Andric // There could be subprograms from inlined functions referenced from 2020b57cec5SDimitry Andric // instructions only. Walk the function to find them. 2030b57cec5SDimitry Andric for (const BasicBlock &BB : F) 2040b57cec5SDimitry Andric for (const Instruction &I : BB) 2050b57cec5SDimitry Andric processInstruction(M, I); 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) { 2100b57cec5SDimitry Andric if (!addCompileUnit(CU)) 2110b57cec5SDimitry Andric return; 212bdd1243dSDimitry Andric for (auto *DIG : CU->getGlobalVariables()) { 2130b57cec5SDimitry Andric if (!addGlobalVariable(DIG)) 2140b57cec5SDimitry Andric continue; 2150b57cec5SDimitry Andric auto *GV = DIG->getVariable(); 2160b57cec5SDimitry Andric processScope(GV->getScope()); 2170b57cec5SDimitry Andric processType(GV->getType()); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric for (auto *ET : CU->getEnumTypes()) 2200b57cec5SDimitry Andric processType(ET); 2210b57cec5SDimitry Andric for (auto *RT : CU->getRetainedTypes()) 2220b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(RT)) 2230b57cec5SDimitry Andric processType(T); 2240b57cec5SDimitry Andric else 2250b57cec5SDimitry Andric processSubprogram(cast<DISubprogram>(RT)); 2260b57cec5SDimitry Andric for (auto *Import : CU->getImportedEntities()) { 2270b57cec5SDimitry Andric auto *Entity = Import->getEntity(); 2280b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(Entity)) 2290b57cec5SDimitry Andric processType(T); 2300b57cec5SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(Entity)) 2310b57cec5SDimitry Andric processSubprogram(SP); 2320b57cec5SDimitry Andric else if (auto *NS = dyn_cast<DINamespace>(Entity)) 2330b57cec5SDimitry Andric processScope(NS->getScope()); 2340b57cec5SDimitry Andric else if (auto *M = dyn_cast<DIModule>(Entity)) 2350b57cec5SDimitry Andric processScope(M->getScope()); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric void DebugInfoFinder::processInstruction(const Module &M, 2400b57cec5SDimitry Andric const Instruction &I) { 2415ffd83dbSDimitry Andric if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) 2425f757f3fSDimitry Andric processVariable(M, DVI->getVariable()); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric if (auto DbgLoc = I.getDebugLoc()) 2450b57cec5SDimitry Andric processLocation(M, DbgLoc.get()); 2465f757f3fSDimitry Andric 247*0fca6ea1SDimitry Andric for (const DbgRecord &DPR : I.getDbgRecordRange()) 248*0fca6ea1SDimitry Andric processDbgRecord(M, DPR); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) { 2520b57cec5SDimitry Andric if (!Loc) 2530b57cec5SDimitry Andric return; 2540b57cec5SDimitry Andric processScope(Loc->getScope()); 2550b57cec5SDimitry Andric processLocation(M, Loc->getInlinedAt()); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 258*0fca6ea1SDimitry Andric void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DR) { 259*0fca6ea1SDimitry Andric if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR)) 260*0fca6ea1SDimitry Andric processVariable(M, DVR->getVariable()); 261*0fca6ea1SDimitry Andric processLocation(M, DR.getDebugLoc().get()); 2625f757f3fSDimitry Andric } 2635f757f3fSDimitry Andric 2640b57cec5SDimitry Andric void DebugInfoFinder::processType(DIType *DT) { 2650b57cec5SDimitry Andric if (!addType(DT)) 2660b57cec5SDimitry Andric return; 2670b57cec5SDimitry Andric processScope(DT->getScope()); 2680b57cec5SDimitry Andric if (auto *ST = dyn_cast<DISubroutineType>(DT)) { 2690b57cec5SDimitry Andric for (DIType *Ref : ST->getTypeArray()) 2700b57cec5SDimitry Andric processType(Ref); 2710b57cec5SDimitry Andric return; 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric if (auto *DCT = dyn_cast<DICompositeType>(DT)) { 2740b57cec5SDimitry Andric processType(DCT->getBaseType()); 2750b57cec5SDimitry Andric for (Metadata *D : DCT->getElements()) { 2760b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(D)) 2770b57cec5SDimitry Andric processType(T); 2780b57cec5SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(D)) 2790b57cec5SDimitry Andric processSubprogram(SP); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric return; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric if (auto *DDT = dyn_cast<DIDerivedType>(DT)) { 2840b57cec5SDimitry Andric processType(DDT->getBaseType()); 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric void DebugInfoFinder::processScope(DIScope *Scope) { 2890b57cec5SDimitry Andric if (!Scope) 2900b57cec5SDimitry Andric return; 2910b57cec5SDimitry Andric if (auto *Ty = dyn_cast<DIType>(Scope)) { 2920b57cec5SDimitry Andric processType(Ty); 2930b57cec5SDimitry Andric return; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric if (auto *CU = dyn_cast<DICompileUnit>(Scope)) { 2960b57cec5SDimitry Andric addCompileUnit(CU); 2970b57cec5SDimitry Andric return; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(Scope)) { 3000b57cec5SDimitry Andric processSubprogram(SP); 3010b57cec5SDimitry Andric return; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric if (!addScope(Scope)) 3040b57cec5SDimitry Andric return; 3050b57cec5SDimitry Andric if (auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) { 3060b57cec5SDimitry Andric processScope(LB->getScope()); 3070b57cec5SDimitry Andric } else if (auto *NS = dyn_cast<DINamespace>(Scope)) { 3080b57cec5SDimitry Andric processScope(NS->getScope()); 3090b57cec5SDimitry Andric } else if (auto *M = dyn_cast<DIModule>(Scope)) { 3100b57cec5SDimitry Andric processScope(M->getScope()); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric void DebugInfoFinder::processSubprogram(DISubprogram *SP) { 3150b57cec5SDimitry Andric if (!addSubprogram(SP)) 3160b57cec5SDimitry Andric return; 3170b57cec5SDimitry Andric processScope(SP->getScope()); 3180b57cec5SDimitry Andric // Some of the users, e.g. CloneFunctionInto / CloneModule, need to set up a 3190b57cec5SDimitry Andric // ValueMap containing identity mappings for all of the DICompileUnit's, not 3200b57cec5SDimitry Andric // just DISubprogram's, referenced from anywhere within the Function being 3210b57cec5SDimitry Andric // cloned prior to calling MapMetadata / RemapInstruction to avoid their 3220b57cec5SDimitry Andric // duplication later as DICompileUnit's are also directly referenced by 3230b57cec5SDimitry Andric // llvm.dbg.cu list. Thefore we need to collect DICompileUnit's here as well. 3240b57cec5SDimitry Andric // Also, DICompileUnit's may reference DISubprogram's too and therefore need 3250b57cec5SDimitry Andric // to be at least looked through. 3260b57cec5SDimitry Andric processCompileUnit(SP->getUnit()); 3270b57cec5SDimitry Andric processType(SP->getType()); 3280b57cec5SDimitry Andric for (auto *Element : SP->getTemplateParams()) { 3290b57cec5SDimitry Andric if (auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) { 3300b57cec5SDimitry Andric processType(TType->getType()); 3310b57cec5SDimitry Andric } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) { 3320b57cec5SDimitry Andric processType(TVal->getType()); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 3375ffd83dbSDimitry Andric void DebugInfoFinder::processVariable(const Module &M, 3385f757f3fSDimitry Andric const DILocalVariable *DV) { 3390b57cec5SDimitry Andric if (!NodesSeen.insert(DV).second) 3400b57cec5SDimitry Andric return; 3410b57cec5SDimitry Andric processScope(DV->getScope()); 3420b57cec5SDimitry Andric processType(DV->getType()); 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric bool DebugInfoFinder::addType(DIType *DT) { 3460b57cec5SDimitry Andric if (!DT) 3470b57cec5SDimitry Andric return false; 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric if (!NodesSeen.insert(DT).second) 3500b57cec5SDimitry Andric return false; 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric TYs.push_back(const_cast<DIType *>(DT)); 3530b57cec5SDimitry Andric return true; 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) { 3570b57cec5SDimitry Andric if (!CU) 3580b57cec5SDimitry Andric return false; 3590b57cec5SDimitry Andric if (!NodesSeen.insert(CU).second) 3600b57cec5SDimitry Andric return false; 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric CUs.push_back(CU); 3630b57cec5SDimitry Andric return true; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric bool DebugInfoFinder::addGlobalVariable(DIGlobalVariableExpression *DIG) { 3670b57cec5SDimitry Andric if (!NodesSeen.insert(DIG).second) 3680b57cec5SDimitry Andric return false; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric GVs.push_back(DIG); 3710b57cec5SDimitry Andric return true; 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric bool DebugInfoFinder::addSubprogram(DISubprogram *SP) { 3750b57cec5SDimitry Andric if (!SP) 3760b57cec5SDimitry Andric return false; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric if (!NodesSeen.insert(SP).second) 3790b57cec5SDimitry Andric return false; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric SPs.push_back(SP); 3820b57cec5SDimitry Andric return true; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric bool DebugInfoFinder::addScope(DIScope *Scope) { 3860b57cec5SDimitry Andric if (!Scope) 3870b57cec5SDimitry Andric return false; 3880b57cec5SDimitry Andric // FIXME: Ocaml binding generates a scope with no content, we treat it 3890b57cec5SDimitry Andric // as null for now. 3900b57cec5SDimitry Andric if (Scope->getNumOperands() == 0) 3910b57cec5SDimitry Andric return false; 3920b57cec5SDimitry Andric if (!NodesSeen.insert(Scope).second) 3930b57cec5SDimitry Andric return false; 3940b57cec5SDimitry Andric Scopes.push_back(Scope); 3950b57cec5SDimitry Andric return true; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3985ffd83dbSDimitry Andric static MDNode *updateLoopMetadataDebugLocationsImpl( 399fe6060f1SDimitry Andric MDNode *OrigLoopID, function_ref<Metadata *(Metadata *)> Updater) { 4005ffd83dbSDimitry Andric assert(OrigLoopID && OrigLoopID->getNumOperands() > 0 && 4015ffd83dbSDimitry Andric "Loop ID needs at least one operand"); 4025ffd83dbSDimitry Andric assert(OrigLoopID && OrigLoopID->getOperand(0).get() == OrigLoopID && 4035ffd83dbSDimitry Andric "Loop ID should refer to itself"); 4045ffd83dbSDimitry Andric 4055ffd83dbSDimitry Andric // Save space for the self-referential LoopID. 4065ffd83dbSDimitry Andric SmallVector<Metadata *, 4> MDs = {nullptr}; 4075ffd83dbSDimitry Andric 4085ffd83dbSDimitry Andric for (unsigned i = 1; i < OrigLoopID->getNumOperands(); ++i) { 4095ffd83dbSDimitry Andric Metadata *MD = OrigLoopID->getOperand(i); 410fe6060f1SDimitry Andric if (!MD) 411fe6060f1SDimitry Andric MDs.push_back(nullptr); 412fe6060f1SDimitry Andric else if (Metadata *NewMD = Updater(MD)) 413fe6060f1SDimitry Andric MDs.push_back(NewMD); 4145ffd83dbSDimitry Andric } 4155ffd83dbSDimitry Andric 4165ffd83dbSDimitry Andric MDNode *NewLoopID = MDNode::getDistinct(OrigLoopID->getContext(), MDs); 4175ffd83dbSDimitry Andric // Insert the self-referential LoopID. 4185ffd83dbSDimitry Andric NewLoopID->replaceOperandWith(0, NewLoopID); 4195ffd83dbSDimitry Andric return NewLoopID; 4205ffd83dbSDimitry Andric } 4215ffd83dbSDimitry Andric 4225ffd83dbSDimitry Andric void llvm::updateLoopMetadataDebugLocations( 423fe6060f1SDimitry Andric Instruction &I, function_ref<Metadata *(Metadata *)> Updater) { 4245ffd83dbSDimitry Andric MDNode *OrigLoopID = I.getMetadata(LLVMContext::MD_loop); 4255ffd83dbSDimitry Andric if (!OrigLoopID) 4265ffd83dbSDimitry Andric return; 4275ffd83dbSDimitry Andric MDNode *NewLoopID = updateLoopMetadataDebugLocationsImpl(OrigLoopID, Updater); 4285ffd83dbSDimitry Andric I.setMetadata(LLVMContext::MD_loop, NewLoopID); 4295ffd83dbSDimitry Andric } 4305ffd83dbSDimitry Andric 431fe6060f1SDimitry Andric /// Return true if a node is a DILocation or if a DILocation is 432fe6060f1SDimitry Andric /// indirectly referenced by one of the node's children. 433fe6060f1SDimitry Andric static bool isDILocationReachable(SmallPtrSetImpl<Metadata *> &Visited, 434fe6060f1SDimitry Andric SmallPtrSetImpl<Metadata *> &Reachable, 435fe6060f1SDimitry Andric Metadata *MD) { 436fe6060f1SDimitry Andric MDNode *N = dyn_cast_or_null<MDNode>(MD); 437fe6060f1SDimitry Andric if (!N) 438fe6060f1SDimitry Andric return false; 439fe6060f1SDimitry Andric if (isa<DILocation>(N) || Reachable.count(N)) 440fe6060f1SDimitry Andric return true; 441fe6060f1SDimitry Andric if (!Visited.insert(N).second) 442fe6060f1SDimitry Andric return false; 443fe6060f1SDimitry Andric for (auto &OpIt : N->operands()) { 444fe6060f1SDimitry Andric Metadata *Op = OpIt.get(); 445fe6060f1SDimitry Andric if (isDILocationReachable(Visited, Reachable, Op)) { 44606c3fb27SDimitry Andric // Don't return just yet as we want to visit all MD's children to 44706c3fb27SDimitry Andric // initialize DILocationReachable in stripDebugLocFromLoopID 448fe6060f1SDimitry Andric Reachable.insert(N); 44906c3fb27SDimitry Andric } 45006c3fb27SDimitry Andric } 45106c3fb27SDimitry Andric return Reachable.count(N); 45206c3fb27SDimitry Andric } 45306c3fb27SDimitry Andric 45406c3fb27SDimitry Andric static bool isAllDILocation(SmallPtrSetImpl<Metadata *> &Visited, 45506c3fb27SDimitry Andric SmallPtrSetImpl<Metadata *> &AllDILocation, 45606c3fb27SDimitry Andric const SmallPtrSetImpl<Metadata *> &DIReachable, 45706c3fb27SDimitry Andric Metadata *MD) { 45806c3fb27SDimitry Andric MDNode *N = dyn_cast_or_null<MDNode>(MD); 45906c3fb27SDimitry Andric if (!N) 46006c3fb27SDimitry Andric return false; 46106c3fb27SDimitry Andric if (isa<DILocation>(N) || AllDILocation.count(N)) 46206c3fb27SDimitry Andric return true; 46306c3fb27SDimitry Andric if (!DIReachable.count(N)) 46406c3fb27SDimitry Andric return false; 46506c3fb27SDimitry Andric if (!Visited.insert(N).second) 46606c3fb27SDimitry Andric return false; 46706c3fb27SDimitry Andric for (auto &OpIt : N->operands()) { 46806c3fb27SDimitry Andric Metadata *Op = OpIt.get(); 46906c3fb27SDimitry Andric if (Op == MD) 47006c3fb27SDimitry Andric continue; 47106c3fb27SDimitry Andric if (!isAllDILocation(Visited, AllDILocation, DIReachable, Op)) { 47206c3fb27SDimitry Andric return false; 47306c3fb27SDimitry Andric } 47406c3fb27SDimitry Andric } 47506c3fb27SDimitry Andric AllDILocation.insert(N); 476fe6060f1SDimitry Andric return true; 477fe6060f1SDimitry Andric } 47806c3fb27SDimitry Andric 47906c3fb27SDimitry Andric static Metadata * 48006c3fb27SDimitry Andric stripLoopMDLoc(const SmallPtrSetImpl<Metadata *> &AllDILocation, 48106c3fb27SDimitry Andric const SmallPtrSetImpl<Metadata *> &DIReachable, Metadata *MD) { 48206c3fb27SDimitry Andric if (isa<DILocation>(MD) || AllDILocation.count(MD)) 48306c3fb27SDimitry Andric return nullptr; 48406c3fb27SDimitry Andric 48506c3fb27SDimitry Andric if (!DIReachable.count(MD)) 48606c3fb27SDimitry Andric return MD; 48706c3fb27SDimitry Andric 48806c3fb27SDimitry Andric MDNode *N = dyn_cast_or_null<MDNode>(MD); 48906c3fb27SDimitry Andric if (!N) 49006c3fb27SDimitry Andric return MD; 49106c3fb27SDimitry Andric 49206c3fb27SDimitry Andric SmallVector<Metadata *, 4> Args; 49306c3fb27SDimitry Andric bool HasSelfRef = false; 49406c3fb27SDimitry Andric for (unsigned i = 0; i < N->getNumOperands(); ++i) { 49506c3fb27SDimitry Andric Metadata *A = N->getOperand(i); 49606c3fb27SDimitry Andric if (!A) { 49706c3fb27SDimitry Andric Args.push_back(nullptr); 49806c3fb27SDimitry Andric } else if (A == MD) { 49906c3fb27SDimitry Andric assert(i == 0 && "expected i==0 for self-reference"); 50006c3fb27SDimitry Andric HasSelfRef = true; 50106c3fb27SDimitry Andric Args.push_back(nullptr); 50206c3fb27SDimitry Andric } else if (Metadata *NewArg = 50306c3fb27SDimitry Andric stripLoopMDLoc(AllDILocation, DIReachable, A)) { 50406c3fb27SDimitry Andric Args.push_back(NewArg); 505fe6060f1SDimitry Andric } 50606c3fb27SDimitry Andric } 50706c3fb27SDimitry Andric if (Args.empty() || (HasSelfRef && Args.size() == 1)) 50806c3fb27SDimitry Andric return nullptr; 50906c3fb27SDimitry Andric 51006c3fb27SDimitry Andric MDNode *NewMD = N->isDistinct() ? MDNode::getDistinct(N->getContext(), Args) 51106c3fb27SDimitry Andric : MDNode::get(N->getContext(), Args); 51206c3fb27SDimitry Andric if (HasSelfRef) 51306c3fb27SDimitry Andric NewMD->replaceOperandWith(0, NewMD); 51406c3fb27SDimitry Andric return NewMD; 515fe6060f1SDimitry Andric } 516fe6060f1SDimitry Andric 5170b57cec5SDimitry Andric static MDNode *stripDebugLocFromLoopID(MDNode *N) { 5188bcb0991SDimitry Andric assert(!N->operands().empty() && "Missing self reference?"); 51906c3fb27SDimitry Andric SmallPtrSet<Metadata *, 8> Visited, DILocationReachable, AllDILocation; 520fe6060f1SDimitry Andric // If we already visited N, there is nothing to do. 521fe6060f1SDimitry Andric if (!Visited.insert(N).second) 522fe6060f1SDimitry Andric return N; 5230b57cec5SDimitry Andric 524fe6060f1SDimitry Andric // If there is no debug location, we do not have to rewrite this 525fe6060f1SDimitry Andric // MDNode. This loop also initializes DILocationReachable, later 526fe6060f1SDimitry Andric // needed by updateLoopMetadataDebugLocationsImpl; the use of 527fe6060f1SDimitry Andric // count_if avoids an early exit. 52806c3fb27SDimitry Andric if (!llvm::count_if(llvm::drop_begin(N->operands()), 529fe6060f1SDimitry Andric [&Visited, &DILocationReachable](const MDOperand &Op) { 530fe6060f1SDimitry Andric return isDILocationReachable( 531fe6060f1SDimitry Andric Visited, DILocationReachable, Op.get()); 5320b57cec5SDimitry Andric })) 5330b57cec5SDimitry Andric return N; 5340b57cec5SDimitry Andric 53506c3fb27SDimitry Andric Visited.clear(); 5360b57cec5SDimitry Andric // If there is only the debug location without any actual loop metadata, we 5370b57cec5SDimitry Andric // can remove the metadata. 538bdd1243dSDimitry Andric if (llvm::all_of(llvm::drop_begin(N->operands()), 53906c3fb27SDimitry Andric [&Visited, &AllDILocation, 54006c3fb27SDimitry Andric &DILocationReachable](const MDOperand &Op) { 54106c3fb27SDimitry Andric return isAllDILocation(Visited, AllDILocation, 54206c3fb27SDimitry Andric DILocationReachable, Op.get()); 5430b57cec5SDimitry Andric })) 5440b57cec5SDimitry Andric return nullptr; 5450b57cec5SDimitry Andric 546fe6060f1SDimitry Andric return updateLoopMetadataDebugLocationsImpl( 54706c3fb27SDimitry Andric N, [&AllDILocation, &DILocationReachable](Metadata *MD) -> Metadata * { 54806c3fb27SDimitry Andric return stripLoopMDLoc(AllDILocation, DILocationReachable, MD); 549fe6060f1SDimitry Andric }); 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric bool llvm::stripDebugInfo(Function &F) { 5530b57cec5SDimitry Andric bool Changed = false; 5540b57cec5SDimitry Andric if (F.hasMetadata(LLVMContext::MD_dbg)) { 5550b57cec5SDimitry Andric Changed = true; 5560b57cec5SDimitry Andric F.setSubprogram(nullptr); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric DenseMap<MDNode *, MDNode *> LoopIDsMap; 5600b57cec5SDimitry Andric for (BasicBlock &BB : F) { 561349cc55cSDimitry Andric for (Instruction &I : llvm::make_early_inc_range(BB)) { 5620b57cec5SDimitry Andric if (isa<DbgInfoIntrinsic>(&I)) { 5630b57cec5SDimitry Andric I.eraseFromParent(); 5640b57cec5SDimitry Andric Changed = true; 5650b57cec5SDimitry Andric continue; 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric if (I.getDebugLoc()) { 5680b57cec5SDimitry Andric Changed = true; 5690b57cec5SDimitry Andric I.setDebugLoc(DebugLoc()); 5700b57cec5SDimitry Andric } 571fe6060f1SDimitry Andric if (auto *LoopID = I.getMetadata(LLVMContext::MD_loop)) { 5720b57cec5SDimitry Andric auto *NewLoopID = LoopIDsMap.lookup(LoopID); 5730b57cec5SDimitry Andric if (!NewLoopID) 5740b57cec5SDimitry Andric NewLoopID = LoopIDsMap[LoopID] = stripDebugLocFromLoopID(LoopID); 5750b57cec5SDimitry Andric if (NewLoopID != LoopID) 576fe6060f1SDimitry Andric I.setMetadata(LLVMContext::MD_loop, NewLoopID); 577fe6060f1SDimitry Andric } 578bdd1243dSDimitry Andric // Strip other attachments that are or use debug info. 579bdd1243dSDimitry Andric if (I.hasMetadataOtherThanDebugLoc()) { 580bdd1243dSDimitry Andric // Heapallocsites point into the DIType system. 581fe6060f1SDimitry Andric I.setMetadata("heapallocsite", nullptr); 582bdd1243dSDimitry Andric // DIAssignID are debug info metadata primitives. 583bdd1243dSDimitry Andric I.setMetadata(LLVMContext::MD_DIAssignID, nullptr); 584bdd1243dSDimitry Andric } 585*0fca6ea1SDimitry Andric I.dropDbgRecords(); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric return Changed; 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric bool llvm::StripDebugInfo(Module &M) { 5920b57cec5SDimitry Andric bool Changed = false; 5930b57cec5SDimitry Andric 594fe6060f1SDimitry Andric for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata())) { 5950b57cec5SDimitry Andric // We're stripping debug info, and without them, coverage information 5960b57cec5SDimitry Andric // doesn't quite make sense. 5975f757f3fSDimitry Andric if (NMD.getName().starts_with("llvm.dbg.") || 598fe6060f1SDimitry Andric NMD.getName() == "llvm.gcov") { 599fe6060f1SDimitry Andric NMD.eraseFromParent(); 6000b57cec5SDimitry Andric Changed = true; 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric for (Function &F : M) 6050b57cec5SDimitry Andric Changed |= stripDebugInfo(F); 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric for (auto &GV : M.globals()) { 6080b57cec5SDimitry Andric Changed |= GV.eraseMetadata(LLVMContext::MD_dbg); 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric if (GVMaterializer *Materializer = M.getMaterializer()) 6120b57cec5SDimitry Andric Materializer->setStripDebugInfo(); 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric return Changed; 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric namespace { 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric /// Helper class to downgrade -g metadata to -gline-tables-only metadata. 6200b57cec5SDimitry Andric class DebugTypeInfoRemoval { 6210b57cec5SDimitry Andric DenseMap<Metadata *, Metadata *> Replacements; 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric public: 6240b57cec5SDimitry Andric /// The (void)() type. 6250b57cec5SDimitry Andric MDNode *EmptySubroutineType; 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric private: 6280b57cec5SDimitry Andric /// Remember what linkage name we originally had before stripping. If we end 6290b57cec5SDimitry Andric /// up making two subprograms identical who originally had different linkage 6300b57cec5SDimitry Andric /// names, then we need to make one of them distinct, to avoid them getting 6310b57cec5SDimitry Andric /// uniqued. Maps the new node to the old linkage name. 6320b57cec5SDimitry Andric DenseMap<DISubprogram *, StringRef> NewToLinkageName; 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric // TODO: Remember the distinct subprogram we created for a given linkage name, 6350b57cec5SDimitry Andric // so that we can continue to unique whenever possible. Map <newly created 6360b57cec5SDimitry Andric // node, old linkage name> to the first (possibly distinct) mdsubprogram 6370b57cec5SDimitry Andric // created for that combination. This is not strictly needed for correctness, 6380b57cec5SDimitry Andric // but can cut down on the number of MDNodes and let us diff cleanly with the 6390b57cec5SDimitry Andric // output of -gline-tables-only. 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric public: 6420b57cec5SDimitry Andric DebugTypeInfoRemoval(LLVMContext &C) 6430b57cec5SDimitry Andric : EmptySubroutineType(DISubroutineType::get(C, DINode::FlagZero, 0, 6440b57cec5SDimitry Andric MDNode::get(C, {}))) {} 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric Metadata *map(Metadata *M) { 6470b57cec5SDimitry Andric if (!M) 6480b57cec5SDimitry Andric return nullptr; 6490b57cec5SDimitry Andric auto Replacement = Replacements.find(M); 6500b57cec5SDimitry Andric if (Replacement != Replacements.end()) 6510b57cec5SDimitry Andric return Replacement->second; 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric return M; 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric MDNode *mapNode(Metadata *N) { return dyn_cast_or_null<MDNode>(map(N)); } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric /// Recursively remap N and all its referenced children. Does a DF post-order 6580b57cec5SDimitry Andric /// traversal, so as to remap bottoms up. 6590b57cec5SDimitry Andric void traverseAndRemap(MDNode *N) { traverse(N); } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric private: 6620b57cec5SDimitry Andric // Create a new DISubprogram, to replace the one given. 6630b57cec5SDimitry Andric DISubprogram *getReplacementSubprogram(DISubprogram *MDS) { 6640b57cec5SDimitry Andric auto *FileAndScope = cast_or_null<DIFile>(map(MDS->getFile())); 6650b57cec5SDimitry Andric StringRef LinkageName = MDS->getName().empty() ? MDS->getLinkageName() : ""; 6660b57cec5SDimitry Andric DISubprogram *Declaration = nullptr; 6670b57cec5SDimitry Andric auto *Type = cast_or_null<DISubroutineType>(map(MDS->getType())); 6680b57cec5SDimitry Andric DIType *ContainingType = 6690b57cec5SDimitry Andric cast_or_null<DIType>(map(MDS->getContainingType())); 6700b57cec5SDimitry Andric auto *Unit = cast_or_null<DICompileUnit>(map(MDS->getUnit())); 6710b57cec5SDimitry Andric auto Variables = nullptr; 6720b57cec5SDimitry Andric auto TemplateParams = nullptr; 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric // Make a distinct DISubprogram, for situations that warrent it. 6750b57cec5SDimitry Andric auto distinctMDSubprogram = [&]() { 6760b57cec5SDimitry Andric return DISubprogram::getDistinct( 6770b57cec5SDimitry Andric MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, 6780b57cec5SDimitry Andric FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), 6790b57cec5SDimitry Andric ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(), 6800b57cec5SDimitry Andric MDS->getFlags(), MDS->getSPFlags(), Unit, TemplateParams, Declaration, 6810b57cec5SDimitry Andric Variables); 6820b57cec5SDimitry Andric }; 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric if (MDS->isDistinct()) 6850b57cec5SDimitry Andric return distinctMDSubprogram(); 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric auto *NewMDS = DISubprogram::get( 6880b57cec5SDimitry Andric MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, 6890b57cec5SDimitry Andric FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType, 6900b57cec5SDimitry Andric MDS->getVirtualIndex(), MDS->getThisAdjustment(), MDS->getFlags(), 6910b57cec5SDimitry Andric MDS->getSPFlags(), Unit, TemplateParams, Declaration, Variables); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric StringRef OldLinkageName = MDS->getLinkageName(); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric // See if we need to make a distinct one. 6960b57cec5SDimitry Andric auto OrigLinkage = NewToLinkageName.find(NewMDS); 6970b57cec5SDimitry Andric if (OrigLinkage != NewToLinkageName.end()) { 6980b57cec5SDimitry Andric if (OrigLinkage->second == OldLinkageName) 6990b57cec5SDimitry Andric // We're good. 7000b57cec5SDimitry Andric return NewMDS; 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric // Otherwise, need to make a distinct one. 7030b57cec5SDimitry Andric // TODO: Query the map to see if we already have one. 7040b57cec5SDimitry Andric return distinctMDSubprogram(); 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric NewToLinkageName.insert({NewMDS, MDS->getLinkageName()}); 7080b57cec5SDimitry Andric return NewMDS; 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric /// Create a new compile unit, to replace the one given 7120b57cec5SDimitry Andric DICompileUnit *getReplacementCU(DICompileUnit *CU) { 7130b57cec5SDimitry Andric // Drop skeleton CUs. 7140b57cec5SDimitry Andric if (CU->getDWOId()) 7150b57cec5SDimitry Andric return nullptr; 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric auto *File = cast_or_null<DIFile>(map(CU->getFile())); 7180b57cec5SDimitry Andric MDTuple *EnumTypes = nullptr; 7190b57cec5SDimitry Andric MDTuple *RetainedTypes = nullptr; 7200b57cec5SDimitry Andric MDTuple *GlobalVariables = nullptr; 7210b57cec5SDimitry Andric MDTuple *ImportedEntities = nullptr; 7220b57cec5SDimitry Andric return DICompileUnit::getDistinct( 7230b57cec5SDimitry Andric CU->getContext(), CU->getSourceLanguage(), File, CU->getProducer(), 7240b57cec5SDimitry Andric CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(), 7250b57cec5SDimitry Andric CU->getSplitDebugFilename(), DICompileUnit::LineTablesOnly, EnumTypes, 7260b57cec5SDimitry Andric RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(), 7270b57cec5SDimitry Andric CU->getDWOId(), CU->getSplitDebugInlining(), 7280b57cec5SDimitry Andric CU->getDebugInfoForProfiling(), CU->getNameTableKind(), 7295ffd83dbSDimitry Andric CU->getRangesBaseAddress(), CU->getSysRoot(), CU->getSDK()); 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric DILocation *getReplacementMDLocation(DILocation *MLD) { 7330b57cec5SDimitry Andric auto *Scope = map(MLD->getScope()); 7340b57cec5SDimitry Andric auto *InlinedAt = map(MLD->getInlinedAt()); 7350b57cec5SDimitry Andric if (MLD->isDistinct()) 7360b57cec5SDimitry Andric return DILocation::getDistinct(MLD->getContext(), MLD->getLine(), 7370b57cec5SDimitry Andric MLD->getColumn(), Scope, InlinedAt); 7380b57cec5SDimitry Andric return DILocation::get(MLD->getContext(), MLD->getLine(), MLD->getColumn(), 7390b57cec5SDimitry Andric Scope, InlinedAt); 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric /// Create a new generic MDNode, to replace the one given 7430b57cec5SDimitry Andric MDNode *getReplacementMDNode(MDNode *N) { 7440b57cec5SDimitry Andric SmallVector<Metadata *, 8> Ops; 7450b57cec5SDimitry Andric Ops.reserve(N->getNumOperands()); 7460b57cec5SDimitry Andric for (auto &I : N->operands()) 7470b57cec5SDimitry Andric if (I) 7480b57cec5SDimitry Andric Ops.push_back(map(I)); 7490b57cec5SDimitry Andric auto *Ret = MDNode::get(N->getContext(), Ops); 7500b57cec5SDimitry Andric return Ret; 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric /// Attempt to re-map N to a newly created node. 7540b57cec5SDimitry Andric void remap(MDNode *N) { 7550b57cec5SDimitry Andric if (Replacements.count(N)) 7560b57cec5SDimitry Andric return; 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric auto doRemap = [&](MDNode *N) -> MDNode * { 7590b57cec5SDimitry Andric if (!N) 7600b57cec5SDimitry Andric return nullptr; 7610b57cec5SDimitry Andric if (auto *MDSub = dyn_cast<DISubprogram>(N)) { 7620b57cec5SDimitry Andric remap(MDSub->getUnit()); 7630b57cec5SDimitry Andric return getReplacementSubprogram(MDSub); 7640b57cec5SDimitry Andric } 7650b57cec5SDimitry Andric if (isa<DISubroutineType>(N)) 7660b57cec5SDimitry Andric return EmptySubroutineType; 7670b57cec5SDimitry Andric if (auto *CU = dyn_cast<DICompileUnit>(N)) 7680b57cec5SDimitry Andric return getReplacementCU(CU); 7690b57cec5SDimitry Andric if (isa<DIFile>(N)) 7700b57cec5SDimitry Andric return N; 7710b57cec5SDimitry Andric if (auto *MDLB = dyn_cast<DILexicalBlockBase>(N)) 7720b57cec5SDimitry Andric // Remap to our referenced scope (recursively). 7730b57cec5SDimitry Andric return mapNode(MDLB->getScope()); 7740b57cec5SDimitry Andric if (auto *MLD = dyn_cast<DILocation>(N)) 7750b57cec5SDimitry Andric return getReplacementMDLocation(MLD); 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric // Otherwise, if we see these, just drop them now. Not strictly necessary, 7780b57cec5SDimitry Andric // but this speeds things up a little. 7790b57cec5SDimitry Andric if (isa<DINode>(N)) 7800b57cec5SDimitry Andric return nullptr; 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric return getReplacementMDNode(N); 7830b57cec5SDimitry Andric }; 7840b57cec5SDimitry Andric Replacements[N] = doRemap(N); 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric /// Do the remapping traversal. 7880b57cec5SDimitry Andric void traverse(MDNode *); 7890b57cec5SDimitry Andric }; 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric } // end anonymous namespace 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric void DebugTypeInfoRemoval::traverse(MDNode *N) { 7940b57cec5SDimitry Andric if (!N || Replacements.count(N)) 7950b57cec5SDimitry Andric return; 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric // To avoid cycles, as well as for efficiency sake, we will sometimes prune 7980b57cec5SDimitry Andric // parts of the graph. 7990b57cec5SDimitry Andric auto prune = [](MDNode *Parent, MDNode *Child) { 8000b57cec5SDimitry Andric if (auto *MDS = dyn_cast<DISubprogram>(Parent)) 8010b57cec5SDimitry Andric return Child == MDS->getRetainedNodes().get(); 8020b57cec5SDimitry Andric return false; 8030b57cec5SDimitry Andric }; 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric SmallVector<MDNode *, 16> ToVisit; 8060b57cec5SDimitry Andric DenseSet<MDNode *> Opened; 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric // Visit each node starting at N in post order, and map them. 8090b57cec5SDimitry Andric ToVisit.push_back(N); 8100b57cec5SDimitry Andric while (!ToVisit.empty()) { 8110b57cec5SDimitry Andric auto *N = ToVisit.back(); 8120b57cec5SDimitry Andric if (!Opened.insert(N).second) { 8130b57cec5SDimitry Andric // Close it. 8140b57cec5SDimitry Andric remap(N); 8150b57cec5SDimitry Andric ToVisit.pop_back(); 8160b57cec5SDimitry Andric continue; 8170b57cec5SDimitry Andric } 8180b57cec5SDimitry Andric for (auto &I : N->operands()) 8190b57cec5SDimitry Andric if (auto *MDN = dyn_cast_or_null<MDNode>(I)) 8200b57cec5SDimitry Andric if (!Opened.count(MDN) && !Replacements.count(MDN) && !prune(N, MDN) && 8210b57cec5SDimitry Andric !isa<DICompileUnit>(MDN)) 8220b57cec5SDimitry Andric ToVisit.push_back(MDN); 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric bool llvm::stripNonLineTableDebugInfo(Module &M) { 8270b57cec5SDimitry Andric bool Changed = false; 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric // First off, delete the debug intrinsics. 8300b57cec5SDimitry Andric auto RemoveUses = [&](StringRef Name) { 8310b57cec5SDimitry Andric if (auto *DbgVal = M.getFunction(Name)) { 8320b57cec5SDimitry Andric while (!DbgVal->use_empty()) 8330b57cec5SDimitry Andric cast<Instruction>(DbgVal->user_back())->eraseFromParent(); 8340b57cec5SDimitry Andric DbgVal->eraseFromParent(); 8350b57cec5SDimitry Andric Changed = true; 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric }; 8380b57cec5SDimitry Andric RemoveUses("llvm.dbg.declare"); 8395ffd83dbSDimitry Andric RemoveUses("llvm.dbg.label"); 8400b57cec5SDimitry Andric RemoveUses("llvm.dbg.value"); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric // Delete non-CU debug info named metadata nodes. 8430b57cec5SDimitry Andric for (auto NMI = M.named_metadata_begin(), NME = M.named_metadata_end(); 8440b57cec5SDimitry Andric NMI != NME;) { 8450b57cec5SDimitry Andric NamedMDNode *NMD = &*NMI; 8460b57cec5SDimitry Andric ++NMI; 8470b57cec5SDimitry Andric // Specifically keep dbg.cu around. 8480b57cec5SDimitry Andric if (NMD->getName() == "llvm.dbg.cu") 8490b57cec5SDimitry Andric continue; 8500b57cec5SDimitry Andric } 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric // Drop all dbg attachments from global variables. 8530b57cec5SDimitry Andric for (auto &GV : M.globals()) 8540b57cec5SDimitry Andric GV.eraseMetadata(LLVMContext::MD_dbg); 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric DebugTypeInfoRemoval Mapper(M.getContext()); 8570b57cec5SDimitry Andric auto remap = [&](MDNode *Node) -> MDNode * { 8580b57cec5SDimitry Andric if (!Node) 8590b57cec5SDimitry Andric return nullptr; 8600b57cec5SDimitry Andric Mapper.traverseAndRemap(Node); 8610b57cec5SDimitry Andric auto *NewNode = Mapper.mapNode(Node); 8620b57cec5SDimitry Andric Changed |= Node != NewNode; 8630b57cec5SDimitry Andric Node = NewNode; 8640b57cec5SDimitry Andric return NewNode; 8650b57cec5SDimitry Andric }; 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric // Rewrite the DebugLocs to be equivalent to what 8680b57cec5SDimitry Andric // -gline-tables-only would have created. 8690b57cec5SDimitry Andric for (auto &F : M) { 8700b57cec5SDimitry Andric if (auto *SP = F.getSubprogram()) { 8710b57cec5SDimitry Andric Mapper.traverseAndRemap(SP); 8720b57cec5SDimitry Andric auto *NewSP = cast<DISubprogram>(Mapper.mapNode(SP)); 8730b57cec5SDimitry Andric Changed |= SP != NewSP; 8740b57cec5SDimitry Andric F.setSubprogram(NewSP); 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric for (auto &BB : F) { 8770b57cec5SDimitry Andric for (auto &I : BB) { 8785ffd83dbSDimitry Andric auto remapDebugLoc = [&](const DebugLoc &DL) -> DebugLoc { 8790b57cec5SDimitry Andric auto *Scope = DL.getScope(); 8800b57cec5SDimitry Andric MDNode *InlinedAt = DL.getInlinedAt(); 8810b57cec5SDimitry Andric Scope = remap(Scope); 8820b57cec5SDimitry Andric InlinedAt = remap(InlinedAt); 883e8d8bef9SDimitry Andric return DILocation::get(M.getContext(), DL.getLine(), DL.getCol(), 884e8d8bef9SDimitry Andric Scope, InlinedAt); 8850b57cec5SDimitry Andric }; 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric if (I.getDebugLoc() != DebugLoc()) 8880b57cec5SDimitry Andric I.setDebugLoc(remapDebugLoc(I.getDebugLoc())); 8890b57cec5SDimitry Andric 8905ffd83dbSDimitry Andric // Remap DILocations in llvm.loop attachments. 891fe6060f1SDimitry Andric updateLoopMetadataDebugLocations(I, [&](Metadata *MD) -> Metadata * { 892fe6060f1SDimitry Andric if (auto *Loc = dyn_cast_or_null<DILocation>(MD)) 893fe6060f1SDimitry Andric return remapDebugLoc(Loc).get(); 894fe6060f1SDimitry Andric return MD; 8955ffd83dbSDimitry Andric }); 896fe6060f1SDimitry Andric 897fe6060f1SDimitry Andric // Strip heapallocsite attachments, they point into the DIType system. 898fe6060f1SDimitry Andric if (I.hasMetadataOtherThanDebugLoc()) 899fe6060f1SDimitry Andric I.setMetadata("heapallocsite", nullptr); 9007a6dacacSDimitry Andric 901*0fca6ea1SDimitry Andric // Strip any DbgRecords attached. 902*0fca6ea1SDimitry Andric I.dropDbgRecords(); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric } 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric // Create a new llvm.dbg.cu, which is equivalent to the one 9080b57cec5SDimitry Andric // -gline-tables-only would have created. 90906c3fb27SDimitry Andric for (auto &NMD : M.named_metadata()) { 9100b57cec5SDimitry Andric SmallVector<MDNode *, 8> Ops; 9110b57cec5SDimitry Andric for (MDNode *Op : NMD.operands()) 9120b57cec5SDimitry Andric Ops.push_back(remap(Op)); 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric if (!Changed) 9150b57cec5SDimitry Andric continue; 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric NMD.clearOperands(); 9180b57cec5SDimitry Andric for (auto *Op : Ops) 9190b57cec5SDimitry Andric if (Op) 9200b57cec5SDimitry Andric NMD.addOperand(Op); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric return Changed; 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { 9260b57cec5SDimitry Andric if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>( 9270b57cec5SDimitry Andric M.getModuleFlag("Debug Info Version"))) 9280b57cec5SDimitry Andric return Val->getZExtValue(); 9290b57cec5SDimitry Andric return 0; 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric 93206c3fb27SDimitry Andric void Instruction::applyMergedLocation(DILocation *LocA, DILocation *LocB) { 9330b57cec5SDimitry Andric setDebugLoc(DILocation::getMergedLocation(LocA, LocB)); 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric 936bdd1243dSDimitry Andric void Instruction::mergeDIAssignID( 937bdd1243dSDimitry Andric ArrayRef<const Instruction *> SourceInstructions) { 938bdd1243dSDimitry Andric // Replace all uses (and attachments) of all the DIAssignIDs 939bdd1243dSDimitry Andric // on SourceInstructions with a single merged value. 940bdd1243dSDimitry Andric assert(getFunction() && "Uninserted instruction merged"); 941bdd1243dSDimitry Andric // Collect up the DIAssignID tags. 942bdd1243dSDimitry Andric SmallVector<DIAssignID *, 4> IDs; 943bdd1243dSDimitry Andric for (const Instruction *I : SourceInstructions) { 944bdd1243dSDimitry Andric if (auto *MD = I->getMetadata(LLVMContext::MD_DIAssignID)) 945bdd1243dSDimitry Andric IDs.push_back(cast<DIAssignID>(MD)); 946bdd1243dSDimitry Andric assert(getFunction() == I->getFunction() && 947bdd1243dSDimitry Andric "Merging with instruction from another function not allowed"); 948bdd1243dSDimitry Andric } 949bdd1243dSDimitry Andric 950bdd1243dSDimitry Andric // Add this instruction's DIAssignID too, if it has one. 951bdd1243dSDimitry Andric if (auto *MD = getMetadata(LLVMContext::MD_DIAssignID)) 952bdd1243dSDimitry Andric IDs.push_back(cast<DIAssignID>(MD)); 953bdd1243dSDimitry Andric 954bdd1243dSDimitry Andric if (IDs.empty()) 955bdd1243dSDimitry Andric return; // No DIAssignID tags to process. 956bdd1243dSDimitry Andric 957bdd1243dSDimitry Andric DIAssignID *MergeID = IDs[0]; 958bdd1243dSDimitry Andric for (auto It = std::next(IDs.begin()), End = IDs.end(); It != End; ++It) { 959bdd1243dSDimitry Andric if (*It != MergeID) 960bdd1243dSDimitry Andric at::RAUW(*It, MergeID); 961bdd1243dSDimitry Andric } 962bdd1243dSDimitry Andric setMetadata(LLVMContext::MD_DIAssignID, MergeID); 963bdd1243dSDimitry Andric } 964bdd1243dSDimitry Andric 965e8d8bef9SDimitry Andric void Instruction::updateLocationAfterHoist() { dropLocation(); } 966e8d8bef9SDimitry Andric 967e8d8bef9SDimitry Andric void Instruction::dropLocation() { 968e8d8bef9SDimitry Andric const DebugLoc &DL = getDebugLoc(); 969e8d8bef9SDimitry Andric if (!DL) 970e8d8bef9SDimitry Andric return; 971e8d8bef9SDimitry Andric 972e8d8bef9SDimitry Andric // If this isn't a call, drop the location to allow a location from a 973e8d8bef9SDimitry Andric // preceding instruction to propagate. 974bdd1243dSDimitry Andric bool MayLowerToCall = false; 975bdd1243dSDimitry Andric if (isa<CallBase>(this)) { 976bdd1243dSDimitry Andric auto *II = dyn_cast<IntrinsicInst>(this); 977bdd1243dSDimitry Andric MayLowerToCall = 978bdd1243dSDimitry Andric !II || IntrinsicInst::mayLowerToFunctionCall(II->getIntrinsicID()); 979bdd1243dSDimitry Andric } 980bdd1243dSDimitry Andric 981bdd1243dSDimitry Andric if (!MayLowerToCall) { 982e8d8bef9SDimitry Andric setDebugLoc(DebugLoc()); 983e8d8bef9SDimitry Andric return; 984e8d8bef9SDimitry Andric } 985e8d8bef9SDimitry Andric 986e8d8bef9SDimitry Andric // Set a line 0 location for calls to preserve scope information in case 987e8d8bef9SDimitry Andric // inlining occurs. 988e8d8bef9SDimitry Andric DISubprogram *SP = getFunction()->getSubprogram(); 989e8d8bef9SDimitry Andric if (SP) 990e8d8bef9SDimitry Andric // If a function scope is available, set it on the line 0 location. When 991e8d8bef9SDimitry Andric // hoisting a call to a predecessor block, using the function scope avoids 992e8d8bef9SDimitry Andric // making it look like the callee was reached earlier than it should be. 993e8d8bef9SDimitry Andric setDebugLoc(DILocation::get(getContext(), 0, 0, SP)); 994e8d8bef9SDimitry Andric else 995e8d8bef9SDimitry Andric // The parent function has no scope. Go ahead and drop the location. If 996e8d8bef9SDimitry Andric // the parent function is inlined, and the callee has a subprogram, the 997e8d8bef9SDimitry Andric // inliner will attach a location to the call. 998e8d8bef9SDimitry Andric // 999e8d8bef9SDimitry Andric // One alternative is to set a line 0 location with the existing scope and 1000e8d8bef9SDimitry Andric // inlinedAt info. The location might be sensitive to when inlining occurs. 1001e8d8bef9SDimitry Andric setDebugLoc(DebugLoc()); 1002e8d8bef9SDimitry Andric } 1003e8d8bef9SDimitry Andric 10040b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10050b57cec5SDimitry Andric // LLVM C API implementations. 10060b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric static unsigned map_from_llvmDWARFsourcelanguage(LLVMDWARFSourceLanguage lang) { 10090b57cec5SDimitry Andric switch (lang) { 10100b57cec5SDimitry Andric #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ 10110b57cec5SDimitry Andric case LLVMDWARFSourceLanguage##NAME: \ 10120b57cec5SDimitry Andric return ID; 10130b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.def" 10140b57cec5SDimitry Andric #undef HANDLE_DW_LANG 10150b57cec5SDimitry Andric } 10160b57cec5SDimitry Andric llvm_unreachable("Unhandled Tag"); 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric template <typename DIT> DIT *unwrapDI(LLVMMetadataRef Ref) { 10200b57cec5SDimitry Andric return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr); 10210b57cec5SDimitry Andric } 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric static DINode::DIFlags map_from_llvmDIFlags(LLVMDIFlags Flags) { 10240b57cec5SDimitry Andric return static_cast<DINode::DIFlags>(Flags); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric static LLVMDIFlags map_to_llvmDIFlags(DINode::DIFlags Flags) { 10280b57cec5SDimitry Andric return static_cast<LLVMDIFlags>(Flags); 10290b57cec5SDimitry Andric } 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric static DISubprogram::DISPFlags 10320b57cec5SDimitry Andric pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) { 10330b57cec5SDimitry Andric return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized); 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric unsigned LLVMDebugMetadataVersion() { 10370b57cec5SDimitry Andric return DEBUG_METADATA_VERSION; 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M) { 10410b57cec5SDimitry Andric return wrap(new DIBuilder(*unwrap(M), false)); 10420b57cec5SDimitry Andric } 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M) { 10450b57cec5SDimitry Andric return wrap(new DIBuilder(*unwrap(M))); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef M) { 10490b57cec5SDimitry Andric return getDebugMetadataVersionFromModule(*unwrap(M)); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef M) { 10530b57cec5SDimitry Andric return StripDebugInfo(*unwrap(M)); 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric 10560b57cec5SDimitry Andric void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder) { 10570b57cec5SDimitry Andric delete unwrap(Builder); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder) { 10610b57cec5SDimitry Andric unwrap(Builder)->finalize(); 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric 1064349cc55cSDimitry Andric void LLVMDIBuilderFinalizeSubprogram(LLVMDIBuilderRef Builder, 1065349cc55cSDimitry Andric LLVMMetadataRef subprogram) { 1066349cc55cSDimitry Andric unwrap(Builder)->finalizeSubprogram(unwrapDI<DISubprogram>(subprogram)); 1067349cc55cSDimitry Andric } 1068349cc55cSDimitry Andric 10690b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateCompileUnit( 10700b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang, 10710b57cec5SDimitry Andric LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen, 10720b57cec5SDimitry Andric LLVMBool isOptimized, const char *Flags, size_t FlagsLen, 10730b57cec5SDimitry Andric unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen, 10740b57cec5SDimitry Andric LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining, 10755ffd83dbSDimitry Andric LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen, 10765ffd83dbSDimitry Andric const char *SDK, size_t SDKLen) { 10770b57cec5SDimitry Andric auto File = unwrapDI<DIFile>(FileRef); 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric return wrap(unwrap(Builder)->createCompileUnit( 10800b57cec5SDimitry Andric map_from_llvmDWARFsourcelanguage(Lang), File, 10815ffd83dbSDimitry Andric StringRef(Producer, ProducerLen), isOptimized, StringRef(Flags, FlagsLen), 10825ffd83dbSDimitry Andric RuntimeVer, StringRef(SplitName, SplitNameLen), 10830b57cec5SDimitry Andric static_cast<DICompileUnit::DebugEmissionKind>(Kind), DWOId, 10845ffd83dbSDimitry Andric SplitDebugInlining, DebugInfoForProfiling, 10855ffd83dbSDimitry Andric DICompileUnit::DebugNameTableKind::Default, false, 10865ffd83dbSDimitry Andric StringRef(SysRoot, SysRootLen), StringRef(SDK, SDKLen))); 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric LLVMMetadataRef 10900b57cec5SDimitry Andric LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, 10910b57cec5SDimitry Andric size_t FilenameLen, const char *Directory, 10920b57cec5SDimitry Andric size_t DirectoryLen) { 10930b57cec5SDimitry Andric return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen), 10940b57cec5SDimitry Andric StringRef(Directory, DirectoryLen))); 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric LLVMMetadataRef 10980b57cec5SDimitry Andric LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope, 10990b57cec5SDimitry Andric const char *Name, size_t NameLen, 11000b57cec5SDimitry Andric const char *ConfigMacros, size_t ConfigMacrosLen, 11010b57cec5SDimitry Andric const char *IncludePath, size_t IncludePathLen, 11025ffd83dbSDimitry Andric const char *APINotesFile, size_t APINotesFileLen) { 11030b57cec5SDimitry Andric return wrap(unwrap(Builder)->createModule( 11040b57cec5SDimitry Andric unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen), 11050b57cec5SDimitry Andric StringRef(ConfigMacros, ConfigMacrosLen), 11060b57cec5SDimitry Andric StringRef(IncludePath, IncludePathLen), 11075ffd83dbSDimitry Andric StringRef(APINotesFile, APINotesFileLen))); 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder, 11110b57cec5SDimitry Andric LLVMMetadataRef ParentScope, 11120b57cec5SDimitry Andric const char *Name, size_t NameLen, 11130b57cec5SDimitry Andric LLVMBool ExportSymbols) { 11140b57cec5SDimitry Andric return wrap(unwrap(Builder)->createNameSpace( 11150b57cec5SDimitry Andric unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen), ExportSymbols)); 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateFunction( 11190b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 11200b57cec5SDimitry Andric size_t NameLen, const char *LinkageName, size_t LinkageNameLen, 11210b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, 11220b57cec5SDimitry Andric LLVMBool IsLocalToUnit, LLVMBool IsDefinition, 11230b57cec5SDimitry Andric unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) { 11240b57cec5SDimitry Andric return wrap(unwrap(Builder)->createFunction( 11250b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen}, 11260b57cec5SDimitry Andric unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine, 11270b57cec5SDimitry Andric map_from_llvmDIFlags(Flags), 11280b57cec5SDimitry Andric pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr, 11290b57cec5SDimitry Andric nullptr, nullptr)); 11300b57cec5SDimitry Andric } 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock( 11340b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, 11350b57cec5SDimitry Andric LLVMMetadataRef File, unsigned Line, unsigned Col) { 11360b57cec5SDimitry Andric return wrap(unwrap(Builder)->createLexicalBlock(unwrapDI<DIScope>(Scope), 11370b57cec5SDimitry Andric unwrapDI<DIFile>(File), 11380b57cec5SDimitry Andric Line, Col)); 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric LLVMMetadataRef 11420b57cec5SDimitry Andric LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Builder, 11430b57cec5SDimitry Andric LLVMMetadataRef Scope, 11440b57cec5SDimitry Andric LLVMMetadataRef File, 11450b57cec5SDimitry Andric unsigned Discriminator) { 11460b57cec5SDimitry Andric return wrap(unwrap(Builder)->createLexicalBlockFile(unwrapDI<DIScope>(Scope), 11470b57cec5SDimitry Andric unwrapDI<DIFile>(File), 11480b57cec5SDimitry Andric Discriminator)); 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric LLVMMetadataRef 11520b57cec5SDimitry Andric LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder, 11530b57cec5SDimitry Andric LLVMMetadataRef Scope, 11540b57cec5SDimitry Andric LLVMMetadataRef NS, 11550b57cec5SDimitry Andric LLVMMetadataRef File, 11560b57cec5SDimitry Andric unsigned Line) { 11570b57cec5SDimitry Andric return wrap(unwrap(Builder)->createImportedModule(unwrapDI<DIScope>(Scope), 11580b57cec5SDimitry Andric unwrapDI<DINamespace>(NS), 11590b57cec5SDimitry Andric unwrapDI<DIFile>(File), 11600b57cec5SDimitry Andric Line)); 11610b57cec5SDimitry Andric } 11620b57cec5SDimitry Andric 1163349cc55cSDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias( 1164349cc55cSDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, 1165349cc55cSDimitry Andric LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line, 1166349cc55cSDimitry Andric LLVMMetadataRef *Elements, unsigned NumElements) { 1167349cc55cSDimitry Andric auto Elts = 1168349cc55cSDimitry Andric (NumElements > 0) 1169349cc55cSDimitry Andric ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements}) 1170349cc55cSDimitry Andric : nullptr; 11710b57cec5SDimitry Andric return wrap(unwrap(Builder)->createImportedModule( 1172349cc55cSDimitry Andric unwrapDI<DIScope>(Scope), unwrapDI<DIImportedEntity>(ImportedEntity), 1173349cc55cSDimitry Andric unwrapDI<DIFile>(File), Line, Elts)); 11740b57cec5SDimitry Andric } 11750b57cec5SDimitry Andric 1176349cc55cSDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule( 1177349cc55cSDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M, 1178349cc55cSDimitry Andric LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements, 1179349cc55cSDimitry Andric unsigned NumElements) { 1180349cc55cSDimitry Andric auto Elts = 1181349cc55cSDimitry Andric (NumElements > 0) 1182349cc55cSDimitry Andric ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements}) 1183349cc55cSDimitry Andric : nullptr; 1184349cc55cSDimitry Andric return wrap(unwrap(Builder)->createImportedModule( 1185349cc55cSDimitry Andric unwrapDI<DIScope>(Scope), unwrapDI<DIModule>(M), unwrapDI<DIFile>(File), 1186349cc55cSDimitry Andric Line, Elts)); 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric 1189349cc55cSDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration( 1190349cc55cSDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl, 1191349cc55cSDimitry Andric LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen, 1192349cc55cSDimitry Andric LLVMMetadataRef *Elements, unsigned NumElements) { 1193349cc55cSDimitry Andric auto Elts = 1194349cc55cSDimitry Andric (NumElements > 0) 1195349cc55cSDimitry Andric ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements}) 1196349cc55cSDimitry Andric : nullptr; 11970b57cec5SDimitry Andric return wrap(unwrap(Builder)->createImportedDeclaration( 1198349cc55cSDimitry Andric unwrapDI<DIScope>(Scope), unwrapDI<DINode>(Decl), unwrapDI<DIFile>(File), 1199349cc55cSDimitry Andric Line, {Name, NameLen}, Elts)); 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric LLVMMetadataRef 12030b57cec5SDimitry Andric LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line, 12040b57cec5SDimitry Andric unsigned Column, LLVMMetadataRef Scope, 12050b57cec5SDimitry Andric LLVMMetadataRef InlinedAt) { 12060b57cec5SDimitry Andric return wrap(DILocation::get(*unwrap(Ctx), Line, Column, unwrap(Scope), 12070b57cec5SDimitry Andric unwrap(InlinedAt))); 12080b57cec5SDimitry Andric } 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric unsigned LLVMDILocationGetLine(LLVMMetadataRef Location) { 12110b57cec5SDimitry Andric return unwrapDI<DILocation>(Location)->getLine(); 12120b57cec5SDimitry Andric } 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric unsigned LLVMDILocationGetColumn(LLVMMetadataRef Location) { 12150b57cec5SDimitry Andric return unwrapDI<DILocation>(Location)->getColumn(); 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric LLVMMetadataRef LLVMDILocationGetScope(LLVMMetadataRef Location) { 12190b57cec5SDimitry Andric return wrap(unwrapDI<DILocation>(Location)->getScope()); 12200b57cec5SDimitry Andric } 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric LLVMMetadataRef LLVMDILocationGetInlinedAt(LLVMMetadataRef Location) { 12230b57cec5SDimitry Andric return wrap(unwrapDI<DILocation>(Location)->getInlinedAt()); 12240b57cec5SDimitry Andric } 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope) { 12270b57cec5SDimitry Andric return wrap(unwrapDI<DIScope>(Scope)->getFile()); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len) { 12310b57cec5SDimitry Andric auto Dir = unwrapDI<DIFile>(File)->getDirectory(); 12320b57cec5SDimitry Andric *Len = Dir.size(); 12330b57cec5SDimitry Andric return Dir.data(); 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len) { 12370b57cec5SDimitry Andric auto Name = unwrapDI<DIFile>(File)->getFilename(); 12380b57cec5SDimitry Andric *Len = Name.size(); 12390b57cec5SDimitry Andric return Name.data(); 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len) { 12430b57cec5SDimitry Andric if (auto Src = unwrapDI<DIFile>(File)->getSource()) { 12440b57cec5SDimitry Andric *Len = Src->size(); 12450b57cec5SDimitry Andric return Src->data(); 12460b57cec5SDimitry Andric } 12470b57cec5SDimitry Andric *Len = 0; 12480b57cec5SDimitry Andric return ""; 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric 12518bcb0991SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateMacro(LLVMDIBuilderRef Builder, 12528bcb0991SDimitry Andric LLVMMetadataRef ParentMacroFile, 12538bcb0991SDimitry Andric unsigned Line, 12548bcb0991SDimitry Andric LLVMDWARFMacinfoRecordType RecordType, 12558bcb0991SDimitry Andric const char *Name, size_t NameLen, 12568bcb0991SDimitry Andric const char *Value, size_t ValueLen) { 12578bcb0991SDimitry Andric return wrap( 12588bcb0991SDimitry Andric unwrap(Builder)->createMacro(unwrapDI<DIMacroFile>(ParentMacroFile), Line, 12598bcb0991SDimitry Andric static_cast<MacinfoRecordType>(RecordType), 12608bcb0991SDimitry Andric {Name, NameLen}, {Value, ValueLen})); 12618bcb0991SDimitry Andric } 12628bcb0991SDimitry Andric 12638bcb0991SDimitry Andric LLVMMetadataRef 12648bcb0991SDimitry Andric LLVMDIBuilderCreateTempMacroFile(LLVMDIBuilderRef Builder, 12658bcb0991SDimitry Andric LLVMMetadataRef ParentMacroFile, unsigned Line, 12668bcb0991SDimitry Andric LLVMMetadataRef File) { 12678bcb0991SDimitry Andric return wrap(unwrap(Builder)->createTempMacroFile( 12688bcb0991SDimitry Andric unwrapDI<DIMacroFile>(ParentMacroFile), Line, unwrapDI<DIFile>(File))); 12698bcb0991SDimitry Andric } 12708bcb0991SDimitry Andric 12710b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, 12720b57cec5SDimitry Andric const char *Name, size_t NameLen, 12730b57cec5SDimitry Andric int64_t Value, 12740b57cec5SDimitry Andric LLVMBool IsUnsigned) { 12750b57cec5SDimitry Andric return wrap(unwrap(Builder)->createEnumerator({Name, NameLen}, Value, 12760b57cec5SDimitry Andric IsUnsigned != 0)); 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateEnumerationType( 12800b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 12810b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, 12820b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef *Elements, 12830b57cec5SDimitry Andric unsigned NumElements, LLVMMetadataRef ClassTy) { 12840b57cec5SDimitry Andric auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), 12850b57cec5SDimitry Andric NumElements}); 12860b57cec5SDimitry Andric return wrap(unwrap(Builder)->createEnumerationType( 12870b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), 12880b57cec5SDimitry Andric LineNumber, SizeInBits, AlignInBits, Elts, unwrapDI<DIType>(ClassTy))); 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateUnionType( 12920b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 12930b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, 12940b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, 12950b57cec5SDimitry Andric LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang, 12960b57cec5SDimitry Andric const char *UniqueId, size_t UniqueIdLen) { 12970b57cec5SDimitry Andric auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), 12980b57cec5SDimitry Andric NumElements}); 12990b57cec5SDimitry Andric return wrap(unwrap(Builder)->createUnionType( 13000b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), 13010b57cec5SDimitry Andric LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags), 13020b57cec5SDimitry Andric Elts, RunTimeLang, {UniqueId, UniqueIdLen})); 13030b57cec5SDimitry Andric } 13040b57cec5SDimitry Andric 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric LLVMMetadataRef 13070b57cec5SDimitry Andric LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, 13080b57cec5SDimitry Andric uint32_t AlignInBits, LLVMMetadataRef Ty, 13090b57cec5SDimitry Andric LLVMMetadataRef *Subscripts, 13100b57cec5SDimitry Andric unsigned NumSubscripts) { 13110b57cec5SDimitry Andric auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts), 13120b57cec5SDimitry Andric NumSubscripts}); 13130b57cec5SDimitry Andric return wrap(unwrap(Builder)->createArrayType(Size, AlignInBits, 13140b57cec5SDimitry Andric unwrapDI<DIType>(Ty), Subs)); 13150b57cec5SDimitry Andric } 13160b57cec5SDimitry Andric 13170b57cec5SDimitry Andric LLVMMetadataRef 13180b57cec5SDimitry Andric LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size, 13190b57cec5SDimitry Andric uint32_t AlignInBits, LLVMMetadataRef Ty, 13200b57cec5SDimitry Andric LLVMMetadataRef *Subscripts, 13210b57cec5SDimitry Andric unsigned NumSubscripts) { 13220b57cec5SDimitry Andric auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts), 13230b57cec5SDimitry Andric NumSubscripts}); 13240b57cec5SDimitry Andric return wrap(unwrap(Builder)->createVectorType(Size, AlignInBits, 13250b57cec5SDimitry Andric unwrapDI<DIType>(Ty), Subs)); 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric LLVMMetadataRef 13290b57cec5SDimitry Andric LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, 13300b57cec5SDimitry Andric size_t NameLen, uint64_t SizeInBits, 13310b57cec5SDimitry Andric LLVMDWARFTypeEncoding Encoding, 13320b57cec5SDimitry Andric LLVMDIFlags Flags) { 13330b57cec5SDimitry Andric return wrap(unwrap(Builder)->createBasicType({Name, NameLen}, 13340b57cec5SDimitry Andric SizeInBits, Encoding, 13350b57cec5SDimitry Andric map_from_llvmDIFlags(Flags))); 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric 13380b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreatePointerType( 13390b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, 13400b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, 13410b57cec5SDimitry Andric const char *Name, size_t NameLen) { 1342*0fca6ea1SDimitry Andric return wrap(unwrap(Builder)->createPointerType( 1343*0fca6ea1SDimitry Andric unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace, 1344*0fca6ea1SDimitry Andric {Name, NameLen})); 13450b57cec5SDimitry Andric } 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateStructType( 13480b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 13490b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, 13500b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, 13510b57cec5SDimitry Andric LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements, 13520b57cec5SDimitry Andric unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder, 13530b57cec5SDimitry Andric const char *UniqueId, size_t UniqueIdLen) { 13540b57cec5SDimitry Andric auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), 13550b57cec5SDimitry Andric NumElements}); 13560b57cec5SDimitry Andric return wrap(unwrap(Builder)->createStructType( 13570b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), 13580b57cec5SDimitry Andric LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags), 13590b57cec5SDimitry Andric unwrapDI<DIType>(DerivedFrom), Elts, RunTimeLang, 13600b57cec5SDimitry Andric unwrapDI<DIType>(VTableHolder), {UniqueId, UniqueIdLen})); 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateMemberType( 13640b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 13650b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, 13660b57cec5SDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, 13670b57cec5SDimitry Andric LLVMMetadataRef Ty) { 13680b57cec5SDimitry Andric return wrap(unwrap(Builder)->createMemberType(unwrapDI<DIScope>(Scope), 13690b57cec5SDimitry Andric {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, 13700b57cec5SDimitry Andric OffsetInBits, map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Ty))); 13710b57cec5SDimitry Andric } 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric LLVMMetadataRef 13740b57cec5SDimitry Andric LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name, 13750b57cec5SDimitry Andric size_t NameLen) { 13760b57cec5SDimitry Andric return wrap(unwrap(Builder)->createUnspecifiedType({Name, NameLen})); 13770b57cec5SDimitry Andric } 13780b57cec5SDimitry Andric 13795f757f3fSDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType( 13800b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 13810b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, 13820b57cec5SDimitry Andric LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, 13830b57cec5SDimitry Andric uint32_t AlignInBits) { 13840b57cec5SDimitry Andric return wrap(unwrap(Builder)->createStaticMemberType( 13855f757f3fSDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), 13865f757f3fSDimitry Andric LineNumber, unwrapDI<DIType>(Type), map_from_llvmDIFlags(Flags), 13875f757f3fSDimitry Andric unwrap<Constant>(ConstantVal), DW_TAG_member, AlignInBits)); 13880b57cec5SDimitry Andric } 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andric LLVMMetadataRef 13910b57cec5SDimitry Andric LLVMDIBuilderCreateObjCIVar(LLVMDIBuilderRef Builder, 13920b57cec5SDimitry Andric const char *Name, size_t NameLen, 13930b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNo, 13940b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, 13950b57cec5SDimitry Andric uint64_t OffsetInBits, LLVMDIFlags Flags, 13960b57cec5SDimitry Andric LLVMMetadataRef Ty, LLVMMetadataRef PropertyNode) { 13970b57cec5SDimitry Andric return wrap(unwrap(Builder)->createObjCIVar( 13980b57cec5SDimitry Andric {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, 13990b57cec5SDimitry Andric SizeInBits, AlignInBits, OffsetInBits, 14000b57cec5SDimitry Andric map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Ty), 14010b57cec5SDimitry Andric unwrapDI<MDNode>(PropertyNode))); 14020b57cec5SDimitry Andric } 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric LLVMMetadataRef 14050b57cec5SDimitry Andric LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder, 14060b57cec5SDimitry Andric const char *Name, size_t NameLen, 14070b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNo, 14080b57cec5SDimitry Andric const char *GetterName, size_t GetterNameLen, 14090b57cec5SDimitry Andric const char *SetterName, size_t SetterNameLen, 14100b57cec5SDimitry Andric unsigned PropertyAttributes, 14110b57cec5SDimitry Andric LLVMMetadataRef Ty) { 14120b57cec5SDimitry Andric return wrap(unwrap(Builder)->createObjCProperty( 14130b57cec5SDimitry Andric {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, 14140b57cec5SDimitry Andric {GetterName, GetterNameLen}, {SetterName, SetterNameLen}, 14150b57cec5SDimitry Andric PropertyAttributes, unwrapDI<DIType>(Ty))); 14160b57cec5SDimitry Andric } 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric LLVMMetadataRef 14190b57cec5SDimitry Andric LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder, 14200b57cec5SDimitry Andric LLVMMetadataRef Type) { 14210b57cec5SDimitry Andric return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI<DIType>(Type))); 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric LLVMMetadataRef 14250b57cec5SDimitry Andric LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, 14260b57cec5SDimitry Andric const char *Name, size_t NameLen, 14270b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNo, 1428480093f4SDimitry Andric LLVMMetadataRef Scope, uint32_t AlignInBits) { 14290b57cec5SDimitry Andric return wrap(unwrap(Builder)->createTypedef( 1430480093f4SDimitry Andric unwrapDI<DIType>(Type), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, 1431480093f4SDimitry Andric unwrapDI<DIScope>(Scope), AlignInBits)); 14320b57cec5SDimitry Andric } 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric LLVMMetadataRef 14350b57cec5SDimitry Andric LLVMDIBuilderCreateInheritance(LLVMDIBuilderRef Builder, 14360b57cec5SDimitry Andric LLVMMetadataRef Ty, LLVMMetadataRef BaseTy, 14370b57cec5SDimitry Andric uint64_t BaseOffset, uint32_t VBPtrOffset, 14380b57cec5SDimitry Andric LLVMDIFlags Flags) { 14390b57cec5SDimitry Andric return wrap(unwrap(Builder)->createInheritance( 14400b57cec5SDimitry Andric unwrapDI<DIType>(Ty), unwrapDI<DIType>(BaseTy), 14410b57cec5SDimitry Andric BaseOffset, VBPtrOffset, map_from_llvmDIFlags(Flags))); 14420b57cec5SDimitry Andric } 14430b57cec5SDimitry Andric 14440b57cec5SDimitry Andric LLVMMetadataRef 14450b57cec5SDimitry Andric LLVMDIBuilderCreateForwardDecl( 14460b57cec5SDimitry Andric LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, 14470b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, 14480b57cec5SDimitry Andric unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, 14490b57cec5SDimitry Andric const char *UniqueIdentifier, size_t UniqueIdentifierLen) { 14500b57cec5SDimitry Andric return wrap(unwrap(Builder)->createForwardDecl( 14510b57cec5SDimitry Andric Tag, {Name, NameLen}, unwrapDI<DIScope>(Scope), 14520b57cec5SDimitry Andric unwrapDI<DIFile>(File), Line, RuntimeLang, SizeInBits, 14530b57cec5SDimitry Andric AlignInBits, {UniqueIdentifier, UniqueIdentifierLen})); 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric LLVMMetadataRef 14570b57cec5SDimitry Andric LLVMDIBuilderCreateReplaceableCompositeType( 14580b57cec5SDimitry Andric LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, 14590b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, 14600b57cec5SDimitry Andric unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, 14610b57cec5SDimitry Andric LLVMDIFlags Flags, const char *UniqueIdentifier, 14620b57cec5SDimitry Andric size_t UniqueIdentifierLen) { 14630b57cec5SDimitry Andric return wrap(unwrap(Builder)->createReplaceableCompositeType( 14640b57cec5SDimitry Andric Tag, {Name, NameLen}, unwrapDI<DIScope>(Scope), 14650b57cec5SDimitry Andric unwrapDI<DIFile>(File), Line, RuntimeLang, SizeInBits, 14660b57cec5SDimitry Andric AlignInBits, map_from_llvmDIFlags(Flags), 14670b57cec5SDimitry Andric {UniqueIdentifier, UniqueIdentifierLen})); 14680b57cec5SDimitry Andric } 14690b57cec5SDimitry Andric 14700b57cec5SDimitry Andric LLVMMetadataRef 14710b57cec5SDimitry Andric LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, 14720b57cec5SDimitry Andric LLVMMetadataRef Type) { 14730b57cec5SDimitry Andric return wrap(unwrap(Builder)->createQualifiedType(Tag, 14740b57cec5SDimitry Andric unwrapDI<DIType>(Type))); 14750b57cec5SDimitry Andric } 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric LLVMMetadataRef 14780b57cec5SDimitry Andric LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag, 14790b57cec5SDimitry Andric LLVMMetadataRef Type) { 14800b57cec5SDimitry Andric return wrap(unwrap(Builder)->createReferenceType(Tag, 14810b57cec5SDimitry Andric unwrapDI<DIType>(Type))); 14820b57cec5SDimitry Andric } 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric LLVMMetadataRef 14850b57cec5SDimitry Andric LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder) { 14860b57cec5SDimitry Andric return wrap(unwrap(Builder)->createNullPtrType()); 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric LLVMMetadataRef 14900b57cec5SDimitry Andric LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder, 14910b57cec5SDimitry Andric LLVMMetadataRef PointeeType, 14920b57cec5SDimitry Andric LLVMMetadataRef ClassType, 14930b57cec5SDimitry Andric uint64_t SizeInBits, 14940b57cec5SDimitry Andric uint32_t AlignInBits, 14950b57cec5SDimitry Andric LLVMDIFlags Flags) { 14960b57cec5SDimitry Andric return wrap(unwrap(Builder)->createMemberPointerType( 14970b57cec5SDimitry Andric unwrapDI<DIType>(PointeeType), 14980b57cec5SDimitry Andric unwrapDI<DIType>(ClassType), AlignInBits, SizeInBits, 14990b57cec5SDimitry Andric map_from_llvmDIFlags(Flags))); 15000b57cec5SDimitry Andric } 15010b57cec5SDimitry Andric 15020b57cec5SDimitry Andric LLVMMetadataRef 15030b57cec5SDimitry Andric LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder, 15040b57cec5SDimitry Andric LLVMMetadataRef Scope, 15050b57cec5SDimitry Andric const char *Name, size_t NameLen, 15060b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNumber, 15070b57cec5SDimitry Andric uint64_t SizeInBits, 15080b57cec5SDimitry Andric uint64_t OffsetInBits, 15090b57cec5SDimitry Andric uint64_t StorageOffsetInBits, 15100b57cec5SDimitry Andric LLVMDIFlags Flags, LLVMMetadataRef Type) { 15110b57cec5SDimitry Andric return wrap(unwrap(Builder)->createBitFieldMemberType( 15120b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, 15130b57cec5SDimitry Andric unwrapDI<DIFile>(File), LineNumber, 15140b57cec5SDimitry Andric SizeInBits, OffsetInBits, StorageOffsetInBits, 15150b57cec5SDimitry Andric map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Type))); 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric 15180b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder, 15190b57cec5SDimitry Andric LLVMMetadataRef Scope, const char *Name, size_t NameLen, 15200b57cec5SDimitry Andric LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, 15210b57cec5SDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, 15220b57cec5SDimitry Andric LLVMMetadataRef DerivedFrom, 15230b57cec5SDimitry Andric LLVMMetadataRef *Elements, unsigned NumElements, 15240b57cec5SDimitry Andric LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode, 15250b57cec5SDimitry Andric const char *UniqueIdentifier, size_t UniqueIdentifierLen) { 15260b57cec5SDimitry Andric auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), 15270b57cec5SDimitry Andric NumElements}); 15280b57cec5SDimitry Andric return wrap(unwrap(Builder)->createClassType( 15295f757f3fSDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), 15305f757f3fSDimitry Andric LineNumber, SizeInBits, AlignInBits, OffsetInBits, 15315f757f3fSDimitry Andric map_from_llvmDIFlags(Flags), unwrapDI<DIType>(DerivedFrom), Elts, 15325f757f3fSDimitry Andric /*RunTimeLang=*/0, unwrapDI<DIType>(VTableHolder), 15330b57cec5SDimitry Andric unwrapDI<MDNode>(TemplateParamsNode), 15340b57cec5SDimitry Andric {UniqueIdentifier, UniqueIdentifierLen})); 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric 15370b57cec5SDimitry Andric LLVMMetadataRef 15380b57cec5SDimitry Andric LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder, 15390b57cec5SDimitry Andric LLVMMetadataRef Type) { 15400b57cec5SDimitry Andric return wrap(unwrap(Builder)->createArtificialType(unwrapDI<DIType>(Type))); 15410b57cec5SDimitry Andric } 15420b57cec5SDimitry Andric 154306c3fb27SDimitry Andric uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD) { 154406c3fb27SDimitry Andric return unwrapDI<DINode>(MD)->getTag(); 154506c3fb27SDimitry Andric } 154606c3fb27SDimitry Andric 15470b57cec5SDimitry Andric const char *LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length) { 154806c3fb27SDimitry Andric StringRef Str = unwrapDI<DIType>(DType)->getName(); 15490b57cec5SDimitry Andric *Length = Str.size(); 15500b57cec5SDimitry Andric return Str.data(); 15510b57cec5SDimitry Andric } 15520b57cec5SDimitry Andric 15530b57cec5SDimitry Andric uint64_t LLVMDITypeGetSizeInBits(LLVMMetadataRef DType) { 15540b57cec5SDimitry Andric return unwrapDI<DIType>(DType)->getSizeInBits(); 15550b57cec5SDimitry Andric } 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric uint64_t LLVMDITypeGetOffsetInBits(LLVMMetadataRef DType) { 15580b57cec5SDimitry Andric return unwrapDI<DIType>(DType)->getOffsetInBits(); 15590b57cec5SDimitry Andric } 15600b57cec5SDimitry Andric 15610b57cec5SDimitry Andric uint32_t LLVMDITypeGetAlignInBits(LLVMMetadataRef DType) { 15620b57cec5SDimitry Andric return unwrapDI<DIType>(DType)->getAlignInBits(); 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric unsigned LLVMDITypeGetLine(LLVMMetadataRef DType) { 15660b57cec5SDimitry Andric return unwrapDI<DIType>(DType)->getLine(); 15670b57cec5SDimitry Andric } 15680b57cec5SDimitry Andric 15690b57cec5SDimitry Andric LLVMDIFlags LLVMDITypeGetFlags(LLVMMetadataRef DType) { 15700b57cec5SDimitry Andric return map_to_llvmDIFlags(unwrapDI<DIType>(DType)->getFlags()); 15710b57cec5SDimitry Andric } 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder, 15740b57cec5SDimitry Andric LLVMMetadataRef *Types, 15750b57cec5SDimitry Andric size_t Length) { 15760b57cec5SDimitry Andric return wrap( 15770b57cec5SDimitry Andric unwrap(Builder)->getOrCreateTypeArray({unwrap(Types), Length}).get()); 15780b57cec5SDimitry Andric } 15790b57cec5SDimitry Andric 15800b57cec5SDimitry Andric LLVMMetadataRef 15810b57cec5SDimitry Andric LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, 15820b57cec5SDimitry Andric LLVMMetadataRef File, 15830b57cec5SDimitry Andric LLVMMetadataRef *ParameterTypes, 15840b57cec5SDimitry Andric unsigned NumParameterTypes, 15850b57cec5SDimitry Andric LLVMDIFlags Flags) { 15860b57cec5SDimitry Andric auto Elts = unwrap(Builder)->getOrCreateTypeArray({unwrap(ParameterTypes), 15870b57cec5SDimitry Andric NumParameterTypes}); 15880b57cec5SDimitry Andric return wrap(unwrap(Builder)->createSubroutineType( 15890b57cec5SDimitry Andric Elts, map_from_llvmDIFlags(Flags))); 15900b57cec5SDimitry Andric } 15910b57cec5SDimitry Andric 15920b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder, 159304eeddc0SDimitry Andric uint64_t *Addr, size_t Length) { 159404eeddc0SDimitry Andric return wrap( 159504eeddc0SDimitry Andric unwrap(Builder)->createExpression(ArrayRef<uint64_t>(Addr, Length))); 15960b57cec5SDimitry Andric } 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric LLVMMetadataRef 15990b57cec5SDimitry Andric LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder, 160004eeddc0SDimitry Andric uint64_t Value) { 16010b57cec5SDimitry Andric return wrap(unwrap(Builder)->createConstantValueExpression(Value)); 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( 16050b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 16060b57cec5SDimitry Andric size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, 16070b57cec5SDimitry Andric unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, 16080b57cec5SDimitry Andric LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) { 16090b57cec5SDimitry Andric return wrap(unwrap(Builder)->createGlobalVariableExpression( 16100b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen}, 16110b57cec5SDimitry Andric unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit, 1612480093f4SDimitry Andric true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl), 16130b57cec5SDimitry Andric nullptr, AlignInBits)); 16140b57cec5SDimitry Andric } 16150b57cec5SDimitry Andric 16160b57cec5SDimitry Andric LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) { 16170b57cec5SDimitry Andric return wrap(unwrapDI<DIGlobalVariableExpression>(GVE)->getVariable()); 16180b57cec5SDimitry Andric } 16190b57cec5SDimitry Andric 16200b57cec5SDimitry Andric LLVMMetadataRef LLVMDIGlobalVariableExpressionGetExpression( 16210b57cec5SDimitry Andric LLVMMetadataRef GVE) { 16220b57cec5SDimitry Andric return wrap(unwrapDI<DIGlobalVariableExpression>(GVE)->getExpression()); 16230b57cec5SDimitry Andric } 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric LLVMMetadataRef LLVMDIVariableGetFile(LLVMMetadataRef Var) { 16260b57cec5SDimitry Andric return wrap(unwrapDI<DIVariable>(Var)->getFile()); 16270b57cec5SDimitry Andric } 16280b57cec5SDimitry Andric 16290b57cec5SDimitry Andric LLVMMetadataRef LLVMDIVariableGetScope(LLVMMetadataRef Var) { 16300b57cec5SDimitry Andric return wrap(unwrapDI<DIVariable>(Var)->getScope()); 16310b57cec5SDimitry Andric } 16320b57cec5SDimitry Andric 16330b57cec5SDimitry Andric unsigned LLVMDIVariableGetLine(LLVMMetadataRef Var) { 16340b57cec5SDimitry Andric return unwrapDI<DIVariable>(Var)->getLine(); 16350b57cec5SDimitry Andric } 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andric LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data, 16380b57cec5SDimitry Andric size_t Count) { 16390b57cec5SDimitry Andric return wrap( 16400b57cec5SDimitry Andric MDTuple::getTemporary(*unwrap(Ctx), {unwrap(Data), Count}).release()); 16410b57cec5SDimitry Andric } 16420b57cec5SDimitry Andric 16430b57cec5SDimitry Andric void LLVMDisposeTemporaryMDNode(LLVMMetadataRef TempNode) { 16440b57cec5SDimitry Andric MDNode::deleteTemporary(unwrapDI<MDNode>(TempNode)); 16450b57cec5SDimitry Andric } 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andric void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TargetMetadata, 16480b57cec5SDimitry Andric LLVMMetadataRef Replacement) { 16490b57cec5SDimitry Andric auto *Node = unwrapDI<MDNode>(TargetMetadata); 1650bdd1243dSDimitry Andric Node->replaceAllUsesWith(unwrap(Replacement)); 16510b57cec5SDimitry Andric MDNode::deleteTemporary(Node); 16520b57cec5SDimitry Andric } 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( 16550b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 16560b57cec5SDimitry Andric size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, 16570b57cec5SDimitry Andric unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, 16580b57cec5SDimitry Andric LLVMMetadataRef Decl, uint32_t AlignInBits) { 16590b57cec5SDimitry Andric return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl( 16600b57cec5SDimitry Andric unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen}, 16610b57cec5SDimitry Andric unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit, 16620b57cec5SDimitry Andric unwrapDI<MDNode>(Decl), nullptr, AlignInBits)); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric 1665*0fca6ea1SDimitry Andric LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore( 1666*0fca6ea1SDimitry Andric LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, 1667*0fca6ea1SDimitry Andric LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) { 1668*0fca6ea1SDimitry Andric DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare( 16690b57cec5SDimitry Andric unwrap(Storage), unwrap<DILocalVariable>(VarInfo), 16700b57cec5SDimitry Andric unwrap<DIExpression>(Expr), unwrap<DILocation>(DL), 1671*0fca6ea1SDimitry Andric unwrap<Instruction>(Instr)); 1672*0fca6ea1SDimitry Andric // This assert will fail if the module is in the old debug info format. 1673*0fca6ea1SDimitry Andric // This function should only be called if the module is in the new 1674*0fca6ea1SDimitry Andric // debug info format. 1675*0fca6ea1SDimitry Andric // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, 1676*0fca6ea1SDimitry Andric // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. 1677*0fca6ea1SDimitry Andric assert(isa<DbgRecord *>(DbgInst) && 1678*0fca6ea1SDimitry Andric "Function unexpectedly in old debug info format"); 1679*0fca6ea1SDimitry Andric return wrap(cast<DbgRecord *>(DbgInst)); 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric 1682*0fca6ea1SDimitry Andric LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd( 16830b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, 16840b57cec5SDimitry Andric LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) { 1685*0fca6ea1SDimitry Andric DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare( 16860b57cec5SDimitry Andric unwrap(Storage), unwrap<DILocalVariable>(VarInfo), 1687*0fca6ea1SDimitry Andric unwrap<DIExpression>(Expr), unwrap<DILocation>(DL), unwrap(Block)); 1688*0fca6ea1SDimitry Andric // This assert will fail if the module is in the old debug info format. 1689*0fca6ea1SDimitry Andric // This function should only be called if the module is in the new 1690*0fca6ea1SDimitry Andric // debug info format. 1691*0fca6ea1SDimitry Andric // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, 1692*0fca6ea1SDimitry Andric // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. 1693*0fca6ea1SDimitry Andric assert(isa<DbgRecord *>(DbgInst) && 1694*0fca6ea1SDimitry Andric "Function unexpectedly in old debug info format"); 1695*0fca6ea1SDimitry Andric return wrap(cast<DbgRecord *>(DbgInst)); 16960b57cec5SDimitry Andric } 16970b57cec5SDimitry Andric 1698*0fca6ea1SDimitry Andric LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore( 1699*0fca6ea1SDimitry Andric LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, 1700*0fca6ea1SDimitry Andric LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr) { 1701*0fca6ea1SDimitry Andric DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( 1702*0fca6ea1SDimitry Andric unwrap(Val), unwrap<DILocalVariable>(VarInfo), unwrap<DIExpression>(Expr), 1703*0fca6ea1SDimitry Andric unwrap<DILocation>(DebugLoc), unwrap<Instruction>(Instr)); 1704*0fca6ea1SDimitry Andric // This assert will fail if the module is in the old debug info format. 1705*0fca6ea1SDimitry Andric // This function should only be called if the module is in the new 1706*0fca6ea1SDimitry Andric // debug info format. 1707*0fca6ea1SDimitry Andric // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, 1708*0fca6ea1SDimitry Andric // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. 1709*0fca6ea1SDimitry Andric assert(isa<DbgRecord *>(DbgInst) && 1710*0fca6ea1SDimitry Andric "Function unexpectedly in old debug info format"); 1711*0fca6ea1SDimitry Andric return wrap(cast<DbgRecord *>(DbgInst)); 17120b57cec5SDimitry Andric } 17130b57cec5SDimitry Andric 1714*0fca6ea1SDimitry Andric LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordAtEnd( 1715*0fca6ea1SDimitry Andric LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, 1716*0fca6ea1SDimitry Andric LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) { 1717*0fca6ea1SDimitry Andric DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( 1718*0fca6ea1SDimitry Andric unwrap(Val), unwrap<DILocalVariable>(VarInfo), unwrap<DIExpression>(Expr), 1719*0fca6ea1SDimitry Andric unwrap<DILocation>(DebugLoc), unwrap(Block)); 1720*0fca6ea1SDimitry Andric // This assert will fail if the module is in the old debug info format. 1721*0fca6ea1SDimitry Andric // This function should only be called if the module is in the new 1722*0fca6ea1SDimitry Andric // debug info format. 1723*0fca6ea1SDimitry Andric // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, 1724*0fca6ea1SDimitry Andric // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. 1725*0fca6ea1SDimitry Andric assert(isa<DbgRecord *>(DbgInst) && 1726*0fca6ea1SDimitry Andric "Function unexpectedly in old debug info format"); 1727*0fca6ea1SDimitry Andric return wrap(cast<DbgRecord *>(DbgInst)); 17280b57cec5SDimitry Andric } 17290b57cec5SDimitry Andric 17300b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( 17310b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 17320b57cec5SDimitry Andric size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, 17330b57cec5SDimitry Andric LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits) { 17340b57cec5SDimitry Andric return wrap(unwrap(Builder)->createAutoVariable( 17350b57cec5SDimitry Andric unwrap<DIScope>(Scope), {Name, NameLen}, unwrap<DIFile>(File), 17360b57cec5SDimitry Andric LineNo, unwrap<DIType>(Ty), AlwaysPreserve, 17370b57cec5SDimitry Andric map_from_llvmDIFlags(Flags), AlignInBits)); 17380b57cec5SDimitry Andric } 17390b57cec5SDimitry Andric 17400b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( 17410b57cec5SDimitry Andric LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, 17420b57cec5SDimitry Andric size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, 17430b57cec5SDimitry Andric LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags) { 17440b57cec5SDimitry Andric return wrap(unwrap(Builder)->createParameterVariable( 17450b57cec5SDimitry Andric unwrap<DIScope>(Scope), {Name, NameLen}, ArgNo, unwrap<DIFile>(File), 17460b57cec5SDimitry Andric LineNo, unwrap<DIType>(Ty), AlwaysPreserve, 17470b57cec5SDimitry Andric map_from_llvmDIFlags(Flags))); 17480b57cec5SDimitry Andric } 17490b57cec5SDimitry Andric 17500b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, 17510b57cec5SDimitry Andric int64_t Lo, int64_t Count) { 17520b57cec5SDimitry Andric return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count)); 17530b57cec5SDimitry Andric } 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder, 17560b57cec5SDimitry Andric LLVMMetadataRef *Data, 17570b57cec5SDimitry Andric size_t Length) { 17580b57cec5SDimitry Andric Metadata **DataValue = unwrap(Data); 17590b57cec5SDimitry Andric return wrap(unwrap(Builder)->getOrCreateArray({DataValue, Length}).get()); 17600b57cec5SDimitry Andric } 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func) { 17630b57cec5SDimitry Andric return wrap(unwrap<Function>(Func)->getSubprogram()); 17640b57cec5SDimitry Andric } 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP) { 17670b57cec5SDimitry Andric unwrap<Function>(Func)->setSubprogram(unwrap<DISubprogram>(SP)); 17680b57cec5SDimitry Andric } 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andric unsigned LLVMDISubprogramGetLine(LLVMMetadataRef Subprogram) { 17710b57cec5SDimitry Andric return unwrapDI<DISubprogram>(Subprogram)->getLine(); 17720b57cec5SDimitry Andric } 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst) { 17750b57cec5SDimitry Andric return wrap(unwrap<Instruction>(Inst)->getDebugLoc().getAsMDNode()); 17760b57cec5SDimitry Andric } 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc) { 17790b57cec5SDimitry Andric if (Loc) 17800b57cec5SDimitry Andric unwrap<Instruction>(Inst)->setDebugLoc(DebugLoc(unwrap<MDNode>(Loc))); 17810b57cec5SDimitry Andric else 17820b57cec5SDimitry Andric unwrap<Instruction>(Inst)->setDebugLoc(DebugLoc()); 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andric LLVMMetadataKind LLVMGetMetadataKind(LLVMMetadataRef Metadata) { 17860b57cec5SDimitry Andric switch(unwrap(Metadata)->getMetadataID()) { 17870b57cec5SDimitry Andric #define HANDLE_METADATA_LEAF(CLASS) \ 17880b57cec5SDimitry Andric case Metadata::CLASS##Kind: \ 17890b57cec5SDimitry Andric return (LLVMMetadataKind)LLVM##CLASS##MetadataKind; 17900b57cec5SDimitry Andric #include "llvm/IR/Metadata.def" 17910b57cec5SDimitry Andric default: 17920b57cec5SDimitry Andric return (LLVMMetadataKind)LLVMGenericDINodeMetadataKind; 17930b57cec5SDimitry Andric } 17940b57cec5SDimitry Andric } 1795bdd1243dSDimitry Andric 1796bdd1243dSDimitry Andric AssignmentInstRange at::getAssignmentInsts(DIAssignID *ID) { 1797bdd1243dSDimitry Andric assert(ID && "Expected non-null ID"); 1798bdd1243dSDimitry Andric LLVMContext &Ctx = ID->getContext(); 1799bdd1243dSDimitry Andric auto &Map = Ctx.pImpl->AssignmentIDToInstrs; 1800bdd1243dSDimitry Andric 1801bdd1243dSDimitry Andric auto MapIt = Map.find(ID); 1802bdd1243dSDimitry Andric if (MapIt == Map.end()) 1803bdd1243dSDimitry Andric return make_range(nullptr, nullptr); 1804bdd1243dSDimitry Andric 1805bdd1243dSDimitry Andric return make_range(MapIt->second.begin(), MapIt->second.end()); 1806bdd1243dSDimitry Andric } 1807bdd1243dSDimitry Andric 1808bdd1243dSDimitry Andric AssignmentMarkerRange at::getAssignmentMarkers(DIAssignID *ID) { 1809bdd1243dSDimitry Andric assert(ID && "Expected non-null ID"); 1810bdd1243dSDimitry Andric LLVMContext &Ctx = ID->getContext(); 1811bdd1243dSDimitry Andric 1812bdd1243dSDimitry Andric auto *IDAsValue = MetadataAsValue::getIfExists(Ctx, ID); 1813bdd1243dSDimitry Andric 1814bdd1243dSDimitry Andric // The ID is only used wrapped in MetadataAsValue(ID), so lets check that 1815bdd1243dSDimitry Andric // one of those already exists first. 1816bdd1243dSDimitry Andric if (!IDAsValue) 1817bdd1243dSDimitry Andric return make_range(Value::user_iterator(), Value::user_iterator()); 1818bdd1243dSDimitry Andric 1819bdd1243dSDimitry Andric return make_range(IDAsValue->user_begin(), IDAsValue->user_end()); 1820bdd1243dSDimitry Andric } 1821bdd1243dSDimitry Andric 1822bdd1243dSDimitry Andric void at::deleteAssignmentMarkers(const Instruction *Inst) { 1823bdd1243dSDimitry Andric auto Range = getAssignmentMarkers(Inst); 1824*0fca6ea1SDimitry Andric SmallVector<DbgVariableRecord *> DVRAssigns = getDVRAssignmentMarkers(Inst); 1825*0fca6ea1SDimitry Andric if (Range.empty() && DVRAssigns.empty()) 1826bdd1243dSDimitry Andric return; 1827bdd1243dSDimitry Andric SmallVector<DbgAssignIntrinsic *> ToDelete(Range.begin(), Range.end()); 1828bdd1243dSDimitry Andric for (auto *DAI : ToDelete) 1829bdd1243dSDimitry Andric DAI->eraseFromParent(); 1830*0fca6ea1SDimitry Andric for (auto *DVR : DVRAssigns) 1831*0fca6ea1SDimitry Andric DVR->eraseFromParent(); 1832bdd1243dSDimitry Andric } 1833bdd1243dSDimitry Andric 1834bdd1243dSDimitry Andric void at::RAUW(DIAssignID *Old, DIAssignID *New) { 1835bdd1243dSDimitry Andric // Replace attachments. 1836bdd1243dSDimitry Andric AssignmentInstRange InstRange = getAssignmentInsts(Old); 1837bdd1243dSDimitry Andric // Use intermediate storage for the instruction ptrs because the 1838bdd1243dSDimitry Andric // getAssignmentInsts range iterators will be invalidated by adding and 1839bdd1243dSDimitry Andric // removing DIAssignID attachments. 1840bdd1243dSDimitry Andric SmallVector<Instruction *> InstVec(InstRange.begin(), InstRange.end()); 1841bdd1243dSDimitry Andric for (auto *I : InstVec) 1842bdd1243dSDimitry Andric I->setMetadata(LLVMContext::MD_DIAssignID, New); 18437a6dacacSDimitry Andric 18447a6dacacSDimitry Andric Old->replaceAllUsesWith(New); 1845bdd1243dSDimitry Andric } 1846bdd1243dSDimitry Andric 1847bdd1243dSDimitry Andric void at::deleteAll(Function *F) { 1848bdd1243dSDimitry Andric SmallVector<DbgAssignIntrinsic *, 12> ToDelete; 1849*0fca6ea1SDimitry Andric SmallVector<DbgVariableRecord *, 12> DPToDelete; 1850bdd1243dSDimitry Andric for (BasicBlock &BB : *F) { 1851bdd1243dSDimitry Andric for (Instruction &I : BB) { 1852*0fca6ea1SDimitry Andric for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) 1853*0fca6ea1SDimitry Andric if (DVR.isDbgAssign()) 1854*0fca6ea1SDimitry Andric DPToDelete.push_back(&DVR); 1855bdd1243dSDimitry Andric if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) 1856bdd1243dSDimitry Andric ToDelete.push_back(DAI); 1857bdd1243dSDimitry Andric else 1858bdd1243dSDimitry Andric I.setMetadata(LLVMContext::MD_DIAssignID, nullptr); 1859bdd1243dSDimitry Andric } 1860bdd1243dSDimitry Andric } 1861bdd1243dSDimitry Andric for (auto *DAI : ToDelete) 1862bdd1243dSDimitry Andric DAI->eraseFromParent(); 1863*0fca6ea1SDimitry Andric for (auto *DVR : DPToDelete) 1864*0fca6ea1SDimitry Andric DVR->eraseFromParent(); 1865bdd1243dSDimitry Andric } 1866bdd1243dSDimitry Andric 1867*0fca6ea1SDimitry Andric /// FIXME: Remove this wrapper function and call 1868*0fca6ea1SDimitry Andric /// DIExpression::calculateFragmentIntersect directly. 18697a6dacacSDimitry Andric template <typename T> 18707a6dacacSDimitry Andric bool calculateFragmentIntersectImpl( 187106c3fb27SDimitry Andric const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, 18727a6dacacSDimitry Andric uint64_t SliceSizeInBits, const T *AssignRecord, 187306c3fb27SDimitry Andric std::optional<DIExpression::FragmentInfo> &Result) { 1874*0fca6ea1SDimitry Andric // No overlap if this DbgRecord describes a killed location. 18757a6dacacSDimitry Andric if (AssignRecord->isKillAddress()) 187606c3fb27SDimitry Andric return false; 187706c3fb27SDimitry Andric 1878*0fca6ea1SDimitry Andric int64_t AddrOffsetInBits; 187906c3fb27SDimitry Andric { 1880*0fca6ea1SDimitry Andric int64_t AddrOffsetInBytes; 1881*0fca6ea1SDimitry Andric SmallVector<uint64_t> PostOffsetOps; //< Unused. 1882*0fca6ea1SDimitry Andric // Bail if we can't find a constant offset (or none) in the expression. 1883*0fca6ea1SDimitry Andric if (!AssignRecord->getAddressExpression()->extractLeadingOffset( 1884*0fca6ea1SDimitry Andric AddrOffsetInBytes, PostOffsetOps)) 188506c3fb27SDimitry Andric return false; 1886*0fca6ea1SDimitry Andric AddrOffsetInBits = AddrOffsetInBytes * 8; 188706c3fb27SDimitry Andric } 188806c3fb27SDimitry Andric 1889*0fca6ea1SDimitry Andric Value *Addr = AssignRecord->getAddress(); 1890*0fca6ea1SDimitry Andric // FIXME: It may not always be zero. 1891*0fca6ea1SDimitry Andric int64_t BitExtractOffsetInBits = 0; 1892*0fca6ea1SDimitry Andric DIExpression::FragmentInfo VarFrag = 1893*0fca6ea1SDimitry Andric AssignRecord->getFragmentOrEntireVariable(); 1894*0fca6ea1SDimitry Andric 1895*0fca6ea1SDimitry Andric int64_t OffsetFromLocationInBits; //< Unused. 1896*0fca6ea1SDimitry Andric return DIExpression::calculateFragmentIntersect( 1897*0fca6ea1SDimitry Andric DL, Dest, SliceOffsetInBits, SliceSizeInBits, Addr, AddrOffsetInBits, 1898*0fca6ea1SDimitry Andric BitExtractOffsetInBits, VarFrag, Result, OffsetFromLocationInBits); 189906c3fb27SDimitry Andric } 1900*0fca6ea1SDimitry Andric 1901*0fca6ea1SDimitry Andric /// FIXME: Remove this wrapper function and call 1902*0fca6ea1SDimitry Andric /// DIExpression::calculateFragmentIntersect directly. 19037a6dacacSDimitry Andric bool at::calculateFragmentIntersect( 19047a6dacacSDimitry Andric const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, 19057a6dacacSDimitry Andric uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign, 19067a6dacacSDimitry Andric std::optional<DIExpression::FragmentInfo> &Result) { 19077a6dacacSDimitry Andric return calculateFragmentIntersectImpl(DL, Dest, SliceOffsetInBits, 19087a6dacacSDimitry Andric SliceSizeInBits, DbgAssign, Result); 19097a6dacacSDimitry Andric } 1910*0fca6ea1SDimitry Andric 1911*0fca6ea1SDimitry Andric /// FIXME: Remove this wrapper function and call 1912*0fca6ea1SDimitry Andric /// DIExpression::calculateFragmentIntersect directly. 19137a6dacacSDimitry Andric bool at::calculateFragmentIntersect( 19147a6dacacSDimitry Andric const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, 1915*0fca6ea1SDimitry Andric uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign, 19167a6dacacSDimitry Andric std::optional<DIExpression::FragmentInfo> &Result) { 19177a6dacacSDimitry Andric return calculateFragmentIntersectImpl(DL, Dest, SliceOffsetInBits, 1918*0fca6ea1SDimitry Andric SliceSizeInBits, DVRAssign, Result); 1919*0fca6ea1SDimitry Andric } 1920*0fca6ea1SDimitry Andric 1921*0fca6ea1SDimitry Andric /// Update inlined instructions' DIAssignID metadata. We need to do this 1922*0fca6ea1SDimitry Andric /// otherwise a function inlined more than once into the same function 1923*0fca6ea1SDimitry Andric /// will cause DIAssignID to be shared by many instructions. 1924*0fca6ea1SDimitry Andric void at::remapAssignID(DenseMap<DIAssignID *, DIAssignID *> &Map, 1925*0fca6ea1SDimitry Andric Instruction &I) { 1926*0fca6ea1SDimitry Andric auto GetNewID = [&Map](Metadata *Old) { 1927*0fca6ea1SDimitry Andric DIAssignID *OldID = cast<DIAssignID>(Old); 1928*0fca6ea1SDimitry Andric if (DIAssignID *NewID = Map.lookup(OldID)) 1929*0fca6ea1SDimitry Andric return NewID; 1930*0fca6ea1SDimitry Andric DIAssignID *NewID = DIAssignID::getDistinct(OldID->getContext()); 1931*0fca6ea1SDimitry Andric Map[OldID] = NewID; 1932*0fca6ea1SDimitry Andric return NewID; 1933*0fca6ea1SDimitry Andric }; 1934*0fca6ea1SDimitry Andric // If we find a DIAssignID attachment or use, replace it with a new version. 1935*0fca6ea1SDimitry Andric for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { 1936*0fca6ea1SDimitry Andric if (DVR.isDbgAssign()) 1937*0fca6ea1SDimitry Andric DVR.setAssignId(GetNewID(DVR.getAssignID())); 1938*0fca6ea1SDimitry Andric } 1939*0fca6ea1SDimitry Andric if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID)) 1940*0fca6ea1SDimitry Andric I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID)); 1941*0fca6ea1SDimitry Andric else if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) 1942*0fca6ea1SDimitry Andric DAI->setAssignId(GetNewID(DAI->getAssignID())); 19437a6dacacSDimitry Andric } 194406c3fb27SDimitry Andric 1945bdd1243dSDimitry Andric /// Collect constant properies (base, size, offset) of \p StoreDest. 194606c3fb27SDimitry Andric /// Return std::nullopt if any properties are not constants or the 194706c3fb27SDimitry Andric /// offset from the base pointer is negative. 1948bdd1243dSDimitry Andric static std::optional<AssignmentInfo> 1949bdd1243dSDimitry Andric getAssignmentInfoImpl(const DataLayout &DL, const Value *StoreDest, 195006c3fb27SDimitry Andric TypeSize SizeInBits) { 195106c3fb27SDimitry Andric if (SizeInBits.isScalable()) 195206c3fb27SDimitry Andric return std::nullopt; 1953bdd1243dSDimitry Andric APInt GEPOffset(DL.getIndexTypeSizeInBits(StoreDest->getType()), 0); 1954bdd1243dSDimitry Andric const Value *Base = StoreDest->stripAndAccumulateConstantOffsets( 1955bdd1243dSDimitry Andric DL, GEPOffset, /*AllowNonInbounds*/ true); 195606c3fb27SDimitry Andric 195706c3fb27SDimitry Andric if (GEPOffset.isNegative()) 195806c3fb27SDimitry Andric return std::nullopt; 195906c3fb27SDimitry Andric 1960bdd1243dSDimitry Andric uint64_t OffsetInBytes = GEPOffset.getLimitedValue(); 1961bdd1243dSDimitry Andric // Check for overflow. 1962bdd1243dSDimitry Andric if (OffsetInBytes == UINT64_MAX) 1963bdd1243dSDimitry Andric return std::nullopt; 1964bdd1243dSDimitry Andric if (const auto *Alloca = dyn_cast<AllocaInst>(Base)) 1965bdd1243dSDimitry Andric return AssignmentInfo(DL, Alloca, OffsetInBytes * 8, SizeInBits); 1966bdd1243dSDimitry Andric return std::nullopt; 1967bdd1243dSDimitry Andric } 1968bdd1243dSDimitry Andric 1969bdd1243dSDimitry Andric std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL, 1970bdd1243dSDimitry Andric const MemIntrinsic *I) { 1971bdd1243dSDimitry Andric const Value *StoreDest = I->getRawDest(); 1972bdd1243dSDimitry Andric // Assume 8 bit bytes. 1973bdd1243dSDimitry Andric auto *ConstLengthInBytes = dyn_cast<ConstantInt>(I->getLength()); 1974bdd1243dSDimitry Andric if (!ConstLengthInBytes) 1975bdd1243dSDimitry Andric // We can't use a non-const size, bail. 1976bdd1243dSDimitry Andric return std::nullopt; 1977bdd1243dSDimitry Andric uint64_t SizeInBits = 8 * ConstLengthInBytes->getZExtValue(); 197806c3fb27SDimitry Andric return getAssignmentInfoImpl(DL, StoreDest, TypeSize::getFixed(SizeInBits)); 1979bdd1243dSDimitry Andric } 1980bdd1243dSDimitry Andric 1981bdd1243dSDimitry Andric std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL, 1982bdd1243dSDimitry Andric const StoreInst *SI) { 198306c3fb27SDimitry Andric TypeSize SizeInBits = DL.getTypeSizeInBits(SI->getValueOperand()->getType()); 198406c3fb27SDimitry Andric return getAssignmentInfoImpl(DL, SI->getPointerOperand(), SizeInBits); 1985bdd1243dSDimitry Andric } 1986bdd1243dSDimitry Andric 1987bdd1243dSDimitry Andric std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL, 1988bdd1243dSDimitry Andric const AllocaInst *AI) { 198906c3fb27SDimitry Andric TypeSize SizeInBits = DL.getTypeSizeInBits(AI->getAllocatedType()); 1990bdd1243dSDimitry Andric return getAssignmentInfoImpl(DL, AI, SizeInBits); 1991bdd1243dSDimitry Andric } 1992bdd1243dSDimitry Andric 199306c3fb27SDimitry Andric /// Returns nullptr if the assignment shouldn't be attributed to this variable. 19947a6dacacSDimitry Andric static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest, 19957a6dacacSDimitry Andric Instruction &StoreLikeInst, const VarRecord &VarRec, 19967a6dacacSDimitry Andric DIBuilder &DIB) { 1997bdd1243dSDimitry Andric auto *ID = StoreLikeInst.getMetadata(LLVMContext::MD_DIAssignID); 1998bdd1243dSDimitry Andric assert(ID && "Store instruction must have DIAssignID metadata"); 1999bdd1243dSDimitry Andric (void)ID; 2000bdd1243dSDimitry Andric 200106c3fb27SDimitry Andric const uint64_t StoreStartBit = Info.OffsetInBits; 200206c3fb27SDimitry Andric const uint64_t StoreEndBit = Info.OffsetInBits + Info.SizeInBits; 200306c3fb27SDimitry Andric 200406c3fb27SDimitry Andric uint64_t FragStartBit = StoreStartBit; 200506c3fb27SDimitry Andric uint64_t FragEndBit = StoreEndBit; 200606c3fb27SDimitry Andric 200706c3fb27SDimitry Andric bool StoreToWholeVariable = Info.StoreToWholeAlloca; 200806c3fb27SDimitry Andric if (auto Size = VarRec.Var->getSizeInBits()) { 200906c3fb27SDimitry Andric // NOTE: trackAssignments doesn't understand base expressions yet, so all 201006c3fb27SDimitry Andric // variables that reach here are guaranteed to start at offset 0 in the 201106c3fb27SDimitry Andric // alloca. 201206c3fb27SDimitry Andric const uint64_t VarStartBit = 0; 201306c3fb27SDimitry Andric const uint64_t VarEndBit = *Size; 201406c3fb27SDimitry Andric 201506c3fb27SDimitry Andric // FIXME: trim FragStartBit when nonzero VarStartBit is supported. 201606c3fb27SDimitry Andric FragEndBit = std::min(FragEndBit, VarEndBit); 201706c3fb27SDimitry Andric 201806c3fb27SDimitry Andric // Discard stores to bits outside this variable. 201906c3fb27SDimitry Andric if (FragStartBit >= FragEndBit) 20207a6dacacSDimitry Andric return; 202106c3fb27SDimitry Andric 202206c3fb27SDimitry Andric StoreToWholeVariable = FragStartBit <= VarStartBit && FragEndBit >= *Size; 202306c3fb27SDimitry Andric } 202406c3fb27SDimitry Andric 2025bdd1243dSDimitry Andric DIExpression *Expr = 2026bdd1243dSDimitry Andric DIExpression::get(StoreLikeInst.getContext(), std::nullopt); 202706c3fb27SDimitry Andric if (!StoreToWholeVariable) { 202806c3fb27SDimitry Andric auto R = DIExpression::createFragmentExpression(Expr, FragStartBit, 202906c3fb27SDimitry Andric FragEndBit - FragStartBit); 2030bdd1243dSDimitry Andric assert(R.has_value() && "failed to create fragment expression"); 2031bdd1243dSDimitry Andric Expr = *R; 2032bdd1243dSDimitry Andric } 2033bdd1243dSDimitry Andric DIExpression *AddrExpr = 2034bdd1243dSDimitry Andric DIExpression::get(StoreLikeInst.getContext(), std::nullopt); 20357a6dacacSDimitry Andric if (StoreLikeInst.getParent()->IsNewDbgInfoFormat) { 2036*0fca6ea1SDimitry Andric auto *Assign = DbgVariableRecord::createLinkedDVRAssign( 20377a6dacacSDimitry Andric &StoreLikeInst, Val, VarRec.Var, Expr, Dest, AddrExpr, VarRec.DL); 20387a6dacacSDimitry Andric (void)Assign; 20397a6dacacSDimitry Andric LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n"); 20407a6dacacSDimitry Andric return; 20417a6dacacSDimitry Andric } 2042*0fca6ea1SDimitry Andric auto Assign = DIB.insertDbgAssign(&StoreLikeInst, Val, VarRec.Var, Expr, Dest, 2043*0fca6ea1SDimitry Andric AddrExpr, VarRec.DL); 20447a6dacacSDimitry Andric (void)Assign; 2045*0fca6ea1SDimitry Andric LLVM_DEBUG(if (!Assign.isNull()) { 2046*0fca6ea1SDimitry Andric if (Assign.is<DbgRecord *>()) 2047*0fca6ea1SDimitry Andric errs() << " > INSERT: " << *Assign.get<DbgRecord *>() << "\n"; 2048*0fca6ea1SDimitry Andric else 2049*0fca6ea1SDimitry Andric errs() << " > INSERT: " << *Assign.get<Instruction *>() << "\n"; 2050*0fca6ea1SDimitry Andric }); 2051bdd1243dSDimitry Andric } 2052bdd1243dSDimitry Andric 2053bdd1243dSDimitry Andric #undef DEBUG_TYPE // Silence redefinition warning (from ConstantsContext.h). 2054bdd1243dSDimitry Andric #define DEBUG_TYPE "assignment-tracking" 2055bdd1243dSDimitry Andric 2056bdd1243dSDimitry Andric void at::trackAssignments(Function::iterator Start, Function::iterator End, 2057bdd1243dSDimitry Andric const StorageToVarsMap &Vars, const DataLayout &DL, 2058bdd1243dSDimitry Andric bool DebugPrints) { 2059bdd1243dSDimitry Andric // Early-exit if there are no interesting variables. 2060bdd1243dSDimitry Andric if (Vars.empty()) 2061bdd1243dSDimitry Andric return; 2062bdd1243dSDimitry Andric 2063bdd1243dSDimitry Andric auto &Ctx = Start->getContext(); 2064bdd1243dSDimitry Andric auto &Module = *Start->getModule(); 2065bdd1243dSDimitry Andric 2066bdd1243dSDimitry Andric // Undef type doesn't matter, so long as it isn't void. Let's just use i1. 2067bdd1243dSDimitry Andric auto *Undef = UndefValue::get(Type::getInt1Ty(Ctx)); 2068bdd1243dSDimitry Andric DIBuilder DIB(Module, /*AllowUnresolved*/ false); 2069bdd1243dSDimitry Andric 2070bdd1243dSDimitry Andric // Scan the instructions looking for stores to local variables' storage. 2071bdd1243dSDimitry Andric LLVM_DEBUG(errs() << "# Scanning instructions\n"); 2072bdd1243dSDimitry Andric for (auto BBI = Start; BBI != End; ++BBI) { 2073bdd1243dSDimitry Andric for (Instruction &I : *BBI) { 2074bdd1243dSDimitry Andric 2075bdd1243dSDimitry Andric std::optional<AssignmentInfo> Info; 2076bdd1243dSDimitry Andric Value *ValueComponent = nullptr; 2077bdd1243dSDimitry Andric Value *DestComponent = nullptr; 2078bdd1243dSDimitry Andric if (auto *AI = dyn_cast<AllocaInst>(&I)) { 2079bdd1243dSDimitry Andric // We want to track the variable's stack home from its alloca's 2080bdd1243dSDimitry Andric // position onwards so we treat it as an assignment (where the stored 2081bdd1243dSDimitry Andric // value is Undef). 2082bdd1243dSDimitry Andric Info = getAssignmentInfo(DL, AI); 2083bdd1243dSDimitry Andric ValueComponent = Undef; 2084bdd1243dSDimitry Andric DestComponent = AI; 2085bdd1243dSDimitry Andric } else if (auto *SI = dyn_cast<StoreInst>(&I)) { 2086bdd1243dSDimitry Andric Info = getAssignmentInfo(DL, SI); 2087bdd1243dSDimitry Andric ValueComponent = SI->getValueOperand(); 2088bdd1243dSDimitry Andric DestComponent = SI->getPointerOperand(); 2089bdd1243dSDimitry Andric } else if (auto *MI = dyn_cast<MemTransferInst>(&I)) { 2090bdd1243dSDimitry Andric Info = getAssignmentInfo(DL, MI); 2091bdd1243dSDimitry Andric // May not be able to represent this value easily. 2092bdd1243dSDimitry Andric ValueComponent = Undef; 2093bdd1243dSDimitry Andric DestComponent = MI->getOperand(0); 2094bdd1243dSDimitry Andric } else if (auto *MI = dyn_cast<MemSetInst>(&I)) { 2095bdd1243dSDimitry Andric Info = getAssignmentInfo(DL, MI); 2096bdd1243dSDimitry Andric // If we're zero-initing we can state the assigned value is zero, 2097bdd1243dSDimitry Andric // otherwise use undef. 2098bdd1243dSDimitry Andric auto *ConstValue = dyn_cast<ConstantInt>(MI->getOperand(1)); 2099bdd1243dSDimitry Andric if (ConstValue && ConstValue->isZero()) 2100bdd1243dSDimitry Andric ValueComponent = ConstValue; 2101bdd1243dSDimitry Andric else 2102bdd1243dSDimitry Andric ValueComponent = Undef; 2103bdd1243dSDimitry Andric DestComponent = MI->getOperand(0); 2104bdd1243dSDimitry Andric } else { 2105bdd1243dSDimitry Andric // Not a store-like instruction. 2106bdd1243dSDimitry Andric continue; 2107bdd1243dSDimitry Andric } 2108bdd1243dSDimitry Andric 2109bdd1243dSDimitry Andric assert(ValueComponent && DestComponent); 2110bdd1243dSDimitry Andric LLVM_DEBUG(errs() << "SCAN: Found store-like: " << I << "\n"); 2111bdd1243dSDimitry Andric 2112bdd1243dSDimitry Andric // Check if getAssignmentInfo failed to understand this store. 2113bdd1243dSDimitry Andric if (!Info.has_value()) { 2114bdd1243dSDimitry Andric LLVM_DEBUG( 2115bdd1243dSDimitry Andric errs() 2116bdd1243dSDimitry Andric << " | SKIP: Untrackable store (e.g. through non-const gep)\n"); 2117bdd1243dSDimitry Andric continue; 2118bdd1243dSDimitry Andric } 2119bdd1243dSDimitry Andric LLVM_DEBUG(errs() << " | BASE: " << *Info->Base << "\n"); 2120bdd1243dSDimitry Andric 2121bdd1243dSDimitry Andric // Check if the store destination is a local variable with debug info. 2122bdd1243dSDimitry Andric auto LocalIt = Vars.find(Info->Base); 2123bdd1243dSDimitry Andric if (LocalIt == Vars.end()) { 2124bdd1243dSDimitry Andric LLVM_DEBUG( 2125bdd1243dSDimitry Andric errs() 2126bdd1243dSDimitry Andric << " | SKIP: Base address not associated with local variable\n"); 2127bdd1243dSDimitry Andric continue; 2128bdd1243dSDimitry Andric } 2129bdd1243dSDimitry Andric 2130bdd1243dSDimitry Andric DIAssignID *ID = 2131bdd1243dSDimitry Andric cast_or_null<DIAssignID>(I.getMetadata(LLVMContext::MD_DIAssignID)); 2132bdd1243dSDimitry Andric if (!ID) { 2133bdd1243dSDimitry Andric ID = DIAssignID::getDistinct(Ctx); 2134bdd1243dSDimitry Andric I.setMetadata(LLVMContext::MD_DIAssignID, ID); 2135bdd1243dSDimitry Andric } 2136bdd1243dSDimitry Andric 21377a6dacacSDimitry Andric for (const VarRecord &R : LocalIt->second) 2138bdd1243dSDimitry Andric emitDbgAssign(*Info, ValueComponent, DestComponent, I, R, DIB); 2139bdd1243dSDimitry Andric } 2140bdd1243dSDimitry Andric } 2141bdd1243dSDimitry Andric } 2142bdd1243dSDimitry Andric 214306c3fb27SDimitry Andric bool AssignmentTrackingPass::runOnFunction(Function &F) { 214406c3fb27SDimitry Andric // No value in assignment tracking without optimisations. 214506c3fb27SDimitry Andric if (F.hasFnAttribute(Attribute::OptimizeNone)) 214606c3fb27SDimitry Andric return /*Changed*/ false; 214706c3fb27SDimitry Andric 214806c3fb27SDimitry Andric bool Changed = false; 2149*0fca6ea1SDimitry Andric auto *DL = &F.getDataLayout(); 2150bdd1243dSDimitry Andric // Collect a map of {backing storage : dbg.declares} (currently "backing 2151bdd1243dSDimitry Andric // storage" is limited to Allocas). We'll use this to find dbg.declares to 2152bdd1243dSDimitry Andric // delete after running `trackAssignments`. 2153bdd1243dSDimitry Andric DenseMap<const AllocaInst *, SmallPtrSet<DbgDeclareInst *, 2>> DbgDeclares; 2154*0fca6ea1SDimitry Andric DenseMap<const AllocaInst *, SmallPtrSet<DbgVariableRecord *, 2>> DVRDeclares; 2155bdd1243dSDimitry Andric // Create another similar map of {storage : variables} that we'll pass to 2156bdd1243dSDimitry Andric // trackAssignments. 2157bdd1243dSDimitry Andric StorageToVarsMap Vars; 21587a6dacacSDimitry Andric auto ProcessDeclare = [&](auto *Declare, auto &DeclareList) { 2159bdd1243dSDimitry Andric // FIXME: trackAssignments doesn't let you specify any modifiers to the 2160bdd1243dSDimitry Andric // variable (e.g. fragment) or location (e.g. offset), so we have to 2161bdd1243dSDimitry Andric // leave dbg.declares with non-empty expressions in place. 21627a6dacacSDimitry Andric if (Declare->getExpression()->getNumElements() != 0) 21637a6dacacSDimitry Andric return; 21647a6dacacSDimitry Andric if (!Declare->getAddress()) 21657a6dacacSDimitry Andric return; 2166bdd1243dSDimitry Andric if (AllocaInst *Alloca = 21677a6dacacSDimitry Andric dyn_cast<AllocaInst>(Declare->getAddress()->stripPointerCasts())) { 216806c3fb27SDimitry Andric // FIXME: Skip VLAs for now (let these variables use dbg.declares). 216906c3fb27SDimitry Andric if (!Alloca->isStaticAlloca()) 21707a6dacacSDimitry Andric return; 217106c3fb27SDimitry Andric // Similarly, skip scalable vectors (use dbg.declares instead). 217206c3fb27SDimitry Andric if (auto Sz = Alloca->getAllocationSize(*DL); Sz && Sz->isScalable()) 21737a6dacacSDimitry Andric return; 21747a6dacacSDimitry Andric DeclareList[Alloca].insert(Declare); 21757a6dacacSDimitry Andric Vars[Alloca].insert(VarRecord(Declare)); 2176bdd1243dSDimitry Andric } 21777a6dacacSDimitry Andric }; 21787a6dacacSDimitry Andric for (auto &BB : F) { 21797a6dacacSDimitry Andric for (auto &I : BB) { 2180*0fca6ea1SDimitry Andric for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { 2181*0fca6ea1SDimitry Andric if (DVR.isDbgDeclare()) 2182*0fca6ea1SDimitry Andric ProcessDeclare(&DVR, DVRDeclares); 21837a6dacacSDimitry Andric } 21847a6dacacSDimitry Andric if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(&I)) 21857a6dacacSDimitry Andric ProcessDeclare(DDI, DbgDeclares); 2186bdd1243dSDimitry Andric } 2187bdd1243dSDimitry Andric } 2188bdd1243dSDimitry Andric 2189bdd1243dSDimitry Andric // FIXME: Locals can be backed by caller allocas (sret, byval). 2190bdd1243dSDimitry Andric // Note: trackAssignments doesn't respect dbg.declare's IR positions (as it 2191bdd1243dSDimitry Andric // doesn't "understand" dbg.declares). However, this doesn't appear to break 2192bdd1243dSDimitry Andric // any rules given this description of dbg.declare from 2193bdd1243dSDimitry Andric // llvm/docs/SourceLevelDebugging.rst: 2194bdd1243dSDimitry Andric // 2195bdd1243dSDimitry Andric // It is not control-dependent, meaning that if a call to llvm.dbg.declare 2196bdd1243dSDimitry Andric // exists and has a valid location argument, that address is considered to 2197bdd1243dSDimitry Andric // be the true home of the variable across its entire lifetime. 2198bdd1243dSDimitry Andric trackAssignments(F.begin(), F.end(), Vars, *DL); 2199bdd1243dSDimitry Andric 2200bdd1243dSDimitry Andric // Delete dbg.declares for variables now tracked with assignment tracking. 22017a6dacacSDimitry Andric auto DeleteSubsumedDeclare = [&](const auto &Markers, auto &Declares) { 2202bdd1243dSDimitry Andric (void)Markers; 22037a6dacacSDimitry Andric for (auto *Declare : Declares) { 22047a6dacacSDimitry Andric // Assert that the alloca that Declare uses is now linked to a dbg.assign 220506c3fb27SDimitry Andric // describing the same variable (i.e. check that this dbg.declare has 220606c3fb27SDimitry Andric // been replaced by a dbg.assign). Use DebugVariableAggregate to Discard 220706c3fb27SDimitry Andric // the fragment part because trackAssignments may alter the 220806c3fb27SDimitry Andric // fragment. e.g. if the alloca is smaller than the variable, then 220906c3fb27SDimitry Andric // trackAssignments will create an alloca-sized fragment for the 221006c3fb27SDimitry Andric // dbg.assign. 22117a6dacacSDimitry Andric assert(llvm::any_of(Markers, [Declare](auto *Assign) { 22127a6dacacSDimitry Andric return DebugVariableAggregate(Assign) == 22137a6dacacSDimitry Andric DebugVariableAggregate(Declare); 2214bdd1243dSDimitry Andric })); 22157a6dacacSDimitry Andric // Delete Declare because the variable location is now tracked using 2216bdd1243dSDimitry Andric // assignment tracking. 22177a6dacacSDimitry Andric Declare->eraseFromParent(); 221806c3fb27SDimitry Andric Changed = true; 2219bdd1243dSDimitry Andric } 22207a6dacacSDimitry Andric }; 22217a6dacacSDimitry Andric for (auto &P : DbgDeclares) 22227a6dacacSDimitry Andric DeleteSubsumedDeclare(at::getAssignmentMarkers(P.first), P.second); 2223*0fca6ea1SDimitry Andric for (auto &P : DVRDeclares) 2224*0fca6ea1SDimitry Andric DeleteSubsumedDeclare(at::getDVRAssignmentMarkers(P.first), P.second); 222506c3fb27SDimitry Andric return Changed; 2226bdd1243dSDimitry Andric } 2227bdd1243dSDimitry Andric 2228bdd1243dSDimitry Andric static const char *AssignmentTrackingModuleFlag = 2229bdd1243dSDimitry Andric "debug-info-assignment-tracking"; 2230bdd1243dSDimitry Andric 2231bdd1243dSDimitry Andric static void setAssignmentTrackingModuleFlag(Module &M) { 2232bdd1243dSDimitry Andric M.setModuleFlag(Module::ModFlagBehavior::Max, AssignmentTrackingModuleFlag, 2233bdd1243dSDimitry Andric ConstantAsMetadata::get( 2234bdd1243dSDimitry Andric ConstantInt::get(Type::getInt1Ty(M.getContext()), 1))); 2235bdd1243dSDimitry Andric } 2236bdd1243dSDimitry Andric 2237bdd1243dSDimitry Andric static bool getAssignmentTrackingModuleFlag(const Module &M) { 2238bdd1243dSDimitry Andric Metadata *Value = M.getModuleFlag(AssignmentTrackingModuleFlag); 2239bdd1243dSDimitry Andric return Value && !cast<ConstantAsMetadata>(Value)->getValue()->isZeroValue(); 2240bdd1243dSDimitry Andric } 2241bdd1243dSDimitry Andric 2242bdd1243dSDimitry Andric bool llvm::isAssignmentTrackingEnabled(const Module &M) { 2243bdd1243dSDimitry Andric return getAssignmentTrackingModuleFlag(M); 2244bdd1243dSDimitry Andric } 2245bdd1243dSDimitry Andric 2246bdd1243dSDimitry Andric PreservedAnalyses AssignmentTrackingPass::run(Function &F, 2247bdd1243dSDimitry Andric FunctionAnalysisManager &AM) { 224806c3fb27SDimitry Andric if (!runOnFunction(F)) 224906c3fb27SDimitry Andric return PreservedAnalyses::all(); 2250bdd1243dSDimitry Andric 2251bdd1243dSDimitry Andric // Record that this module uses assignment tracking. It doesn't matter that 2252bdd1243dSDimitry Andric // some functons in the module may not use it - the debug info in those 2253bdd1243dSDimitry Andric // functions will still be handled properly. 2254bdd1243dSDimitry Andric setAssignmentTrackingModuleFlag(*F.getParent()); 2255bdd1243dSDimitry Andric 2256bdd1243dSDimitry Andric // Q: Can we return a less conservative set than just CFGAnalyses? Can we 2257bdd1243dSDimitry Andric // return PreservedAnalyses::all()? 2258bdd1243dSDimitry Andric PreservedAnalyses PA; 2259bdd1243dSDimitry Andric PA.preserveSet<CFGAnalyses>(); 2260bdd1243dSDimitry Andric return PA; 2261bdd1243dSDimitry Andric } 2262bdd1243dSDimitry Andric 2263bdd1243dSDimitry Andric PreservedAnalyses AssignmentTrackingPass::run(Module &M, 2264bdd1243dSDimitry Andric ModuleAnalysisManager &AM) { 226506c3fb27SDimitry Andric bool Changed = false; 2266bdd1243dSDimitry Andric for (auto &F : M) 226706c3fb27SDimitry Andric Changed |= runOnFunction(F); 226806c3fb27SDimitry Andric 226906c3fb27SDimitry Andric if (!Changed) 227006c3fb27SDimitry Andric return PreservedAnalyses::all(); 2271bdd1243dSDimitry Andric 2272bdd1243dSDimitry Andric // Record that this module uses assignment tracking. 2273bdd1243dSDimitry Andric setAssignmentTrackingModuleFlag(M); 2274bdd1243dSDimitry Andric 2275bdd1243dSDimitry Andric // Q: Can we return a less conservative set than just CFGAnalyses? Can we 2276bdd1243dSDimitry Andric // return PreservedAnalyses::all()? 2277bdd1243dSDimitry Andric PreservedAnalyses PA; 2278bdd1243dSDimitry Andric PA.preserveSet<CFGAnalyses>(); 2279bdd1243dSDimitry Andric return PA; 2280bdd1243dSDimitry Andric } 2281bdd1243dSDimitry Andric 2282bdd1243dSDimitry Andric #undef DEBUG_TYPE 2283