Optimization Flashcards

(23 cards)

1
Q

What criteria do we us to decide if one compiled MIPS code is better than another?

A

Time it takes for the program to run

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

In the context of compilation, what is heuristics?

A

Recognizing a pattern of instructions and replacing them with an equivalent set that:

a) runs quicker or
b) uses a smaller # of instructions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Do repeated patterns in generated code come from the WLP4 source code?

A

Not necessarily, patterns can appear because code is generated from individual nodes in a parse tree

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is the basic idea behind common subexpression elimination?

A

Store the results of common subexpressions in registers that can be called when code is generated

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How would you generate code for (a+b) * (a+b) using common subexpression elimination?

A
  • Calculate a+b and store in $3
    mult $3, $3
    mflo $3
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What do you need to be careful of when using common subexpression elimination?

A

It may not work with functions (e.g. f(1) + (f(1) ) because the function may have side effects that won’t be repeated if you only run the function once.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is the justification for keeping track of live ranges?

A
  • We want a way to store common subexpressions
  • But what if we have a lot of local variables or subexpressions?
  • We want to use registers as much as possible since accessing registers is quick and reduces the amount of time we have to use lw and sw
  • So we want a way to optimize our register allocation
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is a live range?

A

The live range of a variable is the range starting from where it is a assigned a value to where it is last used with that value

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Why do we use live ranges

A

Live ranges allow us to determine if we can re-use registers for values. If the live ranges of two variables don’t intersect, then the register can be reused

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What are the live ranges for each variable?

int x = 0 ; 
int y = 0 ; 
int z = 0 ; 
x = 4 ; 
y = 5 ; 
x = x + 1 ; 
println(x) ; 
println(y) ; 
z = 7 ; 
println(z) ;
A

The live range for x is 4-7 inclusive

The live range for y is 5-8 inclusive

The live range for z is 9-10 inclusive

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How does code generation with avail work?

A

Avail - List of available registers

Code(Parse tree node, avail) -> register where result is located

When evaluating more than one node, the next code() is called with the old avail, without the register used to store the previous result

This allows us to keep track of what registers are being used to store results

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
Using avail and the new code(), generate code for:
expr1 -> expr2 + term
A
code(expr1, avail) = 
s = code(expr2, avail)
t = code(term, avail\{s} ) 
add $s, $s, $t 
return s
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q
This is the code for (2 + 5): 
lis $3
; load 2
lis $3
.word 2
.word 5
sw $3, -4(30) ; push 2 on stack
sub $30, $30, $4
lis $3 ; load 3
.word 3
lw $5, 0($30) ; pop 2 off stack
add $30, $30, $4
add $3, $5, $3 ; answer

How can you use constant folding to make this more efficient?

A

Instead of loading constants, just calculate answers involving constants at compile time:

lis $3
.word 5

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How many lines of MIPS does the following WLP4 code need without constant propogation?

int x = 2 ;
return x + x ;

A

Answer: 10

  • load 2 into $3 (2: lis, .word)
  • store result in x (1: sw)
  • push onto stack (3: lw, sw, sub)
  • load value stored in x into $3 (1: lw)
  • move x from stack into $5 (2: lw, sub)
  • add $5, $3, store in $3 (1: add)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is constant propagation?

Give an example

A

When the compiler recognizes that a constant can be used in place of a variable, greatly simplifying the code associated with the instruction.

The compiler recognizes that:
x = 5 ;
y = 3 ;
z = x + y ;

Is the same as:
z = 8 ;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How would one implement constant propagation?

A

When nodes of a parse tree are evaluated, instead of just placing the value in $3, return an (encoding, value) pair.

This way, most expressions can be evaluated with two lines of MIPS

e.g. expr1 -> expr2 + term

expr2 -> (const, 2)
term -> (const, 3)

So expr1 is just (const, 5), which is just
lis $3
.word 5

17
Q

What is dead code?

A

Code that never gets executed :(

18
Q

When can dead code occur?

A

The logical test in an if statement is always false

Code is after a return statement

19
Q

What is strength reduction?

A

Replacing operations with faster ones

20
Q

What is inlining?

A

Replace the function call with the body of the entire code

21
Q

What are the pros and cons of inlining?

A

Pros:

  • No need to generate code for that function
  • Save overhead of creating a stack frame for f

Cons:

  • If the function is used often, generate a lot of extra code
  • Difficult for recursive functions
22
Q

How can you optimize tail recursion?

A

Since the recursive call is the very last thing a function does, you can re-use the stack frame since you dont need to save the local variables

23
Q

Since patterns are hard to find in source code, what can we do?

A

Use intermediate code after lexical, syntactic and semantic analysis is finished.

The intermediate code is easier to optimize and is then converted into assembly.