This is an archive of the discontinued LLVM Phabricator instance.

[Polly] Revise the simplification of regions
ClosedPublic

Authored by Meinersbur on Aug 8 2015, 10:53 AM.

Details

Reviewers
grosser
Summary

The previous code had several problems:

For newly created BasicBlocks it did not (always) call RegionInfo::setRegionFor in order to update its analysis. At the moment RegionInfo does not verify its BBMap, but will in the future. This is fixed by determining the region new BBs belong to and set it accordingly.

Which block is created by SplitEdge depends on the incoming and outgoing edges of the blocks it connects, which makes handling its output more difficult than it needs to be. Especially for finding which block has been created an to assign a region to it for the setRegionFor problem above. This patch uses an implementation for splitEdge that always creates a block between the predecessor and successor. simplifyRegion has also been simplified by using SplitBlockPredecessors instead of SplitEdge. Isolating the entries and exits have been refectored into individual functions.

Previously simplifyRegion did more than just ensuring that there is only one entering and one exiting edge. It ensured that the entering block had no other outgoing edge which was necessary for executeScopConditionally(). Now the latter uses the alternative splitEdge implementation which can handle this situation so simplifyRegion really only needs to simplify the region.

Also, executeScopConditionally assumed that there can be no PHI nodes in blocks with one incoming edge. This is wrong and LCSSA deliberately produces such edges. However, previous passes ensured that there can be no such PHIs in exit nodes, but which will no longer hold in the future.

In some cases the old code assigned the wrong entry/exit node to function. This happened in some circumstances if there were other edges from other regions to the exit node (could be a sibling or ancestor node) or edges from nested regions to the entry node. RegionInfo::splitBlock() made the latter mistake.

The new code that the property that it preserves the identity of region block (the property that the memory address of the BasicBlock containing the instructions remains the same; new blocks only contain PHI nodes and a terminator), especially the entry block. As a result, there is no need to update the reference to the BasicBlock of ScopStmt that contain its instructions because they have been moved to other basic blocks.

Diff Detail

Event Timeline

Meinersbur updated this revision to Diff 31585.Aug 8 2015, 10:53 AM
Meinersbur retitled this revision from to [Polly] Simplify the simplification of regions.
Meinersbur updated this object.
Meinersbur added a reviewer: grosser.
Meinersbur added a project: Restricted Project.
Meinersbur added a subscriber: pollydev.
grosser edited edge metadata.Aug 9 2015, 3:39 PM

Hi Michael,

Ensure that RegionInfo (setRegionFor) is updated, make the location of block creation stable (not dependent on unrelated edges) so there are fewer cases to consider and keep the identity of the region's entry block (ScopStmts do not need to be updated anymore).

This is a preparation to allow PHI nodes in exit blocks.

for such a large patch (500 new lines), the commit message is really short. Would it be possible to summarize the changes in this commit in a bit more detail (or give some context) and give some motivation on why they are needed?

Some questions I asked myself:

  1. Was the RegionInfo correct before and only the BB <-> Region was lacking or were there other issues with the RegionInfo that have been addressed. If only the BB <-> Region mapping was lacking, I would mention that only your recent changes to LLVM allow us to check and verify this mapping.

    (If this is indeed the only fix to the RegionInfo, than this part of the patch seems to be independent of the rest and should be submitted and discussed separately)
  1. "make the location of block creation stable (not dependent on unrelated edges) so there are fewer cases to consider"

Some context explaining the current problem, would help the reader to understand what the issue
is at the moment.

  1. "keep the identity of the region's entry block (ScopStmts do not need to be updated anymore)"

This seems a real improvement, but the readers likely lacks context to understand what exactly why ScopStms
had to be updated before and why the new approach does not require this any more.

I started to lock at the actual semantically complicated parts of the patch, but did not yet finish. It would probably help if you could add 2-3 sentences on how the way we split regions differs to what was done before and how this affects (or does not affect other ScoPs). This would make it easier to understand if this patch may invalidate assumptions that may have been taken in other parts of Polly.

Best,
Tobias

