Adding an object to llc

Hi

I have just written an pass which does some simple ASAP scheduling. First i
registered it as optimization pass because it so nice documented and speeds
up the compilation and testing times dramaticly :-).

Then i just registered this part as an analysis part which should be used in a
modified cbackend. All seems to work fine, exept that llc fails to link. I
tried removing the SHARED_LIBRARY = 1 and LOADABLE_MODULE= 1 options from the
Makefile since it should be included by default in my build. Then i tried to
add the .a file to the llc makefile. But it didn't help either... :frowning: Any
hints what's missing?

Btw. there was a way to make the makefile run more verbose. It was documented
somewhere but i don't find it anymore? (S.t. like debug=1 make)

Thanks
ST

make VERBOSE=1
:slight_smile:

Andrew

Hi

I have just written an pass which does some simple ASAP scheduling. First i
registered it as optimization pass because it so nice documented and speeds
up the compilation and testing times dramaticly :-).

Then i just registered this part as an analysis part which should be used in a
modified cbackend. All seems to work fine, exept that llc fails to link. I
tried removing the SHARED_LIBRARY = 1 and LOADABLE_MODULE= 1 options from the
Makefile since it should be included by default in my build. Then i tried to
add the .a file to the llc makefile. But it didn't help either... :frowning: Any
hints what's missing?

Its hard to say without knowing the error you got.

Can you provide the link error that was generated?

Btw. there was a way to make the makefile run more verbose. It was documented
somewhere but i don't find it anymore? (S.t. like debug=1 make)

The option is: make VERBOSE=1

Reid

I have just written an pass which does some simple ASAP scheduling. First i
registered it as optimization pass because it so nice documented and speeds
up the compilation and testing times dramaticly :-).

Ok, so this is an LLVM->LLVM pass?

Then i just registered this part as an analysis part which should be used in a
modified cbackend. All seems to work fine, exept that llc fails to link. I
tried removing the SHARED_LIBRARY = 1 and LOADABLE_MODULE= 1 options from the
Makefile since it should be included by default in my build. Then i tried to
add the .a file to the llc makefile. But it didn't help either... :frowning: Any
hints what's missing?

I'm not sure, this is too vauge to give you specific directions. Note that LLC isn't set up to dynamically load passes. Is there any reason you can't use 'opt -yourpass | llc'? If you really have to have it in llc, you can modify the C backend's CTargetMachine::addPassesToEmitFile method to include your pass.

-Chris

Hi

Thanks for all your feedback. I just found the reason for the compile failure
for my analysis pass: I had to add my object to the namespace llvm instead of
anonymous. This took me some time since i was looking for an linking
failure... but as errors go i should have looked at the error message a
little closer.

So for all those trying to add an analysis path:
* add the object name to the USEDLIBS variable in the tools/llc/Makefile
* use the llvm namespace instead of anonyous

This mail is intended as references for people using the search engines, prior
to asking questions :-). But maybe this information could also be added to
http://llvm.org/docs/WritingAnLLVMPass.html?

Thanks
ST

Hi

Thanks for all your feedback. I just found the reason for the compile failure
for my analysis pass: I had to add my object to the namespace llvm instead of
anonymous. This took me some time since i was looking for an linking
failure... but as errors go i should have looked at the error message a
little closer.

One would expect this, its a facility of the C++ language. The anonymous
namespace is, essentially, the same as declaring everything in it
static. That is, the symbols are not exported and not available for
linking.

So for all those trying to add an analysis path:
* add the object name to the USEDLIBS variable in the tools/llc/Makefile
* use the llvm namespace instead of anonyous

These statements are only true if you're adding an analysis pass to
LLVM. If the pass is for use outside of LLVM then you want to:

* use the SHARED_LIBRARY=1 flag in your makefile
* use the --load option on llc to load your shared library
* use any namespace other than llvm or anonymous for declaring those
symbols that need
  to be linked.

This mail is intended as references for people using the search engines, prior
to asking questions :-). But maybe this information could also be added to
http://llvm.org/docs/WritingAnLLVMPass.html?

Such a patch would be readily accepted.

Thanks,

Reid.

Hi

One would expect this, its a facility of the C++ language. The anonymous
namespace is, essentially, the same as declaring everything in it
static. That is, the symbols are not exported and not available for
linking.

Yes, it was pretty clear after finding out that this isn't a linking error
which i suspected...

> So for all those trying to add an analysis path:
> * add the object name to the USEDLIBS variable in the tools/llc/Makefile
> * use the llvm namespace instead of anonyous

These statements are only true if you're adding an analysis pass to
LLVM. If the pass is for use outside of LLVM then you want to:

<snip>
Yes, but this is already documented on the Website and works really well :-).

> This mail is intended as references for people using the search engines,
> prior to asking questions :-). But maybe this information could also be
> added to http://llvm.org/docs/WritingAnLLVMPass.html?

Such a patch would be readily accepted.

Ok, if i get my pass flying i'll write s.t. unfortunatly i hit another
roadblock:

Everthing now compiles fine, but when running llc with invoking my own backend
derived from the cbackend i get the following error:

llc -f -march my_backend a.out.bc
llc: PassManagerT.h:387: void llvm::PassManagerT<Trait>::markPassUsed(const
llvm::PassInfo*, llvm::Pass*) [with Trait = llvm::MTraits]: Assertion
`getAnalysisOrNullUp(P) &&
dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) && "Pass available but
not found! " "Perhaps this is a module pass requiring a function pass?"'
failed.
llc((anonymous namespace)::PrintStackTrace()+0x1f)[0x880791f]
/lib/tls/libc.so.6(abort+0x1d2)[0xb7d00fa2]
/lib/tls/libc.so.6(__assert_fail+0x10f)[0xb7cf92df]
llc(llvm::PassManagerT<llvm::MTraits>::markPassUsed(llvm::PassInfo const*,
llvm::Pass*)+0xf6)[0x8736c36]
Aborted

The requirements of this pass are quite modest:
void MParSchedule::getAnalysisUsage(AnalysisUsage &AU) const {
        AU.setPreservesAll();
}

The Header looks of this pass looks like this:

namespace llvm {
        class MParSchedule : public BasicBlockPass {
                public:
                        virtual bool runOnBasicBlock(BasicBlock &B);
                        void getAnalysisUsage(AnalysisUsage &AU) const;
                        virtual void releaseMemory();
                        map<const BasicBlock *,list<Schedule*> *>
BlockSchedule;
                        list<Schedule*>* lookupBasicBlock(BasicBlock *);
                private:
                        bool in_ValueList(Value *val);
                        list<const Value*> ValueList;
                        list<Instruction*> InstructionList;
        };
};

It gets Registered in the cpp file via:
RegisterAnalysis<MParSchedule> X("MParSchedule","Maximal Parallel Schedule");

This pass has been tested as optimization pass with opt, and everything worked
in this configuration.

Thanks
ST

What requires MParSchedule? Note that, since it's a basic block pass, only other basic block passes can require it. If you have a FunctionPass that requires a BasicBlockPass, it will fail the same was as when a ModulePass requires a FunctionPass.

-Chris

Hi. I remember I had some similar problems some weeks ago. My problem was
that I was using "makellvm llc" from my working directory, but it caused
the libraries to be "unsynchronized". To solve, just make your application
from the root directory (e.g.: $HOME/llvm> make).

Hi

> Everthing now compiles fine, but when running llc with invoking my own
> backend derived from the cbackend i get the following error:
> namespace llvm {
> class MParSchedule : public BasicBlockPass {
> public:
>
> This pass has been tested as optimization pass with opt, and everything
> worked in this configuration.

What requires MParSchedule? Note that, since it's a basic block pass,
only other basic block passes can require it. If you have a FunctionPass
that requires a BasicBlockPass, it will fail the same was as when a
ModulePass requires a FunctionPass.

void MParSchedule::getAnalysisUsage(AnalysisUsage &AU) const {
        AU.setPreservesAll();
}

MParSchedule requires nothing and changes nothing. So hopefully the above code
represents this fact?

I also did an make clean && make in my llvm root directory to check if this is
a build system problem. Which it is not.

For easier reference i just attached the files of this pass to this mail. They
are under GPL.

Best Regards
ST

Makefile (213 Bytes)

MParSchedule.cpp (3.86 KB)

ScheduleList.h (300 Bytes)

MParSchedule.h (605 Bytes)

that requires a BasicBlockPass, it will fail the same was as when a
ModulePass requires a FunctionPass.

void MParSchedule::getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
}

MParSchedule requires nothing and changes nothing. So hopefully the above code
represents this fact?

Right it does. However, does something *else* require MParSchedule? If so, what?

-Chris

I also did an make clean && make in my llvm root directory to check if this is
a build system problem. Which it is not.

For easier reference i just attached the files of this pass to this mail. They
are under GPL.

Best Regards
ST

-Chris

Hi

Right it does. However, does something *else* require MParSchedule? If
so, what?

Ok, i am writing on a different backend based on the cbackend.

The test usage of this pass looks like this:

void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LoopInfo>();
      AU.addRequired<MParSchedule>();
      AU.setPreservesAll();
}

and then in the runOnFunction pass of this backend:
LI = &getAnalysis<LoopInfo>();
MParSchedule &MPar = getAnalysis<MParSchedule>();
lowerIntrinsics(F);
printFloatingPointConstants(F);
F.renameLocalSymbols();
list<Schedule *>* ScheduleList;
Schedule *currentSchedule;
for (Function::iterator i = F.begin(), e = F.end(); i != e; ++i) {
  for(BasicBlock::iterator j=i->begin(),bbe=i->end();j!=bbe;++j) {
          BasicBlock *bb;
    if((bb=dyn_cast<BasicBlock>(j))) {
                  ScheduleList=MPar.lookupBasicBlock(bb);
                        if(ScheduleList) {
                          cerr<<"Schedule List: "<<bb->getName()<<endl;
                                for(list<Schedule*>::iterator
lsi=ScheduleList->begin(),lse=ScheduleList->end();lsi!=lse;++lsi) {
        cerr<<(*lsi)->cycle<<" "<<(*(*lsi)->instr);
        }
                         cerr<<endl;
      } else cerr<<"Schedule not found"<<endl;
               } else cerr<<"Instruction not a basic block"<<endl;
  }
}
return false;

Compiling and linking works fine but
llc -f -march my_backend a.out.bc
gives this error:
llc: PassManagerT.h:387: void llvm::PassManagerT<Trait>::markPassUsed(const
llvm::PassInfo*, llvm::Pass*) [with Trait = llvm::MTraits]: Assertion
`getAnalysisOrNullUp(P) &&
dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) && "Pass available but
not found! " "Perhaps this is a module pass requiring a function pass?"'
failed.
llc((anonymous namespace)::PrintStackTrace()+0x1f)[0x880791f]
/lib/tls/libc.so.6(abort+0x1d2)[0xb7da7fa2]
/lib/tls/libc.so.6(__assert_fail+0x10f)[0xb7da02df]
llc(llvm::PassManagerT<llvm::MTraits>::markPassUsed(llvm::PassInfo const*,
llvm::Pass*)+0xf6)[0x8736c36]
Aborted

