This is an archive of the discontinued LLVM Phabricator instance.

[OpenMP][OMPIRBuilder][BugFix] Handle Unreachable Finalization blocks in `parallel` generation
AbandonedPublic

Authored by fghanim on Jan 23 2020, 11:34 AM.

Details

Reviewers
jdoerfert
Summary

In some situations (e.g. while(1); ) the body block(s) will not contain a branch to the finalization block.
In this patch, CreateParallel has been modified to check if the PRegPreFiniBB is reachable before
generating finalization code. If not, will remove all unreachable blocks.

Event Timeline

fghanim created this revision.Jan 23 2020, 11:34 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJan 23 2020, 11:34 AM
fghanim updated this revision to Diff 239991.Jan 23 2020, 1:10 PM
  • Cleaning up some leftover code.
fghanim updated this revision to Diff 240451.EditedJan 26 2020, 11:33 AM

Adding a new unittest for the this fix. Thanks to JDoerfert for Writing and providing me with this patch.

fghanim updated this revision to Diff 240886.Jan 28 2020, 7:31 AM

Adding lit test to clang for testing the fix

fghanim updated this revision to Diff 240949.Jan 28 2020, 11:10 AM
  • Squashing all the commits
jdoerfert added inline comments.Jan 28 2020, 11:25 AM
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
685

Why do we need all of this? Can't we just *not do it* instead? This is code complexity that we should avoid.

fghanim marked an inline comment as done.Jan 28 2020, 1:24 PM
fghanim added inline comments.
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
685

Depends.
If we want to conform with the way things are done in clang; namely, not have unreachable blocks, then yes we need to do this. If not, then no, nothing needs to change. An optimization pass will be executed at some point later that should clean all that up.

However, we should be careful, for example, The lit test for critical checks that no basic blocks were generated from the rest of the body that comes after the infinite loop. So if the choice is to not conform with clang, then we should keep an eye on these lit tests, and disable such checks for the OMPBuilder.

jdoerfert added inline comments.Jan 28 2020, 2:48 PM
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
685

If we want to conform with the way things are done in clang;

It's not like we introduce much extra code, break anything, or make the final result different.

If not, then no, nothing needs to change. An optimization pass will be executed at some point later that should clean all that up.

Let's go with that solution and keep this code here simple, less error prone, and easier to manage.

However, we should be careful, for example, The lit test for critical checks that no basic blocks were generated from the rest of the body that comes after the infinite loop. So if the choice is to not conform with clang, then we should keep an eye on these lit tests, and disable such checks for the OMPBuilder.

We already do things different and that will only become more evident (TRegions!). For example, to simplify this code we do *not* cache runtime calls (anymore). That is we emit a new get_thread_id call every time. (We know the OpenMPOpt pass will clean it up eventually.) I get that the tests change and for a while we will have clang and OMPBuilder check lines. Though, once the clang CG is gone there is arguably no difference anymore because the OMPBuilder behavior is then the default. As soon as we have the privatization parts properly hooked up we can even start running the OMPBuilder by default and soon after removing clang CG parts. If anything, we should modernize the clang tests as they are a constant critique point that hinders outside involvement. We could start using the llvm/utils/update_XXXX_checks scripts for example. We could also minimize the check lines and focus on the most important bits only. (I prefer the update scripts with the pending extensions, e.g., D69701)

fghanim marked an inline comment as done.Jan 29 2020, 6:15 AM
fghanim added inline comments.
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
685

In that case, This revision is not necessary. The only fix needed is the branch erasure/creation change in the body CallBack (a bit more on this later), all the rest including the tests is not necessary. The only tests needed are already being done by the llvm verifier, which already reports if a BB is used by an orphan branch sticking around, or if a BB contains more than one terminator.

Regarding the issue of the branch, given that our finalization and body callbacks are very similar across different directives (Parallel, master, critical), the plan as we discussed on D72304 , is to write helper functions/class that we could use instead. So whoever, ends up writing that should make sure to include the branch changes, which makes them here redundant.

So, in the interest of everyone's time, my suggestion is to abandon this revision entirely for now, and just make sure that the implementation of these helper functions takes care of this everywhere.

fghanim abandoned this revision.Feb 24 2020, 7:32 AM

The bug this revision attempted to fix has been resolved as part of patch D74562