Loop Induction Variable Canonicalization. Motivation Background: Open64 Compilation Scheme Loop Induction Variable Canonicalization Project Tracing and.

Slides:



Advertisements
Similar presentations
CSC 4181 Compiler Construction Code Generation & Optimization.
Advertisements

8. Static Single Assignment Form Marcus Denker. © Marcus Denker SSA Roadmap  Static Single Assignment Form (SSA)  Converting to SSA Form  Examples.
Synopsys University Courseware Copyright © 2012 Synopsys, Inc. All rights reserved. Compiler Optimization and Code Generation Lecture - 3 Developed By:
School of EECS, Peking University “Advanced Compiler Techniques” (Fall 2011) SSA Guo, Yao.
P3 / 2004 Register Allocation. Kostis Sagonas 2 Spring 2004 Outline What is register allocation Webs Interference Graphs Graph coloring Spilling Live-Range.
ANALYSIS OF PROG. LANG. PROGRAM ANALYSIS Instructors: Crista Lopes Copyright © Instructors. 1.
Course Outline Traditional Static Program Analysis Software Testing
Lecture 11: Code Optimization CS 540 George Mason University.
Chapter 9 Code optimization Section 0 overview 1.Position of code optimizer 2.Purpose of code optimizer to get better efficiency –Run faster –Take less.
Architecture-dependent optimizations Functional units, delay slots and dependency analysis.
ECE 454 Computer Systems Programming Compiler and Optimization (I) Ding Yuan ECE Dept., University of Toronto
Jeffrey D. Ullman Stanford University. 2  A never-published Stanford technical report by Fran Allen in  Fran won the Turing award in  Flow.
Control-Flow Graphs & Dataflow Analysis CS153: Compilers Greg Morrisett.
SSA.
Chapter 10 Code Optimization. A main goal is to achieve a better performance Front End Code Gen Intermediate Code source Code target Code user Machine-
1 Code Optimization Code produced by compilation algorithms can often be improved (ideally optimized) in terms of run-time speed and the amount of memory.
1 Compiler Construction Intermediate Code Generation.
CS412/413 Introduction to Compilers Radu Rugina Lecture 16: Efficient Translation to Low IR 25 Feb 02.
Determining Tree-Traversals Orientation using Feedback-Directed Analysis Stephen Curial, Kevin Andrusky and José Nelson Amaral University of Alberta Stephen.
Improving code generation. Better code generation requires greater context Over expressions: optimal ordering of subtrees Over basic blocks: Common subexpression.
CS 536 Spring Intermediate Code. Local Optimizations. Lecture 22.
1 Intermediate representation Goals: –encode knowledge about the program –facilitate analysis –facilitate retargeting –facilitate optimization scanning.
CS Data Structures Appendix 1 How to transfer a simple loop- expression to a recursive function (factorial calculation)
1 Intermediate representation Goals: encode knowledge about the program facilitate analysis facilitate retargeting facilitate optimization scanning parsing.
Idiom Recognition in the Polaris Parallelizing Compiler Bill Pottenger and Rudolf Eigenmann Presented by Vincent Yau.
Intermediate Code. Local Optimizations
Improving Code Generation Honors Compilers April 16 th 2002.
Improving code generation. Better code generation requires greater context Over expressions: optimal ordering of subtrees Over basic blocks: Common subexpression.
Compiler Construction A Compulsory Module for Students in Computer Science Department Faculty of IT / Al – Al Bayt University Second Semester 2008/2009.
SM1205 Interactivity Topic 06: Iteration and Multiple Objects Spring 2010SCM-CityU1.
Optimizing Compilers Nai-Wei Lin Department of Computer Science and Information Engineering National Chung Cheng University.
2.2 A Simple Syntax-Directed Translator Syntax-Directed Translation 2.4 Parsing 2.5 A Translator for Simple Expressions 2.6 Lexical Analysis.
Topic #10: Optimization EE 456 – Compiling Techniques Prof. Carl Sable Fall 2003.
U NIVERSITY OF M ASSACHUSETTS, A MHERST D EPARTMENT OF C OMPUTER S CIENCE Emery Berger University of Massachusetts, Amherst Advanced Compilers CMPSCI 710.
What’s in an optimizing compiler?
1 Code Generation Part II Chapter 9 COP5621 Compiler Construction Copyright Robert van Engelen, Florida State University, 2005.
CS 363 Comparative Programming Languages Semantics.
Copyright © 2010 Certification Partners, LLC -- All Rights Reserved Perl Specialist.
1 Code optimization “Code optimization refers to the techniques used by the compiler to improve the execution efficiency of the generated object code”
Compiler Principles Fall Compiler Principles Lecture 0: Local Optimizations Roman Manevich Ben-Gurion University.
Synopsys University Courseware Copyright © 2012 Synopsys, Inc. All rights reserved. Compiler Optimization and Code Generation Lecture - 1 Developed By:
High-Level Transformations for Embedded Computing
A System to Generate Test Data and Symbolically Execute Programs Lori A. Clarke Presented by: Xia Cheng.
Compiler Optimizations ECE 454 Computer Systems Programming Topics: The Role of the Compiler Common Compiler (Automatic) Code Optimizations Cristiana Amza.
CMPUT Compiler Design and Optimization1 CMPUT680 - Fall 2006 Topic 3: Intermediate Representation in the ORC José Nelson Amaral
CS412/413 Introduction to Compilers Radu Rugina Lecture 18: Control Flow Graphs 29 Feb 02.
1 Control Flow Graphs. 2 Optimizations Code transformations to improve program –Mainly: improve execution time –Also: reduce program size Can be done.
1 Structure of a Compiler Source Language Target Language Semantic Analyzer Syntax Analyzer Lexical Analyzer Front End Code Optimizer Target Code Generator.
3/6/20161 WHIRL SSA: A New Optimization Infrastructure for Open64 Keqiao Yang, Zhemin Yang Parallel Processing Institute, Fudan University, Shanghai Hui.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Dr. Hussien Sharaf Dr Emad Nabil. Dr. Hussien M. Sharaf 2 position := initial + rate * Lexical analyzer 2. Syntax analyzer id 1 := id 2 + id 3 *
©SoftMoore ConsultingSlide 1 Code Optimization. ©SoftMoore ConsultingSlide 2 Code Optimization Code generation techniques and transformations that result.
Credible Compilation With Pointers Martin Rinard and Darko Marinov Laboratory for Computer Science Massachusetts Institute of Technology.
Code Optimization More Optimization Techniques. More Optimization Techniques  Loop optimization  Code motion  Strength reduction for induction variables.
Single Static Assignment Intermediate Representation (or SSA IR) Many examples and pictures taken from Wikipedia.
Code Optimization Code produced by compilation algorithms can often be improved (ideally optimized) in terms of run-time speed and the amount of memory.
Code Optimization Overview and Examples
Code Optimization.
© Seth Copen Goldstein & Todd C. Mowry
Optimization Code Optimization ©SoftMoore Consulting.
Princeton University Spring 2016
Code Generation Part III
Preliminary Transformations
Code Optimization Overview and Examples Control Flow Graph
Code Generation Part III
Optimizations using SSA
Intermediate Code Generation
EECS 583 – Class 9 Classic and ILP Optimization
The SGI Pro64 Compiler Infrastructure
Code Optimization.
Presentation transcript:

