X86AsmPrinter + MASM and NASM backends

I have “refactored” the X86AsmPrinter into a number of files ready for the MASM and NASM backends to be added.

There is a new namespace llvm::X86 to replace the anomonous namespace as this does not work accross mutiple .h and .cpp files. Other than that everything is pritty straight forward, t may possibly need tweeking though.

It has been built under MS VS2003, but I am not sure how to add it to the makefiles for the Cygwin and Linux platforms, help on this would be appreciated.

Afaik there are no specific tests for the X86AsmPrinter. If not it would be good to create some.

Also I am wondering about how to go about creating tests for the MASM and NASM backends, hints and help are welcomed.

Aaron
.

NewX86AsmPrinter.tar.gz (5.73 KB)

Builds fine on Linux, but there seems to be a problem building it on Cygwin, will look into this.

Aaron

Some wheird problem, Target/X86 builds okay now.

But there seems to be another problem with the Cygwin build :-

make[4]: Entering directory /usr/build/llvm/lib/Target/SparcV9/ModuloScheduling' llvm[4]: Compiling ModuloSchedulingSuperBlock.cpp for Debug build /usr/src/llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp : In member function virtual bool llvm::ModuloSchedulingSBPass::runOnFunction(l
lvm::Function&)’:
/usr/src/llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp
:151: error: alarm' undeclared (first use this function) /usr/src/llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp :151: error: (Each undeclared identifier is reported only once for each function it appears in.) make[4]: *** [/usr/build/llvm/lib/Target/SparcV9/ModuloScheduling/Debug/ModuloSc hedulingSuperBlock.o] Error 1 make[4]: Leaving directory /usr/build/llvm/lib/Target/SparcV9/ModuloScheduling’

