Code Generation for Control Flow Mooly Sagiv html

  • Slides: 47
Download presentation
Code Generation for Control Flow Mooly Sagiv html: //www. math. tau. ac. il/~msagiv/courses/wcc 03.

Code Generation for Control Flow Mooly Sagiv html: //www. math. tau. ac. il/~msagiv/courses/wcc 03. html Chapter 6. 4

Outline • Local flow of control – Conditionals – Switch – Loops • •

Outline • Local flow of control – Conditionals – Switch – Loops • • • Routine Invocation Non-local gotos Runtime errors Handling Exceptions Summary

Machine Code Assumptions Instruction Meaning GOTO Label Jump to Label Indirect jump Conditional Jump

Machine Code Assumptions Instruction Meaning GOTO Label Jump to Label Indirect jump Conditional Jump GOTO label register IF condition register then GOTO Label IF not condition register then GOTO Label

Boolean Expressions • In principle behave like arithmetic expressions • But are treated specially

Boolean Expressions • In principle behave like arithmetic expressions • But are treated specially – Different machine instructions – Shortcut computations if (a < b) goto l Code for a < b yielding a condition value Conversion condition value into Boolean Conversion from Boolean in condition value Jump to l on condition value

Shortcut computations • Languages such as C define shortcut computation rules for Boolean •

Shortcut computations • Languages such as C define shortcut computation rules for Boolean • Incorrect translation of e 1 && e 2 Code to compute e 1 in loc 1 Code to compute e 2 in loc 2 Code for && operator on loc 1 and loc 2

Code for Booleans (Location Computation) • Top-Down tree traversal • Generate code sequences instructions

Code for Booleans (Location Computation) • Top-Down tree traversal • Generate code sequences instructions • Jump to a designated ‘true’ label when the Boolean expression evaluates to 1 • Jump to a designated ‘false’ label when the Boolean expression evaluates to 0 • The true and the false labels are passed as parameters

Example if ((a==0) && (b > 5)) x = ((7 * a) + b)

Example if ((a==0) && (b > 5)) x = ((7 * a) + b) if && == a : = x > 0 b 5 + * 7 b a

if Lt Lf && No label Lf Lt == x Lf > Cmp_Constant R

if Lt Lf && No label Lf Lt == x Lf > Cmp_Constant R 0, 0 Cmp_Constant R 0, 5 IF NOT EQ THEN GOTO Lf IF GT THEN GOTO Lt Lf: : = Lt: + * 7 b a GOTO Lf Code for : = a 0 Load_Local -8(FP), R 0 b 5 Load_Local -12(FP), R 0

Location Computation for Booleans

Location Computation for Booleans

Code generation for IF Allocate two new labels Lf, Lend if Generate code for

Code generation for IF Allocate two new labels Lf, Lend if Generate code for Boolean(left, 0, Lf) GOTO Lend: Lf: Boolean expression true sequence Code for Boolean with jumps to Lf true sequence false sequence Code for false sequence

Code generation for IF (no-else) Allocate new label Lend if Generate code for Boolean(left,

Code generation for IF (no-else) Allocate new label Lend if Generate code for Boolean(left, 0, Lend) Boolean expression true sequence Code for Boolean with jumps to Lend true sequence Lend:

Coercions into value computations : = Generate new label Lf Load_Constant R 0, 0;

Coercions into value computations : = Generate new label Lf Load_Constant R 0, 0; Generate code for Boolean(right, 0, Lf) x a>b Load_Local -8(FP), R 1; CMP R 1, -12(FP) ; IF <= GOTO Lf; Load_Constant R 0, 1 Lf: Store_Local R 0, -20(FP)

Effects on performance • • • Number of executed instructions Unconditional vs. conditional branches

Effects on performance • • • Number of executed instructions Unconditional vs. conditional branches Instruction cache Branch prediction Target look-ahead

Code for case statements • Three possibilities – Sequence of IFs • O(n) comparisons

Code for case statements • Three possibilities – Sequence of IFs • O(n) comparisons – Jump table • O(1) comparisons – Balanced binary tree • O(log n) comparisons • Performance depends on n • Need to handle runtime errors

Simple Translation

Simple Translation

Jump Table • Generate a table of Lhigh-Llow+1 entries – Filled at ? time

Jump Table • Generate a table of Lhigh-Llow+1 entries – Filled at ? time • Each entry contains the start location of the corresponding case or a special label • Generated code tmp_case_value: = case expression; if tmp_case_value <Llow GOTO label_else; if tmp_case_value>Lhigh GOTO label_else; GOTO table[tmp_case_value –Llow];

Balanced trees • The jump table may be inefficient – Space consumption – Cache

Balanced trees • The jump table may be inefficient – Space consumption – Cache performance • Organize the case labels in a balanced tree – Left subtrees smaller labels – Right subtrees larger labels • Code generated for node_k label_k: IF tmp_case_value < lk THEN GOTO label of left branch ; IF tmp_case_value >lk THEN GOTO label of right branch; code for statement sequence; GOTO label_next;

Repetition Statements (loops) • Similar to IFs • Preserve language semantics • Performance can

Repetition Statements (loops) • Similar to IFs • Preserve language semantics • Performance can be affected by different instruction orderings • Some work can be shifted to compile-time – Loop invariant – Strength reduction – Loop unrolling

while statements Generate new labels test_label, Lend test_label: while Generate code for Boolean(left, 0,

while statements Generate new labels test_label, Lend test_label: while Generate code for Boolean(left, 0, L ) end GOTO test_label; Lend: statement Boolean expression Sequence Code for Boolean with jumps to Lend statement sequence

while statements(2) Generate labels test_label, Ls GOTO test_label: Ls: test_label: while Generate code for

while statements(2) Generate labels test_label, Ls GOTO test_label: Ls: test_label: while Generate code for Boolean(left, Ls, 0) Code for statement sequence Boolean expression Code for Boolean with jumps to LS statement Sequence

For-Statements • Special case of while • Tricky semantics – Number of executions –

For-Statements • Special case of while • Tricky semantics – Number of executions – Effect on induction variables – Overflow

Simple-minded translation FOR i in lower bound. . upper bound DO statement sequence END

Simple-minded translation FOR i in lower bound. . upper bound DO statement sequence END for i : = lower_bound; tmp_ub : = upper_bound; WHILE I <= tmp_ub DO code for statement sequence i : = i + 1; END WHILE

Correct Translation FOR i in lower bound. . upper bound DO statement sequence END

Correct Translation FOR i in lower bound. . upper bound DO statement sequence END for i : = lower_bound; tmp_ub : = upper_bound; IF i >tmp_ub THEN GOTO end_label; loop_label: code for statement sequence if (i==tmp_ub) GOTO end_label; i : = i + 1; GOTO loop_label; end_label:

Tricky question

Tricky question

Loop unrolling FOR i : = 1 to n DO sum : = sum

Loop unrolling FOR i : = 1 to n DO sum : = sum + a[i]; END FOR;

Summary • Handling control flow statements is usually simple • Complicated aspects – Routine

Summary • Handling control flow statements is usually simple • Complicated aspects – Routine invocation – Non local gotos – Runtime errors • Runtime profiling can help

Routine Invocation • Identify the called routine • Generate calling sequence – Some instructions

Routine Invocation • Identify the called routine • Generate calling sequence – Some instructions are executed by the callee • Filling the activation record – Actual parameters (caller) – Administrative part – The local variable area – The working stack

Parameter Passing Mechanisms • • By value By reference By result By value-result •

Parameter Passing Mechanisms • • By value By reference By result By value-result • Pass the R-value of the parameter • Pass the L-value of the parameter • The callee creates a temporary • Stores the temporary upon return • Can use registers • Pass the L-value of the parameter • The callee creates a temporary • Store the temporary upon return

Caller Sequence • Save caller-save registers • Pass actual parameters – In stack –

Caller Sequence • Save caller-save registers • Pass actual parameters – In stack – In register • Pass lexical pointer • Generate code for the call – Store return address – Pass flow of control

Callee Sequence • • Allocate the frame Store callee-save registers Perform the procedure code

Callee Sequence • • Allocate the frame Store callee-save registers Perform the procedure code Return function result Restore callee-save registers Deallocate the frame Transfer the control back to the caller

Two activation records on the stack

Two activation records on the stack

Non-Local goto in C syntax

Non-Local goto in C syntax

Non-local gotos • Close activation records • Restore callee-save registers code p: l: q:

Non-local gotos • Close activation records • Restore callee-save registers code p: l: q: goto l; Memory before Main p r q Memory After Main p

Runtime errors • The smartest compiler cannot catch all potential errors at compile-time –

Runtime errors • The smartest compiler cannot catch all potential errors at compile-time – Missing information – Undecidability • Compiler need to generate code to identify runtime errors – Non-trivial

Common runtime errors • Overflow – Integers – Stack frame • • • Limited

Common runtime errors • Overflow – Integers – Stack frame • • • Limited resources Division by zero Null pointer dereferences Dangling pointer dereferences Buffer overrun (array out of bound)

Runtime Errors • C – No support for runtime errors – Situations with “undefined”

Runtime Errors • C – No support for runtime errors – Situations with “undefined” ANSI C semantics • Leads to security vulnerabilities • Pascal – Runtime errors abort execution • Java – Runtime errors result in raised exceptions – Can be handled by the programmer code

Detecting a runtime error • Array bound-check foo() { int a[100], i, j; scanf(“%d%d”,

Detecting a runtime error • Array bound-check foo() { int a[100], i, j; scanf(“%d%d”, &i, &j); while (i < j) { a[i] = i ; i++; } if (“i” < 0 || “i” >=100) THROW range_error;

Detecting a runtime error(2) • Array bound-check foo() { int a[100], i, j; scanf(“%d%d”,

Detecting a runtime error(2) • Array bound-check foo() { int a[100], i, j; scanf(“%d%d”, &i, &j); if ((i >=0) && j <=100) { while (i < j) { a[i] = i ; i++; } else … }

Handling Runtime Errors • Abort • Statically assigned error handlers (signal) • Exceptions

Handling Runtime Errors • Abort • Statically assigned error handlers (signal) • Exceptions

Signal Handlers • Binds errors to handler routines • Invoke a specific routine when

Signal Handlers • Binds errors to handler routines • Invoke a specific routine when runtime error occurs • Report an error – Close open resources and exit – Resume immediately after the error – Resume in some “synchronization” point

Signal Example

Signal Example

Exceptions • • Flexible mechanism for handling runtime errors Available in modern programming languages

Exceptions • • Flexible mechanism for handling runtime errors Available in modern programming languages Useful programming paradigm But are hard to compile void f() { { … g() … catch(error 1) { …} } } void g() { void h() { … h() … … throw error 1 … } }

Why are exceptions hard to compile? • Dynamic addresses – Not always known when

Why are exceptions hard to compile? • Dynamic addresses – Not always known when at compile time – Non local goto – Register state • The handler may change in the execution of a routine • The handler code assumes sequential execution

Handling Exceptions • At compile time store mappings from exceptions to handlers • Store

Handling Exceptions • At compile time store mappings from exceptions to handlers • Store a pointer to the table in the activation record • When an exception is raised scan the stack frames to locate the most recent handler • Perform a non-goto

Handler Code • Generate code for handler • Terminate with a jump to the

Handler Code • Generate code for handler • Terminate with a jump to the end of block/routine • A unique label where the handler code begins Block/Routine • Generate a table exception handler • Store a pointer to the table at the activation record

Code for raising exception • Extract the pointer to the table from the activation

Code for raising exception • Extract the pointer to the table from the activation record • Search for a handler for the exception raised • If not found pop the stack and repeat • If found perform a non-local goto • Usually combine the search and the goto

Summary • Non local transfer of control can be expensive – Hard to understand

Summary • Non local transfer of control can be expensive – Hard to understand = Hard to implement • But are necessary • Challenging optimization problems