-
Notifications
You must be signed in to change notification settings - Fork 4k
GH-33701: [C++] Add support for LTO (link time optimization) build #33847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -288,31 +288,46 @@ std::shared_ptr<DataType> GetPhysicalType(const std::shared_ptr<DataType>& type) | |||||
| class ARROW_EXPORT FixedWidthType : public DataType { | ||||||
| public: | ||||||
| using DataType::DataType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~FixedWidthType() override; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably don't need to define the destructor separately?
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried |
||||||
| }; | ||||||
|
|
||||||
| /// \brief Base class for all data types representing primitive values | ||||||
| class ARROW_EXPORT PrimitiveCType : public FixedWidthType { | ||||||
| public: | ||||||
| using FixedWidthType::FixedWidthType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~PrimitiveCType() override; | ||||||
| }; | ||||||
|
|
||||||
| /// \brief Base class for all numeric data types | ||||||
| class ARROW_EXPORT NumberType : public PrimitiveCType { | ||||||
| public: | ||||||
| using PrimitiveCType::PrimitiveCType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~NumberType() override; | ||||||
| }; | ||||||
|
|
||||||
| /// \brief Base class for all integral data types | ||||||
| class ARROW_EXPORT IntegerType : public NumberType { | ||||||
| public: | ||||||
| using NumberType::NumberType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~IntegerType() override; | ||||||
| virtual bool is_signed() const = 0; | ||||||
| }; | ||||||
|
|
||||||
| /// \brief Base class for all floating-point data types | ||||||
| class ARROW_EXPORT FloatingPointType : public NumberType { | ||||||
| public: | ||||||
| using NumberType::NumberType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~FloatingPointType() override; | ||||||
| enum Precision { HALF, SINGLE, DOUBLE }; | ||||||
| virtual Precision precision() const = 0; | ||||||
| }; | ||||||
|
|
@@ -323,6 +338,9 @@ class ParametricType {}; | |||||
| class ARROW_EXPORT NestedType : public DataType, public ParametricType { | ||||||
| public: | ||||||
| using DataType::DataType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~NestedType() override; | ||||||
| }; | ||||||
|
|
||||||
| /// \brief The combination of a field name and data type, with optional metadata | ||||||
|
|
@@ -650,6 +668,9 @@ class ARROW_EXPORT DoubleType | |||||
| class ARROW_EXPORT BaseBinaryType : public DataType { | ||||||
| public: | ||||||
| using DataType::DataType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~BaseBinaryType() override; | ||||||
| }; | ||||||
|
|
||||||
| constexpr int64_t kBinaryMemoryLimit = std::numeric_limits<int32_t>::max() - 1; | ||||||
|
|
@@ -893,6 +914,9 @@ class ARROW_EXPORT Decimal256Type : public DecimalType { | |||||
| class ARROW_EXPORT BaseListType : public NestedType { | ||||||
| public: | ||||||
| using NestedType::NestedType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~BaseListType() override; | ||||||
| const std::shared_ptr<Field>& value_field() const { return children_[0]; } | ||||||
|
|
||||||
| std::shared_ptr<DataType> value_type() const { return children_[0]->type(); } | ||||||
|
|
@@ -1209,6 +1233,9 @@ class ARROW_EXPORT DenseUnionType : public UnionType { | |||||
| class ARROW_EXPORT TemporalType : public FixedWidthType { | ||||||
| public: | ||||||
| using FixedWidthType::FixedWidthType; | ||||||
| // This is only for preventing defining this class in each | ||||||
| // translation unit to avoid one-definition-rule violation. | ||||||
| ~TemporalType() override; | ||||||
|
|
||||||
| DataTypeLayout layout() const override { | ||||||
| return DataTypeLayout( | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why it causes ODR violation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I don't know much about this but...
I tried to create a small example to reproduce this case but couldn't create it... So I explain what I observed:
If we don't have this,
.oof a C++ code that hasstd::make_shared<arrow::XXXType>such asstd::make_shared<arrow::ListType>has the followingnmresult:Wis a global weak symbol.https://linux.die.net/man/1/nm
If we have this, the symbol becomes a undefined symbol:
https://linux.die.net/man/1/nm
If there are multiple
W vtable for arrow::FloatingPointTypein our.o. linkinglibarrow.sowith-fltois failed:It seems that
Wand-fltois a bad combination. If we changeWtoUby defining a not-inlined deconstructor, we don't get the ODR error.Do you notice anything from this observation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why it happens. Clang doesn't complain ODR issue.
cc @pitrou, @westonpace, @lidavidm for comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand why adding that destructor changes W to U. You are defining a non-inline key function. Therefore the vtable is defined in only one place.
However, I don't understand why it is an ODR error. For example, in the clang docs:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this is only happen with GCC (GNU ld?).
I couldn't reproduce this with
CC=clang CXX=clang++ CFLAGS="-flto" CXXFLAGS="-flto" cmake .... (Wsymbol is still generated but there is no link error.)Is it acceptable that we add this change only for GCC and LTO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change is okay. And I wonder how you find this solution, it's not obvious from the error log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just a try and error...
There are some abstract classes for
arrow::DataTypefamily. Most of them are in error messages butarrow::DataTypeisn't shown. I noticed thatarrow::DataTypeisUand others areWinnm --demangleresult. I found thatarrow::DataType::~DataType()is defined intype.ccbut other abstract classes don't define their destructors. So I tried to define them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean if a class has virtual functions, it's recommended that at least one of them should be in
.cc?I find it hard to understand
a class has no non-pure, non-inline, virtual functions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is what it means. I think "wasteful" is too strong of a word though. I think the consequence should generally be minor enough that it isn't really a concern.