P.S: Thank you for the nice illustrative graphics and the extended documentation.

include/polly/Support/ScopHelper.h
86

The second part of the sentence seems incomplete.

108

grammar?

112

Suffix

114

LoopInfo

lib/CodeGen/Utils.cpp
27

Please drop the 'splitEdge -' part.

Also, I lack a comment that explains how the edge is actually spitted.

72

Why is there an if 0 section?

lib/Support/ScopHelper.cpp
249

Very nice illustrations

255

Why did you move around this function? This (unnecessarily?) bloats the diff.

268

LLVM suggests to use C++ style // comments. See http://llvm.org/docs/CodingStandards.html#comment-formatting.

I understand that just dropping the */ at the end of the line will cause a warning about multi-line comments due to the trailing '\', but you can probably just use another character between the '\' and the line ending to avoid this (not a space, as this gives trailing space warnings).

276

Too many spaces?

289

Why is RegionInfo commented out?

I can not find any use of this function. Is this code actually needed?

292

Grammar?

Meinersbur retitled this revision from [Polly] Simplify the simplification of regions to [Polly] Revise the simplification of regions.
Meinersbur updated this object.
Meinersbur edited edge metadata.
Meinersbur marked 8 inline comments as done.

Addressed comments
Remove conditional preprocessor blocks, fix some whitespace.

Meinersbur updated this object.Aug 10 2015, 10:44 AM

I started to lock at the actual semantically complicated parts of the patch, but did not yet finish. It would probably help if you could add 2-3 sentences on how the way we split regions differs to what was done before and how this affects (or does not affect other ScoPs). This would make it easier to understand if this patch may invalidate assumptions that may have been taken in other parts of Polly.

Sorry, but you have to understand the code by yourself. The illustrations should make it relatively easy to understand what it does and is relatively straigtforward. Regarding the way it was done before you have to to ask its author, as I found it too complicated.

What remains complicated is updating the RegionInfo. I tried to find an abstraction which would handle all cases (this is because there war a commented RegionInfo *RI in one parameter list), but did not find one.

lib/Support/ScopHelper.cpp
255

It tried to match the functions I rewrote with the order in the header (where I placed the new function splitBlock and splitBlockNonPredecessors at the end).

splitEntryBlockForAlloca only appears to have moved because this diff did not match it correctly.

268

As said, the standard is no absolute requirement and here I have reason to diverge from it.

Having stray characters in such lines look really awful and someone would probably wonder what they mean.

This comment style also has the benefit to be more stable in code editors and formatters (clang-format, Visual Studio).

289

Mmmh, at some intermediate point executeScopConditionally used it but it looks like simplified that function such that a call to this function wasn't necessary anymore.

In any case, the function is still needed for createExitingBlockForExitNodePHIs, but not yet in this patch.

Remove some outdated comments, add some new
Add some ASCII-graphs
Use llvm::predecessors where possible

grosser accepted this revision.Aug 10 2015, 2:04 PM
grosser edited edge metadata.

Hi Michael,

I went through the patch. Overall, it looks very good. Indeed, while reading the code, it seems it became
a lot more readable. I still found a couple of issues, but most of them are minor (often stylistic).

Now, while looking through the patch, it seems there are four independent changes:

  1. Introduce splitBlock and use it in splitEntryBlockForAlloca
  1. Introduce splitEdge and use it to simplify executeScopConditionally
  1. Rework simplifyRegion
  1. fixRegionInfo

Committing them separately might make each patch easier to understand and also makes clear which part of the commit message belongs to which changes.

lib/CodeGen/CodeGeneration.cpp
126

Was this not asserted three lines earlier already?

lib/CodeGen/Utils.cpp
47

The grammar of this comment and as a result the comment itself is unclear. Are you suggesting the use of SplitBlockPredecessors is not the best choice? It looks pretty reasonable to me. Unfortunately, I do not understand the other options.

80–81

OK, I now went through this function and it looks indeed a lot cleaner. Thank you again for restructuring this.

154

Uppercase, point.

159

Point

161

