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

source code of llvm/lib/IR/DebugInfo.cpp