Sign in to follow this  
  • entries
    557
  • comments
    1237
  • views
    421501

Untitled

Sign in to follow this  
Evil Steve

54 views

Whee. Optimising is fun.
Given my previous sample input of:
void Test() {
int test = 12 + 5 * 4 - 100 / 50;
}

I now get (Comments mine):

func Test
{
mov r0, 100
div r0, 50
push r0
mov r0, 5 ;
mul r0, 4 ;
mov r1, r0 ; *Cough*
mov r0, 12 ;
add r0, r1 ;
pop r1
sub r0, r1
mov test, r0
}


Next stage


Next up is compile time evaluation of operators. I know that r0 contains 100 at the start there, so I can substitute r0 for 100 until it's written to. My ICodeNodeOpBinary class tells me that the div instruction writes to (and reads from) r0, so I stop substituting r0 there. My ICodeNodeOpBinary class is able to evaluate any opcode, if the two values are constant (Or it will shortly), so it evaluates it to mov r0, 2. r0 isn't read from between it's initialisation on the first opcode and it's termination on the second one, so that opcode can be dropped entirely. Going through all the code doing that should give me:

func Test
{
mov r0, 2
push r0
mov r0, 32
pop r1
sub r0, r1
mov test, r0
}


The bit commented in the code above should optimise away nicely, since:

; Original:
mov r0, 5
mul r0, 4
mov r1, r0
mov r0, 12
add r0, r1

; After first substitution (mov r0, 5):
mov r0, 20
mov r1, r0
mov r0, 12
add r0, r1

; After second substitution (mov r0, 20):
mov r1, 20
mov r0, 12
add r0, r1

; After third substitution (mov r1, 20):
mov r0, 12
add r0, 20

; After fourth substitution (mov r0, 12):
mov r0, 32

; mov r0, 32 can then be substituted elsewhere


And that should all work our automatically, since I go through the I-code nodes in order.

Later on


Once the mov's and opcodes have been evaluated, I should be able to do away with mov-push pairs. E.g:

; Original:
func Test
{
mov r0, 2
push r0
mov r0, 32
pop r1
sub r0, r1
mov test, r0
}

; Becomes:
func Test
{
push 2
mov r0, 32
pop r1
sub r0, r1
mov test, r0
}

After that, I can change push/pop's into a mov (Perhaps I should do this earlier?). That'll give:

func Test
{
mov r1, 2
mov r0, 32
sub r0, r1
mov test, r0
}

Hmm. Yeah, I should do the push/pop reduction first. Then I won't need a second pass of evaluating mov's and operators.

Anyway, once this is all done, it should boil down to:
mov test 30
Then I need to test the living crap out of it [smile]



Todo list

  1. Source code annotation as comments

  2. Make the VM support stack offsets for variables. Maybe just a simple mov command that'll grab a stack index into a register, that should need the least modification. movstack or something I think.

  3. Proper control structures. There's no support for anything like if, while, for, return, whatever. They should be a piece of piss to implement though. And hopefully it won't need much optimising.

  4. Dead code removal. Control structures can be optimised away if the expression can be evaluated at compile time.


Anyway, back to work for now...
Sign in to follow this  


1 Comment


Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now