This is an archive of the discontinued LLVM Phabricator instance.

[WPD] Extend checking mode to support fallback to indirect call
ClosedPublic

Authored by tejohnson on Mar 10 2022, 3:15 PM.

Details

Summary

Extend -wholeprogramdevirt-check to support both the existing
trapping mode on an incorrect devirtualization, as well as a new
mode to fallback to an indirect call on a mismatch. The new mode is

The new mode is useful in cases where we want to enable
devirtualization but cannot fully guarantee whole program visibility
(e.g in the case where LTO has been disabled for a small set of objects
that could potentially override virtual methods without having a symbol
reference to anything in the base class including the vtable).

Diff Detail

Event Timeline

tejohnson created this revision.Mar 10 2022, 3:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 10 2022, 3:15 PM
tejohnson requested review of this revision.Mar 10 2022, 3:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 10 2022, 3:15 PM
mingmingl accepted this revision.Mar 10 2022, 5:33 PM

It occurred to me that the WPD internal doc also mentions --wholeprogramdevirt-check, and current example uses it as a boolean.

Overall changing type of a debugging option makes sense (users would be able to figure out if they see an error, and there are enough time to update g3doc before a release)

llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
84

nit pick

I'm wondering if it's more conventional to keep examples [1] in cpp or in the header (both are pretty readable IMO)

[1] https://github.com/llvm/llvm-project/blob/fc968bcba4d7e02390f1c1cba76a6a2cad1ae59f/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp#L195-L281

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
1174

llvm::promoteCall [1] clears two types of metadata and then compares function type.

Function types are the same (for virtual functions); I'm wondering if it's needed to clear two types of metadata here (for my understanding)

[1] https://github.com/llvm/llvm-project/blob/fc968bcba4d7e02390f1c1cba76a6a2cad1ae59f/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp#L456

This revision is now accepted and ready to land.Mar 10 2022, 5:33 PM
tejohnson updated this revision to Diff 414665.Mar 11 2022, 8:10 AM

Address comments

In D121419#3374225, @luna wrote:

It occurred to me that the WPD internal doc also mentions --wholeprogramdevirt-check, and current example uses it as a boolean.

Yep, I'll be updating the internal doc - afaik no one is using it (was previously just used by me for debugging).

llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
84

Not sure of the convention, but I wanted to keep the comment block in the header reasonable and similar in size to the existing ones. The examples comment block in the source file is really large for this function. I'll keep it there for now.

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
1174

Good catch. Looks like leaving this metadata on direct calls doesn't cause any issues, since it hasn't been stripped for the normal WPD (non-fallback) case before. But it causes a real issue when left on the fallback indirect case in the new handling, because ICP will come along and promote again. This isn't a correctness issue, but could bloat codesize - although in the case I tested the optimizer smartly merged the redundant promoted direct calls. But I have fixed it in all cases (fallback and for the direct calls under all options) and added tests for all of these cases.

mingmingl accepted this revision.Mar 11 2022, 12:03 PM
In D121419#3374225, @luna wrote:

It occurred to me that the WPD internal doc also mentions --wholeprogramdevirt-check, and current example uses it as a boolean.

Yep, I'll be updating the internal doc - afaik no one is using it (was previously just used by me for debugging).

Thanks for making the change!

llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
84

Not sure of the convention, but I wanted to keep the comment block in the header reasonable and similar in size to the existing ones. The examples comment block in the source file is really large for this function. I'll keep it there for now.

Yeah the current way is reasonable and readable, so sounds good to keep it as is.

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
1174

thanks for figuring it out and making the fix!

This revision was landed with ongoing or failed builds.Mar 14 2022, 10:16 AM
This revision was automatically updated to reflect the committed changes.