forked from OSchip/llvm-project
Don't use invalidated iterators in FlattenCFGPass
Summary: FlattenCFG may erase unnecessary blocks, which also invalidates iterators to those erased blocks. Before this patch, `iterativelyFlattenCFG` could try to increment a BB iterator after that BB has been removed and crash. This patch makes FlattenCFGPass use `WeakVH` to skip over erased blocks. Reviewers: dblaikie, tstellar, davide, sanjoy, asbirlea, grosser Reviewed By: asbirlea Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67672 llvm-svn: 372347
This commit is contained in:
parent
d89f2d872d
commit
e6b2164723
|
@ -11,10 +11,12 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "flattencfg"
|
||||
|
@ -52,15 +54,23 @@ FunctionPass *llvm::createFlattenCFGPass() { return new FlattenCFGPass(); }
|
|||
static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {
|
||||
bool Changed = false;
|
||||
bool LocalChange = true;
|
||||
|
||||
// Use block handles instead of iterating over function blocks directly
|
||||
// to avoid using iterators invalidated by erasing blocks.
|
||||
std::vector<WeakVH> Blocks;
|
||||
Blocks.reserve(F.size());
|
||||
for (auto &BB : F)
|
||||
Blocks.push_back(&BB);
|
||||
|
||||
while (LocalChange) {
|
||||
LocalChange = false;
|
||||
|
||||
// Loop over all of the basic blocks and remove them if they are unneeded...
|
||||
//
|
||||
for (Function::iterator BBIt = F.begin(); BBIt != F.end();) {
|
||||
if (FlattenCFG(&*BBIt++, AA)) {
|
||||
LocalChange = true;
|
||||
}
|
||||
// Loop over all of the basic blocks and try to flatten them.
|
||||
for (WeakVH &BlockHandle : Blocks) {
|
||||
// Skip blocks erased by FlattenCFG.
|
||||
if (auto *BB = cast_or_null<BasicBlock>(BlockHandle))
|
||||
if (FlattenCFG(BB, AA))
|
||||
LocalChange = true;
|
||||
}
|
||||
Changed |= LocalChange;
|
||||
}
|
||||
|
|
|
@ -24,3 +24,33 @@ b1: ; preds = %entry, %b0
|
|||
exit: ; preds = %entry, %b0, %b1
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test_not_crash2
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: %0 = fcmp ult float %a
|
||||
; CHECK-NEXT: %1 = fcmp ult float %b
|
||||
; CHECK-NEXT: [[COND:%[a-z0-9]+]] = or i1 %0, %1
|
||||
; CHECK-NEXT: br i1 [[COND]], label %bb4, label %bb3
|
||||
; CHECK: bb3:
|
||||
; CHECK-NEXT: br label %bb4
|
||||
; CHECK: bb4:
|
||||
; CHECK-NEXT: ret void
|
||||
define void @test_not_crash2(float %a, float %b) #0 {
|
||||
entry:
|
||||
%0 = fcmp ult float %a, 1.000000e+00
|
||||
br i1 %0, label %bb0, label %bb1
|
||||
|
||||
bb3: ; preds = %bb0
|
||||
br label %bb4
|
||||
|
||||
bb4: ; preds = %bb0, %bb3
|
||||
ret void
|
||||
|
||||
bb1: ; preds = %entry
|
||||
br label %bb0
|
||||
|
||||
bb0: ; preds = %bb1, %entry
|
||||
%1 = fcmp ult float %b, 1.000000e+00
|
||||
br i1 %1, label %bb4, label %bb3
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue