1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

Make succ_iterator a real random access iterator and clean up a couple of users.

llvm-svn: 201088
This commit is contained in:
Benjamin Kramer 2014-02-10 14:17:42 +00:00
parent 6f5190be6c
commit 4779ebf069
5 changed files with 74 additions and 51 deletions

View File

@ -101,23 +101,45 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
template <class Term_, class BB_> // Successor Iterator template <class Term_, class BB_> // Successor Iterator
class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB_,
BB_, ptrdiff_t, BB_*, BB_*> { int, BB_ *, BB_ *> {
typedef std::iterator<std::random_access_iterator_tag, BB_, int, BB_ *, BB_ *>
super;
public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
private:
const Term_ Term; const Term_ Term;
unsigned idx; unsigned idx;
typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*,
BB_*> super;
typedef SuccIterator<Term_, BB_> Self; typedef SuccIterator<Term_, BB_> Self;
inline bool index_is_valid(int idx) { inline bool index_is_valid(int idx) {
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
} }
public: /// \brief Proxy object to allow write access in operator[]
typedef typename super::pointer pointer; class SuccessorProxy {
typedef typename super::reference reference; Self it;
// TODO: This can be random access iterator, only operator[] missing.
public:
explicit SuccessorProxy(const Self &it) : it(it) {}
SuccessorProxy &operator=(SuccessorProxy r) {
*this = reference(r);
return *this;
}
SuccessorProxy &operator=(reference r) {
it.Term->setSuccessor(it.idx, r);
return *this;
}
operator reference() const { return *it; }
};
public:
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
} }
inline SuccIterator(Term_ T, bool) // end iterator inline SuccIterator(Term_ T, bool) // end iterator
@ -206,15 +228,11 @@ public:
return distance; return distance;
} }
// This works for read access, however write access is difficult as changes inline SuccessorProxy operator[](int offset) {
// to Term are only possible with Term->setSuccessor(idx). Pointers that can Self tmp = *this;
// be modified are not available. tmp += offset;
// return SuccessorProxy(tmp);
// inline pointer operator[](int offset) { }
// Self tmp = *this;
// tmp += offset;
// return tmp.operator*();
// }
/// Get the source BB of this iterator. /// Get the source BB of this iterator.
inline BB_ *getSource() { inline BB_ *getSource() {

View File

@ -168,8 +168,7 @@ static bool isPotentiallyReachableInner(SmallVectorImpl<BasicBlock *> &Worklist,
// ignoring any other blocks inside the loop body. // ignoring any other blocks inside the loop body.
Outer->getExitBlocks(Worklist); Outer->getExitBlocks(Worklist);
} else { } else {
for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) Worklist.append(succ_begin(BB), succ_end(BB));
Worklist.push_back(*I);
} }
} while (!Worklist.empty()); } while (!Worklist.empty());
@ -222,8 +221,7 @@ bool llvm::isPotentiallyReachable(const Instruction *A, const Instruction *B,
return false; return false;
// Otherwise, continue doing the normal per-BB CFG walk. // Otherwise, continue doing the normal per-BB CFG walk.
for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) Worklist.append(succ_begin(BB), succ_end(BB));
Worklist.push_back(*I);
if (Worklist.empty()) { if (Worklist.empty()) {
// We've proven that there's no path! // We've proven that there's no path!

View File

@ -437,12 +437,7 @@ struct NoTTI LLVM_FINAL : ImmutablePass, TargetTransformInfo {
return TopTTI->getCallCost(cast<FunctionType>(FTy), CS.arg_size()); return TopTTI->getCallCost(cast<FunctionType>(FTy), CS.arg_size());
} }
SmallVector<const Value *, 8> Arguments; SmallVector<const Value *, 8> Arguments(CS.arg_begin(), CS.arg_end());
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(),
AE = CS.arg_end();
AI != AE; ++AI)
Arguments.push_back(*AI);
return TopTTI->getCallCost(F, Arguments); return TopTTI->getCallCost(F, Arguments);
} }

View File

@ -817,8 +817,7 @@ SpeculationFailure:
// Mark as unavailable. // Mark as unavailable.
EntryVal = 0; EntryVal = 0;
for (succ_iterator I = succ_begin(Entry), E = succ_end(Entry); I != E; ++I) BBWorklist.append(succ_begin(Entry), succ_end(Entry));
BBWorklist.push_back(*I);
} while (!BBWorklist.empty()); } while (!BBWorklist.empty());
return false; return false;

View File

@ -115,7 +115,7 @@ protected:
PM.add(P); PM.add(P);
PM.run(*M); PM.run(*M);
} }
private:
OwningPtr<Module> M; OwningPtr<Module> M;
Instruction *A, *B; Instruction *A, *B;
}; };
@ -352,27 +352,40 @@ TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
ExpectPath(true); ExpectPath(true);
} }
static const char *BranchInsideLoopIR =
"declare i1 @switch()\n"
"\n"
"define void @test() {\n"
"entry:\n"
" br label %loop\n"
"loop:\n"
" %x = call i1 @switch()\n"
" br i1 %x, label %nextloopblock, label %exit\n"
"nextloopblock:\n"
" %y = call i1 @switch()\n"
" br i1 %y, label %left, label %right\n"
"left:\n"
" %A = bitcast i8 undef to i8\n"
" br label %loop\n"
"right:\n"
" %B = bitcast i8 undef to i8\n"
" br label %loop\n"
"exit:\n"
" ret void\n"
"}";
TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) { TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
ParseAssembly( ParseAssembly(BranchInsideLoopIR);
"declare i1 @switch()\n" ExpectPath(true);
"\n" }
"define void @test() {\n"
"entry:\n" TEST_F(IsPotentiallyReachableTest, ModifyTest) {
" br label %loop\n" ParseAssembly(BranchInsideLoopIR);
"loop:\n"
" %x = call i1 @switch()\n" succ_iterator S = succ_begin(++M->getFunction("test")->begin());
" br i1 %x, label %nextloopblock, label %exit\n" BasicBlock *OldBB = S[0];
"nextloopblock:\n" S[0] = S[1];
" %y = call i1 @switch()\n" ExpectPath(false);
" br i1 %y, label %left, label %right\n" S[0] = OldBB;
"left:\n"
" %A = bitcast i8 undef to i8\n"
" br label %loop\n"
"right:\n"
" %B = bitcast i8 undef to i8\n"
" br label %loop\n"
"exit:\n"
" ret void\n"
"}");
ExpectPath(true); ExpectPath(true);
} }