This is an archive of the discontinued LLVM Phabricator instance.

Delay initialization of OptBisect
ClosedPublic

Authored by kparzysz on Jun 18 2021, 10:33 AM.

Details

Summary

When LLVM is used in other projects, it may happen that global constructors will execute before the call to ParseCommandLineOptions. [Thanks to @dblaikie for the correction.]

In a project I'm working with there are multiple LLVM codegen executions (targeting different architectures). The OptBisect object is initialized (via a constructor) the first time it's queried by skipFunction, and has no ability to be updated at a later time.

When debugging codegen for the second target, passing -opt-bisect-limit to ParseCommandLineOptions will no longer have any effect if it takes place after the OptBisect object has already been created.

To avoid this problem use a cl::cb (callback) to set the bisection limit when the option is actually processed.

Diff Detail

Event Timeline

kparzysz created this revision.Jun 18 2021, 10:33 AM
kparzysz requested review of this revision.Jun 18 2021, 10:33 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 18 2021, 10:33 AM
This revision was not accepted when it landed; it landed in state Needs Review.Jun 18 2021, 11:15 AM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
kparzysz reopened this revision.Jun 18 2021, 11:16 AM

Committed by accident.

What situation are you dealing with where OptBisect is created during global constructors? OptBisect uses ManagedStatic which only creates the object on first access, right? So maybe it'd be suitable to change the code so it doesn't try to access OptBisect during global construction?

kparzysz edited the summary of this revision. (Show Details)Jun 22 2021, 7:08 AM
kparzysz added a comment.EditedJun 22 2021, 7:12 AM

Sorry, I was incorrect in my original statement. I have fixed it.

Sorry, I was incorrect in my original statement. I have fixed it.

Ah, thanks - maybe that's a motivation/opportunity to revisit the design here and make it more scalable. Moving this state into the LLVMContext, for instance, if possible? (I guess most of these choices were considered in the past - but with new use cases it might motivate re-examining & trying a bit more to find ways to avoid this global mutable state)

I'm open to that, but it would likely take a while to come up with, and implement an alternative.

Would you be opposed to merging this as a workaround for the time being?

I'm open to that, but it would likely take a while to come up with, and implement an alternative.

Would you be opposed to merging this as a workaround for the time being?

Oh, I'm only offering suggestions, not mandates/requirements - I'll leave it up to folks more familiar with OptBisect to offer approvals/disapprovals, etc.

Sorry for the non-response, I hadn't notice this review earlier.

Can you describe the flow of execution that causes the option to be parsed after the bisector is initialized? Do you parse the options, run passes, and then parse a different set of options for the second target within the same compilation process? Does your patch need to reset CurBisectNum?

Yes, that's exactly what happens. The project uses LLVM as a code generator for multiple targets. The OptBisector object is constructed the first time it's queried by shouldRunPass, which happened during the code generation for the first target. We set up the second target by passing some extra flags to ParseCommandLineOptions, but passing -opt-bisect-limit at this time no longer has any effect (i.e. the setting from the construction time remains).

Yes, that's exactly what happens. The project uses LLVM as a code generator for multiple targets. The OptBisector object is constructed the first time it's queried by shouldRunPass, which happened during the code generation for the first target. We set up the second target by passing some extra flags to ParseCommandLineOptions, but passing -opt-bisect-limit at this time no longer has any effect (i.e. the setting from the construction time remains).

That case is more complex than opt-bisect was originally designed for, but I guess if you have a way to independently specify the bisect limit for each target, you should be able to make it work. To make the implementation more general, I'd suggest that the CurBisectNum should be reset between the targets and probably any time the limit is changed.

Replacing the default OptBisect with a custom OptGate might be a better solution. That said, I wouldn't be opposed to your current change as a quick and possibly temporary solution if you add something to reset the counter.

kparzysz updated this revision to Diff 363167.Jul 30 2021, 11:42 AM

Added resetting of the counter when new limit is set.

kparzysz updated this revision to Diff 363176.Jul 30 2021, 12:02 PM

Added definition of OptBisect::Disabled.

This revision is now accepted and ready to land.Aug 4 2021, 10:13 AM
This revision was automatically updated to reflect the committed changes.