Originally, the blocks were saved in variables "SplitBlock" and "MergeBlock" and were named "split_new_and_old" and "merge_new_and_old".

The new code leaves the basic block names unchanged, but uses variable names JunctionBlock and MergeBlock and refers in the comments to these basic blocks with "fork" and "join". This seems inconsistent.

172

Point?

lib/Support/ScopHelper.cpp
79–80

Why is this change needed? The ternary condition you introduce seems redundant.

80

Why is this change needed? The ternary condition you introduce seems redundant.

85

Make this an assert?

107

'entry' does not belong here

206

assert?

208

Why is this change needed? The ternary condition you introduce seems redundant.

210

Why is this change needed? The ternary condition you introduce seems redundant.

223

Early return?

247

Why is this change needed? The ternary condition you introduce seems redundant.

249

Why is this change needed? The ternary condition you introduce seems redundant.

251

Why is this change needed? The ternary condition you introduce seems redundant.

268

I think LLVM is very consistent in avoiding these kind of comments. The only use I can find is to comment parameters in function calls.

If you look for the kind of graphics you add, the following have been used e.g.:

grep -R '\\ ' lib/

​ //    \ /    |
​ //    Old    |
​ //    / \    |
​ //    \ /    //
​ //    Old    //
​ //    / \    //
test/Isl/CodeGen/loop_with_conditional_entry_edge_splitted_hard_case.ll
1 ↗(On Diff #31701)

Why is this file executable (mode 755)?

This revision is now accepted and ready to land.Aug 10 2015, 2:04 PM
Meinersbur updated this revision to Diff 31801.Aug 11 2015, 6:21 AM
Meinersbur edited edge metadata.
Meinersbur marked 18 inline comments as done.

Rebased to trunk.
Addressed comments.
Made simplifyRegion parameters for each updated analysis
Privatized splitBlock since only used by splitEntryBlockForAlloca

Since this already got accepted, I will go on to commit it in 4 individual commits as suggested.

Meinersbur added inline comments.Aug 11 2015, 6:22 AM
lib/Support/ScopHelper.cpp
80

It's not required in the strict sense, but I like to keep it general, allowing for not passing the pass.

IMHO this function fits much better into RegionInfo.cpp. The RegionInfo comments mention the definition of a simple region, that it can be made simple, but there is no function there which does this.

Alternatively, we may pass DT, LI, RI as arguments as the other functions do.

223

I prefer this style here, which shows which conditions are valid at the end whatever case is taken, including the ASCII-graphs.

test/Isl/CodeGen/loop_with_conditional_entry_edge_splitted_hard_case.ll
1 ↗(On Diff #31701)

This comes from a Windows file system.

I renamed the file separately, so no issue anymore.

Hi Michael,

looking forward to see this change in. (Some replies to your final comments)

Best,
Tobias

lib/Support/ScopHelper.cpp
80

It's not required in the strict sense, but I like to keep it general, allowing for not passing the pass.

OK, so you want to generalize this. It probably helps if you explain this intention in the commit message.

IMHO this function fits much better into RegionInfo.cpp. The RegionInfo comments mention the definition of a simple region, that it can be made simple, but there is no function there which does this.

The problem is that RegionInfo.cpp is an analysis, not a transformation. If there is a need, we can at some point create some RegionUtils in LLVM and possibly also provide a pass that does region-simplification.

Alternatively, we may pass DT, LI, RI as arguments as the other functions do.

I have no strong opinion. I just dislike such kind of "cleanups" being mixed with larger refactorings as they just cause diff-noise which makes it hard to see the important changes. As separate changes, such things are trivial to review and easy to explain in the commit message. As you anyway factor out the cleanup of splitEntryBlockForAlloc, that should not be an issue any more.

223

OK.

I can't separate 2. and 3.

The new executeScopConditionally assumes that RegionInfo::getRegionFor is up-to-date that the old simplifyRegion does not do.

The new simplifyRegion does not make sure that the EnteringBB has just one exiting edge, a requirement for the old executeScopConditionally.

Meinersbur closed this revision.Aug 11 2015, 7:50 AM

Committed as r244600, r244606 and r244608