[llvm] r338346 - [VPlan] Introduce VPLoopInfo analysis.

Diego Caballero via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 30 18:57:29 PDT 2018


Author: dcaballe
Date: Mon Jul 30 18:57:29 2018
New Revision: 338346

URL: http://llvm.org/viewvc/llvm-project?rev=338346&view=rev
Log:
[VPlan] Introduce VPLoopInfo analysis.

The patch introduces loop analysis (VPLoopInfo/VPLoop) for VPBlockBases.
This analysis will be necessary to perform some H-CFG transformations and
detect and introduce regions representing a loop in the H-CFG.

Reviewers: fhahn, rengolin, mkuper, hfinkel, mssimpso

Reviewed By: fhahn 

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


Added:
    llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h   (with props)
    llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp   (with props)
Modified:
    llvm/trunk/lib/Transforms/Vectorize/VPlan.h
    llvm/trunk/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
    llvm/trunk/unittests/Transforms/Vectorize/CMakeLists.txt

Modified: llvm/trunk/lib/Transforms/Vectorize/VPlan.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/VPlan.h?rev=338346&r1=338345&r2=338346&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/VPlan.h (original)
+++ llvm/trunk/lib/Transforms/Vectorize/VPlan.h Mon Jul 30 18:57:29 2018
@@ -26,6 +26,7 @@
 #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
 #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
 
+#include "VPlanLoopInfo.h"
 #include "VPlanValue.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DepthFirstIterator.h"
@@ -52,7 +53,6 @@ class BasicBlock;
 class DominatorTree;
 class InnerLoopVectorizer;
 class InterleaveGroup;
-class LoopInfo;
 class raw_ostream;
 class Value;
 class VPBasicBlock;
@@ -527,6 +527,13 @@ public:
     // support for VPInstructions/Recipes.
     printAsOperand(OS, false);
   }
+
+  /// Return true if it is legal to hoist instructions into this block.
+  bool isLegalToHoistInto() {
+    // There are currently no constraints that prevent an instruction to be
+    // hoisted into a VPBlockBase.
+    return true;
+  }
 };
 
 /// VPRecipeBase is a base class modeling a sequence of one or more output IR
@@ -1104,6 +1111,9 @@ private:
   /// VPlan.
   Value2VPValueTy Value2VPValue;
 
+  /// Holds the VPLoopInfo analysis for this VPlan.
+  VPLoopInfo VPLInfo;
+
 public:
   VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) {}
 
@@ -1150,6 +1160,10 @@ public:
     return Value2VPValue[V];
   }
 
+  /// Return the VPLoopInfo analysis for this VPlan.
+  VPLoopInfo &getVPLoopInfo() { return VPLInfo; }
+  const VPLoopInfo &getVPLoopInfo() const { return VPLInfo; }
+
 private:
   /// Add to the given dominator tree the header block and every new basic block
   /// that was created between it and the latch block, inclusive.

Modified: llvm/trunk/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp?rev=338346&r1=338345&r2=338346&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp Mon Jul 30 18:57:29 2018
@@ -342,4 +342,10 @@ void VPlanHCFGBuilder::buildHierarchical
   VPDomTree.recalculate(*TopRegion);
   LLVM_DEBUG(dbgs() << "Dominator Tree after building the plain CFG.\n";
              VPDomTree.print(dbgs()));
+
+  // Compute VPLInfo and keep it in Plan.
+  VPLoopInfo &VPLInfo = Plan.getVPLoopInfo();
+  VPLInfo.analyze(VPDomTree);
+  LLVM_DEBUG(dbgs() << "VPLoop Info After buildPlainCFG:\n";
+             VPLInfo.print(dbgs()));
 }

