CSc 520 Principles of Programming Languages

Similar documents
Introduction. Inline Expansion. CSc 553. Principles of Compilation. 29 : Optimization IV. Department of Computer Science University of Arizona

CSc 553. Principles of Compilation. 16 : OO Languages Polymorphism. Department of Computer Science University of Arizona

CSc 520. Principles of Programming Languages 46: OO Languages Polymorphism

CSc 520 Principles of Programming Languages

G Programming Languages - Fall 2012

CSc 520 Principles of Programming Languages. Questions. rocedures as Control Abstractions... 30: Procedures Introduction

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

CSc 520 Principles of Programming Languages

CSc 520 Principles of Programming Languages. ameter Passing Reference Parameter. Call-by-Value Parameters. 28 : Control Structures Parameters

CSc 453. Compilers and Systems Software. 16 : Intermediate Code IV. Department of Computer Science University of Arizona

CSc 520 Principles of Programming Languages

Control Structures. Boolean Expressions. CSc 453. Compilers and Systems Software. 16 : Intermediate Code IV

Short Notes of CS201

Chapter 9 :: Subroutines and Control Abstraction

CS201 - Introduction to Programming Glossary By

Weeks 6&7: Procedures and Parameter Passing

CSc 520 Principles of Programming Languages

CSc 520. Principles of Programming Languages 29: Control Flow Iterators

CS558 Programming Languages Winter 2018 Lecture 4a. Andrew Tolmach Portland State University

Compiler Theory. (GCC the GNU Compiler Collection) Sandro Spina 2009

CS558 Programming Languages

Compiler, Assembler, and Linker

Architectures. Code Generation Issues III. Code Generation Issues II. Machine Architectures I

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

CSc 520 Principles of Programming Languages

CSc 520. Principles of Programming Languages 45: OO Languages Introduction

Chapter 3:: Names, Scopes, and Bindings (cont.)

CS 2210 Programming Project (Part IV)

CA Compiler Construction

Functions BCA-105. Few Facts About Functions:

System Software Assignment 1 Runtime Support for Procedures

Run-time Environments

Run-time Environments

Procedure and Object- Oriented Abstraction

Semantic Analysis and Type Checking

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

Chapter 3:: Names, Scopes, and Bindings (cont.)

CSc 453. Code Generation I Christian Collberg. Compiler Phases. Code Generation Issues. Slide Compilers and Systems Software.

CS 314 Principles of Programming Languages

CS356: Discussion #6 Assembly Procedures and Arrays. Marco Paolieri

#include <stdio.h> int main() { printf ("hello class\n"); return 0; }

Introduction. CSc 453. Compilers and Systems Software. 19 : Code Generation I. Department of Computer Science University of Arizona.

CSE 504. Expression evaluation. Expression Evaluation, Runtime Environments. One possible semantics: Problem:

COSC 2P95. Procedural Abstraction. Week 3. Brock University. Brock University (Week 3) Procedural Abstraction 1 / 26

Lecture08: Scope and Lexical Address

Course Administration

CS 406/534 Compiler Construction Putting It All Together

EC 413 Computer Organization

CSc 520. Iterators. CLU-style Iterators... CLU-style Iterators. Principles of Programming Languages. Christian Collberg April 16, 2003

CSc 520 Principles of Programming Languages

Functions in C C Programming and Software Tools

! Those values must be stored somewhere! Therefore, variables must somehow be bound. ! How?

Runtime Environments I. Basilio B. Fraguela

The role of semantic analysis in a compiler

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

The compilation process is driven by the syntactic structure of the program as discovered by the parser

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

Introduction to Programming Using Java (98-388)

Symbol Tables. ASU Textbook Chapter 7.6, 6.5 and 6.3. Tsan-sheng Hsu.

Functions and Procedures

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

CSE 504: Compiler Design. Runtime Environments

11/29/17. Outline. Subprograms. Subroutine. Subroutine. Parameters. Characteristics of Subroutines/ Subprograms

