diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachinePipeliner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachinePipeliner.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp index 9bd07da..99d582c 100644 --- a/llvm/lib/CodeGen/MachinePipeliner.cpp +++ b/llvm/lib/CodeGen/MachinePipeliner.cpp @@ -3297,6 +3297,32 @@ bool SMSchedule::normalizeNonPipelinedInstructions( << ") is not pipelined; moving from cycle " << OldCycle << " to " << NewCycle << " Instr:" << *SU.getInstr()); } + + // We traverse the SUs in the order of the original basic block. Computing + // NewCycle in this order normally works fine because all dependencies + // (except for loop-carried dependencies) don't violate the original order. + // However, an artificial dependency (e.g., added by CopyToPhiMutation) can + // break it. That is, there may be exist an artificial dependency from + // bottom to top. In such a case, NewCycle may become too large to be + // scheduled in Stage 0. For example, assume that Inst0 is in DNP in the + // following case: + // + // | Inst0 <-+ + // SU order | | artificial dep + // | Inst1 --+ + // v + // + // If Inst1 is scheduled at cycle N and is not at Stage 0, then NewCycle of + // Inst0 must be greater than or equal to N so that Inst0 is not be + // scheduled at Stage 0. In such cases, we reject this schedule at this + // time. + // FIXME: The reason for this is the existence of artificial dependencies + // that are contradict to the original SU order. If ignoring artificial + // dependencies does not affect correctness, then it is better to ignore + // them. + if (FirstCycle + InitiationInterval <= NewCycle) + return false; + NewLastCycle = std::max(NewLastCycle, NewCycle); } LastCycle = NewLastCycle; |