make[3]: *** [ModuloScheduling/.makeall] Error 2
make[3]: Leaving directory /usr/build/llvm/lib/Target/SparcV9' make[2]: *** [SparcV9/.makeall] Error 2 make[2]: Leaving directory /usr/build/llvm/lib/Target’
make[1]: *** [Target/.makeall] Error 2
make[1]: Leaving directory `/usr/build/llvm/lib’
make: *** [all] Error 1

Aaron

Hello ,

I am compiling SPEC 2000 benchmarks with llvm .Got stuck with calculating “execution time” of all the .bc and native files.

The log for nightly test itself gives execution times but I am passing the bytecode files to my pass which gives another bytecode file.I have to calculate execution time of such bytecode and native files as well.If i simply do this:

time lli spec_benchmark.bc OR time ./spec_benchmark.native

I need to know the command line options and also how to run for “test” or “ref” etc and like.Is

I run experiments (run my pass) some 30 times so is there any way to achieve it globally ?

I appreciate your time,

Thanks

I am compiling SPEC 2000 benchmarks with llvm .Got stuck with calculating "execution time" of all the .bc and native files.

The log for nightly test itself gives execution times but I am passing the bytecode files to my pass which gives another bytecode file.I have to calculate execution time of such bytecode and native files as well.If i simply do this:

You should look into the llvm-test framework. All of the tests in it (as well as 'external tests' which we don't provide source for, like SPEC) allow you to do things like this. If you look at llvm-test/TEST.*Makefile and llvm-test/TEST.*report files, you'll see ways to automatically generate custom reports.

Unfortunately there is no documentation for how to build a custom report, but there are many examples. The 'jit' report (TEST.jit.Makefile and TEST.jit.report) are a simple example to demonstrate this. For example, go into llvm-test/MultiSource/Benchmarks/Olden and run:

$ make TEST=jit report

This should spit out something like this (on X86):

Name: | Total CodeGen InstSel LiveVar RA FPStack Peep | MCSize #MCInsts #Glob | #store #load #fp #fxch |
treeadd/treeadd | 6.38 0.0300 0.0133 0.0023 0.0054 0.0001 0.0002 | 1000 245 115 | * 10 * * |
power/power | 4.87 0.0899 0.0368 0.0044 0.0366 0.0022 0.0003 | 5720 1336 702 | 105 216 790 58 |
tsp/tsp | 4.72 0.1400 0.0439 0.0073 0.0591 0.0023 0.0005 | 4463 1128 106 | 62 149 469 28 |
bh/bh | 3.09 0.2700 0.1231 0.0107 0.1184 0.0030 0.0006 | 11983 2483 137 | 223 408 968 27 |
bisort/bisort | 2.86 0.0800 0.0332 0.0046 0.0163 0.0002 0.0002 | 3825 914 148 | 17 64 * * |
em3d/em3d | 2.84 0.0600 0.0569 0.0034 0.0195 0.0003 0.0002 | 3005 727 406 | 32 79 58 1 |
voronoi/voronoi | 1.11 0.1900 0.0601 0.0081 0.0755 0.0024 0.0009 | 8676 2205 322 | 141 275 761 38 |
health/health | 0.97 0.0800 0.0298 0.0036 0.0171 0.0004 0.0002 | 3438 823 268 | 35 49 101 6 |
perimeter/perimeter | 0.64 0.0800 0.0307 0.0040 0.0149 0.0002 0.0002 | 4266 987 79 | 21 57 * * |
mst/mst | 0.21 0.0500 0.0167 0.0025 0.0117 0.0001 0.0001 | 2094 491 223 | 15 33 * * |

This recursively traverses llvm-test building all of the programs in the subdirectory from where you start. The report stuff can emit a text file like this, HTML files, CSV, and latex output.

There is a lot of stuff there to play with, I would suggest giving it a try. To use SPEC 95/2K, set up the External/SPEC/* stuff and it should just work (including automatic management of input/output files etc).

BTW, the nightly tester is just one client of this framework.

-Chris

time lli spec_benchmark.bc OR time ./spec_benchmark.native

I need to know the command line options and also how to run for "test" or "ref" etc and like.Is

I run experiments (run my pass) some 30 times so is there any way to achieve it globally ?

I appreciate your time,

Thanks

---------------------------------
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football

-Chris

Some wheird problem, Target/X86 builds okay now.
But there seems to be another problem with the Cygwin build :-

make[4]: Entering directory `/usr/build/llvm/lib/Target/SparcV9/ModuloScheduling'
llvm[4]: Compiling ModuloSchedulingSuperBlock.cpp for Debug build
/usr/src/llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp
: In member function `virtual bool llvm::ModuloSchedulingSBPass::runOnFunction(l
lvm::Function&)':
/usr/src/llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp
:151: error: `alarm' undeclared (first use this function)

This was some debugging code, I've fixed (removed) it. I'll look at your patch next.

-Chris

From: Aaron Gray
To: LLVM Developers Mailing List
Sent: Thursday, June 30, 2005 9:10 PM
Subject: Re: [LLVMdev] X86AsmPrinter + MASM and NASM backends

Builds fine on Linux, but there seems to be a problem building it on Cygwin, will look into this.

Aaron
   From: Aaron Gray
   To: LLVM Developers Mailing List
   Sent: Thursday, June 30, 2005 7:12 PM
   Subject: [LLVMdev] X86AsmPrinter + MASM and NASM backends

   I have "refactored" the X86AsmPrinter into a number of files ready for the MASM and NASM backends to be added.

   There is a new namespace llvm::X86 to replace the anomonous namespace as this does not work accross mutiple .h and .cpp files. Other than that everything is pritty straight forward, t may possibly need tweeking though.

   It has been built under MS VS2003, but I am not sure how to add it to the makefiles for the Cygwin and Linux platforms, help on this would be appreciated.

   Afaik there are no specific tests for the X86AsmPrinter. If not it would be good to create some.

   Also I am wondering about how to go about creating tests for the MASM and NASM backends, hints and help are welcomed.

   Aaron
   .

----------------------------------------------------------------------------

   _______________________________________________
   LLVM Developers mailing list
   LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
   http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

------------------------------------------------------------------------------

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris

I have "refactored" the X86AsmPrinter into a number of files ready for the MASM and NASM backends to be added.

Nice!

There is a new namespace llvm::X86 to replace the anomonous namespace as this does not work accross mutiple .h and .cpp files. Other than that everything is pritty straight forward, t may possibly need tweeking though.

Ok, here are my requests. Overall the code looks really good. I would appreciate it if you could make the following changes:

1. At the top of the X86AsmPrinter.cpp file, you note that the code was
    refactored. The comments should indicate the current state of the
    code, not the history. Please just say that it supports the X/Y/Z
    subclasses, not that it was changed to support them. Likewise in any
    other similar comments. In the CVS commit message, we will explain the
    history of the code.
2. In the .cpp files, please use the 'using namespace llvm;' idiom to
    avoid placing the entire C++ file in two sets of namespaces (which
    indents everything). Check out other .cpp files for how they are
    written as examples.
3. Please #include X86ASmPrinter.h first in X86asmPrinter.cpp (see the
    coding standard for justification). This will expose the fact that the
    .h file needs some #includes to be self contained.
4. I think it would be a good idea to make the isScale/isMem methods
    inline in the header file, even if that means more #includes are
    needed in the .h file. These are pretty performance sensitive for the
    printers, so it would be good for them to be inlined.
5. Please add #include guards around the headers (#ifndef XX_H/#define
    XX_H), like the other llvm headers.

Once you've made these high level changes, please send the code out again and I'll check it once more. Again, the high-level refactoring looks great, and I'm glad you seperated the refactoring from the addition of
new functionality!

It has been built under MS VS2003, but I am not sure how to add it to the makefiles for the Cygwin and Linux platforms, help on this would be appreciated.

There should be no changes required for the Makefiles, unlike those silly VC project files :stuck_out_tongue_winking_eye:

Afaik there are no specific tests for the X86AsmPrinter. If not it would be good to create some.

Correct. X86AsmPrinter is currently only used for debugging: no targets use it. I suspect your target will be the first real test! This also means that if it is doing something wrong, you can change it!

Also I am wondering about how to go about creating tests for the MASM and NASM backends, hints and help are welcomed.

I think the best way to do this is to start pumping code through it. If you can get the llvmgcc front-end to work in your environment, llvm-test is the place to start.

Thanks for the great enhancement!

-Chris

Chris,

Okay, I have done as you have requested.

The only thing I did not like was a clsh between the enum X86 and the new namespace X86, which I had to rename as x86 :frowning:

Anyway, I suppose the lower case 'x' in 'x86' fits in with the lowercase 'llvm' namespace.

Build tested on MS VC2003 and Linux.

Aaron

NewX86AsmPrinter.tar.gz (5.67 KB)

Okay, I have done as you have requested.

Patch committed here:

I made a couple of changes to the code you submitted. The most important
is that I converted this (in the .h files):

using namespace llvm;
namespace x86 {
...

into:

namespace llvm {
namespace x86 {
...

The former defines the "..." stuff in the x86 namespace, the later defines it in the llvm::x86 namespace.

In addition to this, I changed some other minor things, e.g. I changed the tabs in the files to spaces. Also, I reduced the number of #include's in the headers and .cpp files to the minimum. In the future, please be aware of these issues.

Otherwise, the patch looks great!

The only thing I did not like was a clsh between the enum X86 and the new namespace X86, which I had to rename as x86 :frowning:

Anyway, I suppose the lower case 'x' in 'x86' fits in with the lowercase 'llvm' namespace.

I'm not sure I follow. X86 is a namespace. I assume you're running into some strange VC thing or something (?). If not, please submit a patch to change the x86 namespaces to the X86 namespace. It's possible that the problem I described above was causing this issue for you.

Thanks again,

-Chris

Patch committed here:

Just looked at the WebCVS.

I made a couple of changes to the code you submitted. The most important
is that I converted this (in the .h files):

using namespace llvm;
namespace x86 {
...

into:

namespace llvm {
namespace x86 {
...

Right, that is how I had it in the beggining, obviously I miss understood your request regarding the namespaces.

The former defines the "..." stuff in the x86 namespace, the later defines it in the llvm::x86 namespace.

Great :slight_smile:

In addition to this, I changed some other minor things, e.g. I changed the tabs in the files to spaces. Also, I reduced the number of #include's in the headers and .cpp files to the minimum. In the future, please be aware of these issues.

Okay, sorry I missed doing the inlines. Thought I had taken care of using spaces rather than tabs, I'll check my editor preferences.

Otherwise, the patch looks great!

Good. Its not exactly that big a job though :slight_smile:

The only thing I did not like was a clsh between the enum X86 and the new namespace X86, which I had to rename as x86 :frowning:

Anyway, I suppose the lower case 'x' in 'x86' fits in with the lowercase 'llvm' namespace.

I'm not sure I follow. X86 is a namespace. I assume you're running into some strange VC thing or something (?). If not, please submit a patch to change the x86 namespaces to the X86 namespace. It's possible that the problem I described above was causing this issue for you.

No dont worry about that now. Just the X86 namespace was clashing with the X86 instruction enum when it was not nested under the LLVM namespace.

I have written the X86MASMPrinter and will test it tommorow. It had to override behaviour right back to the AsmPrinter class as it had to override the basic 'gas' behaviour of the AsmPrinter class.

I am not really sure whether to do a X86NASMPrinter or whether to bypass that for now and work on an X86COFFWriter which would be more useful to me ?

Also looking at your ELF code I do not know how to fit it in exactly with the command line switches etc.

Thanks,

Aaron

Okay, sorry I missed doing the inlines. Thought I had taken care of using

I ment headers not inlines. Yes I should have checked there usage.

Aaron

I am now getting the following link errors on all executables:

x86.lib(X86AsmPrinter.obj) : error LNK2001: unresolved external symbol "public: virtual bool __thiscall llvm::x86::X86ATTAsmPrinter::runOnMachineFunction(class llvm::MachineFunction &)" (?runOnMachineFunction@X86ATTAsmPrinter@x86@llvm@@UAE_NAAVMachineFunction@3@@Z)
x86.lib(X86AsmPrinter.obj) : error LNK2001: unresolved external symbol "public: virtual bool __thiscall llvm::x86::X86IntelAsmPrinter::runOnMachineFunction(class llvm::MachineFunction &)" (?runOnMachineFunction@X86IntelAsmPrinter@x86@llvm@@UAE_NAAVMachineFunction@3@@Z)
x86.lib(X86AsmPrinter.obj) : error LNK2001: unresolved external symbol "public: virtual bool __thiscall llvm::x86::X86IntelAsmPrinter::doInitialization(class llvm::Module &)" (?doInitialization@X86IntelAsmPrinter@x86@llvm@@UAE_NAAVModule@3@@Z)

Aaron Gray wrote:

Fixed it. You did not add the new files to Visual Studio (or at least forgot to include x86.vcproj with the other files).

Jeff Cohen wrote:

Fixed it. You did not add the new files to Visual Studio (or at least forgot to include x86.vcproj with the other files).

Sorry Jeff thats my fault.

Aaron

Hello,

    I've written a random program generator and have successfuly used it to
locate LLVM and GCC bugs. I'm releasing it to public domain for others to
use or improve as needed.

    It creates a program by generating a call graph and using reverse data
flow to populate local variables, function parameters, and globals. The
programs it generates are all error-free (except for a few corner cases
involving modulus and shift operators), and of arbitrary complexity.

    The generated programs output a hash value after sucessful termination
which is uniquely derrived from the exection of the program. This value may
be used to check for errors in the optimizer by comparing it to the output
from the debug version.

