Hi there, 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, -- Verena Beckham Vice President Engineering Codeplay Software Ltd 45 York Place, Edinburgh, EH1 3HP Tel: 0131 466 0503 Fax: 0131 557 6600 Website: http://www.codeplay.com This email and any attachments may contain confidential and /or privileged information and is for use by the addressee only. If you are not the intended recipient, please notify Codeplay Software Ltd immediately and delete the message from your computer. You may not copy or forward it,or use or disclose its contents to any other person. Any views or other information in this message which do not relate to our business are not authorized by Codeplay software Ltd, nor does this message form part of any contract unless so stated. As internet communications are capable of data corruption Codeplay Software Ltd does not accept any responsibility for any changes made to this message after it was sent. Please note that Codeplay Software Ltd does not accept any liability or responsibility for viruses and it is your responsibility to scan any attachments. Company registered in England and Wales, number: 04567874 Registered office: 81 Linkfield Street, Redhill RH1 6BY
Hi Verena, 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. Regards, Jim On Jun 27, 2012, at 2:22 AM, Verena Beckham <verena at codeplay.com> wrote:> Hi there, > > 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, > > -- > Verena Beckham > > Vice President Engineering > > Codeplay Software Ltd > 45 York Place, Edinburgh, EH1 3HP > Tel: 0131 466 0503 > Fax: 0131 557 6600 > Website: http://www.codeplay.com > > This email and any attachments may contain confidential and /or > privileged information and is for use by the addressee only. If you > are not the intended recipient, please notify Codeplay Software Ltd > immediately and delete the message from your computer. You may not copy > or forward it,or use or disclose its contents to any other person. Any > views or other information in this message which do not relate to our > business are not authorized by Codeplay software Ltd, nor does this > message form part of any contract unless so stated. > As internet communications are capable of data corruption Codeplay > Software Ltd does not accept any responsibility for any changes made to > this message after it was sent. Please note that Codeplay Software Ltd > does not accept any liability or responsibility for viruses and it is > your responsibility to scan any attachments. > Company registered in England and Wales, number: 04567874 > Registered office: 81 Linkfield Street, Redhill RH1 6BY > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Hi Verena, 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) 2 { 3 if (n <= 1) 4 return 1; 5 6 int f = n; 7 while (--n > 1) 8 f *= n; 9 return f; 10 } 11 12 13 int main(int argc, char** argv) 14 { 15 if (argc < 2) 16 return -1; 17 char firstletter = argv[1][0]; 18 int result = compute_factorial(firstletter - '0'); 19 20 // Returned result is clipped at 255... 21 return result; 22 } The result from mcjit is ===-------------------------------------------------------------------------== ... Statistics Collected ... ===-------------------------------------------------------------------------== 45 asm-printer - Number of machine instrs printed I tested this code on x86 32bit machine. To verify above result, we can use gdb. You can get information to debug jitted codes from http://llvm.org/docs/DebuggingJITedCode.html. (gdb) disassem Dump of assembler code for function main: 0xb7c27060 <+0>: sub $0x1c,%esp 0xb7c27063 <+3>: movl $0x0,0x18(%esp) 0xb7c2706b <+11>: mov 0x20(%esp),%eax 0xb7c2706f <+15>: mov %eax,0x14(%esp) 0xb7c27073 <+19>: mov 0x24(%esp),%eax 0xb7c27077 <+23>: mov %eax,0x10(%esp) => 0xb7c2707b <+27>: cmpl $0x1,0x14(%esp) 0xb7c27080 <+32>: jg 0xb7c2708c <main+44> 0xb7c27082 <+34>: movl $0xffffffff,0x18(%esp) 0xb7c2708a <+42>: jmp 0xb7c270b1 <main+81> 0xb7c2708c <+44>: mov 0x10(%esp),%eax 0xb7c27090 <+48>: mov 0x4(%eax),%eax 0xb7c27093 <+51>: mov (%eax),%al 0xb7c27095 <+53>: mov %al,0xf(%esp) 0xb7c27099 <+57>: movsbl 0xf(%esp),%eax 0xb7c2709e <+62>: add $0xffffffd0,%eax 0xb7c270a1 <+65>: mov %eax,(%esp) 0xb7c270a4 <+68>: call 0xb7c27010 <compute_factorial> 0xb7c270a9 <+73>: mov %eax,0x8(%esp) 0xb7c270ad <+77>: mov %eax,0x18(%esp) 0xb7c270b1 <+81>: mov 0x18(%esp),%eax 0xb7c270b5 <+85>: add $0x1c,%esp 0xb7c270b8 <+88>: ret End of assembler dump. (gdb) disassem Dump of assembler code for function compute_factorial: 0xb7c27010 <+0>: sub $0xc,%esp 0xb7c27013 <+3>: mov 0x10(%esp),%eax 0xb7c27017 <+7>: mov %eax,0x4(%esp) 0xb7c2701b <+11>: cmp $0x1,%eax => 0xb7c2701e <+14>: jg 0xb7c2702a <compute_factorial+26> 0xb7c27020 <+16>: movl $0x1,0x8(%esp) 0xb7c27028 <+24>: jmp 0xb7c27050 <compute_factorial+64> 0xb7c2702a <+26>: mov 0x4(%esp),%eax 0xb7c2702e <+30>: jmp 0xb7c27038 <compute_factorial+40> 0xb7c27030 <+32>: mov (%esp),%eax 0xb7c27033 <+35>: imul 0x4(%esp),%eax 0xb7c27038 <+40>: mov %eax,(%esp) 0xb7c2703b <+43>: mov 0x4(%esp),%eax 0xb7c2703f <+47>: dec %eax 0xb7c27040 <+48>: mov %eax,0x4(%esp) 0xb7c27044 <+52>: cmp $0x2,%eax 0xb7c27047 <+55>: jge 0xb7c27030 <compute_factorial+32> 0xb7c27049 <+57>: mov (%esp),%eax 0xb7c2704c <+60>: mov %eax,0x8(%esp) 0xb7c27050 <+64>: mov 0x8(%esp),%eax 0xb7c27054 <+68>: add $0xc,%esp 0xb7c27057 <+71>: ret End of assembler dump. Main function generates 23 instructions and compute_factorial function generates 22 instructions. The number of generated instructions are 45 totally and this is same with the result of "-stats" option. I think that we can count the number of instructions per module using Statistic class. Regards, Jin-Gu Kang ________________________________________ From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On Behalf Of Verena Beckham [verena at codeplay.com] Sent: Wednesday, June 27, 2012 6:22 PM To: llvmdev at cs.uiuc.edu Subject: [LLVMdev] Counting instructions in MCJIT Hi there, 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, -- Verena Beckham Vice President Engineering Codeplay Software Ltd 45 York Place, Edinburgh, EH1 3HP Tel: 0131 466 0503 Fax: 0131 557 6600 Website: http://www.codeplay.com This email and any attachments may contain confidential and /or privileged information and is for use by the addressee only. If you are not the intended recipient, please notify Codeplay Software Ltd immediately and delete the message from your computer. You may not copy or forward it,or use or disclose its contents to any other person. Any views or other information in this message which do not relate to our business are not authorized by Codeplay software Ltd, nor does this message form part of any contract unless so stated. As internet communications are capable of data corruption Codeplay Software Ltd does not accept any responsibility for any changes made to this message after it was sent. Please note that Codeplay Software Ltd does not accept any liability or responsibility for viruses and it is your responsibility to scan any attachments. Company registered in England and Wales, number: 04567874 Registered office: 81 Linkfield Street, Redhill RH1 6BY _______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Hello Jin, 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. Verena On 28/06/2012 03:26, Jin Gu Kang wrote:> Hi Verena, > > 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) > 2 { > 3 if (n<= 1) > 4 return 1; > 5 > 6 int f = n; > 7 while (--n> 1) > 8 f *= n; > 9 return f; > 10 } > 11 > 12 > 13 int main(int argc, char** argv) > 14 { > 15 if (argc< 2) > 16 return -1; > 17 char firstletter = argv[1][0]; > 18 int result = compute_factorial(firstletter - '0'); > 19 > 20 // Returned result is clipped at 255... > 21 return result; > 22 } > > The result from mcjit is > ===-------------------------------------------------------------------------==> ... Statistics Collected ... > ===-------------------------------------------------------------------------==> 45 asm-printer - Number of machine instrs printed > > I tested this code on x86 32bit machine. > > To verify above result, we can use gdb. > You can get information to debug jitted codes from > http://llvm.org/docs/DebuggingJITedCode.html. > > (gdb) disassem > Dump of assembler code for function main: > 0xb7c27060<+0>: sub $0x1c,%esp > 0xb7c27063<+3>: movl $0x0,0x18(%esp) > 0xb7c2706b<+11>: mov 0x20(%esp),%eax > 0xb7c2706f<+15>: mov %eax,0x14(%esp) > 0xb7c27073<+19>: mov 0x24(%esp),%eax > 0xb7c27077<+23>: mov %eax,0x10(%esp) > => 0xb7c2707b<+27>: cmpl $0x1,0x14(%esp) > 0xb7c27080<+32>: jg 0xb7c2708c<main+44> > 0xb7c27082<+34>: movl $0xffffffff,0x18(%esp) > 0xb7c2708a<+42>: jmp 0xb7c270b1<main+81> > 0xb7c2708c<+44>: mov 0x10(%esp),%eax > 0xb7c27090<+48>: mov 0x4(%eax),%eax > 0xb7c27093<+51>: mov (%eax),%al > 0xb7c27095<+53>: mov %al,0xf(%esp) > 0xb7c27099<+57>: movsbl 0xf(%esp),%eax > 0xb7c2709e<+62>: add $0xffffffd0,%eax > 0xb7c270a1<+65>: mov %eax,(%esp) > 0xb7c270a4<+68>: call 0xb7c27010<compute_factorial> > 0xb7c270a9<+73>: mov %eax,0x8(%esp) > 0xb7c270ad<+77>: mov %eax,0x18(%esp) > 0xb7c270b1<+81>: mov 0x18(%esp),%eax > 0xb7c270b5<+85>: add $0x1c,%esp > 0xb7c270b8<+88>: ret > End of assembler dump. > > (gdb) disassem > Dump of assembler code for function compute_factorial: > 0xb7c27010<+0>: sub $0xc,%esp > 0xb7c27013<+3>: mov 0x10(%esp),%eax > 0xb7c27017<+7>: mov %eax,0x4(%esp) > 0xb7c2701b<+11>: cmp $0x1,%eax > => 0xb7c2701e<+14>: jg 0xb7c2702a<compute_factorial+26> > 0xb7c27020<+16>: movl $0x1,0x8(%esp) > 0xb7c27028<+24>: jmp 0xb7c27050<compute_factorial+64> > 0xb7c2702a<+26>: mov 0x4(%esp),%eax > 0xb7c2702e<+30>: jmp 0xb7c27038<compute_factorial+40> > 0xb7c27030<+32>: mov (%esp),%eax > 0xb7c27033<+35>: imul 0x4(%esp),%eax > 0xb7c27038<+40>: mov %eax,(%esp) > 0xb7c2703b<+43>: mov 0x4(%esp),%eax > 0xb7c2703f<+47>: dec %eax > 0xb7c27040<+48>: mov %eax,0x4(%esp) > 0xb7c27044<+52>: cmp $0x2,%eax > 0xb7c27047<+55>: jge 0xb7c27030<compute_factorial+32> > 0xb7c27049<+57>: mov (%esp),%eax > 0xb7c2704c<+60>: mov %eax,0x8(%esp) > 0xb7c27050<+64>: mov 0x8(%esp),%eax > 0xb7c27054<+68>: add $0xc,%esp > 0xb7c27057<+71>: ret > End of assembler dump. > > Main function generates 23 instructions and compute_factorial function > generates 22 instructions. The number of generated instructions are 45 > totally and this is same with the result of "-stats" option. > > I think that we can count the number of instructions per module > using Statistic class. > > Regards, > Jin-Gu Kang > ________________________________________ > From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On Behalf Of Verena Beckham [verena at codeplay.com] > Sent: Wednesday, June 27, 2012 6:22 PM > To: llvmdev at cs.uiuc.edu > Subject: [LLVMdev] Counting instructions in MCJIT > > Hi there, > > 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, > > -- > Verena Beckham > > Vice President Engineering > > Codeplay Software Ltd > 45 York Place, Edinburgh, EH1 3HP > Tel: 0131 466 0503 > Fax: 0131 557 6600 > Website: http://www.codeplay.com > > This email and any attachments may contain confidential and /or > privileged information and is for use by the addressee only. If you > are not the intended recipient, please notify Codeplay Software Ltd > immediately and delete the message from your computer. You may not copy > or forward it,or use or disclose its contents to any other person. Any > views or other information in this message which do not relate to our > business are not authorized by Codeplay software Ltd, nor does this > message form part of any contract unless so stated. > As internet communications are capable of data corruption Codeplay > Software Ltd does not accept any responsibility for any changes made to > this message after it was sent. Please note that Codeplay Software Ltd > does not accept any liability or responsibility for viruses and it is > your responsibility to scan any attachments. > Company registered in England and Wales, number: 04567874 > Registered office: 81 Linkfield Street, Redhill RH1 6BY > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Seemingly Similar Threads
- [LLVMdev] Counting instructions in MCJIT
- [LLVMdev] Comment "FIXME" in X86MachObjectWriter::RecordX86Relocation
- [LLVMdev] Comment "FIXME" in X86MachObjectWriter::RecordX86Relocation
- [LLVMdev] Comment "FIXME" in X86MachObjectWriter::RecordX86Relocation
- [DWARF] prologue_end fix not working for VLIW