CSc 453. Compilers and Systems Software. 13 : Intermediate Code I. Department of Computer Science University of Arizona

Scope, Functions, and Storage Management

Chapter 9 Subroutines and Control Abstraction. June 22, 2016

Code Generation. Lecture 12

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

Chap. 8 :: Subroutines and Control Abstraction

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Object-Oriented Languages. CSc 453. Compilers and Systems Software. 23 : OO Languages. Department of Computer Science University of Arizona

Static Checking and Intermediate Code Generation Pat Morin COMP 3002

CSE 307: Principles of Programming Languages

CSCI565 Compiler Design

Code Generation & Parameter Passing

Control Abstraction. Hwansoo Han

1. Describe History of C++? 2. What is Dev. C++? 3. Why Use Dev. C++ instead of C++ DOS IDE?

Have examined process Creating program Have developed program Written in C Source code

THEORY OF COMPILATION

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Interview Questions of C++

University of Arizona, Department of Computer Science. CSc 453 Assignment 5 Due 23:59, Dec points. Christian Collberg November 19, 2002

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

Today's Topics. CISC 458 Winter J.R. Cordy

CSC 533: Organization of Programming Languages. Spring 2005

Code Generation. Lecture 19

CSc 520 Principles of Programming Languages. 26 : Control Structures Introduction

SOFTWARE ARCHITECTURE 5. COMPILER

Functions in MIPS. Functions in MIPS 1

Flow-sensitive rewritings and Inliner improvements for the Graal JIT compiler

CSC 2400: Computing Systems. X86 Assembly: Function Calls

CS 314 Principles of Programming Languages. Lecture 13

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

An Activation Record for Simple Subprograms. Activation Record for a Language with Stack-Dynamic Local Variables

CS415 Compilers. Procedure Abstractions. These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

CSc 453. OO Languages. Object-Oriented Languages... Object-Oriented Languages. Compiling OO Languages. Compilers and Systems Software

Modules:Context-Sensitive Keyword

Scope. CSC 4181 Compiler Construction. Static Scope. Static Scope Rules. Closest Nested Scope Rule

Functions in C C Programming and Software Tools. N.C. State Department of Computer Science

Transcription:

CSc 520 Principles of Programming Languages 32: Procedures Inlining Christian Collberg collberg@cs.arizona.edu Department of Computer Science University of Arizona Copyright c 2005 Christian Collberg [1]

Inline Expansion The most important and popular inter-procedural optimization is inline expansion, that is replacing the call of a procedure with the procedure s body. Why would you want to perform inlining? There are several reasons: 1. There are a number of things that happen when a procedure call is made: (a) evaluate the arguments of the call, (b) push the arguments onto the stack or move them to argument transfer registers, (c) save registers that contain live values and that might be trashed by the called routine, (d) make the jump to the called routine, [2]

Inline Expansion... 1. continued... (e) make the jump to the called routine, (f) set up an activation record, (g) execute the body of the called routine, (h) return back to the callee, possibly returning a result, (i) deallocate the activation record. 2. Many of these actions don t have to be performed if we inline the callee in the caller, and hence much of the overhead associated with procedure calls is optimized away. 3. More importantly, programs written in modern imperative and OO-languages tend to be so littered with procedure/method calls.... [3]

Inline Expansion... 3.... This is the result of programming with abstract data types. Hence, there is often very little opportunity for optimization. However, when inlining is performed on a sequence of procedure calls, the code from the bodies of several procedures is combined, opening up a larger scope for optimization. There are problems, of course. Obviously, in most cases the size of the procedure call code will be less than the size of the callee s body s code. So, the size of the program will increase as calls are expanded. [4]

Inline Expansion... A larger executable takes longer to load from secondary storage and may affect the paging behavior of the machine. More importantly, a routine (or an inner loop of a routine) that fits within the instruction-cache before expansion, might be too large for the cache after expansion. Also,larger procedures need more registers (the register pressure is higher) than small ones. If, after expansion, a procedure is so large (or contains such complicated expressions) that the number of registers provided by the architecture is not enough, then spill code will have to be inserted when we run out of registers. [5]

Inline Expansion... Several questions remain. Which procedures should be inlined? Some languages (C++, Ada, Modula-3) allow the user to specify (through a keyword or pragma) the procedures that should be eligible for expansions. However, this implies that a given procedure should always be expanded, regardless of the environment in which it is called. This may not be the best thing to do. For example, we might consider inlining a call to P inside a tightly nested inner loop, but choose not to do so in a module initialization code that is only executed once. [6]

Inline Expansion... Some compilers don t rely on the user to decide on what should be inlined. Instead they use 1. A static heuristic, such as procedures which are (a) shorter than 10 lines and have fewer than 5 parameters or (b) are leaf routines (i.e. don t make any calls themselves) are candidates for inlining. 2. A heuristic based on profiling. After running the program through a profiler we know how many times each procedure is likely to be called from each call site. Only inline small, frequently called procedures. [7]

Inline Expansion... How do we inline across module boundaries? We need access to the code of the called procedure. If the procedure is declared in a separately compiled module, this code is not available. What do we do? Good question... What s the difference between inlining and macro expansion? Inlining is performed after semantic analysis, macro expansion before. [8]

Inline Expansion... At which level do we perform the inlining? intermediate code Most common. source code Some source-to-source translators perform inlining. assembly code Doable (with some compiler cooperation), but unusual. [9]

Algorithm 1. Build the call graph: (a) Create an empty directed graph G. (b) Add a node for each routine and for the main program. (c) If procedure P calls procedure Q then insert a directed edge P Q. Main P R T Q S V [10]

Algorithm... G is actually a multigraph since a procedure might make multiple calls to the same procedure. Beware of indirect calls through procedure parameters or variables, as well as method invocations! [11]

Algorithm... 2. Pick routines to inline. Possible heuristics: (a) Discard recursive routines (Perform a topological sort of the call graph. Cycles indicate recursion.) or just inline them one or two levels deep. (b) Select routines with indegree=1. (c) Select calls to small routines in inner loops. (d) Rely on user-defined INLINE pragmas. (e) Use profiling information. (f) Consider effects on caching, paging, register pressure, total code size,... (g)... [12]

Algorithm... 3. FOR each call P (a 1,, a n ) in Q to inline procedure P (f 1,, f n ), in reverse topological order of the call graph DO (a) Replace the call P (a 1,, a n ) with P s body. (b) Replace references to call-by-reference formal f k with a reference to the corresponding actual parameter a k. (c) For each call-by-value formal parameter f k create a new local c k. Insert code to copy the call-by-value actual a k into c k. Replace references to the call-by-value formal f k with a reference to its copy c k. (d) For each of P s local variables l k create a new local v k in Q. Replace references to local variable l k with a reference to v k. [13]

Topological Order Example: main(){ Q();... Q(); }; P(){ R();... S(); }; T(){ R();}; R(){S();}; S(){ V();}; Q(){}; V(){}; Main Topological Order: 7 8 6 P Q 5 4 R S 3 2 1 T V [14]

Topological Order... Performing the inlining in reverse topological order saves time. For example, expanding V in S before expanding S in R and P is faster than expanding S in P, then S in R, and then V in P and R. Note: there is no path main T. Maybe T could be deleted? [15]

Inlining Example (Original) TYPE T = ARRAY [1..100] OF CHAR; PROCEDURE P (n : INTEGER; z : T; VAR y :INTEGER); VAR i : INTEGER; BEGIN IF n < 100 THEN FOR i := 1 TO n DO y := z[i] + y; z[i] := 0; ENDFOR ENDIF END P; VAR S : INTEGER; A : T; BEGIN P(10, A, S); END [16]

Inlining Example (Expanded) TYPE T = ARRAY [1..100] OF CHAR; VAR S, $n, $i : INTEGER; A, $z : T; BEGIN $n := 10; copy($z, A, 100); IF $n < 100 THEN FOR $i := 1 TO $n DO S := $z[$i] + S; $z[$i] := 0; ENDFOR ENDIF END [17]

Inlining Example (Optimized) TYPE T = ARRAY [1..100] OF CHAR; VAR S, $i : INTEGER; A, $z : T; BEGIN copy($z, A, 100); FOR $i := 1 TO 10 DO S := $z[$i] + S; $z[$i] := 0; ENDFOR END [18]

Inlining Methods Consider a method invocation m.p (). The actual procedure called will depend on the run-time type of m. If more than one method can be invoked at a particular call site, we have to inline all possible methods. The appropriate code is selected code by branching on the type of m. To improve on method inlining we would like to find out when a call m.p() can call exactly one method. [19]

Inlining Methods... call m.p () Inline T code for class1::p m.type=class1 m.type=class2 T F F code for class2::p [20]

Inlining Methods Example TYPE T = CLASS [f : T][ METHOD M (); BEGIN END M; ]; TYPE S = CLASS EXTENDS T [ ][ METHOD N (); BEGIN END N; METHOD M (); BEGIN END M; ]; VAR x : T; y : S; BEGIN x.m(); y.m(); END; [21]

Type Hierarchy Analysis For each type T and method M in T, find the set S T,M of method overrides of M in the inheritance hierarchy tree rooted in T. If x is of type T, S T,M contains the methods that can be called by x.m(). We can improve on type hierarchy analysis by using a variant of the Reaching Definitions data flow analysis. [22]

Type Hierarchy Analysis... TYPE T = CLASS [][ METHOD M (); BEGIN END M;]; TYPE S = CLASS EXTENDS T [][ METHOD N (); BEGIN END N; METHOD M (); BEGIN END M;]; VAR x : T; y : S; BEGIN x.m(); S T,M = {T.M, S.M} y.m(); S S,M = {S.M} END; [23]

C Preprocessor The C preprocessor (cpp) is a program that preprocesses a C source file before it is given to the C compiler. The preprocessor s job is to remove comments and apply preprocessor directives that modify the source code. Preprocessor directives begin with #, such as the directive #include <stdio.h> in hello.c. [24]

C Preprocessor... Some popular ones are: #include <file> The preprocessor searches the system directories (e.g. /usr/include) for a file named file and replaces this line with its contents. #define word rest-of-line Replaces word with rest-of-line thoroughout the rest of the source file. #if expression #else #endif If expression is non-zero, the lines up to the #else are included, otherwise the lines between the #else and the #endif are included. [25]

C Preprocessor Examples #define ARRAY_SIZE 1000 char str[array_size]; #define MAX(x,y) ((x) > (y)? (x) : (y)) int max_num; max_num = MAX(i,j); #define DEBUG 1 [26]

C Preprocessor Examples... #define ARRAY_SIZE 1000 #ifdef DEBUG printf("got here!") #endif #if defined(debug) #define Debug(x) printf(x) #else #define Debug(x) #endif Debug(("got here!")); [27]

Macros vs. Inlined Procedures A macro is expanded before syntactic and semantic analysis takes place. An inline function is expanded after semantic analysis. Hence, the body of a macro is analyzed statically in the environment of the caller, the body of an inlined procedure is analyzed in the environment of the callee (itself). [28]

Macros vs. Inlined Procedures... If foo is an inline procedure it will print "yes". If foo is a macro it will not compile. var x : boolean := true; [inline macro] foo(); if x then print "yes" else print "no"; end foo; begin var x : integer := 5; foo(); end. [29]

Readings and References Read Scott: pp. 441-442, 301 303. Read the Dragon book: 530 532, 585 602. [30]