-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[MachinePipeliner] Detect a cycle in PHI dependencies early on #167095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
06c013f
68a3d5f
c2e7487
1060047
4354dd4
10698b7
f7084ce
0d0d3e1
9bac48e
a282ca4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -485,6 +485,56 @@ void MachinePipeliner::setPragmaPipelineOptions(MachineLoop &L) { | |||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| bool hasPHICycle(const MachineBasicBlock *LoopHeader, | ||||||||||||||||||||
| const MachineRegisterInfo &MRI) { | ||||||||||||||||||||
| DenseMap<unsigned, SmallVector<unsigned, 2>> PhiDeps; | ||||||||||||||||||||
| SmallSet<unsigned, 8> PhiRegs; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Collect PHI nodes and their dependencies | ||||||||||||||||||||
| for (const MachineInstr &MI : *LoopHeader) { | ||||||||||||||||||||
| if (!MI.isPHI()) | ||||||||||||||||||||
| continue; | ||||||||||||||||||||
quic-asaravan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| unsigned DefReg = MI.getOperand(0).getReg(); | ||||||||||||||||||||
| PhiRegs.insert(DefReg); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| for (unsigned i = 1; i < MI.getNumOperands(); i += 2) { | ||||||||||||||||||||
| unsigned SrcReg = MI.getOperand(i).getReg(); | ||||||||||||||||||||
| PhiDeps[DefReg].push_back(SrcReg); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
||||||||||||||||||||
| PhiRegs.insert(DefReg); | |
| for (unsigned i = 1; i < MI.getNumOperands(); i += 2) { | |
| unsigned SrcReg = MI.getOperand(i).getReg(); | |
| PhiDeps[DefReg].push_back(SrcReg); | |
| } | |
| auto Ite = PhiDeps.try_emplace(DefReg).first; | |
| for (unsigned i = 1; i < MI.getNumOperands(); i += 2) | |
| Ite->second.push_back(MI.getOperand(i).getReg()); |
To avoid repeated hash lookup.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to define a function like static bool foo(unsigned Reg, ...) rather than using std::function for recursive function.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider calling PhiDeps.find(Reg) instead and remove PhiRegs.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ; RUN: llc -mtriple=hexagon-unknown-linux-gnu -enable-pipeliner -debug-only=pipeliner < %s 2>&1 | FileCheck %s | ||
quic-asaravan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ; CHECK: Cannot pipeline loop due to PHI cycle | ||
|
|
||
| define void @phi_cycle_loop(i32 %a, i32 %b) { | ||
| entry: | ||
| br label %loop | ||
|
|
||
| loop: | ||
| %1 = phi i32 [ %a, %entry ], [ %3, %loop ] | ||
| %2 = phi i32 [ %a, %entry ], [ %1, %loop ] | ||
| %3 = phi i32 [ %b, %entry ], [ %2, %loop ] | ||
|
|
||
| ; Prevent PHI elimination by using all values | ||
| %add1 = add i32 %1, %2 | ||
| %add2 = add i32 %add1, %3 | ||
| %cmp = icmp slt i32 %add2, 100 | ||
| br i1 %cmp, label %loop, label %exit | ||
|
|
||
| exit: | ||
| ret void | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.