Added: llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h?rev=338346&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h (added)
+++ llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h Mon Jul 30 18:57:29 2018
@@ -0,0 +1,45 @@
+//===-- VPLoopInfo.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines VPLoopInfo analysis and VPLoop class. VPLoopInfo is a
+/// specialization of LoopInfoBase for VPBlockBase. VPLoops is a specialization
+/// of LoopBase that is used to hold loop metadata from VPLoopInfo. Further
+/// information can be found in VectorizationPlanner.rst.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H
+#define LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H
+
+#include "llvm/Analysis/LoopInfoImpl.h"
+
+namespace llvm {
+class VPBlockBase;
+
+/// Hold analysis information for every loop detected by VPLoopInfo. It is an
+/// instantiation of LoopBase.
+class VPLoop : public LoopBase<VPBlockBase, VPLoop> {
+private:
+  friend class LoopInfoBase<VPBlockBase, VPLoop>;
+  explicit VPLoop(VPBlockBase *VPB) : LoopBase<VPBlockBase, VPLoop>(VPB) {}
+};
+
+/// VPLoopInfo provides analysis of natural loop for VPBlockBase-based
+/// Hierarchical CFG. It is a specialization of LoopInfoBase class.
+// TODO: VPLoopInfo is initially computed on top of the VPlan plain CFG, which
+// is the same as the incoming IR CFG. If it's more efficient than running the
+// whole loop detection algorithm, we may want to create a mechanism to
+// translate LoopInfo into VPLoopInfo. However, that would require significant
+// changes in LoopInfoBase class.
+typedef LoopInfoBase<VPBlockBase, VPLoop> VPLoopInfo;
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H

Propchange: llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: llvm/trunk/lib/Transforms/Vectorize/VPlanLoopInfo.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: llvm/trunk/unittests/Transforms/Vectorize/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Vectorize/CMakeLists.txt?rev=338346&r1=338345&r2=338346&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Vectorize/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Transforms/Vectorize/CMakeLists.txt Mon Jul 30 18:57:29 2018
@@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_unittest(VectorizeTests
   VPlanDominatorTreeTest.cpp
+  VPlanLoopInfoTest.cpp
   VPlanTest.cpp
   VPlanHCFGTest.cpp
   )

Added: llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp?rev=338346&view=auto
==============================================================================
--- llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp (added)
+++ llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp Mon Jul 30 18:57:29 2018
@@ -0,0 +1,87 @@
+//===- llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../lib/Transforms/Vectorize/VPlanLoopInfo.h"
+#include "VPlanTestBase.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class VPlanLoopInfo : public VPlanTestBase {};
+
+TEST_F(VPlanLoopInfo, BasicLoopInfoTest) {
+  const char *ModuleString =
+      "define void @f(i32* %a, i32* %b, i32* %c, i32 %N, i32 %M, i32 %K) {\n"
+      "entry:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]\n"
+      "  br i1 true, label %if.then, label %if.else\n"
+      "if.then:\n"
+      "  br label %for.inc\n"
+      "if.else:\n"
+      "  br label %for.inc\n"
+      "for.inc:\n"
+      "  %iv.next = add nuw nsw i64 %iv, 1\n"
+      "  %exitcond = icmp eq i64 %iv.next, 300\n"
+      "  br i1 %exitcond, label %for.end, label %for.body\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  Module &M = parseModule(ModuleString);
+
+  Function *F = M.getFunction("f");
+  BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
+  auto Plan = buildHCFG(LoopHeader);
+
+  // Build VPlan domination tree and loop info analyses.
+  VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
+  VPDominatorTree VPDT;
+  VPDT.recalculate(*TopRegion);
+  VPLoopInfo VPLI;
+  VPLI.analyze(VPDT);
+
+  VPBlockBase *PH = TopRegion->getEntry();
+  VPBlockBase *H = PH->getSingleSuccessor();
+  VPBlockBase *IfThen = H->getSuccessors()[0];
+  VPBlockBase *IfElse = H->getSuccessors()[1];
+  VPBlockBase *Latch = IfThen->getSingleSuccessor();
+  VPBlockBase *Exit = Latch->getSuccessors()[0] != H
+                          ? Latch->getSuccessors()[0]
+                          : Latch->getSuccessors()[1];
+
+  // Number of loops.
+  EXPECT_EQ(1, std::distance(VPLI.begin(), VPLI.end()));
+  VPLoop *VPLp = *VPLI.begin();
+
+  // VPBBs contained in VPLoop.
+  EXPECT_FALSE(VPLp->contains(PH));
+  EXPECT_EQ(nullptr, VPLI.getLoopFor(PH));
+  EXPECT_TRUE(VPLp->contains(H));
+  EXPECT_EQ(VPLp, VPLI.getLoopFor(H));
+  EXPECT_TRUE(VPLp->contains(IfThen));
+  EXPECT_EQ(VPLp, VPLI.getLoopFor(IfThen));
+  EXPECT_TRUE(VPLp->contains(IfElse));
+  EXPECT_EQ(VPLp, VPLI.getLoopFor(IfElse));
+  EXPECT_TRUE(VPLp->contains(Latch));
+  EXPECT_EQ(VPLp, VPLI.getLoopFor(Latch));
+  EXPECT_FALSE(VPLp->contains(Exit));
+  EXPECT_EQ(nullptr, VPLI.getLoopFor(Exit));
+
+  // VPLoop's parts.
+  EXPECT_EQ(PH, VPLp->getLoopPreheader());
+  EXPECT_EQ(H, VPLp->getHeader());
+  EXPECT_EQ(Latch, VPLp->getLoopLatch());
+  EXPECT_EQ(Latch, VPLp->getExitingBlock());
+  EXPECT_EQ(Exit, VPLp->getExitBlock());
+}
+} // namespace
+} // namespace llvm

Propchange: llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: llvm/trunk/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the llvm-commits mailing list