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:
parent
6f5190be6c
commit
4779ebf069
@ -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() {
|
||||||
|
@ -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!
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user