This is an archive of the discontinued LLVM Phabricator instance.

Emiting invariant.group.barrier and adding -fstrict-vptrs
ClosedPublic

Authored by Prazek on Aug 24 2015, 8:54 PM.

Diff Detail

Event Timeline

Prazek updated this revision to Diff 33045.Aug 24 2015, 8:54 PM
Prazek retitled this revision from to Emiting invariant.group.barrier and adding -fstrict-vptrs .
Prazek updated this object.
Prazek added reviewers: rsmith, rjmccall, majnemer, nlewycky.
Prazek added a subscriber: cfe-commits.

@rsmith I wonder If we have to put invariant.group.barrier when we call regular new expression

rjmccall edited edge metadata.Aug 25 2015, 12:10 PM

You should add a test that actually checks that your feature works.

lib/CodeGen/CGClass.cpp
1289

Should this just be in InitializeVTablePointers?

Prazek added inline comments.Aug 27 2015, 2:52 PM
lib/CodeGen/CGClass.cpp
1289

I want to add invariant.group.barrier only if it's needed. F.e. I don't want to put before I initialize vptrs for base, or when my class doesn't inherit frome anything. I want emit barrier after I will initialize some other vptrs.

InitializeVptrs is called in EmitBaseInitializer, and also I woudnt want to put some extra flag if it must produce barrier or not (because it is hard to distinguish it from inside)

rjmccall added inline comments.Aug 27 2015, 3:49 PM
include/clang/Driver/Options.td
991

This needs documentation for the --help output, something like "Enable optimizations based on the strict rules for overwriting polymorphic C++ objects".

This option should eventually be promoted to be a driver option, so we might as well figure out the name now. I'd rather not introduce "vptr" to the user lexicon. I suggest -fstrict-vtable-pointers.

lib/CodeGen/CGClass.cpp
1289

Fair enough.

Do we need to emit these barriers in unoptimized builds?

1501

Grammar: "Insert the llvm.invariant.group.barrier intrinsic before initializing the vptrs to cancel any previous assumptions we might have made."

Prazek added inline comments.Aug 27 2015, 4:00 PM
include/clang/Driver/Options.td
991

works for me, if anyone will not come up with better name (or say that the previous name was better) I will change it to fstrict-vtable-pointers

lib/CodeGen/CGClass.cpp
1289

It depends - if we will not add invariant.group metadata to loads/stores without optimizations, then we can not add theis invariant barrier stuff.
My question is, if I will run clang

clang++ stuff.cpp -O0 -fstrict-vptrs

does it mean, that I don't want any optimizations, or it means that I don't want any optimizations except strict-vptrs?
If answer is second one, then I think not checking for optimizations is fine (If we will change it to be default, then we will have to add Optmizations turned check)

rjmccall added inline comments.Aug 27 2015, 10:45 PM
lib/CodeGen/CGClass.cpp
1289

Well, we're not actually going to do the optimizations at -O0 in any case, and "please emit the information necessary to do the optimizations without actually doing them" is not an intermediate state that users actually want.

The basic problem here continues to be that, as designed, this optimization is unsound without cooperation from every module that emitted any IR. In order for this optimization to qualify as a non-experimental feature, you will need to actually fix that so that it decays gracefully in the presence of a non-cooperating module. Once you do that, it will also be reasonable to omit these barriers at -O0.

When we talked about this before, we had a workable, if conservative, plan for how to implement that graceful decay: you need to tag cooperating functions and then untag them when information is merged (e.g. by the inliner) from non-cooperating functions. Do you still see that as practical?

Prazek marked 3 inline comments as done.Sep 1 2015, 6:15 PM
Prazek added inline comments.
lib/CodeGen/CGClass.cpp
1289

Ok, I think I won't add invariant.barrier with O0.

I want to concentrate on !invariant.group optimization more now, so for now the plan is this:

if we are in O0, then we don't care at all about invariant.group.barrier, we just skip emiting it.
If we are in opt, and fstrict-vtable-pointers is true, then we will add module metadata about it
and when LTO will try to link 2 modules
one with strict-vptrs and one without
then for now, we can just raise an error.
In the future we can strip invariant stuff from module without flag.

Because optimizer doesn't care about invariant.group.barrier now, I will add module metadata in next patch.

Prazek updated this revision to Diff 33775.Sep 1 2015, 6:41 PM
Prazek updated this object.
Prazek edited edge metadata.

LGTM.

lib/CodeGen/CGClass.cpp
1234

"Initializer"

But I think you can just inline this into the one call site as BaseInit->getType()->getAsCXXRecordDecl()->isDynamicClass().

Prazek marked an inline comment as done.Sep 15 2015, 2:47 PM
Prazek accepted this revision.Sep 15 2015, 2:47 PM
Prazek added a reviewer: Prazek.

Accept to close

This revision is now accepted and ready to land.Sep 15 2015, 2:47 PM
Prazek closed this revision.Sep 15 2015, 2:48 PM