[llvm] r306070 - Restrict the definition of loop preheader to avoid EH blocks
Andrew Kaylor via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 22 16:27:17 PDT 2017
Author: akaylor
Date: Thu Jun 22 18:27:16 2017
New Revision: 306070
URL: http://llvm.org/viewvc/llvm-project?rev=306070&view=rev
Log:
Restrict the definition of loop preheader to avoid EH blocks
Differential Revision: https://reviews.llvm.org/D34487
Added:
llvm/trunk/test/Transforms/LoopRotate/catchret.ll (with props)
Modified:
llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
llvm/trunk/include/llvm/IR/BasicBlock.h
llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
llvm/trunk/lib/IR/BasicBlock.cpp
Modified: llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h?rev=306070&r1=306069&r2=306070&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h Thu Jun 22 18:27:16 2017
@@ -91,8 +91,9 @@ getExitEdges(SmallVectorImpl<Edge> &Exit
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
-/// from outside of the loop. If this is the case, the block branching to the
-/// header of the loop is the preheader node.
+/// from outside of the loop and it is legal to hoist instructions into the
+/// predecessor. If this is the case, the block branching to the header of the
+/// loop is the preheader node.
///
/// This method returns null if there is no preheader for the loop.
///
@@ -102,6 +103,10 @@ BlockT *LoopBase<BlockT, LoopT>::getLoop
BlockT *Out = getLoopPredecessor();
if (!Out) return nullptr;
+ // Make sure we are allowed to hoist instructions into the predecessor.
+ if (!Out->isLegalToHoistInto())
+ return nullptr;
+
// Make sure there is only one exit out of the preheader.
typedef GraphTraits<BlockT*> BlockTraits;
typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=306070&r1=306069&r2=306070&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Jun 22 18:27:16 2017
@@ -376,6 +376,9 @@ public:
/// Indicates if this is the entry block of a cleanup funclet.
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+ /// Returns true if it is legal to hoist instructions into this block.
+ bool isLegalToHoistInto() const;
+
// Code Layout methods.
/// Move 'this' block before or after the specified block. This only moves
Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=306070&r1=306069&r2=306070&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Thu Jun 22 18:27:16 2017
@@ -395,6 +395,9 @@ public:
static_cast<const BasicBlock *>(this)->getLandingPadInst());
}
+ /// \brief Return true if it is legal to hoist instructions into this block.
+ bool isLegalToHoistInto() const;
+
private:
/// \brief Increment the internal refcount of the number of BlockAddresses
/// referencing this BasicBlock by \p Amt.
Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=306070&r1=306069&r2=306070&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Jun 22 18:27:16 2017
@@ -228,6 +228,12 @@ LLVM_DUMP_METHOD void MachineBasicBlock:
}
#endif
+bool MachineBasicBlock::isLegalToHoistInto() const {
+ if (isReturnBlock() || hasEHPadSuccessor())
+ return false;
+ return true;
+}
+
StringRef MachineBasicBlock::getName() const {
if (const BasicBlock *LBB = getBasicBlock())
return LBB->getName();
Modified: llvm/trunk/lib/IR/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=306070&r1=306069&r2=306070&view=diff
==============================================================================
--- llvm/trunk/lib/IR/BasicBlock.cpp (original)
+++ llvm/trunk/lib/IR/BasicBlock.cpp Thu Jun 22 18:27:16 2017
@@ -355,6 +355,19 @@ bool BasicBlock::canSplitPredecessors()
return true;
}
+bool BasicBlock::isLegalToHoistInto() const {
+ auto *Term = getTerminator();
+ // No terminator means the block is under construction.
+ if (!Term)
+ return true;
+
+ // If the block has no successors, there can be no instructions to hoist.
+ assert(Term->getNumSuccessors() > 0);
+
+ // Instructions should not be hoisted across exception handling boundaries.
+ return !Term->isExceptional();
+}
+
/// This splits a basic block into two at the specified
/// instruction. Note that all instructions BEFORE the specified iterator stay
/// as part of the original basic block, an unconditional branch is added to
Added: llvm/trunk/test/Transforms/LoopRotate/catchret.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/catchret.ll?rev=306070&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopRotate/catchret.ll (added)
+++ llvm/trunk/test/Transforms/LoopRotate/catchret.ll Thu Jun 22 18:27:16 2017
@@ -0,0 +1,41 @@
+; RUN: opt < %s -loop-rotate -S | FileCheck %s
+
+target triple = "x86_64-pc-windows-msvc"
+
+declare void @always_throws()
+
+define i32 @test() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ invoke void @always_throws()
+ to label %continue unwind label %catch.dispatch
+
+continue:
+ unreachable
+
+catch.dispatch:
+ %t0 = catchswitch within none [label %catch] unwind to caller
+
+catch:
+ %t1 = catchpad within %t0 [i8* null, i32 64, i8* null]
+ catchret from %t1 to label %for.cond
+
+for.cond:
+ %sum = phi i32 [ %add, %for.body ], [ 0, %catch ]
+ %i = phi i32 [ %inc, %for.body ], [ 0, %catch ]
+ %cmp = icmp slt i32 %i, 1
+ br i1 %cmp, label %for.body, label %return
+
+for.body:
+ %add = add nsw i32 1, %sum
+ %inc = add nsw i32 %i, 1
+ br label %for.cond
+
+return:
+ ret i32 0
+}
+
+; CHECK: catch:
+; CHECK-NEXT: catchpad
+; CHECK-NEXT: catchret
+
+declare i32 @__CxxFrameHandler3(...)
Propchange: llvm/trunk/test/Transforms/LoopRotate/catchret.ll
------------------------------------------------------------------------------
svn:executable = *
More information about the llvm-commits
mailing list