Loop Induction Variable Canonicalization

Motivation Background: Open64 Compilation Scheme Loop Induction Variable Canonicalization Project Tracing and WHIRL Specification Loops References 3/27/20082 Copyright © Juergen Ributzka. All rights reserved.

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 3 How to copy one array to another array?

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 4 for (int i = 0; i < SIZE; i++) { p[i] = q[i]; } int i = 0; while (i < SIZE) { p[i] = q[i]; i = i + 1; } while (p <= &p[SIZE-1]) { *p++ = *q++; } int i = 1; if (i <= SIZE) { do { p[i-1] = q[i-1]; } while (i++ <= SIZE); } One simple problem – many different solutions

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 5 int i = 0; while (i < SIZE) { p[i] = q[i]; i = i + 1; } Compiler prefer code which is easy to analyze: while (p <= &p[SIZE-1]) { *p++ = *q++; } User want high performance code: Compiler Optimization Compiler Transformation

Just one Induction Variable – starting at 0 – stride of 1 Unified Loop representation 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 6 int iv = 0; while (iv <= SIZE-1) { p[iv] = q[iv]; iv = iv + 1; }

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 7 Front End Loop Nest Optimizer (optional) Global Optimizer Code Generation IVR

Step 1: Induction Variable Injection Step 2: Inserting φ’s and Identity Assignments Step 3: Renaming Step 4: Induction Variable Analysis and Processing Step 5: Copy Propagation and Expression Simplification Step 6: Dead Store Elimination 3/27/20088 Copyright © Juergen Ributzka. All rights reserved.

