mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-30 16:53:02 +00:00
Fix for PR 2323, infinite loop in tail dup.
llvm-svn: 51063
This commit is contained in:
parent
a11adf725d
commit
676a1d026b
@ -32,6 +32,7 @@
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <map>
|
||||
using namespace llvm;
|
||||
|
||||
@ -51,6 +52,7 @@ namespace {
|
||||
private:
|
||||
inline bool shouldEliminateUnconditionalBranch(TerminatorInst *TI);
|
||||
inline void eliminateUnconditionalBranch(BranchInst *BI);
|
||||
SmallPtrSet<BasicBlock*, 4> CycleDetector;
|
||||
};
|
||||
}
|
||||
|
||||
@ -61,17 +63,21 @@ static RegisterPass<TailDup> X("tailduplicate", "Tail Duplication");
|
||||
FunctionPass *llvm::createTailDuplicationPass() { return new TailDup(); }
|
||||
|
||||
/// runOnFunction - Top level algorithm - Loop over each unconditional branch in
|
||||
/// the function, eliminating it if it looks attractive enough.
|
||||
///
|
||||
/// the function, eliminating it if it looks attractive enough. CycleDetector
|
||||
/// prevents infinite loops by checking that we aren't redirecting a branch to
|
||||
/// a place it already pointed to earlier; see PR 2323.
|
||||
bool TailDup::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; )
|
||||
CycleDetector.clear();
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
|
||||
if (shouldEliminateUnconditionalBranch(I->getTerminator())) {
|
||||
eliminateUnconditionalBranch(cast<BranchInst>(I->getTerminator()));
|
||||
Changed = true;
|
||||
} else {
|
||||
++I;
|
||||
CycleDetector.clear();
|
||||
}
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
@ -140,7 +146,7 @@ bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI) {
|
||||
if (TooMany-- == 0) return false;
|
||||
}
|
||||
|
||||
// Finally, if this unconditional branch is a fall-through, be careful about
|
||||
// If this unconditional branch is a fall-through, be careful about
|
||||
// tail duplicating it. In particular, we don't want to taildup it if the
|
||||
// original block will still be there after taildup is completed: doing so
|
||||
// would eliminate the fall-through, requiring unconditional branches.
|
||||
@ -170,6 +176,11 @@ bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI) {
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, check that we haven't redirected to this target block earlier;
|
||||
// there are cases where we loop forever if we don't check this (PR 2323).
|
||||
if (!CycleDetector.insert(Dest))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
26
test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
Normal file
26
test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llvm-as < %s | opt -tailduplicate | llc
|
||||
; PR2323
|
||||
|
||||
define i32 @func_27(i32 %p_28) nounwind {
|
||||
entry:
|
||||
%tmp125 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
|
||||
%tmp5.i = icmp eq i8 %tmp125, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp5.i, label %bb8.i, label %bb.i
|
||||
|
||||
bb.i: ; preds = %entry
|
||||
br label %bb39.i
|
||||
|
||||
bb8.i: ; preds = %entry
|
||||
br label %bb11.i
|
||||
|
||||
bb11.i: ; preds = %bb39.i, %bb8.i
|
||||
%tmp126 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
|
||||
br label %bb39.i
|
||||
|
||||
bb39.i: ; preds = %bb11.i, %bb.i
|
||||
%tmp127 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
|
||||
br label %bb11.i
|
||||
|
||||
func_29.exit: ; No predecessors!
|
||||
ret i32 undef
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user