aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Transforms/Utils/CloningTest.cpp
diff options
context:
space:
mode:
authorVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-07-18 14:22:46 +0200
committerVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-11-02 17:44:52 +0100
commit3b449bd46a11a55a40cbc0016a99b202fa05248e (patch)
tree2f43becc4e0cd830b15db5c075ff5b9c6a378610 /llvm/unittests/Transforms/Utils/CloningTest.cpp
parent98bd0d9dd2da0edec15b5eb7acb480c47c4594cc (diff)
downloadllvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.zip
llvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.tar.gz
llvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.tar.bz2
[DebugMetadata][DwarfDebug] Support function-local types in lexical block scopes (4/7)
RFC https://discourse.llvm.org/t/rfc-dwarfdebug-fix-and-improve-handling-imported-entities-types-and-static-local-in-subprogram-and-lexical-block-scopes/68544 Similar to imported declarations, the patch tracks function-local types in DISubprogram's 'retainedNodes' field. DwarfDebug is adjusted in accordance with the aforementioned metadata change and provided a support of function-local types scoped within a lexical block. The patch assumes that DICompileUnit's 'enums field' no longer tracks local types and DwarfDebug would assert if any locally-scoped types get placed there. Reviewed By: jmmartinez Authored-by: Kristina Bessonova <kbessonova@accesssoftek.com> Differential Revision: https://reviews.llvm.org/D144006
Diffstat (limited to 'llvm/unittests/Transforms/Utils/CloningTest.cpp')
-rw-r--r--llvm/unittests/Transforms/Utils/CloningTest.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp
index e083c75b..9f8225f 100644
--- a/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -801,6 +801,99 @@ TEST(CloneFunction, CloneFunctionWithSubprograms) {
EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
}
+TEST(CloneFunction, CloneFunctionWithRetainedNodes) {
+ StringRef ImplAssembly = R"(
+ declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+ define void @test() !dbg !3 {
+ call void @llvm.dbg.declare(metadata i8* undef, metadata !5, metadata !DIExpression()), !dbg !7
+ ret void
+ }
+
+ declare void @cloned()
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!2}
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, enums: !{!14})
+ !1 = !DIFile(filename: "test.cpp", directory: "")
+ !2 = !{i32 1, !"Debug Info Version", i32 3}
+ !3 = distinct !DISubprogram(name: "test", scope: !1, unit: !0, retainedNodes: !9)
+ !4 = distinct !DISubprogram(name: "inlined", scope: !1, unit: !0, retainedNodes: !{!5})
+ !5 = !DILocalVariable(name: "awaitables", scope: !4, type: !23)
+ !6 = distinct !DILexicalBlock(scope: !4, file: !1, line: 1)
+ !7 = !DILocation(line: 1, scope: !6, inlinedAt: !8)
+ !8 = !DILocation(line: 10, scope: !3)
+ !9 = !{!15, !17, !18}
+ !14 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !0, file: !1, line: 13, size: 200, elements: !{})
+ !15 = !DILocalVariable(name: "a", scope: !3)
+ !16 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !3, file: !1, line: 13, size: 208, elements: !{})
+ !17 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "imported_l", file: !1, line: 14, scope: !3, entity: !16)
+ !18 = !DILabel(scope: !3, name: "l", file: !1, line: 22)
+ !22 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float)
+ !23 = !DIDerivedType(name: "local_float", tag: DW_TAG_const_type, baseType: !22, scope: !3)
+ !float_type = !{!23}
+ )";
+
+ LLVMContext Context;
+ SMDiagnostic Error;
+
+ auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
+ llvm::errs() << Error.getMessage() << Error.getLineNo() << "\n";
+ EXPECT_TRUE(ImplModule != nullptr);
+ auto *Func = ImplModule->getFunction("test");
+ EXPECT_TRUE(Func != nullptr);
+ auto *ClonedFunc = ImplModule->getFunction("cloned");
+ EXPECT_TRUE(ClonedFunc != nullptr);
+
+ EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
+
+ ValueToValueMapTy VMap;
+ SmallVector<ReturnInst *, 8> Returns;
+ ClonedCodeInfo CCI;
+ CloneFunctionInto(ClonedFunc, Func, VMap,
+ CloneFunctionChangeType::GlobalChanges, Returns, "", &CCI);
+
+ EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
+
+ // Check that retained and local types are copied.
+ DISubprogram *FuncSP = Func->getSubprogram();
+ DISubprogram *ClonedSP = ClonedFunc->getSubprogram();
+ EXPECT_NE(FuncSP, nullptr);
+ EXPECT_NE(ClonedSP, nullptr);
+ EXPECT_EQ(FuncSP->getRetainedNodes().size(), 3u);
+ EXPECT_EQ(FuncSP->getRetainedNodes().size(),
+ ClonedSP->getRetainedNodes().size());
+ for (unsigned I = 0; I < FuncSP->getRetainedNodes().size(); ++I) {
+ auto *Node = FuncSP->getRetainedNodes()[I];
+ auto *Copy = ClonedSP->getRetainedNodes()[I];
+
+ // Check that the order of retainedNodes is preserved by
+ // checking that the corresponding node has the same name.
+ if (auto *Var = dyn_cast<DILocalVariable>(Node)) {
+ auto *VarCopy = dyn_cast<DILocalVariable>(Copy);
+ EXPECT_NE(VarCopy, nullptr);
+ EXPECT_EQ(Var->getName(), VarCopy->getName());
+ } else if (auto *Label = dyn_cast<DILabel>(Node)) {
+ auto *LabelCopy = dyn_cast<DILabel>(Copy);
+ EXPECT_NE(LabelCopy, nullptr);
+ EXPECT_EQ(Label->getName(), LabelCopy->getName());
+ } else if (auto *IE = dyn_cast<DIImportedEntity>(Node)) {
+ auto *IECopy = dyn_cast<DIImportedEntity>(Copy);
+ EXPECT_NE(IECopy, nullptr);
+ EXPECT_EQ(IE->getName(), IECopy->getName());
+ }
+
+ // Check that node was copied
+ EXPECT_NE(Node, Copy);
+ }
+
+ auto *FloatType = dyn_cast<DIType>(
+ ImplModule->getNamedMetadata("float_type")->getOperand(0));
+ EXPECT_EQ(FloatType->getName(), "local_float");
+ EXPECT_TRUE(VMap.MD().contains(FloatType));
+ EXPECT_NE(FloatType, VMap.MD()[FloatType]);
+}
+
TEST(CloneFunction, CloneFunctionWithInlinedSubprograms) {
StringRef ImplAssembly = R"(
declare void @llvm.dbg.declare(metadata, metadata, metadata)