[LLVMdev] Questions about trip count

607 views
Skip to first unread message

Douglas do Couto Teixeira

unread,
Aug 12, 2010, 3:41:31 PM8/12/10
to llv...@cs.uiuc.edu
Dear guys,

    I am having problems to obtain good information from the LoopInfo. I am always getting a trip count of 0, even though I am clearly passing a loop with a constant bound. I am using this pass below:

void testLoopInfo(const Function& F) const {
    const LoopInfo *LI = &getAnalysis<LoopInfo>();
    Function::const_iterator BB = F.begin(), E = F.end();
    for (; BB != E; ++BB) {
        const Loop* l = LI->getLoopFor(&*BB);
        if (l != NULL) {
            l->dump();
            errs() << "BB:\t" << BB->getNameStr() << "\n" ;
            errs() << "Is simplifyed loop?\t" << l->isLoopSimplifyForm() << "\n" ;
            errs() << "Tripcount " << l->getSmallConstantTripCount() << "\n" ;
            const PHINode* phi = l->getCanonicalInductionVariable();
            errs() << "Induction variable: " << *phi << "\n";            
        }
    }
}

When I feed it with this program:
int main(int argc, char** argv) {
    int i = 0;
    for (; i < 4; i++) {
        int j = 0;
        for (; j < 8; j++) {
            printf("%c\n", argv[i][j]);
        }
    }
}

It prints the following info, where all the trip counts are zero. What am I doing wrong?

Hello: main
Loop at depth 1 containing: %bb4<header><exiting>,%bb3<latch>,%bb2,%bb,%bb1
    Loop at depth 2 containing: %bb2<header><exiting>,%bb1<latch>
BB:    bb
Is simplifyed loop?    1
Tripcount 0
Induction variable: printing a <null> value

Loop at depth 2 containing: %bb2<header><exiting>,%bb1<latch>
BB:    bb1
Is simplifyed loop?    1
Tripcount 0
Induction variable: printing a <null> value

Loop at depth 2 containing: %bb2<header><exiting>,%bb1<latch>
BB:    bb2
Is simplifyed loop?    1
Tripcount 0
Induction variable: printing a <null> value

Loop at depth 1 containing: %bb4<header><exiting>,%bb3<latch>,%bb2,%bb,%bb1
    Loop at depth 2 containing: %bb2<header><exiting>,%bb1<latch>
BB:    bb3
Is simplifyed loop?    1
Tripcount 0
Induction variable: printing a <null> value

Loop at depth 1 containing: %bb4<header><exiting>,%bb3<latch>,%bb2,%bb,%bb1
    Loop at depth 2 containing: %bb2<header><exiting>,%bb1<latch>
BB:    bb4
Is simplifyed loop?    1
Tripcount 0
Induction variable: printing a <null> value

Regards,

Douglas

Tobias Grosser

unread,
Aug 12, 2010, 4:22:39 PM8/12/10
to Douglas do Couto Teixeira, llv...@cs.uiuc.edu
On 08/12/2010 09:41 PM, Douglas do Couto Teixeira wrote:
> Dear guys,
>
> I am having problems to obtain good information from the LoopInfo.
> I am always getting a trip count of 0, even though I am clearly passing
> a loop with a constant bound. I am using this pass below:
Hi,

I would propose to first check if the trip count is calculated
correctly. I would do this with opt by calling:

opt -mem2reg -loopsimplify -indvars -scalar-evolution -analyze prog.ll

At the end of the output the tripcount of every loop should be written.

To get the trip count in your pass you should ask ScalarEvolution.

ScalarEvolution *SE;
Loop *L;
SE->getBackedgeTakenCount(L);

If you need help trying this please ask back.

Cheers
Tobi
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Douglas do Couto Teixeira

unread,
Aug 14, 2010, 12:16:20 PM8/14/10
to Tobias Grosser, llv...@cs.uiuc.edu


On Thu, Aug 12, 2010 at 5:22 PM, Tobias Grosser <gro...@fim.uni-passau.de> wrote:
On 08/12/2010 09:41 PM, Douglas do Couto Teixeira wrote:
Dear guys,

    I am having problems to obtain good information from the LoopInfo.
I am always getting a trip count of 0, even though I am clearly passing
a loop with a constant bound. I am using this pass below:
Hi,

I would propose to first check if the trip count is calculated correctly. I would do this with opt by calling:

opt -mem2reg -loopsimplify -indvars -scalar-evolution -analyze prog.ll

At the end of the output the tripcount of every loop should be written.

