[LLVMdev] BackedgeTakenCount calculation for fortran loops and DragonEgg gfortran-4.6
Marcello Maggioni
hayarms at gmail.com
Wed Feb 8 12:02:59 PST 2012
Mmm, sorry, the patch I posted crashes if ExitBr is null (which it may
be ...) , this one should be ok (and passess all the ScalarEvolution
tests in LLVM):
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index daf7742..b10fab2 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -4293,9 +4293,15 @@ ScalarEvolution::ComputeExitLimit(const Loop
*L, BasicBlock *ExitingBlock) {
//
// FIXME: we should be able to handle switch instructions (with a
single exit)
BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
+
if (ExitBr == 0) return getCouldNotCompute();
assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
+ BranchInst* BrFirstSucc = dyn_cast<BranchInst>(ExitBr->
+ getSuccessor(0)->getTerminator());
+ BranchInst* BrSecondSucc = dyn_cast<BranchInst>(ExitBr->
+ getSuccessor(1)->getTerminator());
+
// At this point, we know we have a conditional branch that
determines whether
// the loop is exited. However, we don't know if the branch is executed each
// time through the loop. If not, then the execution count of the
branch will
@@ -4316,10 +4322,23 @@ ScalarEvolution::ComputeExitLimit(const Loop
*L, BasicBlock *ExitingBlock) {
if (ExitBr->getSuccessor(0) != L->getHeader() &&
ExitBr->getSuccessor(1) != L->getHeader() &&
ExitBr->getParent() != L->getHeader()) {
- // The simple checks failed, try climbing the unique predecessor chain
- // up to the header.
+
bool Ok = false;
- for (BasicBlock *BB = ExitBr->getParent(); BB; ) {
+ //Check if the one of the successor of the exit branch has the is a block
+ //that has only one predecessor and has an unconditional branch to the
+ //loop header
+ if (BrFirstSucc && BrFirstSucc->isUnconditional() &&
+ BrFirstSucc->getSuccessor(0) == L->getHeader() &&
+ BrFirstSucc->getParent()->getUniquePredecessor())
+ Ok = true;
+ if (BrSecondSucc && BrSecondSucc->isUnconditional() &&
+ BrSecondSucc->getSuccessor(0) == L->getHeader() &&
+ BrSecondSucc->getParent()->getUniquePredecessor())
+ Ok = true;
+ // The simple checks failed, try climbing the unique predecessor chain
+ // up to the header.
+
+ for (BasicBlock *BB = ExitBr->getParent(); BB && !Ok; ) {
BasicBlock *Pred = BB->getUniquePredecessor();
if (!Pred)
return getCouldNotCompute();
anyway, this patch is only "a concept" of what I'm talking about.
PS=Sorry for the bad english in the previous post :p
2012/2/8 Marcello Maggioni <hayarms at gmail.com>:
> Hello, I'm finding problems with BackEdgeTaken count calculation in
> even simple fortran loops with gfortran-4.6 + DragonEgg 3.0.
>
> Even for simple double loops like this one:
>
> program test2
> integer i,j,k
> dimension k(100,100)
> do j=1,100
> do i=1,100
> k(i,j) = i
> enddo
> enddo
> write(*,*) k(1,30)
> end
>
> make the ScalarEvolution engine return "CouldNotCompute" even for the
> outer loop (the inner loop is fine).
>
> You can find a screenshot of the translation of this loop here (with
> -view-cfg Polly version):
> http://i.imgur.com/Jyaqd.png
>
> The problem seems to be the fact that the ScalarEvolution can't
> consider the outer loop exit branch instruction as the trivial case
> (where one of the successors of the exit block is the loop header or
> the exit block is the loop header itself) because of the (strange?)
> loop shape (the exit block instead of jumping to the header of the
> loop jumps instead to another block that increments the induction
> variable and has an unconditional branch to the loop header) and so
> starts backtracking the predecessors of the of the exit block and
> stops when it reaches the inner loop that has a block without a unique
> predecessor.
>
> What do you think about this problem? This makes , for example,
> difficult analyzing even simple fortran loops with Polly .
> I believe the case portrayed in the picture is the same to the trivial
> case (because the exit block jumps to a block with an unconditional
> jump to the header of the loop), am I right?
>
> I've written this little patch that adds this case to the trivial case :
>
> diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
> index daf7742..fcbaffe 100644
> --- a/lib/Analysis/ScalarEvolution.cpp
> +++ b/lib/Analysis/ScalarEvolution.cpp
> @@ -4293,6 +4293,11 @@ ScalarEvolution::ComputeExitLimit(const Loop
> *L, BasicBlock *ExitingBlock) {
> //
> // FIXME: we should be able to handle switch instructions (with a
> single exit)
> BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
> + BranchInst* BrFirstSucc = dyn_cast<BranchInst>(ExitBr->
> + getSuccessor(0)->getTerminator());
> + BranchInst* BrSecondSucc = dyn_cast<BranchInst>(ExitBr->
> + getSuccessor(1)->getTerminator());
> +
> if (ExitBr == 0) return getCouldNotCompute();
> assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
>
> @@ -4315,8 +4320,12 @@ ScalarEvolution::ComputeExitLimit(const Loop
> *L, BasicBlock *ExitingBlock) {
> //
> if (ExitBr->getSuccessor(0) != L->getHeader() &&
> ExitBr->getSuccessor(1) != L->getHeader() &&
> - ExitBr->getParent() != L->getHeader()) {
> - // The simple checks failed, try climbing the unique predecessor chain
> + ExitBr->getParent() != L->getHeader() &&
> + !((BrFirstSucc && BrFirstSucc->isUnconditional() &&
> + BrFirstSucc->getSuccessor(0) == L->getHeader()) ||
> + (BrSecondSucc && BrSecondSucc->isUnconditional() &&
> + BrSecondSucc->getSuccessor(0) == L->getHeader())) ) {
> + // The simple checks failed, try climbing the unique predecessor chain
> // up to the header.
> bool Ok = false;
> for (BasicBlock *BB = ExitBr->getParent(); BB; ) {
>
> what do you think about this? There is a better solution to the
> problem? Is the compiler itself broken?
>
> Thank you
>
> Marcello
More information about the llvm-dev
mailing list