Poking around i tried to inherit the MParSchedule Pass from ImmutablePass then
i get an different error:
llc: /work0/tstone/llvm-1.7/include/llvm/Pass.h:185: AnalysisType&
llvm::Pass::getAnalysisID(const llvm::PassInfo*) const [with AnalysisType =
llvm::FindUsedTypes]: Assertion `i != AnalysisImpls.size() && "getAnalysis*()
called on an analysis that was not " "'required' by pass!"' failed.
llc((anonymous namespace)::PrintStackTrace()+0x1f)[0x8807aaf]
/lib/tls/libc.so.6(abort+0x1d2)[0xb7d98fa2]
/lib/tls/libc.so.6(__assert_fail+0x10f)[0xb7d912df]
llc(llvm::FindUsedTypes&
llvm::Pass::getAnalysisID<llvm::FindUsedTypes>(llvm::PassInfo const*)
const+0xa5)[0x8173da5]
[0x8995e54]
make: *** [a.out.s] Aborted

Thanks for your help
ST

Right it does. However, does something *else* require MParSchedule? If
so, what?

Ok, i am writing on a different backend based on the cbackend.

Ok.

The test usage of this pass looks like this:

void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.addRequired<LoopInfo>();
     AU.addRequired<MParSchedule>();
     AU.setPreservesAll();
}

and then in the runOnFunction pass of this backend:
LI = &getAnalysis<LoopInfo>();
MParSchedule &MPar = getAnalysis<MParSchedule>();

So again, this is the problem I described earlier: you have a pass (MParSchedule) which is a basic block pass. This pass is being required by another pass (your C backend-based thing) which is not a basic block pass. This is the problem, please see the "how to write a pass" doc. The fix is to change MParSchedule to be a function pass or modulepass.

-Chris

Hi Chris and llvm list

Thanks for your answer.

So again, this is the problem I described earlier: you have a pass
(MParSchedule) which is a basic block pass. This pass is being required
by another pass (your C backend-based thing) which is not a basic block
pass. This is the problem, please see the "how to write a pass" doc. The
fix is to change MParSchedule to be a function pass or modulepass.

Ok, after combining all your comments in this thread and reading the
documentation again. I think i figured it out:
Every Pass is allowed to depend on the same granularity (eg. ModulePass
on ModulePass) or coarser (eg. BasicBlockPass on Functionpass but *NOT*
the other way round).

So my here goes my problem: Since my C-Backend modified pass is a module
pass i can only depend on module passes. This stands in contrary to the
proposed way to use the most apropriate (BasicBlock in my case) pass available.
Since there is no way for me in using this pass?

On a sidenote i have promised to update the documentation if i get my pass running.
Is the documentation in revision control somewhere to create my diff against it?

Thanks
ST

All the documentation is in the "docs" directory. You can view the
documentation source by using CVSweb, here:

http://llvm.org/cvsweb/cvsweb.cgi/llvm/docs/

Reid.

Hi Chris and llvm list

Thanks for your answer.

So again, this is the problem I described earlier: you have a pass
(MParSchedule) which is a basic block pass. This pass is being required
by another pass (your C backend-based thing) which is not a basic block
pass. This is the problem, please see the "how to write a pass" doc. The
fix is to change MParSchedule to be a function pass or modulepass.

Ok, after combining all your comments in this thread and reading the
documentation again. I think i figured it out:
Every Pass is allowed to depend on the same granularity (eg. ModulePass
on ModulePass) or coarser (eg. BasicBlockPass on Functionpass but *NOT*
the other way round).

Exactly.

So my here goes my problem: Since my C-Backend modified pass is a module
pass i can only depend on module passes. This stands in contrary to the
proposed way to use the most apropriate (BasicBlock in my case) pass available.

Right.

Since there is no way for me in using this pass?

Why not just define it as a module pass, then iterate over functions and bb's yourself?

-Chris