Code Improvement:Thephasesof Compilation Devoted to Generating Good Code
Total Page:16
File Type:pdf, Size:1020Kb
Load more
Recommended publications
-
Redundancy Elimination Common Subexpression Elimination
Redundancy Elimination Aim: Eliminate redundant operations in dynamic execution Why occur? Loop-invariant code: Ex: constant assignment in loop Same expression computed Ex: addressing Value numbering is an example Requires dataflow analysis Other optimizations: Constant subexpression elimination Loop-invariant code motion Partial redundancy elimination Common Subexpression Elimination Replace recomputation of expression by use of temp which holds value Ex. (s1) y := a + b Ex. (s1) temp := a + b (s1') y := temp (s2) z := a + b (s2) z := temp Illegal? How different from value numbering? Ex. (s1) read(i) (s2) j := i + 1 (s3) k := i i + 1, k+1 (s4) l := k + 1 no cse, same value number Why need temp? Local and Global ¡ Local CSE (BB) Ex. (s1) c := a + b (s1) t1 := a + b (s2) d := m&n (s1') c := t1 (s3) e := a + b (s2) d := m&n (s4) m := 5 (s5) if( m&n) ... (s3) e := t1 (s4) m := 5 (s5) if( m&n) ... 5 instr, 4 ops, 7 vars 6 instr, 3 ops, 8 vars Always better? Method: keep track of expressions computed in block whose operands have not changed value CSE Hash Table (+, a, b) (&,m, n) Global CSE example i := j i := j a := 4*i t := 4*i i := i + 1 i := i + 1 b := 4*i t := 4*i b := t c := 4*i c := t Assumes b is used later ¡ Global CSE An expression e is available at entry to B if on every path p from Entry to B, there is an evaluation of e at B' on p whose values are not redefined between B' and B. -
Polyhedral Compilation As a Design Pattern for Compiler Construction
Polyhedral Compilation as a Design Pattern for Compiler Construction PLISS, May 19-24, 2019 [email protected] Polyhedra? Example: Tiles Polyhedra? Example: Tiles How many of you read “Design Pattern”? → Tiles Everywhere 1. Hardware Example: Google Cloud TPU Architectural Scalability With Tiling Tiles Everywhere 1. Hardware Google Edge TPU Edge computing zoo Tiles Everywhere 1. Hardware 2. Data Layout Example: XLA compiler, Tiled data layout Repeated/Hierarchical Tiling e.g., BF16 (bfloat16) on Cloud TPU (should be 8x128 then 2x1) Tiles Everywhere Tiling in Halide 1. Hardware 2. Data Layout Tiled schedule: strip-mine (a.k.a. split) 3. Control Flow permute (a.k.a. reorder) 4. Data Flow 5. Data Parallelism Vectorized schedule: strip-mine Example: Halide for image processing pipelines vectorize inner loop https://halide-lang.org Meta-programming API and domain-specific language (DSL) for loop transformations, numerical computing kernels Non-divisible bounds/extent: strip-mine shift left/up redundant computation (also forward substitute/inline operand) Tiles Everywhere TVM example: scan cell (RNN) m = tvm.var("m") n = tvm.var("n") 1. Hardware X = tvm.placeholder((m,n), name="X") s_state = tvm.placeholder((m,n)) 2. Data Layout s_init = tvm.compute((1,n), lambda _,i: X[0,i]) s_do = tvm.compute((m,n), lambda t,i: s_state[t-1,i] + X[t,i]) 3. Control Flow s_scan = tvm.scan(s_init, s_do, s_state, inputs=[X]) s = tvm.create_schedule(s_scan.op) 4. Data Flow // Schedule to run the scan cell on a CUDA device block_x = tvm.thread_axis("blockIdx.x") 5. Data Parallelism thread_x = tvm.thread_axis("threadIdx.x") xo,xi = s[s_init].split(s_init.op.axis[1], factor=num_thread) s[s_init].bind(xo, block_x) Example: Halide for image processing pipelines s[s_init].bind(xi, thread_x) xo,xi = s[s_do].split(s_do.op.axis[1], factor=num_thread) https://halide-lang.org s[s_do].bind(xo, block_x) s[s_do].bind(xi, thread_x) print(tvm.lower(s, [X, s_scan], simple_mode=True)) And also TVM for neural networks https://tvm.ai Tiling and Beyond 1. -
Integrating Program Optimizations and Transformations with the Scheduling of Instruction Level Parallelism*
Integrating Program Optimizations and Transformations with the Scheduling of Instruction Level Parallelism* David A. Berson 1 Pohua Chang 1 Rajiv Gupta 2 Mary Lou Sofia2 1 Intel Corporation, Santa Clara, CA 95052 2 University of Pittsburgh, Pittsburgh, PA 15260 Abstract. Code optimizations and restructuring transformations are typically applied before scheduling to improve the quality of generated code. However, in some cases, the optimizations and transformations do not lead to a better schedule or may even adversely affect the schedule. In particular, optimizations for redundancy elimination and restructuring transformations for increasing parallelism axe often accompanied with an increase in register pressure. Therefore their application in situations where register pressure is already too high may result in the generation of additional spill code. In this paper we present an integrated approach to scheduling that enables the selective application of optimizations and restructuring transformations by the scheduler when it determines their application to be beneficial. The integration is necessary because infor- mation that is used to determine the effects of optimizations and trans- formations on the schedule is only available during instruction schedul- ing. Our integrated scheduling approach is applicable to various types of global scheduling techniques; in this paper we present an integrated algorithm for scheduling superblocks. 1 Introduction Compilers for multiple-issue architectures, such as superscalax and very long instruction word (VLIW) architectures, axe typically divided into phases, with code optimizations, scheduling and register allocation being the latter phases. The importance of integrating these latter phases is growing with the recognition that the quality of code produced for parallel systems can be greatly improved through the sharing of information. -
Copy Propagation Optimizations for VLIW DSP Processors with Distributed Register Files ?
Copy Propagation Optimizations for VLIW DSP Processors with Distributed Register Files ? Chung-Ju Wu Sheng-Yuan Chen Jenq-Kuen Lee Department of Computer Science National Tsing-Hua University Hsinchu 300, Taiwan Email: {jasonwu, sychen, jklee}@pllab.cs.nthu.edu.tw Abstract. High-performance and low-power VLIW DSP processors are increasingly deployed on embedded devices to process video and mul- timedia applications. For reducing power and cost in designs of VLIW DSP processors, distributed register files and multi-bank register archi- tectures are being adopted to eliminate the amount of read/write ports in register files. This presents new challenges for devising compiler op- timization schemes for such architectures. In our research work, we ad- dress the compiler optimization issues for PAC architecture, which is a 5-way issue DSP processor with distributed register files. We show how to support an important class of compiler optimization problems, known as copy propagations, for such architecture. We illustrate that a naive deployment of copy propagations in embedded VLIW DSP processors with distributed register files might result in performance anomaly. In our proposed scheme, we derive a communication cost model by clus- ter distance, register port pressures, and the movement type of register sets. This cost model is used to guide the data flow analysis for sup- porting copy propagations over PAC architecture. Experimental results show that our schemes are effective to prevent performance anomaly with copy propagations over embedded VLIW DSP processors with dis- tributed files. 1 Introduction Digital signal processors (DSPs) have been found widely used in an increasing number of computationally intensive applications in the fields such as mobile systems. -
Garbage Collection
Topic 10: Dataflow Analysis COS 320 Compiling Techniques Princeton University Spring 2016 Lennart Beringer 1 Analysis and Transformation analysis spans multiple procedures single-procedure-analysis: intra-procedural Dataflow Analysis Motivation Dataflow Analysis Motivation r2 r3 r4 Assuming only r5 is live-out at instruction 4... Dataflow Analysis Iterative Dataflow Analysis Framework Definitions Iterative Dataflow Analysis Framework Definitions for Liveness Analysis Definitions for Liveness Analysis Remember generic equations: -- r1 r1 r2 r2, r3 r3 r2 r1 r1 -- r3 -- -- Smart ordering: visit nodes in reverse order of execution. -- r1 r1 r2 r2, r3 r3 r2 r1 r3, r1 ? r1 -- r3 r3, r1 r3 -- -- r3 Smart ordering: visit nodes in reverse order of execution. -- r1 r3, r1 r3 r1 r2 r3, r2 r3, r1 r2, r3 r3 r3, r2 r3, r2 r2 r1 r3, r1 r3, r2 ? r1 -- r3 r3, r1 r3 -- -- r3 Smart ordering: visit nodes in reverse order of execution. -- r1 r3, r1 r3 r1 r2 r3, r2 r3, r1 : r2, r3 r3 r3, r2 r3, r2 r2 r1 r3, r1 r3, r2 : r1 -- r3 r3, r1 r3, r1 r3 -- -- r3 -- r3 Smart ordering: visit nodes in reverse order of execution. Live Variable Application 1: Register Allocation Interference Graph r1 r3 ? r2 Interference Graph r1 r3 r2 Live Variable Application 2: Dead Code Elimination of the form of the form Live Variable Application 2: Dead Code Elimination of the form This may lead to further optimization opportunities, as uses of variables in s of the form disappear. repeat all / some analysis / optimization passes! Reaching Definition Analysis Reaching Definition Analysis (details on next slide) Reaching definitions: definition-ID’s 1. -
Phase-Ordering in Optimizing Compilers
Phase-ordering in optimizing compilers Matthieu Qu´eva Kongens Lyngby 2007 IMM-MSC-2007-71 Technical University of Denmark Informatics and Mathematical Modelling Building 321, DK-2800 Kongens Lyngby, Denmark Phone +45 45253351, Fax +45 45882673 [email protected] www.imm.dtu.dk Summary The “quality” of code generated by compilers largely depends on the analyses and optimizations applied to the code during the compilation process. While modern compilers could choose from a plethora of optimizations and analyses, in current compilers the order of these pairs of analyses/transformations is fixed once and for all by the compiler developer. Of course there exist some flags that allow a marginal control of what is executed and how, but the most important source of information regarding what analyses/optimizations to run is ignored- the source code. Indeed, some optimizations might be better to be applied on some source code, while others would be preferable on another. A new compilation model is developed in this thesis by implementing a Phase Manager. This Phase Manager has a set of analyses/transformations available, and can rank the different possible optimizations according to the current state of the intermediate representation. Based on this ranking, the Phase Manager can decide which phase should be run next. Such a Phase Manager has been implemented for a compiler for a simple imper- ative language, the while language, which includes several Data-Flow analyses. The new approach consists in calculating coefficients, called metrics, after each optimization phase. These metrics are used to evaluate where the transforma- tions will be applicable, and are used by the Phase Manager to rank the phases. -
Using Program Analysis for Optimization
Analysis and Optimizations • Program Analysis – Discovers properties of a program Using Program Analysis • Optimizations – Use analysis results to transform program for Optimization – Goal: improve some aspect of program • numbfber of execute diid instructions, num bflber of cycles • cache hit rate • memory space (d(code or data ) • power consumption – Has to be safe: Keep the semantics of the program Control Flow Graph Control Flow Graph entry int add(n, k) { • Nodes represent computation s = 0; a = 4; i = 0; – Each node is a Basic Block if (k == 0) b = 1; s = 0; a = 4; i = 0; k == 0 – Basic Block is a sequence of instructions with else b = 2; • No branches out of middle of basic block while (i < n) { b = 1; b = 2; • No branches into middle of basic block s = s + a*b; • Basic blocks should be maximal ii+1;i = i + 1; i < n } – Execution of basic block starts with first instruction return s; s = s + a*b; – Includes all instructions in basic block return s } i = i + 1; • Edges represent control flow Two Kinds of Variables Basic Block Optimizations • Temporaries introduced by the compiler • Common Sub- • Copy Propagation – Transfer values only within basic block Expression Elimination – a = x+y; b = a; c = b+z; – Introduced as part of instruction flattening – a = (x+y)+z; b = x+y; – a = x+y; b = a; c = a+z; – Introduced by optimizations/transformations – t = x+y; a = t+z;;; b = t; • Program variables • Constant Propagation • Dead Code Elimination – x = 5; b = x+y; – Decldiiillared in original program – a = x+y; b = a; c = a+z; – x = 5; b -
A Tiling Perspective for Register Optimization Fabrice Rastello, Sadayappan Ponnuswany, Duco Van Amstel
A Tiling Perspective for Register Optimization Fabrice Rastello, Sadayappan Ponnuswany, Duco van Amstel To cite this version: Fabrice Rastello, Sadayappan Ponnuswany, Duco van Amstel. A Tiling Perspective for Register Op- timization. [Research Report] RR-8541, Inria. 2014, pp.24. hal-00998915 HAL Id: hal-00998915 https://hal.inria.fr/hal-00998915 Submitted on 3 Jun 2014 HAL is a multi-disciplinary open access L’archive ouverte pluridisciplinaire HAL, est archive for the deposit and dissemination of sci- destinée au dépôt et à la diffusion de documents entific research documents, whether they are pub- scientifiques de niveau recherche, publiés ou non, lished or not. The documents may come from émanant des établissements d’enseignement et de teaching and research institutions in France or recherche français ou étrangers, des laboratoires abroad, or from public or private research centers. publics ou privés. A Tiling Perspective for Register Optimization Łukasz Domagała, Fabrice Rastello, Sadayappan Ponnuswany, Duco van Amstel RESEARCH REPORT N° 8541 May 2014 Project-Teams GCG ISSN 0249-6399 ISRN INRIA/RR--8541--FR+ENG A Tiling Perspective for Register Optimization Lukasz Domaga la∗, Fabrice Rastello†, Sadayappan Ponnuswany‡, Duco van Amstel§ Project-Teams GCG Research Report n° 8541 — May 2014 — 21 pages Abstract: Register allocation is a much studied problem. A particularly important context for optimizing register allocation is within loops, since a significant fraction of the execution time of programs is often inside loop code. A variety of algorithms have been proposed in the past for register allocation, but the complexity of the problem has resulted in a decoupling of several important aspects, including loop unrolling, register promotion, and instruction reordering. -
CSE 401/M501 – Compilers
CSE 401/M501 – Compilers Dataflow Analysis Hal Perkins Autumn 2018 UW CSE 401/M501 Autumn 2018 O-1 Agenda • Dataflow analysis: a framework and algorithm for many common compiler analyses • Initial example: dataflow analysis for common subexpression elimination • Other analysis problems that work in the same framework • Some of these are the same optimizations we’ve seen, but more formally and with details UW CSE 401/M501 Autumn 2018 O-2 Common Subexpression Elimination • Goal: use dataflow analysis to A find common subexpressions m = a + b n = a + b • Idea: calculate available expressions at beginning of B C p = c + d q = a + b each basic block r = c + d r = c + d • Avoid re-evaluation of an D E available expression – use a e = b + 18 e = a + 17 copy operation s = a + b t = c + d u = e + f u = e + f – Simple inside a single block; more complex dataflow analysis used F across bocks v = a + b w = c + d x = e + f G y = a + b z = c + d UW CSE 401/M501 Autumn 2018 O-3 “Available” and Other Terms • An expression e is defined at point p in the CFG if its value a+b is computed at p defined t1 = a + b – Sometimes called definition site ... • An expression e is killed at point p if one of its operands a+b is defined at p available t10 = a + b – Sometimes called kill site … • An expression e is available at point p if every path a+b leading to p contains a prior killed b = 7 definition of e and e is not … killed between that definition and p UW CSE 401/M501 Autumn 2018 O-4 Available Expression Sets • To compute available expressions, for each block -
Loop Transformations and Parallelization
Loop transformations and parallelization Claude Tadonki LAL/CNRS/IN2P3 University of Paris-Sud [email protected] December 2010 Claude Tadonki Loop transformations and parallelization C. Tadonki – Loop transformations Introduction Most of the time, the most time consuming part of a program is on loops. Thus, loops optimization is critical in high performance computing. Depending on the target architecture, the goal of loops transformations are: improve data reuse and data locality efficient use of memory hierarchy reducing overheads associated with executing loops instructions pipeline maximize parallelism Loop transformations can be performed at different levels by the programmer, the compiler, or specialized tools. At high level, some well known transformations are commonly considered: loop interchange loop (node) splitting loop unswitching loop reversal loop fusion loop inversion loop skewing loop fission loop vectorization loop blocking loop unrolling loop parallelization Claude Tadonki Loop transformations and parallelization C. Tadonki – Loop transformations Dependence analysis Extract and analyze the dependencies of a computation from its polyhedral model is a fundamental step toward loop optimization or scheduling. Definition For a given variable V and given indexes I1, I2, if the computation of X(I1) requires the value of X(I2), then I1 ¡ I2 is called a dependence vector for variable V . Drawing all the dependence vectors within the computation polytope yields the so-called dependencies diagram. Example The dependence vectors are (1; 0); (0; 1); (¡1; 1). Claude Tadonki Loop transformations and parallelization C. Tadonki – Loop transformations Scheduling Definition The computation on the entire domain of a given loop can be performed following any valid schedule.A timing function tV for variable V yields a valid schedule if and only if t(x) > t(x ¡ d); 8d 2 DV ; (1) where DV is the set of all dependence vectors for variable V . -
Incremental Computation of Static Single Assignment Form
Incremental Computation of Static Single Assignment Form Jong-Deok Choi 1 and Vivek Sarkar 2 and Edith Schonberg 3 IBM T.J. Watson Research Center, P. O. Box 704, Yorktown Heights, NY 10598 ([email protected]) 2 IBM Software Solutions Division, 555 Bailey Avenue, San Jose, CA 95141 ([email protected]) IBM T.J. Watson Research Center, P. O. Box 704, Yorktown Heights, NY 10598 ([email protected]) Abstract. Static single assignment (SSA) form is an intermediate rep- resentation that is well suited for solving many data flow optimization problems. However, since the standard algorithm for building SSA form is exhaustive, maintaining correct SSA form throughout a multi-pass com- pilation process can be expensive. In this paper, we present incremental algorithms for restoring correct SSA form after program transformations. First, we specify incremental SSA algorithms for insertion and deletion of a use/definition of a variable, and for a large class of updates on intervals. We characterize several cases for which the cost of these algorithms will be proportional to the size of the transformed region and hence poten- tially much smaller than the cost of the exhaustive algorithm. Secondly, we specify customized SSA-update algorithms for a set of common loop transformations. These algorithms are highly efficient: the cost depends at worst on the size of the transformed code, and in many cases the cost is independent of the loop body size and depends only on the number of loops. 1 Introduction Static single assignment (SSA) [8, 6] form is a compact intermediate program representation that is well suited to a large number of compiler optimization algorithms, including constant propagation [19], global value numbering [3], and program equivalence detection [21]. -
Compiler-Based Code-Improvement Techniques
Compiler-Based Code-Improvement Techniques KEITH D. COOPER, KATHRYN S. MCKINLEY, and LINDA TORCZON Since the earliest days of compilation, code quality has been recognized as an important problem [18]. A rich literature has developed around the issue of improving code quality. This paper surveys one part of that literature: code transformations intended to improve the running time of programs on uniprocessor machines. This paper emphasizes transformations intended to improve code quality rather than analysis methods. We describe analytical techniques and specific data-flow problems to the extent that they are necessary to understand the transformations. Other papers provide excellent summaries of the various sub-fields of program analysis. The paper is structured around a simple taxonomy that classifies transformations based on how they change the code. The taxonomy is populated with example transformations drawn from the literature. Each transformation is described at a depth that facilitates broad understanding; detailed references are provided for deeper study of individual transformations. The taxonomy provides the reader with a framework for thinking about code-improving transformations. It also serves as an organizing principle for the paper. Copyright 1998, all rights reserved. You may copy this article for your personal use in Comp 512. Further reproduction or distribution requires written permission from the authors. 1INTRODUCTION This paper presents an overview of compiler-based methods for improving the run-time behavior of programs — often mislabeled code optimization. These techniques have a long history in the literature. For example, Backus makes it quite clear that code quality was a major concern to the implementors of the first Fortran compilers [18].