From 8c07d0c42c78cb698a10036eaf88ea689962b298 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 26 Mar 2018 16:58:40 +0000 Subject: [PATCH] [Pipeliner] Check for affine expression in isLoopCarriedOrder The pipeliner must add a loop carried dependence between two memory operations if the base register is not an affine (linear) exression. The current implementation doesn't check how the base register is defined, which allows non-affine expressions, and then the pipeliner does not add a loop carried dependence when one is needed. This patch adds code to isLoopCarriedOrder that checks if the base register of the memory operations is defined by a phi, and the loop definition for the phi is a constant increment value. This is a very simple check for a linear expression. Patch by Brendon Cahoon. llvm-svn: 328550 --- llvm/lib/CodeGen/MachinePipeliner.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp index 8015eda..c7c5a4a 100644 --- a/llvm/lib/CodeGen/MachinePipeliner.cpp +++ b/llvm/lib/CodeGen/MachinePipeliner.cpp @@ -2647,7 +2647,6 @@ void SwingSchedulerDAG::generateExistingPhis( unsigned NumPhis = std::min(NumStages, MaxPhis); unsigned NewReg = 0; - unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled; // In the epilog, we may need to look back one stage to get the correct // Phi name because the epilog and prolog blocks execute the same stage. @@ -3562,6 +3561,19 @@ bool SwingSchedulerDAG::isLoopCarriedDep(SUnit *Source, const SDep &Dep, if (BaseRegS != BaseRegD) return true; + // Check that the base register is incremented by a constant value for each + // iteration. + MachineInstr *Def = MRI.getVRegDef(BaseRegS); + if (!Def || !Def->isPHI()) + return true; + unsigned InitVal = 0; + unsigned LoopVal = 0; + getPhiRegs(*Def, BB, InitVal, LoopVal); + MachineInstr *LoopDef = MRI.getVRegDef(LoopVal); + int D = 0; + if (!LoopDef || !TII->getIncrementValue(*LoopDef, D)) + return true; + uint64_t AccessSizeS = (*SI->memoperands_begin())->getSize(); uint64_t AccessSizeD = (*DI->memoperands_begin())->getSize(); -- 2.7.4