Midterm 2. CMSC 430 Introduction to Compilers Fall 2018

Similar documents
Midterm 2. CMSC 430 Introduction to Compilers Fall Instructions Total 100. Name: November 11, 2015

Midterm 2. CMSC 430 Introduction to Compilers Fall Instructions Total 100. Name: November 21, 2016

Midterm 2. CMSC 430 Introduction to Compilers Fall Instructions Total 100. Name: November 19, 2014

Midterm 2. CMSC 430 Introduction to Compilers Fall Instructions Total 100. Name: November 20, 2013

Midterm 2. CMSC 430 Introduction to Compilers Spring Instructions Total 100. Name: April 18, 2012

Midterm 1. CMSC 430 Introduction to Compilers Spring Instructions Total 100. Name: March 14, 2012

CMSC430 Spring 2014 Midterm 2 Solutions

CMSC 330 Exam #2 Fall 2008

Problem Score Max Score 1 Syntax directed translation & type

Project 3 Due October 21, 2015, 11:59:59pm

CSE 351 Midterm - Winter 2015

CMSC330 Spring 2017 Midterm 2

CSE 351 Midterm - Winter 2015 Solutions

CMSC 330, Fall 2018 Midterm 2

CMSC330 Fall 2016 Midterm #2 2:00pm/3:30pm

(Practice) Midterm 1

CSE 351 Midterm - Winter 2017

CMSC 330: Organization of Programming Languages. Operational Semantics

16.317: Microprocessor Systems Design I Fall 2013

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

CIS 341 Midterm March 2, 2017 SOLUTIONS

CIS 341 Midterm February 28, Name (printed): Pennkey (login id): SOLUTIONS

CIS 341 Midterm March 2, Name (printed): Pennkey (login id): Do not begin the exam until you are told to do so.

CSE P 501 Exam 8/5/04 Sample Solution. 1. (10 points) Write a regular expression or regular expressions that generate the following sets of strings.

CSC 2400: Computer Systems. Using the Stack for Function Calls

CMSC330 Fall 2017 Final Exam

CSE351 Autumn 2014 Midterm Exam (29 October 2014)

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

Summary: Direct Code Generation

CSC 8400: Computer Systems. Using the Stack for Function Calls

CSE 130, Fall 2005: Final Examination

Project 5 Due 11:59:59pm Wed, Nov 25, 2015 (no late submissions)

CSE351 Autumn 2014 Midterm Exam (29 October 2014)

Lecture 15 CIS 341: COMPILERS

CSE351 Autumn 2012 Midterm Exam (5 Nov 2012)

Compiler Structure. Data Flow Analysis. Control-Flow Graph. Available Expressions. Data Flow Facts

Project 5 Due 11:59:59pm Tuesday, April 25, 2017

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

CSC 2400: Computing Systems. X86 Assembly: Function Calls

Midterm 2 Sample solution

CSE 130, Fall 2006: Final Examination

Exam 3 Chapters 7 & 9

Function Calls COS 217. Reading: Chapter 4 of Programming From the Ground Up (available online from the course Web site)

CMSC330 Spring 2016 Midterm #2 9:30am/12:30pm/3:30pm

CMSC 330: Organization of Programming Languages. Lambda Calculus

Sample Exam I PAC II ANSWERS

Exercise 7 Bytecode Verification self-study exercise sheet

Program Exploitation Intro

Lecture Compiler Middle-End

Metaprogramming assignment 3

CSCI-1200 Data Structures Fall 2017 Lecture 5 Pointers, Arrays, & Pointer Arithmetic

Project 6 Due 11:59:59pm Thu, Dec 10, 2015

COS 471A,COS 471B/ELE 375 Midterm

CSE P 501 Exam Sample Solution 12/1/11

CSE 401 Final Exam. December 16, 2010

CMSC 330, Fall 2018 Midterm 2

CSE351 Spring 2018, Midterm Exam April 27, 2018

CMSC430 Spring 2009 Midterm 2 (Solutions)

EXAMINATIONS 2014 TRIMESTER 1 SWEN 430. Compiler Engineering. This examination will be marked out of 180 marks.

CSE-304 Compiler Design

Lecture 3 Local Optimizations, Intro to SSA

CMSC 330: Organization of Programming Languages

CMSC330 Spring 2015 Final Exam 9:30am/11:00am/12:30pm

COMP 181. Prelude. Intermediate representations. Today. High-level IR. Types of IRs. Intermediate representations and code generation

Midterm II CS164, Spring 2006

CS 33: Week 3 Discussion. x86 Assembly (v1.0) Section 1G

16.317: Microprocessor Systems Design I Fall 2015

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

CSE505, Fall 2012, Midterm Examination October 30, 2012

CSE-321 Programming Languages 2012 Midterm

CMSC330 Fall 2009 Final Exam

CMSC 330: Organization of Programming Languages. Lambda Calculus

Dynamic Types, Concurrency, Type and effect system Section and Practice Problems Apr 24 27, 2018

CSE Lecture In Class Example Handout

CMSC330 Fall 2015 Midterm #1 12:30pm/2:00pm/5:00pm

ECE 468, Fall Midterm 2

EECS 213 Introduction to Computer Systems Dinda, Spring Homework 3. Memory and Cache

JAM 16: The Instruction Set & Sample Programs

CMSC 330: Organization of Programming Languages

15-213/18-243, Spring 2011 Exam 1

CIS 110 Introduction to Computer Programming. February 29, 2012 Midterm

Question Points Score Total 100

CSc 520 final exam Wednesday 13 December 2000 TIME = 2 hours

CSE 401/M501 Compilers

Compilers: The goal. Safe. e : ASM

Static Program Analysis Part 1 the TIP language

CMSC330 Fall 2010 Final Exam Solutions

C Language Part 2 Digital Computer Concept and Practice Copyright 2012 by Jaejin Lee

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CSE 582 Autumn 2002 Exam 11/26/02

x86-64 Programming III & The Stack

Assembly Language: Function Calls

Code Generation Introduction

Project 2 Due 11:59:59pm Wed, Mar 7, 2012

CSCI 334: Principles of Programming Languages. Computer Architecture (a really really fast introduction) Lecture 11: Control Structures II

Midterm 1 1 /8 2 /9 3 /9 4 /12 5 /10. Faculty of Computer Science. Term: Fall 2018 (Sep4-Dec4) Student ID Information. Grade Table Question Score

CMSC330 Spring 2017 Midterm #1 Solution

Assembly Language: Function Calls" Goals of this Lecture"

Programming Languages and Techniques (CIS120)

Transcription:

Name: Directory ID: University ID: Midterm 2 CMSC 430 Introduction to Compilers Fall 2018 Instructions This exam contains 14 pages, including this one. Make sure you have all the pages. Write your name, directory ID, and university ID number on the top of this page, and write your directory ID at the bottom left of every page, before starting the exam. Write your answers on the exam sheets. If you finish at least 15 minutes early, bring your exam to the front when you are finished; otherwise, wait until the end of the exam to turn it in. Please be as quiet as possible. If you have a question, raise your hand. If you feel an exam question assumes something that is not written, write it down on your exam sheet. Barring some unforeseen error on the exam, however, you shouldn t need to do this at all, so be careful when making assumptions. Question Score Max 1 20 2 20 3 20 4 20 5 20 Total 100

Question 1. Short Answer (20 points). a. (3 points) Briefly describe the difference between a function call and a system call. Explain whether the two have the same calling convention and why or why not. Answer: Function calls transfer control from one function to another, within the program s own code or between the code and a library. System calls are used when the program needs the operating system kernel to perform some computation or action on its behalf, with privilege. The conventions for function calls and system calls are typically different. One is defined by the language or compiler for interoperability of program modules. The other is defined by the operating system and must be followed by all programs, regardless of implementation language. b. (3 points) Briefly describe two code generation techniques for compiling C switch statements. Explain how the two techniques compare, i.e., in what situation(s) one technique should be favored over the other. Answer: Cascaded if-then-else. Check each option in succession. Binary search. Order the guards and then use a search algorithm. Jump table. Use the guard as an index into code or a set of code pointers. Jump tables are most effective when the guards are dense, i.e., when they are numerically close. Jump tables are more time efficient, since they require only a single constant-time operation to compute the code location. However, they can be inefficient for space if the guards are spread out. Other answers that describe memory or time efficiency, or ease of implementation, are also acceptable. c. (3 points) Briefly describe symbolic execution and name one application of the technique. What is the fundamental challenge that prevents exhaustive symbolic execution for most real-world programs? Answer: Symbolic execution is a program analysis technique that treats program inputs as symbolic variables, rather than concrete values. Program expressions are computed in terms of the symbolic variables and execution is logically forked at branch points to represent all possible paths. Symbolic execution can simultaneously explore multiple paths that a program could take under different inputs, without testing every possible input. It is a popular technique with testing and bug finding tools. The primary challenge is path/state space explosion. Real programs have an exponential number of paths, making it impossible to symbolically execute every path. Therefore, approximation, path pruning, and search strategies have become a critical component of real symbolic execution systems. Directory ID: 2 CMSC430, Fall 2018, Midterm 2

