Presentation is loading. Please wait.

Presentation is loading. Please wait.

Compiler construction in4020 – lecture 7 Koen Langendoen Delft University of Technology The Netherlands.

Similar presentations


Presentation on theme: "Compiler construction in4020 – lecture 7 Koen Langendoen Delft University of Technology The Netherlands."— Presentation transcript:

1 Compiler construction in4020 – lecture 7 Koen Langendoen Delft University of Technology The Netherlands

2 attribute grammars formal attributes per symbol: inherited & synthesized attribute evaluation rule per production dependency graphs evaluation order Summary of lecture 6 S -attributed grammarsL -attributed grammarsmulti-visit grammars

3 Quiz 3.1 Which of the following items belong to a non-terminal, and which to a production? (a) inherited attribute (b) synthesized attribute (c) attribute evaluation rule (d) dependency graph (e) visiting routine

4 Overview context handling annotating the AST attribute grammars manual methods symbolic interpretation data-flow equations program text lexical analysis syntax analysis context handling annotated AST tokens AST

5 Manual methods for analyzing the AST preparing the grounds for code generation constant propagation last-def analysis (reaching definitions) live analysis common subexpression elimination dead-code elimination... we need flow-of-control information

6 Threading the AST determine the control flow graph that records the successor(s) of AST nodes - * ‘c’‘c’ ‘4’‘4’ * ‘a’‘a’ ‘b’ * first last intermediate code PUSH b MUL PUSH 4 PUSH a MUL PUSH c MUL SUB

7 Threading the AST result is a post-order traversal of the AST global variable: Last node pointer PROCEDURE Thread binary expression (Expr node pointer): Thread expression (Expr node pointer.left operand); Thread expression (Expr node pointer.right operand); // link this node to the dynamically last node SET Last node pointer.successor TO Expr node pointer; // make this node the new dynamically last node SET Last node pointer TO Expr node pointer; * ‘c’‘c’ ‘4’‘4’ * ‘a’‘a’

8 Multiple successors problem: threading is built around single Last node pointer IF condition THENELSE first last

9 Multiple successors problem: threading is built around single Last node pointer solution: introduce join node IF condition THENELSE first last FI

10 Symbolic interpretation behaviour of code is determined by (the values of) variables simulate run-time execution at compile time attach a stack representation to each arrow in the control flow graph an entry summarizes all compile-time knowledge about the variable/constant

11 Symbolic interpretation condition IF THEN ELSE FI

12 Symbolic interpretation condition IF THEN ELSE > y0 y x 5 y x 5 5 y x 5 5 0 y x 5 T y x 5 y x 5 y x 5 x = 7; y x 5 7 y x 5 dead code FI merge

13 Exercise (5 min.) draw the control flow graph for while C do S od propagate initial stack when C represents y>x and S stands for x:=7 y x 5

14 Answers

15 condition WHILE BODY y x 5 y x 5 y x 5 y x 5 b y x 5 7

16 Simple symbolic interpretation used in narrow compiler simple properties + simple control-flow example: detecting the use of uninitialized variables maintain property list advance list through control flow graph int foo(int n) { int first; while (n-- > 0) { if (glob[n] == KEY) first = n; } return first; }

17 Tracking uninitialized variables parameter declaration: variable declaration: expression: assignment: control statement fork nodes: join nodes: add (ID:Initialized) tuple add (ID:Uninitialized) tuple check status of used variables set tuple to (ID:Initialized) copy list merge lists merge( Init, Init) = Init merge( Uninit, Uninit) = Uninit merge( x, x) = Maybe int foo(int n) { int first; while (n-- > 0) { if (glob[n] == KEY) first = n; } return first; }

18 Simple symbolic interpretation flow-of-control structures with one entry and one exit point (no GOTOs) the values of the property are severely constrained (see book) example: constant propagation

19 Constant propagation record the exact value iso Initialized int i = 0; while (condition) { if (i>0) printf("loop reentered\n"); … i++; } simple symbolic interpretation fails // i == 0 // i == 1 // i == {0,1}

20 Full symbolic interpretation maintain a property list for each entry point (label), initially set to empty traverse flow of control graph L:merge current-list into list-L continue with list-L jump L;merge current-list into list-L continue with the empty list repeat until nothing changed guarantee termination – select suitable property

21 int i = 0; while (condition) { if (i>0) printf("loop reentered\n"); … i++; } int i = 0; L: if (condition) { if (i>0) printf("loop reentered\n"); … i++; goto L; } Constant propagation full symbolic interpretation property: unknown < value < any // i == 0 // i == 1 // empty // i == ANY // i == 0 // i == ANY

22 Break

23 Data flow equations “automated” full symbolic interpretation stack replaced by collection of sets IN(N) OUT(N) semantics are expressed by constant sets KILL(N) GEN(N) equations IN(N) =  M  predecessor[N] OUT(M) OUT(N) = IN(N) \ KILL(N)  GEN(N) n = n-1; IN OUT

24 Data flow equations solved through iteration (closure algorithm) data-flow nodes may not change the stack individual statements basic blocks example: tracking uninitialized variables properties: I x, M x, U x GEN(x = expr ;) = KILL(x = expr ;) = int foo(int n) { int first; while (n-- > 0) { if (glob[n] == KEY) first = n; } return first; } {I x} {U x, M x} int foo(int n) { int first; L: n = n-1; if (n >= 0) { if (glob[n] == KEY) first = n; goto L; } return first; }

25 T T Data flow equations solved through iteration (closure algorithm) data-flow nodes may not change the stack individual statements basic blocks example: tracking uninitialized variables properties: I x, M x, U x GEN(x = expr ;) = KILL(x = expr ;) = {I x} {U x, M x} if (glob[n] == KEY) first = n; goto L; return first; L: n = n-1; if (n >= 0) F F 1 2 3 4 5 6

26 {} IN(N) =  M  predecessor[N] OUT(M) OUT(N) = IN(N) \ KILL(N)  GEN(N) Iterative solution initialization: set all sets to empty iterate from top to bottom {I n, U f} {I n, I f} {I n, M f} T T F return first; 6 F first = n; 4 goto L; 5 L: n = n-1; 1 int foo(int n) { int first; 0 if (glob[n] == KEY) 3 if (n >= 0) 2 statementKILLGEN 0I n U f 1U n M n InIn 4U f M f IfIf

27 Iterative solution statement iteration 1iteration 2 KILLGENINOUTINOUT 0 I n U f 1U n M n InIn I n U f 2 I n M f 3I n U f I n M f 4U f M f IfIf I n U f I n I f I n M f I n I f 5I n M f 6I n U f I n M f

28 Efficient data-flow equations limit to (set of) on/off properties set union = bitwise OR set difference = bitwise AND NOT combine statements into basic blocks KILL[S 1 ;S 2 ] = KILL[S 1 ]  KILL[S 2 ] GEN[S 1 ;S 2 ] = GEN[S 2 ]  (GEN[S 1 ] \ KILL[S 2 ]) sort data-flow graph depth-first traversal (break cycles!)

29 Live analysis a variable is live at node N if the value it holds is used on some path further down the control-flow graph; otherwise it is dead useful information for register allocation information must flow “backwards” (up) through the control-flow graph difficult for symbolic interpretation easy for data flow equations

30 Solving data-flow equations forwards backwards IN(N) =  M  predecessor[N] OUT(M) OUT(N) = IN(N) \ KILL(N)  GEN(N) if (cond) IN OUT OUT(N) =  M  successor[N] IN(M) IN(N) = OUT(N) \ KILL(N)  GEN(N)

31 Exercise (5 min.) determine the KILL and GEN sets for the property “V is live here” for the following statements statement SKILLGEN v = a  b v = M[i] M[i] = v f(a 1,...,a n ) v = f(a 1,...,a n ) if a>b then goto L 1 else goto L 2 L: goto L

32 Answers determine the KILL and GEN sets for the property “V is live here” for the following statements statement SKILLGEN v = a  b v = M[i] M[i] = v f(a 1,...,a n ) v = f(a 1,...,a n ) if a>b then goto L 1 else goto L 2 L: goto L {v} {a,b} \ KILLS[S] {v} {i} \ KILLS[S] {} {i,v} {} { a 1,...,a n } {v} { a 1,...,a n } \ KILLS[S] {} {a,b} {}

33 Exercise (7 min.) draw the control-flow graph for the following code fragment perform backwards live analysis using the KILL and GEN sets from the previous exercise double average(int n, double v[]) { int i; double sum = 0.0; for (i=0; i<n; i++) { sum += v[i]; } return sum/n; }

34 Answers OUT(N) =  M  successor[N] IN(M) IN(N) = OUT(N) \ KILL(N)  GEN(N) statementKILLGEN 1 2 3 4 2 3 1 4

35 Answers OUT(N) =  M  successor[N] IN(M) IN(N) = OUT(N) \ KILL(N)  GEN(N) statementKILLGEN 1 2 3 4 sum = 0.0; i = 0; if (i<n) sum += v[i]; i++; return sum/n; 2 3 1 4

36 Answers sum = 0.0; i = 0; if (i<n) sum += v[i]; i++; return sum/n; live: n live: n, i, sum live: n, sum live: n, i, sum OUT(N) =  M  successor[N] IN(M) IN(N) = OUT(N) \ KILL(N)  GEN(N) statementKILLGEN 1sum, i 2i, n 3sum, i 4sum, n 2 3 1 4

37 Answers stat em ent iteration 1iteration 2iteration 3 KILLGENOUTINOUTINOUTIN 0n 1sum, ii, nni, n, sumn 2i, n i, n, sum 3sum, i i, ni, n, sum 4sum, nn, sumi, n, sum process nodes top to bottom (from 0 to 4) processing nodes in reverse (from 4 to 0) requires only two iterations

38 Summary manual methods for annotating the AST threading symbolic interpretation data-flow equations symbolic interpretation data-flow equations simplefull methodstack-based simulationIN, OUT, GEN, KILL sets granularityAST nodebasic block algorithmone-passiterative directionforwardsforwards & backwards

39 Homework study sections: 3.2.4 interprocedural data-flow analysis 3.2.5.1 live analysis by symbolic interpretation assignment 1: replace yacc with LLgen deadline April 9 08:59 print handout for next week [blackboard]


Download ppt "Compiler construction in4020 – lecture 7 Koen Langendoen Delft University of Technology The Netherlands."

Similar presentations


Ads by Google