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

Similar documents
CSc 520 Principles of Programming Languages

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

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

Introduction. Data-flow Analysis by Iteration. CSc 553. Principles of Compilation. 28 : Optimization III

CS 406/534 Compiler Construction Putting It All Together

G Programming Languages - Fall 2012

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

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 520 Principles of Programming Languages

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

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

Liveness Analysis and Register Allocation. Xiao Jia May 3 rd, 2013

CA Compiler Construction

Chapter 9 :: Subroutines and Control Abstraction

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

CSc 520 Principles of Programming Languages

CSc 520 Principles of Programming Languages

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

Functions and Procedures

CSE 504: Compiler Design. Runtime Environments

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

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

Chapter 9 Subroutines and Control Abstraction. June 22, 2016

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

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

Procedure and Object- Oriented Abstraction

Weeks 6&7: Procedures and Parameter Passing

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

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

CSc 553. Principles of Compilation. 23 : Register Allocation. Department of Computer Science University of Arizona

Runtime Environments I. Basilio B. Fraguela

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

CS 2210 Programming Project (Part IV)

Scope, Functions, and Storage Management

Run-time Environments

Control Abstraction. Hwansoo Han

Run-time Environments

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

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

Course Administration

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

CSc 520 Principles of Programming Languages

Code Generation. Lecture 12

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

Short Notes of CS201

Functions in MIPS. Functions in MIPS 1

G Programming Languages - Fall 2012

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

CS558 Programming Languages

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

Code Generation & Parameter Passing

CS201 - Introduction to Programming Glossary By

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

Concepts Introduced in Chapter 7

Exploiting Hardware Resources: Register Assignment across Method Boundaries

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

Programming Languages

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

Chap. 8 :: Subroutines and Control Abstraction

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

Why Global Dataflow Analysis?

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

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

Operational Semantics of Cool

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

Parallelizing Compilers

Data Flow Analysis. Agenda CS738: Advanced Compiler Optimizations. 3-address Code Format. Assumptions

CS 61C: Great Ideas in Computer Architecture (Machine Structures) More MIPS Machine Language

Lecture #16: Introduction to Runtime Organization. Last modified: Fri Mar 19 00:17: CS164: Lecture #16 1

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

Lecture08: Scope and Lexical Address

Functions BCA-105. Few Facts About Functions:

Topic 7: Activation Records

Assembly Language: Function Calls

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

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

Memory Management. Memory Management... Memory Management... Interface to Dynamic allocation

CS 480 Fall Runtime Environments. Mike Lam, Professor. (a.k.a. procedure calls and heap management)

Digital Forensics Lecture 3 - Reverse Engineering

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

Compilers and Code Optimization EDOARDO FUSELLA

The Decaf Language. 1 Lexical considerations

Register Allocation. Global Register Allocation Webs and Graph Coloring Node Splitting and Other Transformations

CS153: Compilers Lecture 8: Compiling Calls

Static Checking and Intermediate Code Generation Pat Morin COMP 3002

About the Authors... iii Introduction... xvii. Chapter 1: System Software... 1

Query Processing & Optimization

Semantic Analysis and Type Checking

Run-Time Data Structures

Chapter 2A Instructions: Language of the Computer

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

CS 536 Introduction to Programming Languages and Compilers Charles N. Fischer Lecture 11

EECS 477: Introduction to algorithms. Lecture 7

Review; questions Basic Analyses (2) Assign (see Schedule for links)

Compiler Architecture

Implementing Procedure Calls

CPSC 213. Introduction to Computer Systems. Readings for Next 2 Lectures. Loops (S5-loop) Control Flow. Static Control Flow. Unit 1d.

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

Functions in C C Programming and Software Tools

Transcription:

CSc 553 Principles of Compilation 29 : Optimization IV Introduction Department of Computer Science University of Arizona collberg@gmail.com Copyright c 2011 Christian Collberg Inline Expansion I Inline Expansion he 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? here are several reasons: 1 here are a number of things that happen when a procedure call is made: 1 evaluate the arguments of the call, 2 push the arguments onto the stack or move them to argument transfer registers, 3 save registers that contain live values and that might be trashed by the called routine, 4 make the jump to the called routine,

Inline Expansion II Inline Expansion III 1 continued... 5 make the jump to the called routine, 6 set up an activation record, 7 execute the body of the called routine, 8 return back to the callee, possibly returning a result, 9 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... his 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. here 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. Inline Expansion IV Inline Expansion V 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. 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. his 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.

Inline Expansion VI Inline Expansion VII 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 1 shorter than 10 lines and have fewer than 5 parameters or 2 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. 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. 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. Algorithm I Algorithm II 1 Build the call graph: 1 Create an empty directed graph G. 2 Add a node for each routine and for the main program. 3 If procedure P calls procedure Q then insert a directed edge P Q. Main P Q 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! R S V 2 Pick routines to inline. Possible heuristics: 1 Discard recursive routines (Perform a topological sort of the call graph. Cycles indicate recursion.) or just inline them one or two levels deep. 2 Select routines with indegree=1. 3 Select calls to small routines in inner loops. 4 Rely on user-defined INLINE pragmas. 5 Use profiling information. 6 Consider effects on caching, paging, register pressure, total code size,... 7...

