akhuang updated this revision to Diff 293579.
akhuang added a comment.
Update ctor homing check, and add some test cases.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87808/new/
https://reviews.llvm.org/D87808
Files:
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
+++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
@@ -20,14 +20,37 @@
};
D::D() {}
+// Test for constexpr constructor.
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name:
"E"{{.*}}DIFlagTypePassByValue
struct E {
constexpr E(){};
} TestE;
+// Tests for trivial constructors.
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name:
"F"{{.*}}DIFlagTypePassByValue
struct F {
F() = default;
F(int) {}
int i;
} TestF;
+
+// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name:
"G"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
+struct G {
+ G() : g_(0) {}
+ struct {
+ int g_;
+ };
+} TestG;
+
+// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
+struct H {
+ B b;
+};
+void f(H h) {}
+
+// CHECK-DAG: !DICompositeType({{.*}}name: "I",{{.*}}DIFlagTypePassByValue
+struct I {
+ B b;
+};
+void f(decltype(I()) i) {}
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2281,22 +2281,18 @@
}
static bool canUseCtorHoming(const CXXRecordDecl *RD) {
- // Constructor homing can be used for classes that have at least one
- // constructor and have no trivial or constexpr constructors.
+ // Constructor homing can be used for classes that don't have any implicit,
+ // trivial default constructors or constexpr constructors.
+ // In other words, the class cannot be constructed without emitting code for
+ // one of its constructors.
+ //
// Skip this optimization if the class or any of its methods are marked
// dllimport.
- if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
- isClassOrMethodDLLImport(RD))
+ if (RD->isLambda() || isClassOrMethodDLLImport(RD))
return false;
- if (RD->ctors().empty())
- return false;
-
- for (const auto *Ctor : RD->ctors())
- if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
- return false;
-
- return true;
+ return !RD->isAggregate() && !RD->hasTrivialDefaultConstructor() &&
+ !RD->hasConstexprNonCopyMoveConstructor();
}
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
+++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
@@ -20,14 +20,37 @@
};
D::D() {}
+// Test for constexpr constructor.
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue
struct E {
constexpr E(){};
} TestE;
+// Tests for trivial constructors.
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "F"{{.*}}DIFlagTypePassByValue
struct F {
F() = default;
F(int) {}
int i;
} TestF;
+
+// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: "G"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
+struct G {
+ G() : g_(0) {}
+ struct {
+ int g_;
+ };
+} TestG;
+
+// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
+struct H {
+ B b;
+};
+void f(H h) {}
+
+// CHECK-DAG: !DICompositeType({{.*}}name: "I",{{.*}}DIFlagTypePassByValue
+struct I {
+ B b;
+};
+void f(decltype(I()) i) {}
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2281,22 +2281,18 @@
}
static bool canUseCtorHoming(const CXXRecordDecl *RD) {
- // Constructor homing can be used for classes that have at least one
- // constructor and have no trivial or constexpr constructors.
+ // Constructor homing can be used for classes that don't have any implicit,
+ // trivial default constructors or constexpr constructors.
+ // In other words, the class cannot be constructed without emitting code for
+ // one of its constructors.
+ //
// Skip this optimization if the class or any of its methods are marked
// dllimport.
- if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
- isClassOrMethodDLLImport(RD))
+ if (RD->isLambda() || isClassOrMethodDLLImport(RD))
return false;
- if (RD->ctors().empty())
- return false;
-
- for (const auto *Ctor : RD->ctors())
- if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
- return false;
-
- return true;
+ return !RD->isAggregate() && !RD->hasTrivialDefaultConstructor() &&
+ !RD->hasConstexprNonCopyMoveConstructor();
}
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits