[polly] r303790 - [Polly] Add handling of Top Level Regions

Philip Pfaffe via llvm-commits llvm-commits at lists.llvm.org
Wed May 24 11:39:39 PDT 2017


Author: pfaffe
Date: Wed May 24 13:39:39 2017
New Revision: 303790

URL: http://llvm.org/viewvc/llvm-project?rev=303790&view=rev
Log:
[Polly] Add handling of Top Level Regions

Summary:
My goal is to make the newly added `AllowWholeFunctions` options more usable/powerful.

The changes to ScopBuilder.cpp are exclusively checks to prevent `Region.getExit()` from being dereferenced, since Top Level Regions (TLRs) don't have an exit block.

In ScopDetection's `isValidCFG`, I removed a check that disallowed ReturnInstructions to have return values. This might of course have been intentional, so I would welcome your feedback on this and maybe a small explanation why return values are forbidden. Maybe it can be done but needs more changes elsewhere?

The remaining changes in ScopDetection are simply to consider the AllowWholeFunctions option in more places, i.e. allow TLRs when it is set and once again avoid derefererncing `getExit()` if it doesn't exist.

Finally, in ScopHelper.cpp I extended `polly::isErrorBlock` to handle regions without exit blocks as well: The original check was if a given BasicBlock dominates all predecessors of the exit block. Therefore I do the same for TLRs by regarding all BasicBlocks terminating with a ReturnInst as predecessors of a "virtual" function exit block.

Patch by: Lukas Boehm

Reviewers: philip.pfaffe, grosser, Meinersbur

Reviewed By: grosser

Subscribers: pollydev, llvm-commits, bollu

Tags: #polly

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

Modified:
    polly/trunk/lib/Analysis/ScopBuilder.cpp
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/Support/ScopHelper.cpp
    polly/trunk/test/ScopInfo/full-function.ll

Modified: polly/trunk/lib/Analysis/ScopBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopBuilder.cpp?rev=303790&r1=303789&r2=303790&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopBuilder.cpp (original)
+++ polly/trunk/lib/Analysis/ScopBuilder.cpp Wed May 24 13:39:39 2017
@@ -894,12 +894,14 @@ static void verifyUses(Scop *S, LoopInfo
     return;
 
   // PHINodes in the SCoP region's exit block are also uses to be checked.
-  for (auto &Inst : *S->getRegion().getExit()) {
-    if (!isa<PHINode>(Inst))
-      break;
-
-    for (auto &Op : Inst.operands())
-      verifyUse(S, Op, LI);
+  if (!S->getRegion().isTopLevelRegion()) {
+    for (auto &Inst : *S->getRegion().getExit()) {
+      if (!isa<PHINode>(Inst))
+        break;
+
+      for (auto &Op : Inst.operands())
+        verifyUse(S, Op, LI);
+    }
   }
 }
 #endif
@@ -917,7 +919,7 @@ void ScopBuilder::buildScop(Region &R, A
   // To handle these PHI nodes later we will now model their operands as scalar
   // accesses. Note that we do not model anything in the exit block if we have
   // an exiting block in the region, as there will not be any splitting later.
-  if (!scop->hasSingleExitEdge())
+  if (!R.isTopLevelRegion() && !scop->hasSingleExitEdge())
     buildAccessFunctions(*R.getExit(), nullptr,
                          /* IsExitBlock */ true);
 

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=303790&r1=303789&r2=303790&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Wed May 24 13:39:39 2017
@@ -578,7 +578,7 @@ bool ScopDetection::isValidCFG(BasicBloc
     return true;
 
   // Return instructions are only valid if the region is the top level region.
-  if (isa<ReturnInst>(TI) && !CurRegion.getExit() && TI->getNumOperands() == 0)
+  if (isa<ReturnInst>(TI) && CurRegion.isTopLevelRegion())
     return true;
 
   Value *Condition = getConditionFromTerminator(TI);
@@ -1485,13 +1485,14 @@ bool ScopDetection::isValidRegion(Detect
 
   DEBUG(dbgs() << "Checking region: " << CurRegion.getNameStr() << "\n\t");
 
-  if (CurRegion.isTopLevelRegion()) {
+  if (!AllowFullFunction && CurRegion.isTopLevelRegion()) {
     DEBUG(dbgs() << "Top level region is invalid\n");
     return false;
   }
 
   DebugLoc DbgLoc;
-  if (isa<UnreachableInst>(CurRegion.getExit()->getTerminator())) {
+  if (CurRegion.getExit() &&
+      isa<UnreachableInst>(CurRegion.getExit()->getTerminator())) {
     DEBUG(dbgs() << "Unreachable in exit\n");
     return invalid<ReportUnreachableInExit>(Context, /*Assert=*/true,
                                             CurRegion.getExit(), DbgLoc);

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=303790&r1=303789&r2=303790&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed May 24 13:39:39 2017
@@ -4824,11 +4824,17 @@ ScopStmt *Scop::getStmtFor(Region *R) co
 }
 
 int Scop::getRelativeLoopDepth(const Loop *L) const {
-  Loop *OuterLoop =
-      L ? R.outermostLoopInRegion(const_cast<Loop *>(L)) : nullptr;
-  if (!OuterLoop)
+  if (!L || !R.contains(L))
     return -1;
-  return L->getLoopDepth() - OuterLoop->getLoopDepth();
+  // outermostLoopInRegion always returns nullptr for top level regions
+  if (R.isTopLevelRegion()) {
+    // LoopInfo's depths start at 1, we start at 0
+    return L->getLoopDepth() - 1;
+  } else {
+    Loop *OuterLoop = R.outermostLoopInRegion(const_cast<Loop *>(L));
+    assert(OuterLoop);
+    return L->getLoopDepth() - OuterLoop->getLoopDepth();
+  }
 }
 
 ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {

Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=303790&r1=303789&r2=303790&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Wed May 24 13:39:39 2017
@@ -380,9 +380,15 @@ bool polly::isErrorBlock(BasicBlock &BB,
   // Basic blocks that are always executed are not considered error blocks,
   // as their execution can not be a rare event.
   bool DominatesAllPredecessors = true;
-  for (auto Pred : predecessors(R.getExit()))
-    if (R.contains(Pred) && !DT.dominates(&BB, Pred))
-      DominatesAllPredecessors = false;
+  if (R.isTopLevelRegion()) {
+    for (BasicBlock &I : *R.getEntry()->getParent())
+      if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I))
+        DominatesAllPredecessors = false;
+  } else {
+    for (auto Pred : predecessors(R.getExit()))
+      if (R.contains(Pred) && !DT.dominates(&BB, Pred))
+        DominatesAllPredecessors = false;
+  }
 
   if (DominatesAllPredecessors)
     return false;

Modified: polly/trunk/test/ScopInfo/full-function.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/full-function.ll?rev=303790&r1=303789&r2=303790&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/full-function.ll (original)
+++ polly/trunk/test/ScopInfo/full-function.ll Wed May 24 13:39:39 2017
@@ -3,6 +3,7 @@
 ; RUN: opt %loadPolly -polly-scops -analyze < %s \
 ; RUN: | FileCheck %s -check-prefix=WITHOUT-FULL
 
+; FULL:      Region: %bb---FunctionExit
 ; FULL:      Statements {
 ; FULL-NEXT: 	Stmt_loop_1
 ; FULL-NEXT:         Domain :=
@@ -20,6 +21,7 @@
 ; FULL-NEXT:             [p] -> { Stmt_loop_2[i0] -> MemRef_A[0] };
 ; FULL-NEXT: }
 
+; WITHOUT-FULL:        Region: %loop.2---%merge
 ; WITHOUT-FULL:        Statements {
 ; WITHOUT-FULL-NEXT:    	Stmt_loop_2
 ; WITHOUT-FULL-NEXT:            Domain :=
@@ -30,6 +32,7 @@
 ; WITHOUT-FULL-NEXT:                { Stmt_loop_2[i0] -> MemRef_A[0] };
 ; WITHOUT-FULL-NEXT:    }
 
+; WITHOUT-FULL:         Region: %loop.1---%merge
 ; WITHOUT-FULL:         Statements {
 ; WITHOUT-FULL-NEXT:    	Stmt_loop_1
 ; WITHOUT-FULL-NEXT:            Domain :=




More information about the llvm-commits mailing list