d. (5 points) The following C program contains two functions, bar() and foo(). bar() calls foo(). Draw a representation of a 32-bit x86 stack just after the assignment on line 9 is executed. Include as much stack history as you can infer from the code snippet. Clearly indicate the current top of the stack (esp), the current frame pointer (ebp), and which direction the stack grows. You can assume the code is compiled without any optimizations and that main() calls bar(). If you make any other assumptions, state those as well. 1 int bar ( int x, int y ) { 2 int z ; 3 z = foo ( x + 10, y 1 0 ) ; 4 return z ; 5 } 6 7 int foo ( int a, int b ) { 8 int c = 1 00; 9 int d = a b + c ; 10 //... 11 return d ; 12 } Answer: Registers Stack Notes higher addresses go up... main s local variables main s activation record... y arguments to bar, pushed in reverse order x main s return address bar s activation record main s saved ebp z bar s local variables... register save space b = y - 10 arguments to foo, pushed in reverse order a = x + 10 bar s return address foo s activation record ebp bar s saved ebp esp c = 100 d = a * b + c stack grows down foo s local variables esp could also point lower if space was pre-allocated Directory ID: 3 CMSC430, Fall 2018, Midterm 2

e. (6 points) Translate the following program to 3-address code. Draw the control-flow graph for the resulting program. 1. x = 10 2. y = 3 3. t1 = y * 10 4. t2 = x + t1 5. z = t2 + 100 x = 10 y = 3 z = x + ( y 10) + 100 while ( ( z > y ) && ( z > x ) ) { i f ( a > 10) { z = z 100 } else { z = z x 2 } } 6. if z > y 7. if z > x 8. if a > 10 9. z = z - 100 10. t3 = x * 2 11. z = z - t3 exit Directory ID: 4 CMSC430, Fall 2018, Midterm 2

Question 2. Code Generation (20 points). Below (left) is a set of types representing a small machine instruction set, followed by (right) a type representing expression ASTs for a small language. n type instr = ILoad of reg val ( dst, src ) IStore of id reg ( dst, src ) IAdd of reg reg reg ( dst, src1, src2 ) ISub of reg reg reg ( dst, src1, src2 ) IIfZero of reg int ( guard, target ) IJmp of int ( target ) IMov of reg reg ( dst, src ) type expr = EInt of int ( integers ) EId of string ( variables ) EAdd of expr expr ( addition ) ESub of expr expr ( subtraction ) EAssn of string expr ( assignment ) ESeq of expr expr ( sequences ) EWhile of expr expr ( while loops ) EDoWhile of expr expr ( do while loops ) The instruction set has direct support for named locations (i.e., variables), which can be read from or written to via the ILoad and IStore instructions, respectively. ILoad also supports loading a register with a constant integer. IAdd and ISub implement register addition and subtraction, respectively. In both cases, the result is stored in a register. The IJmp (absolute jump) and IIfZero (conditional jump) instructions adjust the PC relative to the current instruction s PC. IMov copies the value stored in one register to another. The machine supports an unlimited number of registers. The expressions EInt and EId represent constant integers and variables, respectively. EAdd and ESub are the standard binary addition and subtraction expressions. EAssn represents an assignment to a variable. ESeq is the sequence of two expressions. The expression EWhile(e1, e2) executes the body e2 as long as the guard e1 is not zero, and the whole expression evaluates to 0. EDoWhile(e1, e2) executes e1 until e2 becomes non-zero. Note that a do-while loop always executes the body e1 at least once (so it evaluates e1; checks if e2 is non-zero; if not evaluates e1 again; etc). The loop itself should evaluate to 0. Question is on the next page. Directory ID: 5 CMSC430, Fall 2018, Midterm 2

Write a function comp expr : expr reg ( instr list ) that takes a single expression and returns the output register and a list of instructions that compute the expression. You may define as many helper functions as you need, and you may also use OCaml standard library functions. let next reg = let n = ref 0 in fun () ( let temp =!n in n:=!n+1; temp) let rec comp expr = function EInt n let r = next reg () in (r, [ILoad ( Reg r, Int n)]) EAdd (e1, e2) let (r1, p1) = comp expr e1 in let (r2, p2) = comp expr e2 in let r = next reg () in (r, p1 @ p2 @ [IAdd ( Reg r, Reg r1, Reg r2)]) ESub (e1, e2) let (r1, p1) = comp expr e1 in let (r2, p2) = comp expr e2 in let r = next reg () in (r, p1 @ p2 @ [ISub ( Reg r, Reg r1, Reg r2)]) EId x let r = next reg () in (r, [ILoad ( Reg r, Id x )]) EAssn (x, e) let (r, p) = comp expr e in (r, p @ [ IStore ( Id x, Reg r )]) EWhile (e1, e2) let (r1, ccode) = comp expr e1 in let (r2, ecode) = comp expr e2 in let r3 = next reg () in let elength = List. length ecode in let clength = List. length ccode in let guard = [ IIfZero ( Reg r1, elength+1)] in let loopback = [IJmp ( 1 (elength + clength + 2))] in let return zero = [ILoad( Reg r3, Int 0)] in (r3, List.concat [ccode;guard;ecode;loopback; return zero ]) EDoWhile (e1, e2) let (r1, ccode) = comp expr e1 in let (r2, ecode) = comp expr e2 in let r3 = next reg () in let elength = List. length ecode in let clength = List. length ccode in let guard = [ IIfZero ( Reg r2, 1) ] in let loopback = [IJmp ( 1 (elength + clength) + 2)] in let returnzero = [ILoad( Reg r3, Int 0)] in (r3, List.concat [ecode; ccode; guard; loopback; returnzero ]) ESeq (e1, e2) let (r1, p1) = comp expr e1 in let (r2, p2) = comp expr e2 in (r2, p1 @ p2) Directory ID: 6 CMSC430, Fall 2018, Midterm 2

Question 3. Data Flow (20 points). In the following table, show each iteration of reaching definitions for the control-flow graph on the right. For each iteration, list the statement taken from the worklist in that step, the value of out computed for that statement, and the new worklist at the end of the iteration. You may or may not need all the iterations; you may also add more iterations if needed. Do not add the entry node to the worklist. 0. entry 1. a := 1 2. b := 2 3. if a < 10 4. a:= a + b 8. a:= a - b Use for the set of no definitions, and for the set of all definitions. What is? = 1(a), 2(b), 4(a), 6(b), 7(a), 8(a) 5. if b < 10 6. b := a + 2 7. a := a + 2 9. exit What are the initial out s for each statement? Stmt 0 1 2 3 4 5 6 7 8 Initial out Iteration 0 1 2 3 4 Stmt taken from worklist out of taken stmt N/A 1 2 3 4 N/A 1(a) 1(a),2(b) 1(a),2(b) 2(b),4(a) New worklist 1,2,3,4,5,6,7,8 2,3,4,5,6,7,8 3,4,5,6,7,8 4,5,6,7,8 5,6,7,8 Iteration 5 6 7 8 9 Stmt taken from worklist out of taken stmt 5 6 3 4 5 2(b),4(a) 4(a),6(b) 1(a),2(b),4(a),6(b) 2(b),4(a),6(b) 2(b),4(a),6(b) New worklist 6,7,8 3,7,8 4,7,8 5,7,8 6,7,8 Iteration 10 11 12 13 14 Stmt taken from worklist out of taken stmt 6 7 3 4 8 4(a),6(b) 2(b),6(b),7(a) 1,2,4,6,7 2(b),4(a),6(b) 2(b),6(b),8(a) New worklist 7,8 3,8 4,8 8 Directory ID: 7 CMSC430, Fall 2018, Midterm 2

Question 4. Optimization (20 points). Below are (left) a Simpl function that I wrote to test my project 4 and (right) the RubeVM code that my compiler generated. 1 def foo(x) 2 t = mktab(); 3 i = 0; 4 while ( i < x) do 5 a = x + 10; 6 if a < 5 then 7 t [ i ] = a + x 8 else 9 t [ i ] = a 10 end; 11 i = i + 1 12 end 13 end 1 foo: 2 mov r7, r0 3 const r10, mktab 4 call r10, 9, 8 5 const r11, 0 6 lt r12, r11, r7 7 if zero r12, 15 8 const r14, 10 9 add r13, r7, r14 10 const r17, 5 11 lt r16, r13, r17 12 if zero r16, 4 13 add r18, r13, r7 14 wr tab r9, r11, r18 15 mov r15, r18 16 jmp 2 17 wr tab r9, r11, r13 18 mov r15, r13 19 const r20, 1 20 add r19, r11, r20 21 mov r11, r19 22 jmp 17 23 const r21, 0 24 ret r21 In the space below, identify two (2) local and two (2) global optimizations that could be applied to this code. Clearly identify the type of optimization, the code location, and how the code would change. Hint: you may want to convert the RubeVM code to a more familiar three-address form and draw a control-flow graph first. 2. r7 = r0 3. r10 = mktab 4. r9 = mktab() 5. r11 = 0 6. r12 = (r11 < r7) 7. if r12 == 0 8. r14 = 10 9. r13 = r7 + r14 10. r17 = 5 11. r16 = (r13 < r17) 12. if r16 == 0 13. r18 = r13 + r7 14. r9[r11] = r18 15. r15 = r18 17. r9[r11] = r13 18. r15 = r13 19. r20 = 1 20. r19 = r11 + r20 21. r11 = r19 Directory ID: 8 CMSC430, Fall 2018, Midterm 2

a. (5 points) Local optimization 1 Answer: Using the hint, we converted the RubeVM code into a CFG (see previous page). Now we can easily see statements 13-15 can leverage copy propagation we don t need to use r18 at all. The block becomes: Three-address 13. r15 = r13 + 7 14. r9[r11] = r15 15. <removed> b. (5 points) Local optimization 2 RubeVM 13. add r15, r13, r7 14. wr tab r9, r11, r15 15. <removed> Answer: Copy propagation, like above, but to remove r19. The block becomes: Three-address 19. r20 = 1 20. r11 = r11 + r20 21. <removed> RubeVM 19 const r20, 1 20 add r11, r11, r20 21 <removed> c. (5 points) Global optimization 1 Answer: Loop invariant code motion. The assignment to variable a (r17) does not depend on any modifications inside the loop, so it can be hoisted above the loop (e.g., just after statement 5) to save cycles during the loop. Similarly, a + x (r18) is loop invariant and could be computed once, before the loop. d. (5 points) Global optimization 2 Answer: Code specialization. There is a condition inside the loop (a < 5, 11. lt r16, r13, r17) that does not vary depending on the loop. We can invert the loop and conditional to make one loop for the true case and one for the false, which will run faster during the loop s execution. Alternatively, rather than specialize the loop itself, a more complicated optimization could be performed following the code motion optimization described in part c. Since both branches of the conditional assign to the same table location t[i], the conditional could be used to compute the correct right-hand side (a or a + x) and put the result in the same register. Then, the loop can just iterate through assigning to a constant value. Logically, the same as this: def foo(x) t = mktab(); i = 0; if a < 5 then temp = a + x else temp = a end; while (i < x) do t[i] = temp i = i + 1 end end Directory ID: 9 CMSC430, Fall 2018, Midterm 2

Question 5. Type Systems (20 points). Here is the simply typed lambda calculus with integers, floats, and pairs. e ::= v x e e (e, e) v ::= n f λx: t.e t ::= int float t t t t A ::= x : t, A Int A n : int Float A f : float Var A x : A(x) Pair A e 1 : t A e 2 : t A (e 1, e 2 ) : t t Lam x: t, A e : t A λx: t.e : t t App A e 1 : t t A e 2 : t A e 1 e 2 : t a. (5 points) Draw a derivation showing that the following term is well-typed in the given type environment, where we use i instead of int and f instead of float to save space. You need not label the uses of the rules with their names. A = +: i i i, : f f f A ((λx: i.λy: f.(+ x 5, y 5.0)) 7 7.0): i f Answer: A = +: i i i, : f f f B = x: i, A C = y: f, x: i, A C +: i i i C x: i C : f f f C y: f C (+ x): i i C 5: i C ( y): f f C 5.0: f C (+ x 5): i C ( y 5.0): f C (+ x 5, y 5.0): i f B λy: f.(+ x 5, y 5.0): f i f A (λx: i.λy: f.(+ x 5, y 5.0)): i f i f A ((λx: i.λy: f.(+ x 5, y 5.0)) 7): f i f A ((λx: i.λy: f.(+ x 5, y 5.0)) 7 7.0): i f A 7: i A 7.0: f Directory ID: 10 CMSC430, Fall 2018, Midterm 2

b. (5 points) If we make int a subtype of float, we get the following additional type rules (note that application has been updated): S-NUM int float S-PROD t 1 t 1 t 2 t 2 t 1 t 2 t 1 t 2 App A e 1 : t 1 t 1 A e 2 : t 2 t 2 t 1 A e 1 e 2 : t 1 S-ARROW t 1 t 1 t 2 t 2 i. (2 points) The rule S-ARROW, which extends the subtyping relationship to arrow types (functions), is incomplete. Fill in the rest of the rule. Answer: S-ARROW t 2 t 1 t 1 t 2 t 1 t 1 t 2 t 2 ii. (3 points) Given your rule, can (+: int int int) be used in computations where ( : float float float) is expected? Explain why or why not. If not, give an example of a type that can be used where is expected. Answer: No. The function requires a float input. The + function requires an int. The subtype rule for arrow requires that float int, which is not true by the other type rules. float float int is the only other type of function that can be used in place of float float float. Directory ID: 11 CMSC430, Fall 2018, Midterm 2

c. (10 points) Consider type inference for the simply-typed lambda calculus, this time without the float, pair, and subtyping extensions. Int A n : int Var x dom(a) A x : A(x) e ::= v x e e v ::= n λx.e t ::= α int t t A ::= x : t, A Lam x: α, A e : t α fresh A λx.e : α t App A e 1 : t A e 2 : t t = t β β fresh A e 1 e 2 : β i. (5 points) Draw a derivation showing type inference applied to the following term. Use subscripts to distinguish new instances of type inference variables. For example, α 1, α 2, β 1, β 2, etc. +: int int int (λx. + x 5) 37 Answer: A = +: i i i B = x: α, A B +: int int int B x: α i i i = α β 3 B (+x): β 3 B 5: int β 3 = int β 2 B (+ x 5): β 2 A (λx. + x 5) : α β 2 A (λx. + x 5) 37 : β 1 A 37: int α β 2 = int β 1 ii. (3 points) Draw a union find data structure representing the constraints. α β 3 int β 2 Answer: int int β 1 iii. (2 points) Write down a solution to the associated constraints. Answer: α = β 2 = β 1 = int β 3 = int int Directory ID: 12 CMSC430, Fall 2018, Midterm 2

This page is intentionally blank for extra work space. If you want the work on this page to count, clearly label which question you are answering and write see back page in the answer space for the question. Directory ID: 13 CMSC430, Fall 2018, Midterm 2

This page is intentionally blank for extra work space. If you want the work on this page to count, clearly label which question you are answering and write see back page in the answer space for the question. Directory ID: 14 CMSC430, Fall 2018, Midterm 2