At this point we only have DO and WHILE loops – GOTO statements have been transformed to WHILE loops Loops are annotated with details of the high-level loop construct Inject a unit-stride induction variable into – Non-unit-stride DO loops – All WHILE loops 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 9 p = &a[0]; while (p <= &a[99]) { *p = 0; p = p + 1; } p = &a[0]; iv = 0; while (p <= &a[99]) { *p = 0; p = p + 1; iv = iv + 1; } Before:After:

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 10 Before: After: p ← &a[0] iv ← 0 p ← &a[0] iv ← 0 p ≤ &a[99] ? *p ← 0 p ← p + 4 iv ← iv + 1 *p ← 0 p ← p + 4 iv ← iv + 1 … … p ← &a[0] iv ← 0 p ← &a[0] iv ← 0 iv ← φ(iv, iv) p ← φ(p, p) p ≤ &a[99] ? iv ← φ(iv, iv) p ← φ(p, p) p ≤ &a[99] ? *p ← 0 p ← p + 4 iv ← iv + 1 *p ← 0 p ← p + 4 iv ← iv + 1 iv ← iv p ← p iv ← iv p ← p Insert φ’s

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 11 Before: After: p ← &a[0] iv ← 0 p ← &a[0] iv ← 0 iv ← φ(iv, iv) p ← φ(p, p) p ≤ &a[99] ? iv ← φ(iv, iv) p ← φ(p, p) p ≤ &a[99] ? *p ← 0 p ← p + 4 iv ← iv + 1 *p ← 0 p ← p + 4 iv ← iv + 1 iv ← iv p ← p iv ← iv p ← p p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← φ(p 1, p 3 ) p 2 ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← φ(p 1, p 3 ) p 2 ≤ &a[99] ? *p 2 ← 0 p 3 ← p iv 3 ← iv *p 2 ← 0 p 3 ← p iv 3 ← iv iv 4 ← iv 2 p 4 ← p 2 iv 4 ← iv 2 p 4 ← p 2 Rename variables

Process φ list at the beginning of the loop One operand must correspond to the initial value The other must be defined in the loop Initialize symbolic expression tree with this operand Recursively resolve variables in the expression tree which are not defined by a φ node, except both φ node operands are the same All variables in the symbolic expression tree must be now loop invariant or a result of a φ i 2 is an induction variable, if the expression tree is of the form i 2 ± where i 2 is a φ result. 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 12

i 1 and j 1 are initial values Expression Tree: i 2 ← i 3 i 2 ← j i 2 ← i (found IV) j 2 ← j 3 j 2 ← i j 2 ← i (can’t resolve i 2 ) 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 13 i 2 ← φ(i 1, i 3 ) j 2 ← φ(j 1, j 3 ) i 2 ≤ 100 ? i 2 ← φ(i 1, i 3 ) j 2 ← φ(j 1, j 3 ) i 2 ≤ 100 ? j 3 ← i … i 3 ← j j 3 ← i … i 3 ← j … … Example:

i 1 is initial values Expression Tree: i 2 ← i 5 i 2 ← φ(i 3, i 4 ) i 2 ← i 3 i 2 ← i (found IV) 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 14 i 2 ← φ(i 1, i 5 ) i 2 ≤ 100 ? i 2 ← φ(i 1, i 5 ) i 2 ≤ 100 ? i2 < x ? … i 3 ← i Example: … i 4 ← i i 5 ← φ(i 3, i 4 ) … … ?=?=

Select Primary Induction Variable Compute Trip Count Exit Values s exit ← s init + x s step Define Secondary Induction Variables (s) with Primary Induction Variables (p) s ← s init + (p – p init ) x s step 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 15

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 16 Before: After: p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 p 2 ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 p 2 ≤ &a[99] ? *p 2 ← 0 p 3 ← p iv 3 ← iv *p 2 ← 0 p 3 ← p iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100] p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← φ(p 1, p 3 ) p 2 ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← φ(p 1, p 3 ) p 2 ≤ &a[99] ? *p 2 ← 0 p 3 ← p iv 3 ← iv *p 2 ← 0 p 3 ← p iv 3 ← iv iv 4 ← iv 2 p 4 ← p 2 iv 4 ← iv 2 p 4 ← p 2 Add exit values and replace φ’s

Preorder Traversal of the Dominator Tree If use of x 1 is defined by an assignment of the form x 1 ←, then substitute it by Example: Before:After: x 1 ← i 1 + j 1 x 1 ← i 1 + j 1 y 2 ← x 1 – y 1 y 2 ← i 1 + j 1 – y 1 x 2 ← y 2 + z 3 x 2 ← i 1 + j 1 – y 1 + z 3 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 17

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 18 Before: After: p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 (&a[0]+(iv 2 -0)x4) ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 (&a[0]+(iv 2 -0)x4) ≤ &a[99] ? *(&a[0]+(iv 2 -0)x4) ← 0 p 3 ← &a[0]+(iv 2 -0)x4 + 4 iv 3 ← iv *(&a[0]+(iv 2 -0)x4) ← 0 p 3 ← &a[0]+(iv 2 -0)x4 + 4 iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100] Copy Propagation p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 p 2 ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 p 2 ≤ &a[99] ? *p 2 ← 0 p 3 ← p iv 3 ← iv *p 2 ← 0 p 3 ← p iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100]

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 19 Before: After: p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100] Simplification p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 (&a[0]+(iv 2 -0)x4) ≤ &a[99] ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[0]+(iv 2 -0)x4 (&a[0]+(iv 2 -0)x4) ≤ &a[99] ? *(&a[0]+(iv 2 -0)x4) ← 0 p 3 ← &a[0]+(iv 2 -0)x4 + 4 iv 3 ← iv *(&a[0]+(iv 2 -0)x4) ← 0 p 3 ← &a[0]+(iv 2 -0)x4 + 4 iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100]

Mark all statements dead, except – I/O statements – return statements – procedure calls – statements with side effects (e.g. changes memory) Propagate liveness to the rest of the program – for each variable used in a live statement mark its defining statement alive – mark the conditional branch alive on which the statements depends Remove statements which has not been marked alive 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 20

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 21 After: p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100] Dead Store Elimination Before: p 1 ← &a[0] iv 1 ← 0 p 1 ← &a[0] iv 1 ← 0 iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? iv 2 ← φ(iv 1, iv 3 ) p 2 ← &a[iv 2 ] iv 2 ≤ 99 ? *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv *a[iv 2 ] ← 0 p 3 ← &a[iv 2 ] + 4 iv 3 ← iv iv 4 ← 100 p 4 ← &a[100] iv 4 ← 100 p 4 ← &a[100]

Given a loop, trace the intermediate representation (WHIRL) of the Open64 compiler as explained in the next slides. Create a CFG for each trace and explain what changed between each trace. The behavior that will be exposed by your trace will differ in certain aspects to the one presented in this presentation since Open64 has evolved over time. Is the result optimal? What could be improved? Extra Credit: Explain how the behavior has changed. 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 22

After the Front End opencc -c -O3 -show -keep loop1.c ir_b2a loop1.B > loop1.t After HSSA creation opencc -c -O3 -Wb,-tt25:0x PHASE:w=off filename.c (this will give you the trace before and after IVR) After Induction Variable Recognition opencc -c -O3 -Wb,-tt25:0x PHASE:w=off filename.c (this will give you the trace before and after IVR) 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 23

After Copy Propagation opencc -c -O3 -Wb,-tt25:0x PHASE:w=off filename.c After Boolean Simplification opencc -c -O3 -Wb,-tt26:0x PHASE:w=off filename.c After Dead Code Elimination opencc -c -O3 -Wb,-tt25:0x PHASE:w=off filename.c After each step you will find the trace in filename.t 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 24

3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 25 Example C-Code: int foo (int *p, int size) { int sum = 0; int i; for (i = 0; i < size; i++) { sum += p[i]; } return sum; }

WHIRL: FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 26

LOC 1 4 int sum = 0; I4INTCONST 0 (0x0) I4STID 0 T LOC 1 5 int i; LOC 1 6 LOC 1 7 for (i=0; i<size; i++) { I4INTCONST 0 (0x0) I4STID 0 T WHILE_DO I4I4LDID 0 T I4I4GT 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 27

BODY BLOCK LOC 1 8 sum += p[i]; U8U8LDID 0 T I8I4LDID 0 T U8I8CVT U8INTCONST 4 (0x4) U8MPY U8ADD I4I4ILOAD 0 T T I4I4LDID 0 T I4ADD I4STID 0 T LOC 1 7 LABEL L1 0 I4I4LDID 0 T I4INTCONST 1 (0x1) I4ADD I4STID 0 T END_BLOCK 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 28 = sum+ load + * 4convert i p

LOC 1 9 } LOC 1 10 LOC 1 11 return sum; I4I4LDID 0 T I4RETURN_VAL END_BLOCK 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 29

int loop1 (int *p, int size) { int i = 0; while (i < size) { i = i + 3; p[i] = 0; i = i + 1; } return 0; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 30

int loop2 (int *p, int *q, int size) { int i; for (i=0; i != size; i++) { *p = *q; p = p + 2; q = q + 3; } return 0; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 31

int loop3 (int *p, int *q, int size) { int i = 0; while (i < size) { int j = i + 1; p[j] = 0; i = j + 3; q[i] = 1; } return 0; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 32

int loop4 (int *a, int size) { int *p = a; int *q = &a[size]; while (p != q) { *(++p) = 0; } return 0; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 33

int loop5 (int *a, int size) { int i = 0; while (i++ < size) { a[i] = 0; } return 0; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 34

int loop6 (int *a, int size, int t) { int i = 0; int sum = 0; while (i < size) { if (a[i] < t) { i = i + 1; continue; } sum += a[i]; i = i + 1; } return sum; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 35

int loop7 (int *a, int size) { int i,j; int sum = 0; int k = 0; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { sum += a[k]; k = k + 1; } return sum; } 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 36

Dr. Fred Chow (PathScale, LLC) Dr. Handong Ye (CAPSL) 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 37

Shin-Ming Liu, Raymond Lo and Fred Chow, “Loop Induction Variable Canonicalization in Parallelizing Compilers” WHIRL Intermediate Language Specification ( How to Debug Open64 (Open64/doc/HOW-TO-DEBUG-OPEN64) 3/27/2008 Copyright © Juergen Ributzka. All rights reserved. 38