-
Notifications
You must be signed in to change notification settings - Fork 10.7k
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
Make SmallVectorImpl destructor protected #71439
Conversation
@llvm/pr-subscribers-mlir-gpu @llvm/pr-subscribers-llvm-adt Author: Andy Kaylor (andykaylor) ChangesBecause the SmallVectorImpl destructor is not virtual, the destructor of derived classes will not be called if pointers to the SmallVectorImpl class are deleted directly. Making the SmallVectorImpl destructor protected will prevent this. Full diff: https://github.com/llvm/llvm-project/pull/71439.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 53a107b1574c6a3..2e6d2dc6ce90a2c 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -601,9 +601,6 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
RHS.resetToSmall();
}
-public:
- SmallVectorImpl(const SmallVectorImpl &) = delete;
-
~SmallVectorImpl() {
// Subclass has already destructed this vector's elements.
// If this wasn't grown from the inline copy, deallocate the old space.
@@ -611,6 +608,9 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
free(this->begin());
}
+public:
+ SmallVectorImpl(const SmallVectorImpl &) = delete;
+
void clear() {
this->destroy_range(this->begin(), this->end());
this->Size = 0;
diff --git a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
index 5c288e977ad0f23..97b3b66eda00133 100644
--- a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
+++ b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
@@ -95,7 +95,7 @@ class SerializeToHsacoPass
std::unique_ptr<std::vector<char>>
serializeISA(const std::string &isa) override;
- std::unique_ptr<SmallVectorImpl<char>> assembleIsa(const std::string &isa);
+ std::unique_ptr<SmallVector<char, 16>> assembleIsa(const std::string &isa);
std::unique_ptr<std::vector<char>>
createHsaco(const SmallVectorImpl<char> &isaBinary);
@@ -318,7 +318,7 @@ SerializeToHsacoPass::translateToLLVMIR(llvm::LLVMContext &llvmContext) {
return ret;
}
-std::unique_ptr<SmallVectorImpl<char>>
+std::unique_ptr<SmallVector<char, 16>>
SerializeToHsacoPass::assembleIsa(const std::string &isa) {
auto loc = getOperation().getLoc();
@@ -381,7 +381,7 @@ SerializeToHsacoPass::assembleIsa(const std::string &isa) {
parser->setTargetParser(*tap);
parser->Run(false);
- return std::make_unique<SmallVector<char, 0>>(std::move(result));
+ return std::make_unique<SmallVector<char, 16>>(std::move(result));
}
std::unique_ptr<std::vector<char>>
|
@llvm/pr-subscribers-mlir Author: Andy Kaylor (andykaylor) ChangesBecause the SmallVectorImpl destructor is not virtual, the destructor of derived classes will not be called if pointers to the SmallVectorImpl class are deleted directly. Making the SmallVectorImpl destructor protected will prevent this. Full diff: https://github.com/llvm/llvm-project/pull/71439.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 53a107b1574c6a3..2e6d2dc6ce90a2c 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -601,9 +601,6 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
RHS.resetToSmall();
}
-public:
- SmallVectorImpl(const SmallVectorImpl &) = delete;
-
~SmallVectorImpl() {
// Subclass has already destructed this vector's elements.
// If this wasn't grown from the inline copy, deallocate the old space.
@@ -611,6 +608,9 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
free(this->begin());
}
+public:
+ SmallVectorImpl(const SmallVectorImpl &) = delete;
+
void clear() {
this->destroy_range(this->begin(), this->end());
this->Size = 0;
diff --git a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
index 5c288e977ad0f23..97b3b66eda00133 100644
--- a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
+++ b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
@@ -95,7 +95,7 @@ class SerializeToHsacoPass
std::unique_ptr<std::vector<char>>
serializeISA(const std::string &isa) override;
- std::unique_ptr<SmallVectorImpl<char>> assembleIsa(const std::string &isa);
+ std::unique_ptr<SmallVector<char, 16>> assembleIsa(const std::string &isa);
std::unique_ptr<std::vector<char>>
createHsaco(const SmallVectorImpl<char> &isaBinary);
@@ -318,7 +318,7 @@ SerializeToHsacoPass::translateToLLVMIR(llvm::LLVMContext &llvmContext) {
return ret;
}
-std::unique_ptr<SmallVectorImpl<char>>
+std::unique_ptr<SmallVector<char, 16>>
SerializeToHsacoPass::assembleIsa(const std::string &isa) {
auto loc = getOperation().getLoc();
@@ -381,7 +381,7 @@ SerializeToHsacoPass::assembleIsa(const std::string &isa) {
parser->setTargetParser(*tap);
parser->Run(false);
- return std::make_unique<SmallVector<char, 0>>(std::move(result));
+ return std::make_unique<SmallVector<char, 16>>(std::move(result));
}
std::unique_ptr<std::vector<char>>
|
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.
Overall I think this makes sense, but the SerializeToHsaco
changes look suboptimal
@@ -95,7 +95,7 @@ class SerializeToHsacoPass | |||
std::unique_ptr<std::vector<char>> | |||
serializeISA(const std::string &isa) override; | |||
|
|||
std::unique_ptr<SmallVectorImpl<char>> assembleIsa(const std::string &isa); | |||
std::unique_ptr<SmallVector<char, 16>> assembleIsa(const std::string &isa); |
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.
IMO this should either return SmallVector<char>
(without unique_ptr
and an exact size) or take SmallVectorImpl<char> &
as the second function argument
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'm not familiar enough with this code to know what would be best, and honestly I didn't spend any time trying to figure that out. My goal was just to get it to compile with my SmallVectorImpl change. I hope that the maintainers of this code will make a change that will make my change unnecessary.
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.
@krzysz00 can you change this ahead of the current PR?
We probably (pretty sure) don't want to add a virtual dtor to SmallVector - that'd add a vtable pointer, increasing the size in ways that are probably unacceptable given the pervasive use of the data structure. We should make the Impl dtor protected so it can't be polymorphically destroyed. |
That's what I thought as well. It's not particularly clear since GitHub is highlighting the deleted constructor as the thing that changed, but that is what this PR does -- the "public" line is dropped below the destructor, making it protected. |
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 we have reached consensus that this is the preferred direction. SerializeToHsaco
is a tiny detail in the grand scheme of things, and because this PR doesn't make it any worse, I don't think we should be blocked by it.
I don't know if I'll be able to get to the SerializeToHsaco fix today, but passing in Or really that should be |
I don't think this change is time-critical. I can wait a few days for the SerializeToHsaco fix, but if it's going to be more than a few days, I'd prefer to land this change with an interim fix in SerializeToHsaco. @krzysz00 what's your preference? |
I put up a PR to fix SerializeToHsaco and unblock this |
Enable merging llvm#71439 by removing a definitely-wrong usage of std::unique_ptr<SmallVectorImpl<char>> as a return value with passing in a SmallVectorImpl<char>& Also change the following function to take ArrayRef<char> instead of const SmalVectorImpl<char>& .
Enable merging #71439 by removing a definitely-wrong usage of std::unique_ptr<SmallVectorImpl<char>> as a return value with passing in a SmallVectorImpl<char>& Also change the following function to take ArrayRef<char> instead of const SmalVectorImpl<char>& .
7d56022
to
ef6d187
Compare
I'm not sure what happened here. I reset the branch in my fork so I could update this with the #71702 change in place. I'm testing locally and plan to update this PR (or create a new one) when I'm done. |
You can always force-push here the same branch you pushed for the new PR: that’ll set the same state.
This is solved, but to keep in mind for next time: this is the kind of change to land separately. |
Sure, that makes a lot of sense, and I didn't really expect this to land with the MLIR changes as part of my commit. I was just including them in the first revision because otherwise my change would have made things unbuildable. |
Because the SmallVectorImpl destructor is not virtual, the destructor of derived classes will not be called if pointers to the SmallVectorImpl class are deleted directly. Making the SmallVectorImpl destructor protected will prevent this.