[llvm] r311332 - [PowerPC] Check if the pre-increment PHI Node already exists

Stefan Pintilie via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 21 06:36:18 PDT 2017


Author: stefanp
Date: Mon Aug 21 06:36:18 2017
New Revision: 311332

URL: http://llvm.org/viewvc/llvm-project?rev=311332&view=rev
Log:
[PowerPC] Check if the pre-increment PHI Node already exists

Preparations to use the per-increment are sometimes done in the target
independent pass Loop Strength Reduction. We try to detect them in the PowerPC
specific pass so that they are not done twice and so that we do not add PHIs
that are not required.

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

Added:
    llvm/trunk/test/CodeGen/PowerPC/ppc64-pre-inc-no-extra-phi.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp?rev=311332&r1=311331&r2=311332&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp Mon Aug 21 06:36:18 2017
@@ -28,6 +28,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionExpander.h"
@@ -61,6 +62,8 @@ static cl::opt<unsigned> MaxVars("ppc-pr
                                  cl::Hidden, cl::init(16),
   cl::desc("Potential PHI threshold for PPC preinc loop prep"));
 
+STATISTIC(PHINodeAlreadyExists, "PHI node already in pre-increment form");
+
 namespace llvm {
 
   void initializePPCLoopPreIncPrepPass(PassRegistry&);
@@ -88,6 +91,9 @@ namespace {
       AU.addRequired<ScalarEvolutionWrapperPass>();
     }
 
+    bool alreadyPrepared(Loop *L, Instruction* MemI,
+                         const SCEV *BasePtrStartSCEV,
+                         const SCEVConstant *BasePtrIncSCEV);
     bool runOnFunction(Function &F) override;
 
     bool runOnLoop(Loop *L);
@@ -177,6 +183,62 @@ bool PPCLoopPreIncPrep::runOnFunction(Fu
   return MadeChange;
 }
 
+// In order to prepare for the pre-increment a PHI is added.
+// This function will check to see if that PHI already exists and will return
+//  true if it found an existing PHI with the same start and increment as the
+//  one we wanted to create.
+bool PPCLoopPreIncPrep::alreadyPrepared(Loop *L, Instruction* MemI,
+                                        const SCEV *BasePtrStartSCEV,
+                                        const SCEVConstant *BasePtrIncSCEV) {
+  BasicBlock *BB = MemI->getParent();
+  if (!BB)
+    return false;
+
+  BasicBlock *PredBB = L->getLoopPredecessor();
+  BasicBlock *LatchBB = L->getLoopLatch();
+
+  if (!PredBB || !LatchBB)
+    return false;
+
+  // Run through the PHIs and see if we have some that looks like a preparation
+  iterator_range<BasicBlock::phi_iterator> PHIIter = BB->phis();
+  for (auto & CurrentPHI : PHIIter) {
+    PHINode *CurrentPHINode = dyn_cast<PHINode>(&CurrentPHI);
+    if (!CurrentPHINode)
+      continue;
+
+    if (!SE->isSCEVable(CurrentPHINode->getType()))
+      continue;
+
+    const SCEV *PHISCEV = SE->getSCEVAtScope(CurrentPHINode, L);
+
+    const SCEVAddRecExpr *PHIBasePtrSCEV = dyn_cast<SCEVAddRecExpr>(PHISCEV);
+    if (!PHIBasePtrSCEV)
+      continue;
+
+    const SCEVConstant *PHIBasePtrIncSCEV =
+      dyn_cast<SCEVConstant>(PHIBasePtrSCEV->getStepRecurrence(*SE));
+    if (!PHIBasePtrIncSCEV)
+      continue;
+
+    if (CurrentPHINode->getNumIncomingValues() == 2) {
+      if ( (CurrentPHINode->getIncomingBlock(0) == LatchBB &&
+            CurrentPHINode->getIncomingBlock(1) == PredBB) ||
+            (CurrentPHINode->getIncomingBlock(1) == LatchBB &&
+            CurrentPHINode->getIncomingBlock(0) == PredBB) ) {
+        if (PHIBasePtrSCEV->getStart() == BasePtrStartSCEV &&
+            PHIBasePtrIncSCEV == BasePtrIncSCEV) {
+          // The existing PHI (CurrentPHINode) has the same start and increment
+          //  as the PHI that we wanted to create.
+          ++PHINodeAlreadyExists;
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
 bool PPCLoopPreIncPrep::runOnLoop(Loop *L) {
   bool MadeChange = false;
 
@@ -347,6 +409,9 @@ bool PPCLoopPreIncPrep::runOnLoop(Loop *
 
     DEBUG(dbgs() << "PIP: New start is: " << *BasePtrStartSCEV << "\n");
 
+    if (alreadyPrepared(L, MemI, BasePtrStartSCEV, BasePtrIncSCEV))
+      continue;
+
     PHINode *NewPHI = PHINode::Create(I8PtrTy, HeaderLoopPredCount,
       MemI->hasName() ? MemI->getName() + ".phi" : "",
       Header->getFirstNonPHI());

Added: llvm/trunk/test/CodeGen/PowerPC/ppc64-pre-inc-no-extra-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc64-pre-inc-no-extra-phi.ll?rev=311332&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc64-pre-inc-no-extra-phi.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc64-pre-inc-no-extra-phi.ll Mon Aug 21 06:36:18 2017
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs | FileCheck %s
+
+ at perm = common local_unnamed_addr global [100 x i64] zeroinitializer, align 8
+
+define void @sort_basket() local_unnamed_addr {
+entry:
+  br label %while.cond
+
+while.cond:
+  %l.0 = phi i64 [ 0, %entry ], [ %inc, %while.cond ]
+  %arrayidx = getelementptr inbounds [100 x i64], [100 x i64]* @perm, i64 0, i64 %l.0
+  %0 = load i64, i64* %arrayidx, align 8
+  %cmp = icmp sgt i64 %0, 0
+  %inc = add nuw nsw i64 %l.0, 1
+  br i1 %cmp, label %while.cond, label %while.end
+
+while.end:
+  store i64 0, i64* %arrayidx, align 8
+  ret void
+; CHECK-LABEL: sort_basket
+; CHECK: addi {{[0-9]+}}, {{[0-9]+}}, -8
+; CHECK-NOT: addi {{[0-9]+}}, {{[0-9]+}}, 8
+; CHECK: ldu {{[0-9]+}}, 8({{[0-9]+}})
+; CHECK-NOT: addi {{[0-9]+}}, {{[0-9]+}}, 8
+; CHECK: blr
+}
+




More information about the llvm-commits mailing list