I wondered whether anyone could give me any advice about counting assembly instructions when using MCJIT?
For performance regression testing I would like to be able to count the number of instructions generated during the jit compilation of a given module.
The Statistic class, as far as I understand, cannot collect this data per-module (per-ExecutionEngine/per-MCJIT), and there is no way of extracting a single statistic without doing string manipulation. I'm also doing several code gens in parallel, so even if the class is thread-safe, I cannot find the values for the single modules.
In JIT you can add a JITListener, which can count the MachineInstructions, with the assumption that there is a (more or less) 1-2-1 mapping between machine and assembly instructions. Is there something equivalent for MCJIT?
I can write a MachineFunctionPass to do the same, but I can find no way of inserting that into the PassManager that MCJIT uses. This means I'm replicating the passes and doing code gen twice, basically.
Any advice would be much appreciated!
Thank you very much,
There's currently no explicit support for that, no. The MCJIT uses the same pass handling as the static compiler. In particular, it uses TargetMachine::addPassesToEmitMC().
Where you likely really want to hook into the process is the MCStreamer's EmitInstruction() method, as that really will be a 1:1 mapping to machine instructions, including any that come from pseudo-instructions or even inline assembly.
I think that we can count the number of instructions with "-stats"
command line option. As you mentioned, this option uses Statistic class
like "STATISTIC(EmittedInsts, "Number of machine instrs printed");"
I don't know exactly about parallel code generation environment but
this option seems like to work correctly in common case as following.
This is an example from http://llvm.org/docs/DebuggingJITedCode.html.
1 int compute_factorial(int n)
3 if (n <= 1)
4 return 1;
6 int f = n;
7 while (--n > 1)
8 f *= n;
9 return f;
13 int main(int argc, char** argv)
15 if (argc < 2)
16 return -1;
17 char firstletter = argv;
18 int result = compute_factorial(firstletter - '0');
20 // Returned result is clipped at 255...
21 return result;
The result from mcjit is
Thanks for your advice. However, I still don't think the Statistics class will work for me: I'm compiling two modules at the same time, with a single LLVM instance. Therefore the Statistics of the two will be collected in parallel and I can only get the sum of both. That is because Statistics is not associated with a module.