12 Commits

Author SHA1 Message Date
Ruiling, Song
54d31bde32
Reapply "StructurizeCFG: Optimize phi insertion during ssa reconstruction (#101301)" (#114347)
This reverts commit be40c723ce2b7bf2690d22039d74d21b2bd5b7cf.
2024-11-01 08:29:59 +08:00
Yaxun (Sam) Liu
be40c723ce Revert "StructurizeCFG: Optimize phi insertion during ssa reconstruction (#101301)"
This reverts commit c62e2a2a4ed69d53a3c6ca5c24ee8d2504d6ba2b.

Since it caused regression in HIP buildbot:

https://lab.llvm.org/buildbot/#/builders/123/builds/3282
2024-08-08 11:59:39 -04:00
Ruiling, Song
c62e2a2a4e
StructurizeCFG: Optimize phi insertion during ssa reconstruction (#101301)
After investigating more while-break cases, I think we should try to
optimize
the way we reconstruct phi nodes. Previously, we reconstruct each phi 
nodes separately, but this is not optimal. For example:

```
header:
  %v.1 = phi float [ %v, %entry ], [ %v.2, %latch ]
  br i1 %cc, label %if, label %latch

if:
  %v.if = fadd float %v.1, 1.0 
  br i1 %cc2, label %latch, label %exit

latch:
  %v.2 = phi float [ %v.if, %if ], [ %v.1, %header ]
  br i1 %cc3, label %exit, label %header

exit:
  %v.3 = phi float [ %v.2, %latch ], [ %v.if, %if ]
```

For this case, we have different copies of value `v`, but there is at
most one copy of value `v` alive at any program point shown above.

The existing ssa reconstruction will use the incoming values from the 
old deleted phi. Below is a possible output after ssa reconstruction.

```
header:
  %v.1 = phi float [ %v, %entry ], [ %v.loop, %Flow1 ]
  br i1 %cc, label %if, label %flow

if:
  %v.if = fadd float %v.1, 1.0 
  br label %flow

flow:
  %v.exit.if = phi float [ %v.if, %if ], [ undef, %header ]
  %v.latch = phi float [ %v.if, %if ], [ %v.1, %header ]

latch:
  br label %flow1

flow1:
  %v.loop = phi float [ %v.latch, %latch ], [ undef, %Flow ]
  %v.exit = phi float [ %v.latch, %latch ], [ %v.exit.if, %Flow ]

exit:
  %v.3 = phi float [ %v.exit, %flow1 ]
```

If we look closely, in order to reconstruct `v.1` `v.2` `v.3`, we are 
having two simultaneous copies of `v` alive at `flow` and `flow1`.
We highly depend on register coalescer to coalesce them together.
But register coalescer may not always be able to coalesce them
because of the complexity in the chain of phi.

On the other side, now that we have only one copy of `v` alive at any 
program point before the transform, why not simplify the phi network
as much as we can? Look at the incoming values of these PHIs:
```
      header    if     latch
v.1:   --       --      v.2 
v.2:   v.1      v.if    --  
v.3:   --       v.if    v.2 
```
If we let them share the same incoming values for these three different
incoming blocks, then we would have only one copy of alive `v` at any 
program point after ssa reconstruction. Something like:

```
header:
  %v.1 = phi float [ %v, %entry ], [ %v.2, %Flow1 ]
  br i1 %cc, label %if, label %flow

if:
  %v.if = fadd float %v.1, 1.0 
  br label %flow

flow:
  %v.2 = phi float [ %v.if, %if ], [ %v.1, %header ]

latch:
  br label %flow1

flow1:
  ...

exit:
  %v.3 = phi float [ %v.2, %flow1 ]
```
2024-08-08 14:47:49 +08:00
Matt Arsenault
bf6f82a9df StructurizeCFG: Convert tests to opaque pointers 2022-11-27 20:26:16 -05:00
Ruiling Song
40e9284f3c StructurizeCFG: prefer reduced number of live values
The instruction simplification will try to simplify the affected phis.
In some cases, this might extend the liveness of values. For example:

  BB0:
   | \
   | BB1
   | /
  BB2:phi (BB0, v), (BB1, undef)

The phi in BB2 will be simplified to v as v dominates BB2, but this is
increasing the number of active values in BB1. By setting CanUseUndef
to false, we will not simplify the phi in this way, this would help
register pressure. This is mandatory for the later change to help
reducing VGPR pressure for AMDGPU.

Reviewed by: foad, sameerds

Differential Revision: https://reviews.llvm.org/D132449
2022-09-26 09:54:47 +08:00
Jay Foad
d2e5d3512b [StructurizeCFG] Clean up some boolean not instructions
In some cases StructurizeCFG inserts i1 xor instructions to invert
predicates. Add a quick loop to clean these up afterwards if we can get
away with modifying an existing compare instruction instead.
(StructurizeCFG is generally run late in the pipeline so instcombine
does not clean them up for us.)

Differential Revision: https://reviews.llvm.org/D118623
2022-02-01 09:35:37 +00:00
Jay Foad
8faad29634 Revert "[Local] invertCondition: try modifying an existing ICmpInst"
This reverts commit a6b54ddaba2d5dc0f72dcc4591c92b9544eb0016.

Apparently it is not safe to modify the condition even if it passes the
hasOneUse test, because StructurizeCFG might have other references to
the condition that are not manifest in the IR use-def chains.
2022-01-31 14:55:36 +00:00
Jay Foad
a6b54ddaba [Local] invertCondition: try modifying an existing ICmpInst
This avoids various cases where StructurizeCFG would otherwise insert an
xor i1 instruction, and it since it generally runs late in the pipeline,
instcombine does not clean up the xor-of-cmp pattern.

Differential Revision: https://reviews.llvm.org/D118478
2022-01-31 10:44:17 +00:00
Sameer Sahasrabuddhe
42febbab91 StructurizeCFG: simplify phi nodes when possible
After structurization, some phi nodes can have a single incoming edge
and can be simplified away. This change runs a simplify query on all
phis that are either modified or added by the structurizer. This also
moves some phis closer to their use as a side benefit.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D75500
2020-03-05 10:33:15 +05:30
Eric Christopher
cee313d288 Revert "Temporarily Revert "Add basic loop fusion pass.""
The reversion apparently deleted the test/Transforms directory.

Will be re-reverting again.

llvm-svn: 358552
2019-04-17 04:52:47 +00:00
Eric Christopher
a863435128 Temporarily Revert "Add basic loop fusion pass."
As it's causing some bot failures (and per request from kbarton).

This reverts commit r358543/ab70da07286e618016e78247e4a24fcb84077fda.

llvm-svn: 358546
2019-04-17 02:12:23 +00:00
Changpeng Fang
5f9154618e StructurizeCFG: Adjust the loop depth for a subregion to order the nodes correctly
Summary:
  StructurizeCFG::orderNodes basically uses a reverse post-order (RPO) traversal of the region list to get the order.
The only problem with it is that sometimes backedges for outer loops will be visited before backedges for inner loops.
To solve this problem, a loop depth based approach has been used to make sure all blocks in this loop has been visited
before moving on to outer loop.

However, we found a problem for a SubRegion which is a loop itself:

--> BB1 --> BB2 --> BB3 -->

In this case, BB2 is a SubRegion (loop), and thus its loopdepth is different than that of BB1 and BB3. This fact will lead
BB2 to be placed in the wrong order.

In this work, we treat the SubRegion as a special case and use its exit block to determine the loop and its depth
to guard the sorting.

Reviewers:
  arsenm, jlebar

Differential Revision:
  https://reviews.llvm.org/D46912

llvm-svn: 333111
2018-05-23 18:34:48 +00:00