To get the trip count in your pass you should ask ScalarEvolution.

ScalarEvolution *SE;
Loop *L;
SE->getBackedgeTakenCount(L);

If you need help trying this please ask back.

Cheers
Tobi

Thanks Tobias. Your answer helped me a lot.  Now I can get the trip count of the loop like this:

#define DEBUG_TYPE "hello"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"

using namespace llvm;

STATISTIC(HelloCounter, "Counts number of functions greeted");

namespace {

struct Hello: public FunctionPass {
static char ID; // Pass identification, replacement for typeid
Hello() : FunctionPass(&ID) {}

void getLoopInfo(const Function& F) const {

const LoopInfo *LI = &getAnalysis<LoopInfo> ();
ScalarEvolution *SE = &getAnalysis<ScalarEvolution> ();
Function::const_iterator BB = F.begin(), E = F.end();

for (; BB != E; ++BB) {
const Loop* L = LI->getLoopFor(&*BB);
if (L != NULL) {
errs() << "Trip count: " << *SE->getBackedgeTakenCount(L);
L->dump();
}
}
}

virtual bool runOnFunction(Function &F) {

HelloCounter++;
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
getLoopInfo(F);
return false;
}

// We don't modify the program, so we preserve all analyses
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<LoopInfo> ();
AU.addRequired<ScalarEvolution> ();
}
};
}

char Hello::ID = 0;
static RegisterPass<Hello> Y("hello",
"Hello World Pass (with getAnalysisUsage implemented)");


But when I use that same function within a class I get some compiler errors. I'm trying to use this function like this:


#define DEBUG_TYPE "hello"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"

using namespace llvm;

STATISTIC(HelloCounter, "Counts number of functions greeted");

namespace {

struct Hello: public FunctionPass {
static char ID; // Pass identification, replacement for typeid
Hello() : FunctionPass(&ID) {}

class testLoopInfo {

void getLoopInfo(const Function& F) const {

const LoopInfo *LI = &getAnalysis<LoopInfo> ();
ScalarEvolution *SE = &getAnalysis<ScalarEvolution> ();
Function::const_iterator BB = F.begin(), E = F.end();
for (; BB != E; ++BB) {

const Loop* L = LI->getLoopFor(&*BB);
if (L != NULL) {
errs() << "Trip count: " << *SE->getBackedgeTakenCount(L);
L->dump();
}
}
}

};

virtual bool runOnFunction(Function &F) {

HelloCounter++;
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
//getLoopInfo(F);
return false;
}

// We don't modify the program, so we preserve all analyses
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<LoopInfo> ();
AU.addRequired<ScalarEvolution> ();
}
};
}

char Hello::ID = 0;
static RegisterPass<Hello> Y("hello",
"Hello World Pass (with getAnalysisUsage implemented)");

I get the following errors:

**** Build of configuration Debug for project HelloLLVM ****

make all 
llvm[0]: Compiling Hello.cpp for Release build (PIC)
Hello.cpp: In member function ‘void<unnamed>::Hello::testLoopInfo::getLoopInfo(const llvm::Function&) const’:
Hello.cpp:37: error: no matching function for call to ‘llvm::Pass::getAnalysis()’
/home/douglas/Programas/llvm-2.7/include/llvm/PassAnalysisSupport.h:209: note: candidates are: AnalysisType& llvm::Pass::getAnalysis() const [with AnalysisType = llvm::LoopInfo] <near match>
Hello.cpp:38: error: no matching function for call to ‘llvm::Pass::getAnalysis()’
/home/douglas/Programas/llvm-2.7/include/llvm/PassAnalysisSupport.h:209: note: candidates are: AnalysisType& llvm::Pass::getAnalysis() const [with AnalysisType = llvm::ScalarEvolution] <near match>
Hello.cpp: In member function ‘virtual bool<unnamed>::Hello::runOnFunction(llvm::Function&)’:
Hello.cpp:57: error: ‘getLoopInfo’ was not declared in this scope
make: ** [/home/douglas/Programas/llvm-2.7/lib/Transforms/Hello/Release/Hello.o] Erro 1


Anyone know how can I fix it?


Thanks a lot,

Douglas


Eli Friedman

unread,
Aug 14, 2010, 3:38:18 PM8/14/10
to Douglas do Couto Teixeira, llv...@cs.uiuc.edu, Tobias Grosser

Umm, pass in a "Pass* P", then use "P->getAnalysis<LoopInfo> ()"? C++
isn't Java :)

-Eli

Reply all
Reply to author
Forward
0 new messages