llvm.org GIT mirror llvm / 054c35d
DWARF: Avoid cross-CU references under Fission Turns out that the Fission/Split DWARF package format (DWP) is currently insufficient to handle cross-CU (ref_addr) references. So for now, duplicate any debug info needed in these situations: * inlined_subroutine's abstract_origin * inlined variable's abstract_origin * types Keep the ref_addr behavior in general, including in the split DWARF inline debug info that can be emitted into the object files for online symbolication. Keep a flag to use the old (ref_addr) behavior for testing ways of addressing this limitation in the DWP tool (& for those not using DWP packaging). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302858 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 3 years ago
8 changed file(s) with 292 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
439439 auto *InlinedSP = getDISubprogram(DS);
440440 // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
441441 // was inlined from another compile unit.
442 DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP];
442 DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
443443 assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
444444
445445 auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
633633
634634 void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
635635 LexicalScope *Scope) {
636 DIE *&AbsDef = DU->getAbstractSPDies()[Scope->getScopeNode()];
636 DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
637637 if (AbsDef)
638638 return;
639639
695695
696696 void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
697697 DIE *D = getDIE(SP);
698 if (DIE *AbsSPDIE = DU->getAbstractSPDies().lookup(SP)) {
698 if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
699699 if (D)
700700 // If this subprogram has an abstract definition, reference that
701701 addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
705705 // And attach the attributes
706706 applySubprogramAttributesToDefinition(SP, *D);
707707 }
708 }
709
710 void DwarfCompileUnit::finishVariableDefinition(const DbgVariable &Var) {
711 DbgVariable *AbsVar = getExistingAbstractVariable(
712 InlinedVariable(Var.getVariable(), Var.getInlinedAt()));
713 auto *VariableDie = Var.getDIE();
714 if (AbsVar && AbsVar->getDIE()) {
715 addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
716 *AbsVar->getDIE());
717 } else
718 applyVariableAttributes(Var, *VariableDie);
719 }
720
721 DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(InlinedVariable IV) {
722 const DILocalVariable *Cleansed;
723 return getExistingAbstractVariable(IV, Cleansed);
724 }
725
726 // Find abstract variable, if any, associated with Var.
727 DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(
728 InlinedVariable IV, const DILocalVariable *&Cleansed) {
729 // More then one inlined variable corresponds to one abstract variable.
730 Cleansed = IV.first;
731 auto &AbstractVariables = getAbstractVariables();
732 auto I = AbstractVariables.find(Cleansed);
733 if (I != AbstractVariables.end())
734 return I->second.get();
735 return nullptr;
736 }
737
738 void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var,
739 LexicalScope *Scope) {
740 assert(Scope && Scope->isAbstractScope());
741 auto AbsDbgVariable = make_unique(Var, /* IA */ nullptr);
742 DU->addScopeVariable(Scope, AbsDbgVariable.get());
743 getAbstractVariables()[Var] = std::move(AbsDbgVariable);
708744 }
709745
710746 void DwarfCompileUnit::emitHeader(bool UseOffsets) {
6767 // ranges/locs.
6868 const MCSymbol *BaseAddress;
6969
70 DenseMap AbstractSPDies;
71 DenseMap> AbstractVariables;
72
7073 /// \brief Construct a DIE for the given DbgVariable without initializing the
7174 /// DbgVariable's DIE reference.
7275 DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
7477 bool isDwoUnit() const override;
7578
7679 bool includeMinimalInlineScopes() const;
80
81 DenseMap &getAbstractSPDies() {
82 if (isDwoUnit() && !DD->shareAcrossDWOCUs())
83 return AbstractSPDies;
84 return DU->getAbstractSPDies();
85 }
86
87 DenseMap> &getAbstractVariables() {
88 if (isDwoUnit() && !DD->shareAcrossDWOCUs())
89 return AbstractVariables;
90 return DU->getAbstractVariables();
91 }
7792
7893 public:
7994 DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
188203 DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
189204
190205 void finishSubprogramDefinition(const DISubprogram *SP);
206 void finishVariableDefinition(const DbgVariable &Var);
207 /// Find abstract variable associated with Var.
208 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
209 DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
210 const DILocalVariable *&Cleansed);
211 DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
212 void createAbstractVariable(const DILocalVariable *DV, LexicalScope *Scope);
191213
192214 /// Set the skeleton unit associated with this unit.
193215 void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
7070 cl::desc("Generate dwarf aranges"),
7171 cl::init(false));
7272
73 static cl::opt SplitDwarfCrossCuReferences(
74 "split-dwarf-cross-cu-references", cl::Hidden,
75 cl::desc("Enable cross-cu references in DWO files"), cl::init(false));
76
7377 namespace {
7478 enum DefaultOnOff { Default, Enable, Disable };
7579 }
361365 F(*SkelCU);
362366 }
363367
364 void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
368 bool DwarfDebug::shareAcrossDWOCUs() const {
369 return SplitDwarfCrossCuReferences;
370 }
371
372 void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
373 LexicalScope *Scope) {
365374 assert(Scope && Scope->getScopeNode());
366375 assert(Scope->isAbstractScope());
367376 assert(!Scope->getInlinedAt());
368377
369378 auto *SP = cast(Scope->getScopeNode());
370379
371 ProcessedSPNodes.insert(SP);
372
373380 // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
374381 // was inlined from another compile unit.
375382 auto &CU = *CUMap.lookup(SP->getUnit());
376 forBothCUs(CU, [&](DwarfCompileUnit &CU) {
383 if (auto *SkelCU = CU.getSkeleton()) {
384 (shareAcrossDWOCUs() ? CU : SrcCU)
385 .constructAbstractSubprogramScopeDIE(Scope);
386 if (CU.getCUNode()->getSplitDebugInlining())
387 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
388 } else {
377389 CU.constructAbstractSubprogramScopeDIE(Scope);
378 });
390 }
379391 }
380392
381393 void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
563575 // DIE::getUnit isn't simple - it walks parent pointers, etc.
564576 DwarfCompileUnit *Unit = CUDieMap.lookup(VariableDie->getUnitDie());
565577 assert(Unit);
566 DbgVariable *AbsVar = getExistingAbstractVariable(
567 InlinedVariable(Var->getVariable(), Var->getInlinedAt()));
568 if (AbsVar && AbsVar->getDIE()) {
569 Unit->addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
570 *AbsVar->getDIE());
571 } else
572 Unit->applyVariableAttributes(*Var, *VariableDie);
578 Unit->finishVariableDefinition(*Var);
573579 }
574580 }
575581
717723 }
718724
719725 // clean up.
720 AbstractVariables.clear();
721 }
722
723 // Find abstract variable, if any, associated with Var.
724 DbgVariable *
725 DwarfDebug::getExistingAbstractVariable(InlinedVariable IV,
726 const DILocalVariable *&Cleansed) {
727 // More then one inlined variable corresponds to one abstract variable.
728 Cleansed = IV.first;
729 auto I = AbstractVariables.find(Cleansed);
730 if (I != AbstractVariables.end())
731 return I->second.get();
732 return nullptr;
733 }
734
735 DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) {
736 const DILocalVariable *Cleansed;
737 return getExistingAbstractVariable(IV, Cleansed);
738 }
739
740 void DwarfDebug::createAbstractVariable(const DILocalVariable *Var,
741 LexicalScope *Scope) {
742 assert(Scope && Scope->isAbstractScope());
743 auto AbsDbgVariable = make_unique(Var, /* IA */ nullptr);
744 InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get());
745 AbstractVariables[Var] = std::move(AbsDbgVariable);
746 }
747
748 void DwarfDebug::ensureAbstractVariableIsCreated(InlinedVariable IV,
726 // FIXME: AbstractVariables.clear();
727 }
728
729 void DwarfDebug::ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable IV,
749730 const MDNode *ScopeNode) {
750731 const DILocalVariable *Cleansed = nullptr;
751 if (getExistingAbstractVariable(IV, Cleansed))
732 if (CU.getExistingAbstractVariable(IV, Cleansed))
752733 return;
753734
754 createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
735 CU.createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
755736 cast(ScopeNode)));
756737 }
757738
758 void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(
739 void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU,
759740 InlinedVariable IV, const MDNode *ScopeNode) {
760741 const DILocalVariable *Cleansed = nullptr;
761 if (getExistingAbstractVariable(IV, Cleansed))
742 if (CU.getExistingAbstractVariable(IV, Cleansed))
762743 return;
763744
764745 if (LexicalScope *Scope =
765746 LScopes.findAbstractScope(cast_or_null(ScopeNode)))
766 createAbstractVariable(Cleansed, Scope);
767 }
768
747 CU.createAbstractVariable(Cleansed, Scope);
748 }
769749 // Collect variable information from side table maintained by MF.
770750 void DwarfDebug::collectVariableInfoFromMFTable(
771 DenseSet &Processed) {
751 DwarfCompileUnit &TheCU, DenseSet &Processed) {
772752 for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
773753 if (!VI.Var)
774754 continue;
783763 if (!Scope)
784764 continue;
785765
786 ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode());
766 ensureAbstractVariableIsCreatedIfScoped(TheCU, Var, Scope->getScopeNode());
787767 auto RegVar = make_unique(Var.first, Var.second);
788768 RegVar->initializeMMI(VI.Expr, VI.Slot);
789769 if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
954934 }
955935 }
956936
957 DbgVariable *DwarfDebug::createConcreteVariable(LexicalScope &Scope,
937 DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU,
938 LexicalScope &Scope,
958939 InlinedVariable IV) {
959 ensureAbstractVariableIsCreatedIfScoped(IV, Scope.getScopeNode());
940 ensureAbstractVariableIsCreatedIfScoped(TheCU, IV, Scope.getScopeNode());
960941 ConcreteVariables.push_back(make_unique(IV.first, IV.second));
961942 InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
962943 return ConcreteVariables.back().get();
979960 const DISubprogram *SP,
980961 DenseSet &Processed) {
981962 // Grab the variable info that was squirreled away in the MMI side-table.
982 collectVariableInfoFromMFTable(Processed);
963 collectVariableInfoFromMFTable(TheCU, Processed);
983964
984965 for (const auto &I : DbgValues) {
985966 InlinedVariable IV = I.first;
1001982 continue;
1002983
1003984 Processed.insert(IV);
1004 DbgVariable *RegVar = createConcreteVariable(*Scope, IV);
985 DbgVariable *RegVar = createConcreteVariable(TheCU, *Scope, IV);
1005986
1006987 const MachineInstr *MInsn = Ranges.front().first;
1007988 assert(MInsn->isDebugValue() && "History must begin with debug value");
10371018 for (const DILocalVariable *DV : SP->getVariables()) {
10381019 if (Processed.insert(InlinedVariable(DV, nullptr)).second)
10391020 if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope()))
1040 createConcreteVariable(*Scope, InlinedVariable(DV, nullptr));
1021 createConcreteVariable(TheCU, *Scope, InlinedVariable(DV, nullptr));
10411022 }
10421023 }
10431024
12281209 for (const DILocalVariable *DV : SP->getVariables()) {
12291210 if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
12301211 continue;
1231 ensureAbstractVariableIsCreated(InlinedVariable(DV, nullptr),
1212 ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV, nullptr),
12321213 DV->getScope());
12331214 assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
12341215 && "ensureAbstractVariableIsCreated inserted abstract scopes");
12351216 }
1236 constructAbstractSubprogramScopeDIE(AScope);
1217 constructAbstractSubprogramScopeDIE(TheCU, AScope);
12371218 }
12381219
12391220 ProcessedSPNodes.insert(SP);
209209 DenseMap SymSize;
210210
211211 /// Collection of abstract variables.
212 DenseMap> AbstractVariables;
213212 SmallVector, 64> ConcreteVariables;
214213
215214 /// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
312311
313312 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
314313
315 /// Find abstract variable associated with Var.
316 DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
317 const DILocalVariable *&Cleansed);
318 DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
319 void createAbstractVariable(const DILocalVariable *DV, LexicalScope *Scope);
320 void ensureAbstractVariableIsCreated(InlinedVariable Var,
314 void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable Var,
321315 const MDNode *Scope);
322 void ensureAbstractVariableIsCreatedIfScoped(InlinedVariable Var,
316 void ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU, InlinedVariable Var,
323317 const MDNode *Scope);
324318
325 DbgVariable *createConcreteVariable(LexicalScope &Scope, InlinedVariable IV);
319 DbgVariable *createConcreteVariable(DwarfCompileUnit &TheCU,
320 LexicalScope &Scope, InlinedVariable IV);
326321
327322 /// Construct a DIE for this abstract scope.
328 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
323 void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
329324
330325 void finishVariableDefinitions();
331326
445440 const DbgValueHistoryMap::InstrRanges &Ranges);
446441
447442 /// Collect variable information from the side table maintained by MF.
448 void collectVariableInfoFromMFTable(DenseSet &P);
443 void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,
444 DenseSet &P);
449445
450446 protected:
451447 /// Gather pre-function debug information.
517513 /// split dwarf proposal support.
518514 bool useSplitDwarf() const { return HasSplitDwarf; }
519515
516 bool shareAcrossDWOCUs() const;
517
520518 /// Returns the Dwarf Version.
521519 uint16_t getDwarfVersion() const;
522520
5252
5353 // Collection of abstract subprogram DIEs.
5454 DenseMap AbstractSPDies;
55 DenseMap> AbstractVariables;
5556
5657 /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
5758 /// be shared across CUs, that is why we keep the map here instead
104105 DenseMap &getAbstractSPDies() {
105106 return AbstractSPDies;
106107 }
108 DenseMap> &getAbstractVariables() {
109 return AbstractVariables;
110 }
107111
108112 void insertDIE(const MDNode *TypeMD, DIE *Die) {
109113 DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
172172 }
173173
174174 /// Check whether the DIE for this MDNode can be shared across CUs.
175 static bool isShareableAcrossCUs(const DINode *D) {
175 bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {
176176 // When the MDNode can be part of the type system, the DIE can be shared
177177 // across CUs.
178178 // Combining type units and cross-CU DIE sharing is lower value (since
180180 // level already) but may be implementable for some value in projects
181181 // building multiple independent libraries with LTO and then linking those
182182 // together.
183 if (isDwoUnit() && !DD->shareAcrossDWOCUs())
184 return false;
183185 return (isa(D) ||
184186 (isa(D) && !cast(D)->isDefinition())) &&
185187 !GenerateDwarfTypeUnits;
6464 //===----------------------------------------------------------------------===//
6565 /// This dwarf writer support class manages information associated with a
6666 /// source file.
67 class DwarfUnit : public DIEUnit {
67 class DwarfUnit : public DIEUnit {
6868 protected:
6969 /// MDNode for the compile unit.
7070 const DICompileUnit *CUNode;
101101 DwarfFile *DWU);
102102
103103 bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie);
104
105 bool shareAcrossDWOCUs() const;
106 bool isShareableAcrossCUs(const DINode *D) const;
104107
105108 public:
106109 // Accessors.
None ; RUN: llc -mtriple=x86_64-linux -split-dwarf-file=foo.dwo -filetype=obj -o - < %s | llvm-objdump -r - | FileCheck %s
0 ; RUN: llc -mtriple=x86_64-linux -split-dwarf-cross-cu-references -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s
1 ; RUN: llvm-objdump -r %t | FileCheck %s
2 ; RUN: llvm-dwarfdump -debug-dump=info.dwo %t | FileCheck --check-prefix=ALL --check-prefix=INFO --check-prefix=DWO --check-prefix=CROSS %s
3 ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s
4
5 ; RUN: llc -mtriple=x86_64-linux -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s
6 ; RUN: llvm-objdump -r %t | FileCheck %s
7 ; RUN: llvm-dwarfdump -debug-dump=info.dwo %t | FileCheck --check-prefix=ALL --check-prefix=DWO --check-prefix=NOCROSS %s
8 ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s
9
10 ; Testing cross-CU references for types, subprograms, and variables
11 ; Built from code something like this:
12 ; foo.cpp:
13 ; struct t1 { int i; };
14 ; void f();
15 ; __attribute__((always_inline)) void f1(t1 t) {
16 ; f();
17 ; }
18 ; void foo(t1 t) {
19 ; f1(t);
20 ; }
21 ; bar.cpp:
22 ; struct t1 { int i; };
23 ; void f1(t1);
24 ; void bar(t1 t) {
25 ; f1(t);
26 ; }
27 ; $ clang++-tot -emit-llvm -S {foo,bar}.cpp -g
28 ; $ llvm-link-tot {foo,bar}.ll -S -o foobar.ll
29 ; $ clang++-tot -emit-llvm foobar.ll -o foobar.opt.ll -S -c
30 ;
31 ; Then manually removing the original f1 definition, to simplify the DWARF a bit
32 ; (so it only has the inlined definitions, no concrete definition)
33
34 ; Check that:
35 ; * no relocations are emitted for the debug_info.dwo section no matter what
36 ; * one debug_info->debug_info relocation in debug_info no matter what (for
37 ; split dwarf inlining)
38 ; * debug_info uses relocations and ref_addr no matter what
39 ; * debug_info.dwo uses relocations for types as well as abstract subprograms
40 ; and variables when -split-dwarf-cross-cu-references is used
41 ; * debug_info.dwo contains duplicate types, abstract subprograms and abstract
42 ; variables otherwise to avoid the need for cross-cu references
143
244 ; CHECK-NOT: .rel{{a?}}.debug_info.dwo
345 ; CHECK: RELOCATION RECORDS FOR [.rel{{a?}}.debug_info]:
446 ; CHECK-NOT: RELOCATION RECORDS
5 ; Expect one relocation in debug_info, between f3 and f1.
47 ; Expect one relocation in debug_info, from the inlined f1 in foo to its
48 ; abstract origin in bar
649 ; CHECK: R_X86_64_32 .debug_info
50 ; CHECK-NOT: RELOCATION RECORDS
751 ; CHECK-NOT: .debug_info
852 ; CHECK: RELOCATION RECORDS
953 ; CHECK-NOT: .rel{{a?}}.debug_info.dwo
1054
55 ; ALL: Compile Unit
56 ; ALL: DW_TAG_compile_unit
57 ; DWO: DW_AT_name {{.*}} "foo.cpp"
58 ; ALL: 0x[[F1:.*]]: DW_TAG_subprogram
59 ; ALL: DW_AT_name {{.*}} "f1"
60 ; DWO: 0x[[F1T:.*]]: DW_TAG_formal_parameter
61 ; DWO: DW_AT_name {{.*}} "t"
62 ; DWO: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[T1:.*]]}
63 ; DWO: NULL
64 ; DWO: 0x[[T1]]: DW_TAG_structure_type
65 ; DWO: DW_AT_name {{.*}} "t1"
66 ; ALL: DW_TAG_subprogram
67 ; ALL: DW_AT_name {{.*}} "foo"
68 ; DWO: DW_TAG_formal_parameter
69 ; DWO: DW_AT_name {{.*}} "t"
70 ; DWO: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[T1]]}
71 ; ALL: DW_TAG_inlined_subroutine
72 ; ALL: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[F1]]}
73 ; DWO: DW_TAG_formal_parameter
74 ; DWO: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[F1T]]}
1175
12 ; Function Attrs: noinline nounwind optnone uwtable
13 define void @_Z2f1v() !dbg !7 {
76 ; ALL: Compile Unit
77 ; ALL: DW_TAG_compile_unit
78 ; DWO: DW_AT_name {{.*}} "bar.cpp"
79 ; NOCROSS: 0x[[BAR_F1:.*]]: DW_TAG_subprogram
80 ; NOCROSS: DW_AT_name {{.*}} "f1"
81 ; NOCROSS: 0x[[BAR_F1T:.*]]: DW_TAG_formal_parameter
82 ; NOCROSS: DW_AT_name {{.*}} "t"
83 ; NOCROSS: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[BAR_T1:.*]]}
84 ; NOCROSS: NULL
85 ; NOCROSS: 0x[[BAR_T1]]: DW_TAG_structure_type
86 ; NOCROSS: DW_AT_name {{.*}} "t1"
87 ; ALL: DW_TAG_subprogram
88 ; ALL: DW_AT_name {{.*}} "bar"
89 ; DWO: DW_TAG_formal_parameter
90 ; DWO: DW_AT_name {{.*}} "t"
91 ; CROSS: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[T1]]
92 ; NOCROSS: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[BAR_T1]]}
93 ; ALL: DW_TAG_inlined_subroutine
94 ; INFO: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[F1]]
95 ; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[BAR_F1]]}
96 ; DWO: DW_TAG_formal_parameter
97 ; CROSS: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[F1T]]
98 ; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[BAR_F1T]]
99
100 %struct.t1 = type { i32 }
101
102 ; Function Attrs: nounwind readnone speculatable
103 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
104
105 declare void @_Z1fv() #2
106
107 ; Function Attrs: noinline uwtable
108 define void @_Z3foo2t1(i32 %t.coerce) #3 !dbg !20 {
14109 entry:
15 ret void, !dbg !10
110 %t.i = alloca %struct.t1, align 4
111 call void @llvm.dbg.declare(metadata %struct.t1* %t.i, metadata !15, metadata !16), !dbg !21
112 %t = alloca %struct.t1, align 4
113 %agg.tmp = alloca %struct.t1, align 4
114 %coerce.dive = getelementptr inbounds %struct.t1, %struct.t1* %t, i32 0, i32 0
115 store i32 %t.coerce, i32* %coerce.dive, align 4
116 call void @llvm.dbg.declare(metadata %struct.t1* %t, metadata !23, metadata !16), !dbg !24
117 %0 = bitcast %struct.t1* %agg.tmp to i8*, !dbg !25
118 %1 = bitcast %struct.t1* %t to i8*, !dbg !25
119 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 4, i32 4, i1 false), !dbg !25
120 %coerce.dive1 = getelementptr inbounds %struct.t1, %struct.t1* %agg.tmp, i32 0, i32 0, !dbg !26
121 %2 = load i32, i32* %coerce.dive1, align 4, !dbg !26
122 %coerce.dive.i = getelementptr inbounds %struct.t1, %struct.t1* %t.i, i32 0, i32 0
123 store i32 %2, i32* %coerce.dive.i, align 4
124 call void @_Z1fv(), !dbg !27
125 ret void, !dbg !28
16126 }
17127
128 ; Function Attrs: argmemonly nounwind
129 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #4
130
18131 ; Function Attrs: noinline uwtable
19 define void @_Z2f3v() !dbg !13 {
132 define void @_Z3bar2t1(i32 %t.coerce) #3 !dbg !29 {
20133 entry:
21 call void @_Z2f1v(), !dbg !14
22 ret void, !dbg !16
134 %t.i = alloca %struct.t1, align 4
135 call void @llvm.dbg.declare(metadata %struct.t1* %t.i, metadata !15, metadata !16), !dbg !30
136 %t = alloca %struct.t1, align 4
137 %agg.tmp = alloca %struct.t1, align 4
138 %coerce.dive = getelementptr inbounds %struct.t1, %struct.t1* %t, i32 0, i32 0
139 store i32 %t.coerce, i32* %coerce.dive, align 4
140 call void @llvm.dbg.declare(metadata %struct.t1* %t, metadata !32, metadata !16), !dbg !33
141 %0 = bitcast %struct.t1* %agg.tmp to i8*, !dbg !34
142 %1 = bitcast %struct.t1* %t to i8*, !dbg !34
143 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 4, i32 4, i1 false), !dbg !34
144 %coerce.dive1 = getelementptr inbounds %struct.t1, %struct.t1* %agg.tmp, i32 0, i32 0, !dbg !35
145 %2 = load i32, i32* %coerce.dive1, align 4, !dbg !35
146 %coerce.dive.i = getelementptr inbounds %struct.t1, %struct.t1* %t.i, i32 0, i32 0
147 store i32 %2, i32* %coerce.dive.i, align 4
148 call void @_Z1fv(), !dbg !36
149 ret void, !dbg !37
23150 }
24151
25152 !llvm.dbg.cu = !{!0, !3}
26153 !llvm.ident = !{!5, !5}
27 !llvm.module.flags = !{!6}
154 !llvm.module.flags = !{!6, !7}
28155
29 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 301051) (llvm/trunk 301062)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
30 !1 = !DIFile(filename: "a.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
156 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 302809) (llvm/trunk 302815)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: true)
157 !1 = !DIFile(filename: "foo.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
31158 !2 = !{}
32 !3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "clang version 5.0.0 (trunk 301051) (llvm/trunk 301062)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
33 !4 = !DIFile(filename: "b.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
34 !5 = !{!"clang version 5.0.0 (trunk 301051) (llvm/trunk 301062)"}
35 !6 = !{i32 2, !"Debug Info Version", i32 3}
36 !7 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
37 !8 = !DISubroutineType(types: !9)
38 !9 = !{null}
39 !10 = !DILocation(line: 1, scope: !7)
40 !11 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
41 !12 = !DILocation(line: 1, scope: !11)
42 !13 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !4, file: !4, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !3, variables: !2)
43 !14 = !DILocation(line: 1, scope: !11, inlinedAt: !15)
44 !15 = distinct !DILocation(line: 1, scope: !13)
45 !16 = !DILocation(line: 1, scope: !13)
159 !3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "clang version 5.0.0 (trunk 302809) (llvm/trunk 302815)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: true)
160 !4 = !DIFile(filename: "bar.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
161 !5 = !{!"clang version 5.0.0 (trunk 302809) (llvm/trunk 302815)"}
162 !6 = !{i32 2, !"Dwarf Version", i32 4}
163 !7 = !{i32 2, !"Debug Info Version", i32 3}
164 !8 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f12t1", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
165 !9 = !DISubroutineType(types: !10)
166 !10 = !{null, !11}
167 !11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !1, line: 1, size: 32, elements: !12, identifier: "_ZTS2t1")
168 !12 = !{!13}
169 !13 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !11, file: !1, line: 1, baseType: !14, size: 32)
170 !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
171 !15 = !DILocalVariable(name: "t", arg: 1, scope: !8, file: !1, line: 3, type: !11)
172 !16 = !DIExpression()
173 !17 = !DILocation(line: 3, column: 43, scope: !8)
174 !18 = !DILocation(line: 4, column: 3, scope: !8)
175 !19 = !DILocation(line: 5, column: 1, scope: !8)
176 !20 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foo2t1", scope: !1, file: !1, line: 6, type: !9, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
177 !21 = !DILocation(line: 3, column: 43, scope: !8, inlinedAt: !22)
178 !22 = distinct !DILocation(line: 7, column: 3, scope: !20)
179 !23 = !DILocalVariable(name: "t", arg: 1, scope: !20, file: !1, line: 6, type: !11)
180 !24 = !DILocation(line: 6, column: 13, scope: !20)
181 !25 = !DILocation(line: 7, column: 6, scope: !20)
182 !26 = !DILocation(line: 7, column: 3, scope: !20)
183 !27 = !DILocation(line: 4, column: 3, scope: !8, inlinedAt: !22)
184 !28 = !DILocation(line: 8, column: 1, scope: !20)
185 !29 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bar2t1", scope: !4, file: !4, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !3, variables: !2)
186 !30 = !DILocation(line: 3, column: 43, scope: !8, inlinedAt: !31)
187 !31 = distinct !DILocation(line: 4, column: 3, scope: !29)
188 !32 = !DILocalVariable(name: "t", arg: 1, scope: !29, file: !4, line: 3, type: !11)
189 !33 = !DILocation(line: 3, column: 13, scope: !29)
190 !34 = !DILocation(line: 4, column: 6, scope: !29)
191 !35 = !DILocation(line: 4, column: 3, scope: !29)
192 !36 = !DILocation(line: 4, column: 3, scope: !8, inlinedAt: !31)
193 !37 = !DILocation(line: 5, column: 1, scope: !29)