[PATCH] Devirtualize llvm::Value and all subclasses
Pete Cooper
peter_cooper at apple.com
Mon Jun 22 17:53:57 PDT 2015
So back to 0002.
You were worried about the lack of protection to ensure that a subclass of Constant actually implements destroyConstant. Unfortunately I couldn’t find a good way to check for this statically, but I did go ahead and implement the alternative you suggested. For context, what follows (indented) was the proposal which i’ve basically just implemented exactly as described. It seems to be a very good way to handle this, and isn’t much more code churn.
However, I realize there's already something called
`Constant::destroyConstantImpl()`, which has a `delete this` inside it
(ironic, given that the context for this patch is removing the vtable
that the `delete` call relies on).
I haven't looked at all the patches in this series yet, but I feel like
there ought to be some way of clarifying `Constant` destruction
immediately. My shot-from-the-hip is something like the following:
class Constant {
public:
void destroyConstant();
};
class SomeConstant : public Constant {
friend class Base; // For fooImpl().
/// Destroy and delete the constant.
void destroyConstantImpl();
~SomeConstant();
// Don't provide destroyConstant().
};
void Constant::destroyConstant() {
// Remove lingering references from the constant pool (move from
// old `Constant::destroyConstantImpl()`).
while (!use_empty()) {
// ...
}
// Dispatch to subclass to cleanup and delete.
switch (...) {
default:
llvm_unreachable(...);
// Compile error if there's an unhandled case instead of
// infinite recursion.
#define HANDLE_CONSTANT(NAME) \
case NAME ## Kind: \
cast<NAME>(this)->destroyConstantImpl(); \
break;
}
// When we drop virtual dispatch for the destructor, move the
// delete call inside the switch statement above.
delete this;
}
void SomeConstant::destroyConstantImpl() {
assert(use_empty() && ...);
getContext()->SomeConstantPool.erase(this);
}
This inverts the destroyConstant/Impl relationship.
Maybe this leaves out some case, or doesn't quite fit with the end goal
(you've thought about this more than I have). My main point is, with
static dispatch we can easily catch the "missing destroyConstant()
implementation" at compile-time, and we should.
Cheers,
Pete
> On Jun 22, 2015, at 5:03 PM, Pete Cooper <peter_cooper at apple.com> wrote:
>
>
>> On Jun 22, 2015, at 10:47 AM, Duncan P. N. Exon Smith <dexonsmith at apple.com <mailto:dexonsmith at apple.com>> wrote:
>>
>> This makes sense. I don't have any better ideas. LGTM as is.
> Thanks. Landed 0001 as r240358.
>
> Starting to look at the next one. Trying to work out whether I can statically tell if A::foo != B::foo so that we know methods have been overridden. So far no luck but i’ll keep working on it.
>
> Cheers,
> Pete
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150622/2472fb1a/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002.patch
Type: application/octet-stream
Size: 19134 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150622/2472fb1a/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150622/2472fb1a/attachment-0001.html>
More information about the llvm-commits
mailing list