Sunday, March 1, 2009

Updates for LIR Compiler

Currently, for the LIR Compiler project, I need to make a parser for LIR, which can then generate the required C code to then compile LIR.
Part of this task is also to see how nanojit currently uses LIR. It is pretty simple once you refer to the code snippet provided here - https://developer.mozilla.org/En/Nanojit

Interesting part are the lines 38-44:
// Write a few LIR instructions to the buffer: add the first parameter
// to the constant 2.
writer.ins0(LIR_start);
LIns *two = writer.insImm(2);
LIns *firstParam = writer.insParam(0, 0);
LIns *result = writer.ins2(LIR_add, firstParam, two);
writer.ins1(LIR_ret, result);
Basically, what the code provided above is doing is feeding raw LIR into the LIR Buffer, using the LIRWriter's writer object. From an operational point of view, it is creating a function, which takes an integer input, and adds it to two, and outputs the result. The function is created here on lines 57-69:
// Compile the fragment.
compile(fragmento->assm(), f);
if (fragmento->assm()->error() != None) {
fprintf(stderr, "error compiling fragment\n");
return 1;
}
printf("Compilation successful.\n");

// Call the compiled function.
typedef JS_FASTCALL int32_t (*AddTwoFn)(int32_t);
AddTwoFn fn = reinterpret_cast(f->code());
printf("2 + 5 = %d\n", fn(5));
return 0;

This upper half of this snippet includes code where the raw LIR is first converted into machine code.(where compile(fragmento->assm(), f); is called basically).

Then a pointer to a function is used, which takes an int as input and returns the sum of that parameter with two. (
typedef JS_FASTCALL int32_t (*AddTwoFn)(int32_t); )

Then, printf is hardcoded to call it with a parameter 5, and on linking with nanojit library, the following program will display
2+5=7
Now, what I need to do is generate output for this:

   start
two = int 2
twoPlusTwo = add two, two
ret twoPlusTwo


This adds two and two in the most hardcoded way possible. The conversion from LIR to a program like one shown above is the task of the parser.
What the parser needs to generate for the above code will be this(in a raw form)(changes only):

writer.ins0(LIR_start);
LIns *two = writer.insImm(2);
LIns *firstParam = writer.insImm(2);
LIns *result = writer.ins2(LIR_add, firstParam, two);
writer.ins1(LIR_ret, result);

and
// Call the compiled function.
typedef JS_FASTCALL int32_t (*AddTwoFn)();
AddTwoFn fn = reinterpret_cast(f->code());
printf("2 + 2 = %d\n", fn());
return 0;

Two minor changes, and we have working end product for the parser to produce to complete Goal 0.
Regarding the parser, I am planning to use Flex as suggested by jorendorff

No comments:

Post a Comment