Algorithm III opological Order 3 FOR each call P(a1,, an) in Q to inline procedure P(f1,,fn), in reverse topological order of the call graph DO 1 Replace the call P(a1,, an) with P s body. 2 Replace references to call-by-reference formal fk with a reference to the corresponding actual parameter ak. 3 For each call-by-value formal parameter fk create a new local ck. Insert code to copy the call-by-value actual ak into ck. Replace references to the call-by-value formal fk with a reference to its copy ck. 4 For each of P s local variables lk create a new local vk in Q. Replace references to local variable lk with a reference to vk. Inlining Example (Original) Example: main(){ Q();... Q(); }; P(){ R();... S(); }; (){ R();}; R(){S();}; S(){ V();}; Q(){}; V(){}; Main opological Order: 7 8 6 P Q 5 Performing the inlining in reverse topological order saves time: 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. Maybe could be deleted? Inlining Example (Expanded) 4 R S 3 2 1 V YPE = ARRAY [1..100] OF CHAR; PROCEDURE P (n : INEGER; z : ; VAR y :INEGER); VAR i : INEGER; IF n < 100 HEN FOR i := 1 O n DO y := z[i] + y; z[i] := 0; ENDFOR ENDIF END P; VAR S : INEGER; A : ; P(10, A, S); END YPE = ARRAY [1..100] OF CHAR; VAR S, $n, $i : INEGER; A, $z : ; $n := 10; copy($z, A, 100); IF $n < 100 HEN FOR $i := 1 O $n DO S := $z[$i] + S; $z[$i] := 0; ENDFOR ENDIF END

Inlining Example (Optimized) Optimize YPE = ARRAY [1..100] OF CHAR; VAR S, $i : INEGER; A, $z : ; copy($z, A, 100); Inlining in OO Languages FOR $i := 1 O 10 DO S := $z[$i] + S; $z[$i] := 0; ENDFOR END Inlining Methods I Inlining Methods II Consider a method invocation m.p(). he 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. he appropriate code is selected code by branching on the type of m. call m.p() Inline code for class1::p m.type=class1 m.type=class2 code for class2::p F F o improve on method inlining we would like to find out when a call m.p() can call exactly one method. YPE = CLASS [f : ][ MEHOD M (); END M; ]; YPE S = CLASS EXENDS [ ][ MEHOD N (); END N; MEHOD M (); END M; ]; VAR x : ; y : S; x.m(); y.m(); END;

Inlining Methods III Inlining Methods IV Intraprocedural ype Propagation Inheritance Hierarchy Analysis For each type and method M in, find the set S,M of method overrides of M in the inheritance hierarchy tree rooted in. If x is of type, S,M contains the methods that can be called by x.m(). Example YPE = CLASS [][MEHOD M (); END M;]; YPE S = CLASS EXENDS [][ MEHOD N (); END N; MEHOD M (); END M;]; VAR x : ; y : S; x.m(); S,M = {.M,S.M} y.m(); SS,M = {S.M} END; Inlining Methods V We can improve on type hierarchy analysis by using a variant of the Reaching Definitions data flow analysis. YPE = CLASS [][MEHOD M (); ]; YPE S = CLASS EXENDS [][ MEHOD M (); END M;]; VAR p : S; o : ; p := NEW S; IF e HEN o := NEW ; o.m(); ELSE o := p; o.m(); ENDIF; o.m(); o := NARROW(o, S); o.m(); END; Inlining Methods VI out[b] = Gen[B] (in[b] Kill[B]) in[b] = out[p] preds P of B We ll use sets of pairs t,s, where S is the set of possible types of variable t. he equations are defined over statements, not basic blocks. he function ypeof(x) is the set of current types of x. Gen[B] = { v, {S} } statement B contains an operation that guarantees that v will have type S. Out[B] = { v, {S}, u, {S, } } after statement B, v will have type S and u will have type S or. Gen(v:= NEW t) = v, {t} After v := NEW t, v must have the type t. Gen(v:=u) = v,ypeof(u) After an assignment v := u, the set of possible types of v is the same as the current set of possible types of u. Gen(v:= NARROW(u, )) = v, ypeof(u) After an assignment v:= NARROW(u,), the set of possible types of v contains those current possible types of u that are also a subtype of. Kill(v:=u) = v,ypeof(v) After an assignment v:=u, v may not have the same type that it had before. Kill(v:= NEW t) = v, ypeof(v) Kill(v:= NARROW(u, )) = v, ypeof(v)

o.m(); G = { p, {S} } K = { p, (p) } G = { o, { } } K = { o, (o) } B3 B4 o := NEW o.m() G = { o, (o) {S} } K = { o, (o) } p := NEW S if (e) GOO B2 o := NARROW(o,S) o.m() B1 B2 G = { o, (p) } K = { o, (o) } B5 o := p o.m(); NOE: (x) = ypeof(x) B7 B8 B9 B6 G = { p, {S} } p := NEW S B1 K = { p, (p) } I = {} O = { p, {S} } if (e) GOO B2 B2 G = { o, { } } G = { o, {S} } K = { o, {} } K = { o, {} } B3 o := NEW o := p B5 I = { p, {S} } I = { p, {S} } O = { o, { }, p, {S} } O = { o, {S}, p, {S} } B4 o.m() o.m(); B6 I = O[B4] O[B6] = { o, {S, }, p, {S} } o.m(); B7 G = { o, {S, } {S} } K = { o, {S, } } o := NARROW(o,S) B8 I = { o, {S, }, p, {S} } O = { o, {S}, p, {S} } I = { o, {S}, p, {S} } o.m() B9 Readings and References Summary Read the iger book, Section 15.4. his describes inlining in functional languages, but the ideas are the same.