On Mar 3, 2008, at 5:21 AM, Zack Rusin wrote:
Hey Zack!
> we have two modules, one that we basically use as a library in which
> we store
> a lot of simple function calls, the other is small program generated
> at
> run-time.
Ok.
> Whenever a function call for to one of the builtin functions is
> being called
> we use CloneFunction to clone the instruction from the library
> module and
> insert it in the generated module.
Ok. You might also be interested in doing this in terms of inlining.
In particular, if you're doing code specialization, the
CloneAndPruneFunctionInto method is much faster than doing cloning +
inlining + dead code elimination, at least for cases where
specialization leads to lots of dead code.
> The problem is for example when we have something like:
> declare float @powf(float, float)
> define void @pow(<4 x float>* %res, /*other args*/...) {
> entry:
> ...
> %call = tail call float @powf( float %tmp1, float %tmp3 )
> ...
> }
> while powf has a similar extern declaration in the generated module,
> the
> cloned function after the CloneFunction call obviously refers to the
> powf
> from the library module and asserts as an invalid module. To solve
> that we
> add a mapping to DenseMap from the powf declaration in the library
> module to
> the powf declaration in the generated module, as in:
>
> DenseMap<const Value*, Value *> val;
> val[m_builtins->getFunction("powf")] = currentModule()-
> >getFunction("powf");
> func = CloneFunction(originalFunc, val);
> currentModule()->getFunctionList().push_back(func);
Ok.
> unfortunately after this we get an assert:
> vp-tris: /home/zack/projects/general/llvm/lib/Target/X86/
> X86CodeEmitter.cpp:412:
> unsigned int sizeOfImm(const llvm::TargetInstrDesc*): Assertion `0
> && "Immediate size not set!"' failed.
>
> which I'm a little confused about. Any idea what might be causing
> this and how
> to fix it?
This is very strange, and I'm not sure that one follows from the
other. Are you running the verifier on the module/function after the
IR modifications but before the code generator?
Another approach that might be simpler: instead of juggling two
modules, you might consider just loading the one module (lazily) from
disk, and doing your codegen in that module. This means that you can
directly reference globals and copy code around with no problem. As
long as you use cloning/inlining to copy code into the newly generated
functions before you hack on them, there should be no problem.
-Chris