    Because the call graph is available immediately before the output of the
final program text, it may be possible to integrate this tool with the LLVM
back-end for automatic test-case reduction to locate the offending source
text. Also, as this tool uses general programming concepts, it would be
fairly easy to generate other C-like languages on the back-end (Pascal, Ada,
C#, Java, etc).

You can get the code from here:
http://www.fractalscape.org/RandomProgramGenerator

--Bryan
bryan.turner@pobox.com

The only thing I did not like was a clsh between the enum X86 and the new namespace X86, which I had to rename as x86 :frowning:

Anyway, I suppose the lower case 'x' in 'x86' fits in with the lowercase 'llvm' namespace.

I'm not sure I follow. X86 is a namespace. I assume you're running into some strange VC thing or something (?). If not, please submit a patch to change the x86 namespaces to the X86 namespace. It's possible that the problem I described above was causing this issue for you.

No dont worry about that now. Just the X86 namespace was clashing with the X86 instruction enum when it was not nested under the LLVM namespace.

Ok.

I have written the X86MASMPrinter and will test it tommorow. It had to override behaviour right back to the AsmPrinter class as it had to override the basic 'gas' behaviour of the AsmPrinter class.

Ok.

I am not really sure whether to do a X86NASMPrinter or whether to bypass that for now and work on an X86COFFWriter which would be more useful to me ?

I wouldn't suggest writing an X86NASMPrinter: just change the current Intel printer to do what you want. Noone is currently using the intel printer, so you can do what you wish to it.

Also looking at your ELF code I do not know how to fit it in exactly with the command line switches etc.

I don't know which you would prefer. I'm actively (but slowly) hacking on the ELF writer in my spare time. It will probably be a lot easier to write the COFF writer after the ELF write is done, so you can use it as an example.

In any case, getting the nasm writer working will be much easier still.

-Chris

I am not really sure whether to do a X86NASMPrinter or whether to bypass that for now and work on an X86COFFWriter which would be more useful to me ?

I wouldn't suggest writing an X86NASMPrinter: just change the current Intel printer to do what you want. Noone is currently using the intel printer, so you can do what you wish to it.

Once I have finished rewriting the MASM printer then a NASM one should take no time at all, he says :slight_smile:

The NASM like the MASM does not have % symbols on the register names so will either inherit from the MASM printer or have its own TableGen class.

Also looking at your ELF code I do not know how to fit it in exactly with the command line switches etc.

I don't know which you would prefer. I'm actively (but slowly) hacking on the ELF writer in my spare time. It will probably be a lot easier to write the COFF writer after the ELF write is done, so you can use it as an example.

Yes I will wait till you have done the ELF writer.

In any case, getting the nasm writer working will be much easier still.

I am probably going to do a NASM version after a bit of a break.

Aaron

Couldn't one conditionally output some macros for the assembler to
translate the reg names rather than having another .td file? or is '%'
not a valid part of a macro on NASM?

Andrew

I've already written the code for MASM, besides it is neater that way.

I have augmented the X86InstrInfo.td file with another target class for MASM, and can either use the MASM class for NASM or do the same thing again creating another target class for NASM.

Aaron

The NASM like the MASM does not have % symbols on the register names so will either inherit from the MASM printer or have its own TableGen class.

This is easy, just change X86IntelAsmPrinter::printOp to not add the % prefix:

   case MachineOperand::MO_MachineRegister:
     if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
       // Bug Workaround: See note in Printer::doInitialization about %.
       O << "%" << RI.get(MO.getReg()).Name;
     else
       O << "%reg" << MO.getReg();
     return;

... The comment about a bug workaround is obsolete now (it's referring to a GAS bug in intel mode, which we don't use anymore), so feel free to change it.

Also looking at your ELF code I do not know how to fit it in exactly with the command line switches etc.

I don't know which you would prefer. I'm actively (but slowly) hacking on the ELF writer in my spare time. It will probably be a lot easier to write the COFF writer after the ELF write is done, so you can use it as an example.

Yes I will wait till you have done the ELF writer.

Ok.

In any case, getting the nasm writer working will be much easier still.

I am probably going to do a NASM version after a bit of a break.

ok.

-Chris