xxPIPS High-Level Software Interface Pipsmake configuration

PIPS High-Level Software Interface Pipsmake configuration

Remi Triolet and Franxois Irigoin

with many other contributors MINES ParisTech

Mathx¿œmatiques et Systx¿œmes Centre de Recherche en Informatique

77305 Fontainebleau Cedex France

xId: pipsmake-rc.tex 20626 2011-11-08 10:04:03Z guelton x

You can get a printable version of this document on

http://www.cri.ensmp.fr/pips/pipsmake-rc.htdoc/pipsmake-rc.pdf

and a HTML version on

http://www.cri.ensmp.fr/pips/pipsmake-rc.htdoc.

Chapterx1Introduction This paper describes high-level objects and functions that are potentially user-visible in a

PIPS 1  ^{1http://www.cri.ensmp.fr/pips}  x[?]

interactive environment. It defines the internal software interface between a user interface and program analyses and transformations. This is clearly not a user guide but can be used as a reference guide, the best one before source code because PIPS user interfaces are very closely mapped on this document: some of their features are automatically derived from it.

Objects can be viewed and functions activated by one of PIPS existing user interfaces:

tpips2  ^{2http://www.cri.ensmp.fr/pips/line-interface.html}  ,

the tty style interface which is currently recommended,

pips3  ^{3http://www.cri.ensmp.fr/pips/batch-interface.html}  x[?],

the old batch interface, improved by many shell

scripts4  4Manual pages are available for Init, Select, Perform, Display, and Delete, and pips5  ^{5http://www.cri.ensmp.fr/pips/batch-interface.html}  . ,

wpips and epips, the X-Window System interfaces. The epips interface is an extension of wpips which uses Emacs to display more information in a more convenient way. Unfortunately, right now these window-based interfaces are no longer working and have been replaced by gpips. It is also possible to use PIPS through a Python API, pyps.

From a theoretical point of view, the object types and functions available in PIPS define an heterogeneous algebra with constructors (e.g. parser), extractors (e.g. prettyprinter) and operators (e.g. loop unrolling). Very few combinations of functions make sense, but many functions and object types are available. This abundance is confusing for casual and experiences users as well, and it was deemed necessary to assist them by providing default computation rules and automatic consistency management similar to make. The rule interpretor is called

pipsmake6  ^{6http://www.cri.ensmp.fr/pips/pipsmake.html}

and described inx[?]. Its key concepts are the phase, which correspond to a PIPS function made user-visible, for instance, a parser, the resources, which correspond to objects used or defined by the phases, for instance, a source file or an AST (parsed code), and the virtual rules, which define the set of input resources used by a phase and the set of output resources defined by the phase. Since PIPS is an interprocedural tool, some real inpu resources are not known until execution. Some variables such as CALLERS or CALLEES can be used in virtual rules. They are expanded at execution to obtain an effective rule with the precise resources needed.

For debugging purposes and for advanced users, the precise choice and tuning of an algorithm can be made using properties. Default properties are installed with PIPS but they can be redefined, partly or entirely, by a properties.rc file located in the current directory. Properties can also be redefined from the user interfaces, for example with the command setproperty when the tpips interface is used.

As far as their static structures are concerned, most object types are described in more details in PIPS Internal Representation of Fortran and C

code7  ^{7http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  .

A dynamic view is given here. In which order should functions be applied? Which object do they produce and vice-versa which function does produce such and such objects? How does PIPS cope with bottom-up and top-down interprocedurality?

Resources produced by several rules and their associated rule must be given alias names when they should be explicitly computed or activated by an interactive interfaceFI: I do not understand.. This is otherwise not relevant. The alias names are used to generate automatically header files and/or test files used by PIPS interfaces.

No more than one resource should be produced per line of rule because different files are automatically extracted from this

one8  ^{8See the local Makefile: pipsmake-rc, and alias file: wpips-rc.}  .

Another caveat is that all resources whose names are suffixed with _file are considered printable or displayable, and the others are considered binary data, even though they may be ASCII strings.

This LATEX file is used by several procedures to derive some pieces of C code and ASCII files. The useful information is located in the PipsMake areas, a very simple literate programming environment... For instance alias information is used to generate automatically menus for window-based interfaces such as wpips or gpips. Object (a.k.a resource) types and functions are renamed using the alias declaration. The name space of aliases is global. All aliases must have different names. Function declarations are used to build a mapping table between function names and pointer to C functions, phases.h. Object suffixes are used to derive a header file, resources.h, with all resource names. Parts of this file are also extracted to generate on-line information for wpips and automatic completion for

tpips.

The behavior of PIPS can be slightly tuned by using properties. Most properties are linked to a particular phase, for instance to prettyprint, but some are linked to PIPS infrastructure and are presented in Chapterx2.

1.1 Informal syntax To understand and to be able to write new rules for pipsmake, a few things need to be known.

1.1.1 Example The rule:

proper_referencesxxxxxxx>xMODULE.proper_references
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.summary_effects

means that the method proper_references is used to generate the proper_references resource of a given MODULE. But to generate this resource, the method needs access to the resource holding the symbole table, entities, of the PROGRAM currently analyzed, the code resource (the instructions) of the given MODULE and the summary_effectsx6.2.4 resource (the side effects on the memory) of the functions and procedures called by the given MODULE, the

CALLEES.

Properties are also declared in this file. For instance

ABORT_ON_USER_ERRORxFALSE

declares a property to stop interpreting user commands when an error is made and sets its default value to false, which makes sense most of the time for interactive uses of PIPS. But for non-regression tests, it may be better to turn on this property.

1.1.2 Pipsmake variables The following variables are defined to handle interprocedurality:

PROGRAM: the whole application currently analyzed;

MODULE: the current MODULE (a procedure or function);

ALL: all the MODULEs of the current PROGRAM, functions and compilation units;

ALLFUNC: all the MODULEs of the current PROGRAM that are functions; CALLEES: all the MODULEs called in the given MODULE;

CALLERS: all the MODULEs that call the given MODULE.

These variables are used in the rule definitions and instantiated before pipsmake infers which resources are pre-requisites for a rule.

1.2 Properties This paper also defines and describes global variables used to modify or fine tune PIPS behavior. Since global variables are useful for some purposes, but always dangerous, PIPS programmers are required to avoid them or to declare them explicitly as properties. Properties have an ASCII name and can have boolean, integer or string values.

Casual users should not use them. Some properties are modified for them by the user interface and/or the high-level functions. Some property combinations may be meaningless. More experienced users can set their values, using their names and a user interface.

Experienced users can also modify properties by inserting a file called properties.rc in their local directory. Of course, they cannot declare new properties, since they would not be recognized by the PIPS system. The local property file is read after the default property file, $PIPS_ROOT/etc/properties.rc. Some user-specified property values may be ignored because they are modified by a PIPS function before it had a chance to have any effect. Unfortunately, there is no explicit indication of usefulness for the properties in this report.

The default property file can be used to generate a custom version of properties.rc. It is derived automatically from this documentation,

Documentation/pipsmake-rc.tex.

PIPS behavior can also be altered by Shell environment variables. Their generic names is XXXX_DEBUG_LEVEL, where XXXX is a library or a phase or an interface name (of course, there are exceptions). Theoretically these environment variables are also declared as properties, but this is generally forgotten by programmers. A debug level of 0 is equivalent to no tracing. The amount of tracing increases with the debug level. The maximum useful value is 9.

Another Shell environment variable, NEWGEN_MAX_TABULATED_ELEMENTS, is useful to analyze large programs. Its default value is 12,000 but it is not uncommon to have to set it up to 200,000.

Properties are listed below on a source library basis. Properties used in more than one library or used by PIPS infrastructure are presented first. Sectionx2.3 contains information about properties related to infrastructure, external and user interface libraries. Properties for analyses are grouped in Chapterx6. Properties for program transformations, parallelization and distribution phases are listed in the next section in Chaptersx8 and 7. User output produced by different kinds of prettyprinters are presented in Chapterx9. Chaperx10 is dedicated to properties of the libraries added by CEA to implement Feautrier’s method.

1.3 Outline Rule and object declaration are grouped in chapters: input files (Chapterx3), syntax analysis and abstract syntax tree (Chapterx4), analyses (Chapterx6), parallelizations (Chapterx7), program transformations (Chapterx8) and prettyprinters of output files (Chapterx9). Chapterx10 describes several analyses defined by Paul Feautrier. Chapterx11 contains a set of menu declarations for the window-based interfaces.

Virtually every PIPS programmer contributed some lines in this report. Inconsistencies are likely. Please report them to the PIPS

team9  ^{9pips-support@cri.ensmp.fr}  !

Contents 1 Introduction x1.1 Informal syntax xx1.1.1 Example xx1.1.2 Pipsmake variables x1.2 Properties x1.3 Outline 2 Global Options x2.1 Fortran Loops x2.2 Logging x2.3 PIPS Infrastructure xx2.3.1 Newgen xx2.3.2 C3 Linear Library xx2.3.3 PipsMake xx2.3.4 PipsDBM xx2.3.5 Top Level Control xx2.3.6 Tpips Command Line Interface xx2.3.7 Warning Control xx2.3.8 Option for C Code Generation 3 Input Files x3.1 User File x3.2 Preprocessing and Splitting xx3.2.1 Fortran case of preprocessing and splitting xxx3.2.1.1 Fortran Syntactic Verification xxx3.2.1.2 Fortran file preprocessing xxx3.2.1.3 Fortran Split xxx3.2.1.4 Fortran Syntactic Preprocessing xx3.2.2 C Preprocessing and Splitting xxx3.2.2.1 C Syntactic Verification xx3.2.3 Source File Hierarchy x3.3 Source File x3.4 Regeneration of User Source Files 4 Abstract Syntax Tree x4.1 Entities x4.2 Parsed Code and Callees xx4.2.1 Fortran xxx4.2.1.1 Fortran restrictions xxx4.2.1.2 Some additional remarks xxx4.2.1.3 Some unfriendly features xxx4.2.1.4 Declaration of the standard parser xx4.2.2 Declaration of HPFC parser xx4.2.3 Declaration of the C parsers x4.3 Controlized Code (Hierarchical Control Flow Graph) 5 Pedagogical phases x5.1 Using XML backend x5.2 Prepending a comment x5.3 Prepending a call x5.4 Add a pragma to a module 6 Analyses x6.1 Call Graph x6.2 Memory Effects xx6.2.1 Proper Memory Effects xx6.2.2 Filtered Proper Memory Effects xx6.2.3 Cumulated Memory Effects xx6.2.4 Summary Data Flow Information (SDFI) xx6.2.5 IN and OUT Effects xx6.2.6 Proper and Cumulated References xx6.2.7 Effect Properties x6.3 Reductions xx6.3.1 Reduction Propagation xx6.3.2 Reduction Detection x6.4 Chains (Use-Def Chains) xx6.4.1 Menu for Use-Def Chains xx6.4.2 Standard Use-Def Chains (a.k.a. Atomic Chains) xx6.4.3 READ/WRITE Region-Based Chains xx6.4.4 IN/OUT Region-Based Chains xx6.4.5 Chain Properties xxx6.4.5.1 Add use-use Chains xxx6.4.5.2 Remove Some Chains x6.5 Dependence Graph (DG) xx6.5.1 Menu for Dependence Tests xx6.5.2 Fast Dependence Test xx6.5.3 Full Dependence Test xx6.5.4 Semantics Dependence Test xx6.5.5 Dependence Test with Convex Array Regions xx6.5.6 Dependence Properties (Ricedg) xxx6.5.6.1 Dependence Test Selection xxx6.5.6.2 Statistics xxx6.5.6.3 Algorithmic Dependences xxx6.5.6.4 Printout xxx6.5.6.5 Optimization x6.6 Flinter x6.7 Loop statistics x6.8 Semantics Analysis xx6.8.1 Transformers xxx6.8.1.1 Menu for Transformers xxx6.8.1.2 Fast Intraprocedural Transformers xxx6.8.1.3 Full Intraprocedural Transformers xxx6.8.1.4 Fast Interprocedural Transformers xxx6.8.1.5 Full Interprocedural Transformers xxx6.8.1.6 Full Interprocedural Transformers xx6.8.2 Summary Transformer xx6.8.3 Initial Precondition xx6.8.4 Intraprocedural Summary Precondition xx6.8.5 Preconditions xxx6.8.5.1 Menu for Preconditions xxx6.8.5.2 Intra-Procedural Preconditions xxx6.8.5.3 Fast Inter-Procedural Preconditions xxx6.8.5.4 Full Inter-Procedural Preconditions xx6.8.6 Interprocedural Summary Precondition xx6.8.7 Total Preconditions xxx6.8.7.0.1 Status: xxx6.8.7.1 Menu for Total Preconditions xxx6.8.7.2 Intra-Procedural Total Preconditions xxx6.8.7.3 Inter-Procedural Total Preconditions xx6.8.8 Summary Total Precondition xx6.8.9 Summary Total Postcondition xx6.8.10 Final Postcondition xx6.8.11 Semantic Analysis Properties xxx6.8.11.1 Value types xxx6.8.11.2 Array declarations and accesses xxx6.8.11.3 Flow Sensitivity xxx6.8.11.4 Context for statement and expression transformers xxx6.8.11.5 Interprocedural Semantics Analysis xxx6.8.11.6 Fix Point Operators xxx6.8.11.7 Normalization level xxx6.8.11.8 Prettyprint xxx6.8.11.9 Debugging x6.9 Continuation conditions x6.10 Complexities xx6.10.1 Menu for Complexities xx6.10.2 Uniform Complexities xx6.10.3 Summary Complexity xx6.10.4 Floating Point Complexities xx6.10.5 Complexity properties xxx6.10.5.1 Debugging xxx6.10.5.2 Fine Tuning xxx6.10.5.3 Target Machine and Compiler Selection xxx6.10.5.4 Evaluation Strategy x6.11 Convex Array Regions xx6.11.1 Menu for Convex Array Regions xx6.11.2 MAY READ/WRITE Convex Array Regions xx6.11.3 MUST READ/WRITE Convex Array Regions xx6.11.4 Summary READ/WRITE Convex Array Regions xx6.11.5 IN Convex Array Regions xx6.11.6 IN Summary Convex Array Regions xx6.11.7 OUT Summary Convex Array Regions xx6.11.8 OUT Convex Array Regions xx6.11.9 Properties for Convex Array Regions x6.12 Alias Analysis xx6.12.1 Dynamic Aliases xx6.12.2 Intraprocedural Summary Points to Analysis xx6.12.3 Points to Analysis xx6.12.4 Pointer Values Analyses xx6.12.5 Properties for pointer analyses xx6.12.6 Menu for Alias Views x6.13 Complementary Sections xx6.13.1 READ/WRITE Complementary Sections xx6.13.2 Summary READ/WRITE Complementary Sections 7 Parallelization and Distribution x7.1 Code Parallelization xx7.1.1 Parallelization properties xxx7.1.1.1 Properties controlling Rice parallelization xx7.1.2 Menu for Parallelization Algorithm Selection xx7.1.3 Allen & Kennedy’s Parallelization Algorithm xx7.1.4 Def-Use Based Parallelization Algorithm xx7.1.5 Parallelization and Vectorization for Cray Multiprocessors xx7.1.6 Coarse Grain Parallelization xx7.1.7 Global Loop Nest Parallelization xx7.1.8 Coerce Parallel Code into Sequential Code xx7.1.9 Detect Computation Intensive Loops xx7.1.10 Limit Parallelism in Parallel Loop Nests x7.2 SIMDizer for SIMD Multimedia Instruction Set xx7.2.1 SIMD properties xxx7.2.1.1 Auto-Unroll xxx7.2.1.2 Memory Organisation xxx7.2.1.3 Pattern file xx7.2.2 Scalopes project xxx7.2.2.1 Bufferization xxx7.2.2.2 SCMP generation x7.3 Code Distribution xx7.3.1 Shared-Memory Emulation xx7.3.2 HPF Compiler xxx7.3.2.1 HPFC Filter xxx7.3.2.2 HPFC Initialization xxx7.3.2.3 HPF Directive removal xxx7.3.2.4 HPFC actual compilation xxx7.3.2.5 HPFC completion xxx7.3.2.6 HPFC install xxx7.3.2.7 HPFC High Performance Fortran Compiler properties xx7.3.3 STEP: MPI code generation from OpenMP programs xxx7.3.3.1 STEP Directives xxx7.3.3.2 STEP Analysis xxx7.3.3.3 STEP code generation xx7.3.4 PHRASE: high-level language transformation for partial evaluation

in reconfigurable logic xxx7.3.4.1 Phrase Distributor Initialisation xxx7.3.4.2 Phrase Distributor xxx7.3.4.3 Phrase Distributor Control Code xx7.3.5 Safescale xxx7.3.5.1 Distribution init xxx7.3.5.2 Statement Externalization xx7.3.6 CoMap: Code Generation for Accelerators with DMA xxx7.3.6.1 Phrase Remove Dependences xxx7.3.6.2 Phrase comEngine Distributor xxx7.3.6.3 PHRASE ComEngine properties xx7.3.7 Parallelization for Terapix architecture xxx7.3.7.1 Isolate Statement xxx7.3.7.2 Delay Communications xxx7.3.7.3 Hardware Constraints Solver xxx7.3.7.4 kernelize xxx7.3.7.5 Generating communications xx7.3.8 Code distribution on GPU xx7.3.9 Task generation for SCALOPES project 8 Program Transformations x8.1 Loop Transformations xx8.1.1 Introduction xx8.1.2 Loop range Normalization xx8.1.3 Loop Distribution xx8.1.4 Statement Insertion xx8.1.5 Loop Expansion xx8.1.6 Loop Fusion xx8.1.7 Index Set Splitting xx8.1.8 Loop Unrolling xxx8.1.8.1 Regular Loop Unroll xxx8.1.8.2 Full Loop Unroll xx8.1.9 Loop Fusion xx8.1.10 Strip-mining xx8.1.11 Loop Interchange xx8.1.12 Hyperplane Method xx8.1.13 Loop Nest Tiling xx8.1.14 Symbolic Tiling xx8.1.15 Loop Normalize xx8.1.16 Guard Elimination and Loop Transformations xx8.1.17 Tiling for sequences of loop nests x8.2 Redundancy Elimination xx8.2.1 Loop Invariant Code Motion xx8.2.2 Partial Redundancy Elimination x8.3 Control-Flow Optimizations xx8.3.1 Dead Code Elimination xxx8.3.1.1 Dead Code Elimination properties xx8.3.2 Dead Code Elimination (a.k.a. Use-Def Elimination) xx8.3.3 Control Restructurers xxx8.3.3.1 Unspaghettify xxx8.3.3.2 Restructure Control xxx8.3.3.3 For-loop recovering xxx8.3.3.4 For-loop to do-loop transformation xxx8.3.3.5 For-loop to while-loop transformation xxx8.3.3.6 Do-while to while-loop transformation xxx8.3.3.7 Spaghettify xxx8.3.3.8 Full Spaghettify xx8.3.4 Control Structure Normalisation (STF) xx8.3.5 Trivial Test Elimination xx8.3.6 Finite State Machine Generation xxx8.3.6.1 FSM Generation xxx8.3.6.2 Full FSM Generation xxx8.3.6.3 FSM Split State xxx8.3.6.4 FSM Merge States xxx8.3.6.5 FSM properties xx8.3.7 Control Counters x8.4 Expression Transformations xx8.4.1 Atomizers xxx8.4.1.1 General Atomizer xxx8.4.1.2 Limited Atomizer xxx8.4.1.3 Atomizer properties xx8.4.2 Partial Evaluation xx8.4.3 Reduction Detection xx8.4.4 Reduction Replacement xx8.4.5 Forward Substitution xx8.4.6 Expression Substitution xx8.4.7 Rename operator xx8.4.8 Array to pointer conversion xx8.4.9 Expression Optimizations xxx8.4.9.1 Expression optimization using algebraic properties xxx8.4.9.2 Common subexpression elimination x8.5 Hardware Accelerator xx8.5.1 FREIA Software xx8.5.2 FREIA SPoC xx8.5.3 FREIA Terapix xx8.5.4 FREIA OpenCL x8.6 Function Level Transformations xx8.6.1 Inlining xx8.6.2 Unfolding xx8.6.3 Outlining xx8.6.4 Cloning x8.7 Declaration Transformations xx8.7.1 Declarations cleaning xx8.7.2 Array Resizing xxx8.7.2.1 Top Down Array Resizing xxx8.7.2.2 Bottom Up Array Resizing xxx8.7.2.3 Array Resizing Statistic xxx8.7.2.4 Array Resizing properties xx8.7.3 Scalarization xx8.7.4 Induction Variable Substitution xx8.7.5 Strength Reduction xx8.7.6 Flatten Code xx8.7.7 Split Update Operator xx8.7.8 Split Initializations (C code) xx8.7.9 Set Return Type xx8.7.10 Cast at Call Sites x8.8 Array Bound Checking xx8.8.1 Elimination of Redundant Tests: Bottom-Up Approach xx8.8.2 Insertion of Unavoidable Tests xx8.8.3 Interprocedural Array Bound Checking xx8.8.4 Array Bound Checking Instrumentation x8.9 Alias Verification xx8.9.1 Alias Propagation xx8.9.2 Alias Checking x8.10 Used Before Set x8.11 Miscellaneous transformations xx8.11.1 Type Checker xx8.11.2 Scalar and Array Privatization xxx8.11.2.1 Scalar Privatization xxx8.11.2.2 Array Privatization xx8.11.3 Scalar and Array Expansion xxx8.11.3.1 Scalar Expansion xxx8.11.3.2 Array Expansion xx8.11.4 Freeze variables xx8.11.5 Manual Editing xx8.11.6 Transformation Test x8.12 Extensions Transformations xx8.12.1 OpenMP Pragma 9 Output Files (Prettyprinted Files) x9.1 Parsed Printed Files (User View) xx9.1.1 Menu for User Views xx9.1.2 Standard User View xx9.1.3 User View with Transformers xx9.1.4 User View with Preconditions xx9.1.5 User View with Total Preconditions xx9.1.6 User View with Continuation Conditions xx9.1.7 User View with Convex Array Regions xx9.1.8 User View with Invariant Convex Array Regions xx9.1.9 User View with IN Convex Array Regions xx9.1.10 User View with OUT Convex Array Regions xx9.1.11 User View with Complexities xx9.1.12 User View with Proper Effects xx9.1.13 User View with Cumulated Effects xx9.1.14 User View with IN Effects xx9.1.15 User View with OUT Effects x9.2 Printed File (Sequential Views) xx9.2.1 Html output xx9.2.2 Menu for Sequential Views xx9.2.3 Standard Sequential View xx9.2.4 Sequential View with Transformers xx9.2.5 Sequential View with Initial Preconditions xx9.2.6 Sequential View with Complexities xx9.2.7 Sequential View with Preconditions xx9.2.8 Sequential View with Total Preconditions xx9.2.9 Sequential View with Continuation Conditions xx9.2.10 Sequential View with Convex Array Regions xxx9.2.10.1 Sequential View with Plain Pointer Regions xxx9.2.10.2 Sequential View with Proper Pointer Regions xxx9.2.10.3 Sequential View with Invariant Pointer Regions xxx9.2.10.4 Sequential View with Plain Convex Array Regions xxx9.2.10.5 Sequential View with Proper Convex Array Regions xxx9.2.10.6 Sequential View with Invariant Convex Array Regions xxx9.2.10.7 Sequential View with IN Convex Array Regions xxx9.2.10.8 Sequential View with OUT Convex Array Regions xxx9.2.10.9 Sequential View with Privatized Convex Array Regions xx9.2.11 Sequential View with Complementary Sections xx9.2.12 Sequential View with Proper Effects xx9.2.13 Sequential View with Cumulated Effects xx9.2.14 Sequential View with IN Effects xx9.2.15 Sequential View with OUT Effects xx9.2.16 Sequential View with Proper Reductions xx9.2.17 Sequential View with Cumulated Reductions xx9.2.18 Sequential View with Static Control Information xx9.2.19 Sequential View with Points-To Information xx9.2.20 Sequential View with Simple Pointer Values xx9.2.21 Prettyprint properties xxx9.2.21.1 Language xxx9.2.21.2 Layout xxx9.2.21.3 Target Language Selection xxx9.2.21.3.1 Parallel output style xxx9.2.21.3.2 Default sequential output style xxx9.2.21.4 Display Analysis Results xxx9.2.21.5 Display Internals for Debugging xxx9.2.21.5.1 Warning: xxx9.2.21.6 Declarations xxx9.2.21.7 FORESYS Interface xxx9.2.21.8 HPFC Prettyprinter xxx9.2.21.9 Interface to Emacs x9.3 Printed Files with the Intraprocedural Control Graph xx9.3.1 Menu for Graph Views xx9.3.2 Standard Graph View xx9.3.3 Graph View with Transformers xx9.3.4 Graph View with Complexities xx9.3.5 Graph View with Preconditions xx9.3.6 Graph View with Preconditions xx9.3.7 Graph View with Regions xx9.3.8 Graph View with IN Regions xx9.3.9 Graph View with OUT Regions xx9.3.10 Graph View with Proper Effects xx9.3.11 Graph View with Cumulated Effects xx9.3.12 ICFG properties xx9.3.13 Graph properties xxx9.3.13.1 Interface to Graphics Prettyprinters x9.4 Parallel Printed Files xx9.4.1 Menu for Parallel View xx9.4.2 Fortran 77 Parallel View xx9.4.3 HPF Directives Parallel View xx9.4.4 OpenMP Directives Parallel View xx9.4.5 Fortran 90 Parallel View xx9.4.6 Cray Fortran Parallel View x9.5 Call Graph Files xx9.5.1 Menu for Call Graphs xx9.5.2 Standard Call Graphs xx9.5.3 Call Graphs with Complexities xx9.5.4 Call Graphs with Preconditions xx9.5.5 Call Graphs with Total Preconditions xx9.5.6 Call Graphs with Transformers xx9.5.7 Call Graphs with Proper Effects xx9.5.8 Call Graphs with Cumulated Effects xx9.5.9 Call Graphs with Regions xx9.5.10 Call Graphs with IN Regions xx9.5.11 Call Graphs with OUT Regions x9.6 DrawGraph Interprocedural Control Flow Graph Files (DVICFG) xx9.6.1 Menu for DVICFG’s xx9.6.2 Minimal ICFG with graphical filtered Proper Effects x9.7 Interprocedural Control Flow Graph Files (ICFG) xx9.7.1 Menu for ICFG’s xx9.7.2 Minimal ICFG xx9.7.3 Minimal ICFG with Complexities xx9.7.4 Minimal ICFG with Preconditions xx9.7.5 Minimal ICFG with Preconditions xx9.7.6 Minimal ICFG with Transformers xx9.7.7 Minimal ICFG with Proper Effects xx9.7.8 Minimal ICFG with filtered Proper Effects xx9.7.9 Minimal ICFG with Cumulated Effects xx9.7.10 Minimal ICFG with Regions xx9.7.11 Minimal ICFG with IN Regions xx9.7.12 Minimal ICFG with OUT Regions xx9.7.13 ICFG with Loops xx9.7.14 ICFG with Loops and Complexities xx9.7.15 ICFG with Loops and Preconditions xx9.7.16 ICFG with Loops and Total Preconditions xx9.7.17 ICFG with Loops and Transformers xx9.7.18 ICFG with Loops and Proper Effects xx9.7.19 ICFG with Loops and Cumulated Effects xx9.7.20 ICFG with Loops and Regions xx9.7.21 ICFG with Loops and IN Regions xx9.7.22 ICFG with Loops and OUT Regions xx9.7.23 ICFG with Control xx9.7.24 ICFG with Control and Complexities xx9.7.25 ICFG with Control and Preconditions xx9.7.26 ICFG with Control and Total Preconditions xx9.7.27 ICFG with Control and Transformers xx9.7.28 ICFG with Control and Proper Effects xx9.7.29 ICFG with Control and Cumulated Effects xx9.7.30 ICFG with Control and Regions xx9.7.31 ICFG with Control and IN Regions xx9.7.32 ICFG with Control and OUT Regions x9.8 Dependence Graph File xx9.8.1 Menu For Dependence Graph Views xx9.8.2 Effective Dependence Graph View xx9.8.3 Loop-Carried Dependence Graph View xx9.8.4 Whole Dependence Graph View xx9.8.5 Filtered Dependence Graph View xx9.8.6 Filtered Dependence daVinci Graph View xx9.8.7 Filtered Dependence Graph View xx9.8.8 Chains Graph View xx9.8.9 Chains Graph Graphviz Dot View xx9.8.10 Dependence Graph Graphviz Dot View xx9.8.11 Properties for Dot output x9.9 Fortran to C prettyprinter xx9.9.1 Properties for Fortran to C prettyprinter x9.10 Prettyprinters Smalltalk x9.11 Prettyprinter for the Polyhderal Compiler Collection (PoCC) x9.12 Prettyprinter for CLAIRE 10 Feautrier Methods (a.k.a. Polyhedral Method) x10.1 Static Control Detection x10.2 Scheduling x10.3 Code Generation for Affine Schedule x10.4 Prettyprinters for CM Fortran 11 User Interface Menu Layouts x11.1 View menu x11.2 Transformation menu 12 Conclusion 13 Known Problems

Chapterx2Global Options Options are called properties in PIPS. Most of them are related to a specific phase, for instance the dependence graph computation. They are declared next to the corresponding phase declaration. But some are related to one library or even to several libraries and they are declared in this chapter.

Skip this chapter on first reading. Also skip this chapter on second reading because you are unlikely to need these properties until you develop in PIPS.

2.1 Fortran Loops Are DO loops bodies executed at least once (F-66 style), or not (Fortranx77)?

   xONE_TRIP_DOxFALSE
   x

is useful for use/def and semantics analysis but is not used for region analyses. This dangerous property should be set to FALSE. It is not consistently checked by PIPS phases, because nobody seems to use this obsolete Fortran feature anymore.

2.2 Logging

With

   xLOG_TIMINGSxFALSE
   x

it is possible to display the amount of real, cpu and system times directly spent in each phase as well as the times spent reading/writing data structures from/to PIPS database. The computation of total time used to complete a pipsmake request is broken down into global times, a set of phase times which is the accumulation of the times spent in each phase, and a set of IO times, also accumulated through phases.

Note that the IO times are included in the phase times.

With

   xLOG_MEMORY_USAGExFALSE
   x

it is possible to log the amount of memory used by each phase and by each request. This is mainly useful to check if a computation can be performed on a given machine. This memory log can also be used to track memory leaks. Valgrind may be more useful to track memory leaks.

2.3 PIPS Infrastructure PIPS infrastructure is based on a few external libraries, Newgen and Linear, and on three

key PIPS 1  ^{1http://www.cri.ensmp.fr/pips}

libraries:

pipsdbm which manages resources such as code produced by PIPS and ensures persistance,

pipsmake which ensures consistency within a workspace with respect to the producer-consumer rules declared in this file,

and top-level which defines a common API for all PIPS user interfaces, whether human or API.

2.3.1 Newgen

Newgen offers some debugging support to check object consistency (gen_consistent_p and gen_defined_p), and for dynamic type checking. See Newgen documentation[?][?].

2.3.2 C3 Linear Library

This library is external and offers an independent debugging system.

The following properties specify how null (

   xSYSTEM_NULLx"<null␣system>"
   x

), undefined

   xSYSTEM_UNDEFINEDx"<undefined␣system>"
   x

) or non feasible systems

   xSYSTEM_NOT_FEASIBLEx"{0==-1}"
   x

are prettyprinted by PIPS.

2.3.3 PipsMake

With

   xCHECK_RESOURCE_USAGExFALSE
   x

it is possible to log and report differences between the set of resources actually read and written by the procedures called by pipsmake and the set of resources declared as read or written in pipsmake.rc file.

   xACTIVATE_DEL_DERIVED_RESxTRUE
   x

controls the rule activation process that may delete from the database all the derived resources from the newly activated rule to make sure that non-consistent resources cannot be used by accident.

   xPIPSMAKE_CHECKPOINTSx0
   x

controls how often resources should be saved and freed. 0 means never, and a positive value means every n applications of a rule. This feature was added to allow long big automatic tpips scripts that can coredump and be restarted latter on close to the state before the core. As another side effect, it allows to free the memory and to keep memory consumption as moderate as possible, as opposed to usual tpips runs which keep all memory allocated. Note that it should not be too often saved, because it may last a long time, especially when entities are considered on big workspaces. The frequency may be adapted in a script, rarely at the beginning to more often latter.

2.3.4 PipsDBM

Shell environment variables PIPSDBM_DEBUG_LEVEL can be set to ? to check object consistency when they are stored in the database, and to ? to check object consistency when they are stored or retrieved (in case an intermediate phase has corrupted some data structure unwillingly).

You can control what is done when a workspace is closed and resources are save. The

   xPIPSDBM_RESOURCES_TO_DELETEx"obsolete"
   x

property can be set to to ”obsolete” or to ”all”.

Note that it is not managed from pipsdbm but from pipsmake which knows what is obsolete or not.

2.3.5 Top Level Control

The top-level library is built on top of the pipsmake and pipsdbm libraries to factorize functions useful to build a PIPS user interface or API.

Property

   xUSER_LOG_PxTRUE
   x

controls the logging of the session in the database of the current workspace. This log can be processed by PIPS utility logfile2tpips to generate automatically a tpips script which can be used to replay the current PIPS session, workspace by workspace, regardless of the PIPSuser interface used.

Property

   xABORT_ON_USER_ERRORxFALSE
   x

specifies how user errors impact execution once the error message is printed on stderr: return and go ahead, usually when PIPS is used interactively, or core dump for debugging purposes and for script executions, especially non-regression tests.

Property

   xMAXIMUM_USER_ERRORx2
   x

specifies the number of user error allowed before the programs brutally aborts. Property

   xACTIVE_PHASESx"PRINT_SOURCE␣PRINT_CODE␣PRINT_PARALLELIZED77_CODE␣PRINT_CALL_GRAPH␣PRINT_ICFG␣TRANSFORMERS_INTER_FULL␣INTERPROCEDURAL_SUMMARY_PRECONDITION␣PRECONDITIONS_INTER_FULL␣ATOMIC_CHAINS␣RICE_SEMANTICS_DEPENDENCE_GRAPH␣MAY_REGIONS"
   x

specifies which pipsmake phases should be used when several phases can be used to produce the same resource. This property is used when a workspace is created. A workspace is the database maintained by PIPS to contain all resources defined for a whole application or for the whole set of files used to create it.

Resources that create ambiguities for pipsmake are at least:

parsedxprintedxfile

printedxfile

callgraphxfile

icfgxfile

parsedxcode, because several parsers are available

transformers

summaryxprecondition preconditions

regions

chains

dg

This list must be updated according to new rules and new resources declared in this file. Note that no default parser is usually specified in this property, because it is selected automatically according to the source file suffixes when possible.

Until October 2009, the active phases were:

ACTIVE_PHASESx"PRINT_SOURCExPRINT_CODExPRINT_PARALLELIZED77_CODE
xxxxxxxxxxxxxxxxPRINT_CALL_GRAPHxPRINT_ICFGxTRANSFORMERS_INTRA_FAST
xxxxxxxxxxxxxxxxINTRAPROCEDURAL_SUMMARY_PRECONDITION
xxxxxxxxxxxxxxxxPRECONDITIONS_INTRAxATOMIC_CHAINS
xxxxxxxxxxxxxxxxRICE_FAST_DEPENDENCE_GRAPHxMAY_REGIONS"

They still are used for the old non-regression tests.

2.3.6 Tpips Command Line Interface

tpips is one of PIPS user interfaces.

   xTPIPS_IS_A_SHELLxFALSE
   x

controls whether tpips should behave as an extended shell and consider any input

command that is not a tpips command a Shell command.

This property is automatically set to TRUE when pyps is running.

   xPYPSxFALSE
   x

2.3.7 Warning Control

User warnings may be turned off. Definitely, this is not the default option! Most warnings must be read to understand surprising results. This property is used by library misc.

   xNO_USER_WARNINGxFALSE
   x

By default, PIPS reports errors generated by system call stat which is used in library pipsdbm to check the time a resource has been written and hence its temporal consistency.

   xWARNING_ON_STAT_ERRORxTRUE

2.3.8 Option for C Code Generation The syntactic constraints of C89 have been eased for declarations in C99, where it is possible to intersperse statement declarations within executable statements. This property is used to request C89 compatible code generation.

   xC89_CODE_GENERATIONxFALSE
   x

So the default option is to generate C99 code, which may be changed because it is likely to make the code generated by PIPS unparsable by PIPS.

There is no guarantee that each code generation phase is going to comply with this property. It is up to each developper to decide if this global property is to be used or not in his/her local phase.

Chapterx3Input Files

3.1 User File

An input program is a set of user Fortranx77 or C source files and a name, called a workspace. The files are looked for in the current directory, then by using the colon-separated PIPS_SRCPATH variable for other directories where they might be found. The first occurrence of the file name in the ordered directories is chosen, which is consistent with PATH and MANPATH behaviour.

The source files are splitted by PIPS at the program initialization phase to produce one PIPS-private source file for each procedure, subroutine or function, and for each block data. A function like fsplit is used and the new files are stored in the workspace, which simply is a UNIX sub-directory of the current directory. These new files have names suffixed by .f.orig.

Since PIPS performs interprocedural analyses, it expects to find a source code file for each procedure or function called. Missing modules can be replaced by stubs, which can be made more or less precise with respect to their effects on formal parameters and global variables. A stub may be empty. Empty stubs can be automatically generated if the code is properly typed (see Sectionx3.3).

The user source files should not be edited by the user once PIPS has been started because these editions are not going to be taken into account unless a new workspace is created. But their preprocessed copies, the PIPS source files, safely can be edited while running PIPS. The automatic consistency mechanism makes sure that any information displayed to the user is consistent with the current state of the sources files in the workspace. These source files have names terminated by the standard suffix, .f.

New user source files should be automatically and completely re-built when the program is no longer under PIPS control, i.e. when the workspace is closed. An executable application can easily be regenerated after code transformations using the

tpips1  ^{1http://www.cri.ensmp.fr/pips/line-interface.html}

interface and requesting the PRINTEDxFILE resources for all modules, including compilation units in C:

     display PRINTEDxFILE[%ALL]

Note that compilation units can be left out with:

     display PRINTEDxFILE[%ALLFUNC]

In both cases with C source code, the order of modules may be unsuitable for direct recompilation and compilation units should be included anyway, but this is what is done by explicitly requesting the code regeneration as described in §x3.4.

Note that PIPS expects proper ANSI Fortran 77 code. Its parser was not designed to locate syntax errors. It is highly recommended to check source files with a standard Fortran compiler (see Sectionx3.2) before submitting them to

PIPS.

3.2 Preprocessing and Splitting

3.2.1 Fortran case of preprocessing and splitting The Fortran files specified as input to PIPS by the user are preprocessed in various ways.

3.2.1.1 Fortran Syntactic Verification If the PIPS_CHECK_FORTRAN shell environment variable is defined to false or no or 0, the syntax of the source files is not checked by compiling it with a C compiler.If the PIPS_CHECK_FORTRAN shell environment variable is defined to true or yes or 1, the syntax of the file is checked by compiling it with a Fortran 77 compiler. If the PIPS_CHECK_FORTRAN shell environment variable is not defined, the check is

performed according to CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPSx3.2.1.1.

The Fortran compiler is defined by the PIPS_FLINT environment variable. If it is undefined, the default compiler is f77x-cx-ansi).

In case of failure, a warning is displayed. Note that if the program cannot be compiled properly with a Fortran compiler, it is likely that many problems will be encountered within PIPS.

The next property also triggers this preliminary syntactic verification.

   xCHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPSxTRUE
   x

PIPS requires source code for all leaves in its visible call graph. By default, a user error is raised by Function initializer if a user request cannot be satisfied because some source code is missing. It also is possible to generate some synthetic code (also known as stubs) and to update the current module list but this is not a very satisfying option because all interprocedural analysis results are going to be wrong. The user should retrieve the generated .f files in the workspace, under the Tmp directory, and add some assignments (def ) and uses to mimic the action of the real code to have a sufficient behavior from the point of view of the analysis or transformations you want to apply on the whole program. The user modified synthetic files should then be saved and used to generate a new workspace.

   If PREPROCESSOR_MISSING_FILE_HANDLINGx3.2.1.1 is set to "query",

a script can optionally be set to handle the interactive request using PREPROCESSOR_MISSING_FILE_GENERATORx3.2.1.1. This script is passed the function name and prints the filename on standard output. When empty, it uses an internal one.

Valid settings: error or generate or query.

   xPREPROCESSOR_MISSING_FILE_HANDLINGx"error"
   x
   xPREPROCESSOR_MISSING_FILE_GENERATORx""
   x

The generated stub can have various default effect, say to prevent over-optimistic parallelization.

   xSTUB_MEMORY_BARRIERxFALSE
   x
   xSTUB_IO_BARRIERxFALSE
   x

3.2.1.2 Fortran file preprocessing If the file suffix is .F then the file is preprocessed. By default PIPS uses gfortranx-E for Fortran files. This preprocessor can be changed by setting the PIPS_FPP environment variable.

Moreover the default preprocessing options are -Px-D__PIPS__x-D__HPFC__and they can be extended (not replaced...) with the PIPS_FPP_FLAGS environment variable.

3.2.1.3 Fortran Split The file is then split into one file per module using a PIPS specialized version of

fsplit2 2The PIPS version of fsplit is derived from the BSD fsplit and several improvements have been performed. . This preprocessing also handles

Hollerith constants by converting them to the quoted syntax3 3Hollerith constants are considered obsolete by the new Fortran standards and date back to 1889... ;

     unnamed modules by adding MAIN000 or PROGRAM MAIN000 or or DATA000

or BLOCK DATA DATA000 according to needs.

The output of this phase is a set of .f_initial files in per-module subdirectories. They constitute the resource INITIAL_FILE.

3.2.1.4 Fortran Syntactic Preprocessing

A second step of preprocessing is performed to produce SOURCE_FILE files with standard Fortran suffix .f from the .f_initial files. The two preprocessing steps are shown in Figurex3.1.

PIC Figurex3.1: Preprocessing phases: from a user file to a source file

Each module source file is then processed by top-level to handle Fortran include and to comment out IMPLICIT NONE which are not managed by PIPS. Also this phase performs some transformations of complex constants to help the PIPS parser. Files referenced in Fortran include statements are looked for from the directory where the Fortran file is. The Shell variable PIPS_CPP_FLAGS is not used to locate these include files.

3.2.2 C Preprocessing and Splitting The C preprocessor is applied before the splitting. By default PIPS uses cppx-C for C files. This preprocessor can be changed by setting the PIPS_CPP environment variable.

Moreover the -D__PIPS__x-D__HPFC__x-U__GNUC__preprocessing options are used and can be extended (not replaced) with the PIPS_CPP_FLAGS environment variable.

This PIPS_CPP_FLAGS variable can also be used to locate the include files. Directories to search are specified with the -Ifile option, as usual for the C preprocessor.

3.2.2.1 C Syntactic Verification If the PIPS_CHECK_C shell environment variable is defined to false or no or 0, the syntax of the source files is not checked by compiling it with a C compiler. If the PIPS_CHECK_C shell environment variable is defined to true or yes or 1, the syntax of the file is checked by compiling it with a C compiler. If the PIPS_CHECK_C shell environment variable is not defined, the check is performed according to

CHECK_C_SYNTAX_BEFORE_RUNNING_PIPSx3.2.2.1.

The environment variable PIPS_CC is used to define the C compiler available. If it is undefined, the compiler chosen is gccx-cx).

In case of failure, a warning is displayed.

If the environement variable PIPS_CPP_FLAGS is defined, it should contain the options -Wall and -Werror for the check to be effective.

The next property also triggers this preliminary syntactic verification.

   xCHECK_C_SYNTAX_BEFORE_RUNNING_PIPSxTRUE
   x

Although its default value is FALSE, it is much safer to set it to true when dealing with new sources files. PIPS is not designed to process non-standard source code. Bugs in source files are not well explained or localized. They can result in weird behaviors and inexpected core dumps. Before complaining about PIPS, it is higly recommended to set this property to TRUE.

Note: the C and Fortran syntactic verifications could be controlled by a unique property.

3.2.3 Source File Hierarchy The source files may be placed in different directories and have the same name, which makes resource management more difficult. The default option is to assume that no file name conflicts occur. This is the historical option and it leads to much simpler module names.

   xPREPROCESSOR_FILE_NAME_CONFLICT_HANDLINGxFALSE
   x

3.3 Source File

A source_file contains the code of exactly one module. Source files are created from user source files at program initialization by fsplit or a similar function if fsplit is not available (see Sectionx3.2). A source file may be updated by the

user4  ^{4The X-window interface, wpips has an edit entry in the transformation menu.}  ,

but not by PIPS. Program transformations are performed on the internal representation (seex4) and visible in the prettyprinted output (seex9).

Source code splitting and preprocessing, e.g. cpp, are performed by the function create_workspace() from the top-level library, in collaboration with db_create_workspace() from library pipsdbm which creates the workspace directory. The user source files have names suffixed by .f or .F if cpp must be applied. They are split into original user_files with suffix .f.orig. These so-called original user files are in fact copies stored in the workspace. The syntactic PIPS preprocessor is applied to generate what is known as a source_file by PIPS. This process is fully automatized and not visible from PIPS user interfaces. However, the cpp preprocessor actions can be controlled using the Shell environment variable

PIPS_CPP_FLAGS.

Function initializer is only called when the source code is not found. If the user code is properly typed, it is possible to force initializer to generate empty stubs by setting properties PREPROCESSOR_MISSING_FILE_HANDLINGx3.2.1.1 and, to avoid inconsistency, PARSER_TYPE_CHECK_CALL_SITESx4.2.1.4. But remember that many Fortran codes use subroutines with variable numbers of arguments and with polymorphic types. Fortran varargs mechanism can be achieved by using or not the second argument according to the first one. Polymorphism can be useful to design an IO package or generic array subroutine, e.g. a subroutine setting an array to zero or a subroutine to copy an array into another one.

The current default option is to generate a user error if some source code is missing. This decision was made for two reasons:

too many warnings about typing are generated as soon as polymorphism is used; analysis results and code transformations are potentially wrong because no memory effects are synthesized

Sometimes, a function happen to be defined (and not only declared) inside a header file with the inline keyword. In that case PIPS can consider it as a regular module or just ignore it, as its presence may be system-dependant. Property IGNORE_FUNCTION_IN_HEADERx3.3 control this behavior and must be set before workspace creation.

   xxxIGNORE_FUNCTION_IN_HEADERxTRUE
   x

Modules can be flagged as “stubs”, aka functions provided to PIPS but which shouldn’t

be inlined or modified. Property PREPROCESSOR_INITIALIZER_FLAG_AS_STUBx3.3

controls if the initializer should declare new files as stubs.

bootstrap_stubsx>xPROGRAM.stubs

flag_as_stubxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.stubs
xxxxxxxxxxxxxxxx<xPROGRAM.stubs

   xPREPROCESSOR_INITIALIZER_FLAG_AS_STUBxTRUE
   x

initializerxxxxxxxxxxxxxxxxxxxxx>xMODULE.user_file
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.initial_file

Note: the generation of the resource user_file here above is mainly directed in having the resource concept here. More thought is needed to have the concept of user files managed by pipsmake.

MUST appear after initializer:

filter_filexxxxxxxxxxxxxxxxxxxxx>xMODULE.source_file
xxxxxxxxxxxxxxxx<xMODULE.initial_file
xxxxxxxxxxxxxxxx<xMODULE.user_file

In C, the initializer can generate directly a c_source_file and its compilation unit.

c_initializerxxxxxxxxxxxxxxxxxxxxx>xMODULE.c_source_file
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xCOMPILATION_UNIT.c_source_file

3.4 Regeneration of User Source Files The unsplitx3.4 phase regenerates user files from available printed_file. The various modules that where initially stored in single file are appended together in a file with the same name. Not that just fsplit is reversed, not a preprocessing through cpp. Also the include file preprocessing is not reversed.

Regeneration of user files. The various modules that where initially stored in single file are appended together in a file with the same name.

aliasxunsplitx'UserxfilesxRegeneration'
unsplitxxxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.user_file
xxxxxxxxxxxxxxxx<xALL.user_file
xxxxxxxxxxxxxxxx<xALL.printed_file

Chapterx4Abstract Syntax Tree

The abstract syntax tree, a.k.a intermediate representation, a.k.a. internal representation, is presented inx[?] and in PIPS Internal Representation of Fortran and C

code1  ^{1http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  .

4.1 Entities

Program entities are stored in PIPS unique symbol

table2 2FI: retrospectively, having a unique symbol table for all modules was a design mistake. The decision was made to have homogeneous accesses to local and global entities. It was also made to match NewGen tabulated type declaration. , called entities. Fortran entities, like intrinsics and operators, are created by bootstrap at program initialization. The symbol table is updated with user local and global variables when modules are parsed or linked together. This side effect is not disclosed to pipsmake.

bootstrapxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities

The entity data structure is described in PIPS Internal Representation of Fortran and

C code3  ^{3http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  .

The declaration of new intrinsics is not easy because it was assumed that there number was fixed and limited by the Fortran standard. In fact, Fortran extensions define new ones. To add a new intrinsic, C code in bootstrap/bootstrap.c and in effects-generic/intrinsics.c must be added to declare its name, type and Read/Write memory effects.

Information about entities generated by the parsers is printed out conditionally to property: PARSER_DUMP_SYMBOL_TABLEx4.2.1.4. which is set to false by default. Unless you are debugging the parser, do not set this property to TRUE but display the symbol table file. See Sectionx4.2.1.4 for Fortran and Sectionx4.2.3 for

4.2 Parsed Code and Callees

Each module source code is parsed to produce an internal representation called parsed_code and a list of called module names, callees.

4.2.1 Fortran Source code is assumed to be fully Fortran-77 compliant. On the first encountered error, the parser may be able to emit a useful message or the non-analyzed part of the source code is printed out.

PIPS input language is standard Fortranx77 with few extensions and some restrictions. The input character set includes underscore, _, and varying length variable names, i.e. they are not restricted to 6 characters.

4.2.1.1 Fortran restrictions

ENTRY statements are not recognized and a user error is generated. Very few cases of this obsolete feature were encountered in the codes initially used to benchmark PIPS. ENTRY statements have to be replaced manually by SUBROUTINE or FUNCTION and appropriate commons. If the parser bumps into a call to an ENTRY point, it may wrongly diagnose a missing source code for this entry, or even generate a useless but pipsmake satisfying stub if the corresponding property has been set (see Sectionx3.3).

Multiple returns are not in PIPS Fortran.

ASSIGN and assigned GOTO are not in PIPS Fortran.

Computed GOTOs are not in PIPS Fortran. They are automatically replaced by a IF...ELSEIF...ENDIF construct in the parser.

Functional formal parameters are not accepted. This is deeply exploited

in pipsmake.

Integer PARAMETERs must be initialized with integer constant expressions because conversion functions are not implemented.

DO loop headers should have no label. Add a CONTINUE just before the loop when it happens. This can be performed automatically if the

property PARSER_SIMPLIFY_LABELLED_LOOPSx4.2.1.4 is set to TRUE. This

restriction is imposed by the parallelization phases, not by the parser.

Complex constants, e.g. (0.,1.), are not directly recognized by the parser. They must be replaced by a call to intrinsic CMPLX. The PIPS preprocessing replaces them by a call to COMPLXx.

Function formulae are not recognized by the parser. An undeclared array and/or an unsupported macro is diagnosed. They may be substituted in an unsafe way by the preprocessor if the property

    PARSER_EXPAND_STATEMENT_FUNCTIONSx4.2.1.4

is set. If the substitution is considered possibly unsafe, a warning is displayed.

These parser restrictions were based on funding constraints. They are mostly alleviated by the preprocessing phase. PerfectClub and SPEC-CFP95 benchmarks are handled without manual editing, but for ENTRY statements which are obsoleted by the current Fortran standard.

4.2.1.2 Some additional remarks

The PIPS preprocessing stage included in fsplit() is going to name unnamed modules MAIN000 and unnamed blockdata DATA000 to be consistent with the generated file name.

Hollerith constants are converted to a more readable quoted form, and then output as such by the prettyprinter.

4.2.1.3 Some unfriendly features Source code is read in columns 1-72 only. Lines ending in columns 73 and beyond usually generate incomprehensible errors. A warning is generated for lines ending after column 72.

Comments are carried by the following statement. Comments carried by RETURN, ENDDO, GOTO or CONTINUE statements are not always preserved because the internal representation transforms these statements or because the parallelization phase regenerates some of them. However, they are more likely to be hidden by the prettyprinter. There is a large range of prettyprinter properties to obtain less filtered view of the code.

Formats and character constants are not properly handled. Multi-line formats and constants are not always reprinted in a Fortran correct form.

Declarations are exploited on-the-fly. Thus type and dimension information must be available before common declaration. If not, wrong common offsets are computed at first and fixed later in Function EndOfProcedure). Also, formal arguments implicitly are declared using the default implicit rule. If it is necessary to declare them, this new declarations should occur before an IMPLICIT declaration. Users are surprised by the type redefinition errors displayed.

4.2.1.4 Declaration of the standard parser

parserxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.parsed_code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.source_file

For parser debugging purposes, it is possible to print a summary of the symbol table, when enabling this property:

xPARSER_DUMP_SYMBOL_TABLExFALSE
x

This should be avoided and the resource symbol_table_file be displayed instead. The prettyprint of the symbol table for a Fortran module is generated with:

fortran_symbol_tablexxxxxxxx>xMODULE.symbol_table_file
xxxx<xPROGRAM.entities
xxxx<xMODULE.parsed_code

Input Format Some subtle errors occur because the PIPS parser uses a fixed format. Columns 73 to 80 are ignored, but the parser may emit a warning if some characters are encountered in this comment field.

   xPARSER_WARN_FOR_COLUMNS_73_80xTRUE
   x

ANSI extension

PIPS has been initially developed to parse correct Fortran compliant programs only. Real applications use lots of ANSI extensionsx and they are not always correct! To make sure that PIPS output is correct, the input code should be checked against ANSI extensions using property

CHECKxFORTRANxSYNTAXxBEFORExPIPS

(see Sectionx3.2) and the property below should be set to false.

   xPARSER_ACCEPT_ANSI_EXTENSIONSxTRUE
   x

Currently, this property is not used often enough in PIPS parser which let go many mistakes... as expected by real users!

Array range extension

PIPS has been developed to parse correct Fortran-77 compliant programs only. Array ranges are used to improve readability. They can be generated by PIPS prettyprinter. They are not parsed as correct input by default.

   xPARSER_ACCEPT_ARRAY_RANGE_EXTENSIONxFALSE

Type Checking

Each argument list at calls to a function or a subroutine is compared to the functional type of the callee. Turn this off if you need to support variable numbers of arguments or if you use overloading and do not want to hear about it. For instance, an IO routine can be used to write an array of integers or an array of reals or an array of complex if the length parameter is appropriate.

Since the functional typing is shaky, let’s turn it off by default!

   xPARSER_TYPE_CHECK_CALL_SITESxFALSE
   x

Loop Header with Label

The PIPS implementation of Allen&Kennedy algorithm cannot cope with labeled DO loops because the loop, and hence its label, may be replicated if the loop is distributed. The parser can generate an extra CONTINUE statement to carry the label and produce a label-free loop. This is not the standard option because PIPS is designed to output code as close as possible to the user source code.

   xPARSER_SIMPLIFY_LABELLED_LOOPSxFALSE
   x

Most PIPS analyses work better if do loop bounds are affine. It is sometimes possible to improve results for non-affine bounds by assigning the bound to an integer variables and by using this variable as bound. But this is implemented for Fortran, but not for C.

   xPARSER_LINEARIZE_LOOP_BOUNDSxFALSE
   x

Entry

The entry construct can be seen as an early attempt at object-oriented programming. The same object can be processed by several function. The object is declared as a standard subroutine or function and entry points are placed in the executable code. The entry points have different sets of formal parameters, they may share some common pieces of code, they share the declared variables, especially the static ones.

The entry mechanism is dangerous because of the flow of control between entries. It is now obsolete and is not analyzed directly by PIPS. Instead each entry may be converted into a first class function or subroutine and static variables are gathered in a specific common. This is the default option. If the substitution is not acceptable, the property may be turned off and entries results in a parser error.

   xPARSER_SUBSTITUTE_ENTRIESxTRUE
   x

Alternate Return

Alternate returns are put among the obsolete Fortran features by the Fortranx90 standard. It is possible (1) to refuse them (option ”NO”), or (2) to ignore them and to replace alternate returns by STOP (option ”STOP”), or (3) to substitute them by a semantically equivalent code based on return code values (option ”RC” or option ”HRC”). Option (2) is useful if the alternate returns are used to propagate error conditions. Option (3) is useful to understand the impact of the alternate returns on the control flow graph and to maintain the code semantics. Option ”RC” uses an additional parameter while option ”HRC” uses a set of PIPS run-time functions to hide the set and get of the return code which make declaration regeneration less useful. By default, the first option is selected and alternate returns are refused.

To produce an executable code, the declarations must be regenerated: see property PRETTYPRINT_ALL_DECLARATIONSx9.2.21.6 in Sectionx9.2.21.6. This is not necessary with option ”HRC”. Fewer new declarations are needed if variable PARSER_RETURN_CODE_VARIABLEx4.2.1.4 is implicitly integer because its first letter is in the I-N range.

With option (2), the code can still be executed if alternate returns are used only for errors and if no errors occur. It can also be analyzed to understand what the normal behavior is. For instance, OUT regions are more likely to be exact when exceptions and errors are ignored.

Formal and actual label variables are replaced by string variables to preserve the parameter ordre and as much source information as possible. See

PARSER_FORMAL_LABEL_SUBSTITUTE_PREFIXx4.2.1.4 which is used to generate new

variable names.

   xPARSER_SUBSTITUTE_ALTERNATE_RETURNSx"NO"
   x
   xPARSER_RETURN_CODE_VARIABLEx"I_PIPS_RETURN_CODE_"

   xPARSER_FORMAL_LABEL_SUBSTITUTE_PREFIXx"FORMAL_RETURN_LABEL_"
   x

The internal representation can be hidden and the alternate returns can be prettyprinted at the call sites and modules declaration by turning on the following property:

   xPRETTYPRINT_REGENERATE_ALTERNATE_RETURNSxFALSE
   x

Using a mixed C / Fortran RI is troublesome for comments handling: sometimes the comment guard is stored in the comment, sometime not. Sometimes it is on purpose, sometimes it is not. When following property is set to true,

PIPS 4  ^{4http://www.cri.ensmp.fr/pips}

does its best to prettyprint comments correctly.

   xPRETTYPRINT_CHECK_COMMENTSxTRUE
   x

If all modules have been processed by PIPS, it is possible not to regenerate alternate returns and to use a code close to the internal representation. If they are regenerated in the call sites and module declaration, they are nevertheless not used by the code generated by PIPS which is consistent with the internal representation.

Here is a possible implementation of the two PIPS run-time subroutines required by the hidden return code (”HRC”) option:

subroutine SETxIxPIPSxRETURNxCODEx(irc)

common /PIPSxRETURNxCODExCOMMON/ircxshared ircxshared = irc end subroutine GETxIxPIPSxRETURNxCODEx(irc) common /PIPSxRETURNxCODExCOMMON/ircxshared irc = ircxshared end

Note that the subroutine names depend on the PARSER_RETURN_CODE_VARIABLEx4.2.1.4 property. They are generated by prefixing it with SET_and GET_. There implementation is free. The common name used should not conflict with application common names. The ENTRY mechanism is not used because it would be desugared by PIPS anyway.

Assigned GO TO By default, assigned GO TO and ASSIGN statements are not accepted. These constructs are obsolete and will not be part of future Fortran standards.

However, it is possible to replace them automatically in a way similar to computed GO TO. Each ASSIGN statement is replaced by a standard integer assignment. The label is converted to its numerical value. When an assigned GO TO with its optional list of labels is encountered, it is transformed into a sequence of logical IF statement with appropriate tests and GO TO’s. According to Fortran 77 Standard, Section 11.3, Page 11-2, the control variable must be set to one of the labels in the optional list. Hence a STOP statement is generated to interrupt the execution in case this happens, but note that compilers such as SUN f77 and g77 do not check this condition at run-time (it is undecidable statically).

   xPARSER_SUBSTITUTE_ASSIGNED_GOTOxFALSE
   x

Assigned GO TO without the optional list of labels are not processed. In other words, PIPS make the optional list mandatory for substitution. It usually is quite easy to add manually the list of potential targets.

Also, ASSIGN statements cannot be used to define a FORMAT label. If the desugaring option is selected, an illegal program is produced by PIPS parser.

Statement Function

This property controls the processing of Fortran statement functions by text substitution in the parser. No other processing is available and the parser stops with an error message when a statement function declaration is encountered.

The default used to be not to perform this unchecked replacement, which might change the semantics of the program because type coercion is not enforced and actual parameters are not assigned to intermediate variables. However most statement functions do not require these extra-steps and it is legal to perform the textual substitution. For user convenience, the default option is textual substitution.

Note that the parser does not have enough information to check the validity of the transformation, but a warning is issued if legality is doubtful. If strange results are obtained when executing codes transformed with PIPS, his property should be set to false.

A better method would be to represent them somehow a local functions in the internal representation, but the implications for pipsmake and other issues are clearly not all foreseenx(Fabien Coelho).

   xPARSER_EXPAND_STATEMENT_FUNCTIONSxTRUE

4.2.2 Declaration of HPFC parser This parser takes a different Fortran file but applies the same processing as the previous parser. The Fortran file is the result of the preprocessing by the hpfc_filterx7.3.2.1 phase of the original file in order to extract the directives and switch them to a Fortranx77 parsable form. As another side-effect, this parser hides some callees from pipsmake. This callees are temporary functions used to encode HPF directives. Their call sites are removed from the code before requesting full analyses to PIPS. This parser is triggered automatically by the hpfc_closex7.3.2.5 phase when requested. It should never be selected or activated by hand.

hpfc_parserxxxxxxxxxxxxxxxxxxxxx>xMODULE.parsed_code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.hpfc_filtered_file

4.2.3 Declaration of the C parsers A C file is seen in PIPS as a compilation unit, that contains all the objects declarations that are global to this file, and as many as module (function or procedure) definitions defined in this file.

Thus the compilation unit contains the file-global macros, the include statements, the local and global variable definitions, the type definitions, and the function declarations if any found in the C file.

When the PIPS workspace is created by PIPS preprocessor, each C file is

preprocessed5 5Macros are interpreted and include files are expanded. The result depends on the C preprocessor used,on its option and on the system environment (/usr/include,...). using

for instance gcc -E6 6It can be redefined using CPPxPIPS and PIPSxCPPxFLAGS environment variables as explained in §x3.2.2. and broken into a new which contains only the file-global variable declarations, the function declarations and the type definitions, and one C file for each C function defined in the initial C file.

The new compilation units must be parsed before the new files, containing each one exactly one function definition, can be parsed. The new compilation units are named like the initial file names but with a bang extension.

For example, considering a C file foo.c with 2 function definitions: enumx{xNx=x2008x }; xtypedefx float x dataxt ; xdataxt x matrix [N ] [ N ] ; xexternx int x errno ; xxint x c a l c ( dataxt xa [N ] [ N] ) x{xxx [ …] x}xxint xmain ( int x argc , xcharx∗ argv [ ] ) x{xxx [ . . ] x}

After preprocessing, it leads to a file foo.cpp_processed.c that is then split into a new foo!.cpp_processed.c compilation unit containing

enumx{xNx=x2008x }; xtypedefx float x dataxt ; xdataxt x matrix [N ] [ N ] ; xexternx int x errno ; xxint x c a l c ( dataxt xa [N ] [ N] ) ; } xxint xmain ( int x argc , xcharx∗ argv [ ] ) ;

and 2 module files containing the definitions of the 2 functions, a calc.c

int x c a l c ( dataxt xa [N ] [ N] ) x{xxx [ …] x}

   and a main.c

int xmain ( int x argc , xcharx∗ argv [ ] ) x{xxx [ . . ] x}

Note that it is possible to have an empty compilation unit and no module file if the original file does not contain sensible C informations (such as an empty file containing only blank characters and so on).

compilation_unit_parserxxxxxxxxx>xCOMPILATION_UNIT.declarations
xxxxxxxx<xCOMPILATION_UNIT.c_source_file

   The resource COMPILATION_UNIT.declarations produced by

compilationxunitxparser is a special resource used to force the parsing of the new compilation unit before the parsing of its associated functions. It is in fact a hash table containing the file-global C keywords and typedef names defined in each compilation unit.

In fact phase compilationxunitxparser also produces parsedxcode and callees resources for the compilation unit. This is done to work around the fact that rule cxparser was invoked on compilation units by later phases, in particular for the computation of initial preconditions, breaking the declarations of function prototypes. These two resources are not declared here because pipsmake gets confused between the different rules to compute parsed code : there is no simple way to distinguish between compilation units and modules at some times and handling them similarly at other times.

c_parserxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.parsed_code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.c_source_file
xxxxxxxx<xCOMPILATION_UNIT.declarations

If you want to parse some C code using tpips, it is possible to select the C parser with

activatexC_PARSER

but this is not necessary as the parser is selected according to the source file extension. Some properties useful (have a look at properties) to deal with a C program are

PRETTYPRINT_C_CODExTRUE
PRETTYPRINT_STATEMENT_NUMBERxFALSE
PRETTYPRINT_BLOCK_IF_ONLYxTRUE

A prettyprint of the symbol table for a C module can be generated with

c_symbol_tablexxxxxx>xMODULE.symbol_table_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code

The EXTENDED_VARIABLE_INFORMATIONx4.2.3 property can be used to extend the information available for variables. By default the entity name, the offset and the size are printed. Using this property the type and the user name, which may be different from the internal name, are also displayed.

   xEXTENDED_VARIABLE_INFORMATIONxFALSE

The C_PARSER_RETURN_SUBSTITUTIONx4.2.3 property can be used to handle properly multiple returns within one function. The current default value is false, which preserves best the source aspect but modifies the control flow because the calls to return are assumed to flow in sequence. If the property is set to true, C return statement are replaced, when necessary, either by a simple goto for void functions, or by an assignment of the returned value to a special variable and a goto. A unique return statement is placed at the syntactic end of the function. For functions with no return statement or with a unique return statement placed at the end of their bodies, this property is useless.

   xC_PARSER_RETURN_SUBSTITUTIONxFALSE
   x

The C99 for-loop with a declaration such as for(intxix=xa;...;...) can be represented in the RI with a naive representation such as:

{xxxint x i x=xa ; xxxfor ( ; …; …) x}

   This is done when the C_PARSER_GENERATE_NAIVE_C99_FOR_LOOP_DECLARATIONx4.2.3

property is set to TRUE

   xC_PARSER_GENERATE_NAIVE_C99_FOR_LOOP_DECLARATIONxFALSE
   x

Else, we can generate more or less other representation. For example, with some declaration splitting, we can generate a more representative version:

{xxxint x i ; xxxfor ( i x=xa ; …; …) x}

   if C_PARSER_GENERATE_COMPACT_C99_FOR_LOOP_DECLARATIONx?? property set to
FALSE.
   xC_PARSER_GENERATE_COMPACT_C99_FOR_LOOP_DECLARATIONxFALSE
   x

Else, we can generate a more compact (but newer representation that can choke some parts

of PIPS 7  ^{7http://www.cri.ensmp.fr/pips}  ...)

like:

xxstatement xwithx” i n t i ; ”x d e c l a r a t i o n xxxxx i n s t r u c t i o n x for ( i x=xa ; …; …) x}

This representation is not yet implemented.

4.3 Controlized Code (Hierarchical Control Flow Graph)

PIPS analyses and transformations take advantage of a hierarchical control flow graph (HCFG), which preserves structured part of code as such, and uses a control flow graph only when no syntactic representation is available (seex[?]). The encoding of the relationship between structured and unstructured parts of code is explained elsewhere, mainly in the PIPS Internal Representation of Fortran and C

code8  ^{8http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  .

The controlizerx4.3 is the historical controlizer phase that removes GOTO statements in the parsed code and generates a similar representation with small CFGs. It was developped for Fortranx77 code.

The Fortran controlizer phase was too hacked and undocumented to be improved and debugged for C99 code so a new version has been developed, documented and is designed to be simpler and easier to understand. But, for comparison, the Fortran controlizer phase can still be used.

controlizerxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code

For debugging and validation purpose, by setting at most one of the

PIPS_USE_OLD_CONTROLIZER or PIPS_USE_NEW_CONTROLIZER environment variables,

you can force the use of the specific version of the controlizer you want to use. This override the setting by activateRonan?.

Note that the controlizer choice impacts the HCFG when Fortran entries are used. If you do not know what Fortran entries are, it is deprecated stuff anyway... ☺

The new_controlizerx4.3 removes GOTO statements in the parsed code and generates a similar representation with small CFGs. It is designed to work according to C and C99 standards. Sequences of sequence and variable declarations are handled properly. However, the prettyprinter is tuned for code generated by controlizerx4.3, which does not always minimize the number of goto statements regenerated.

The hierarchical control flow graph built by the controlizerx4.3 is pretty crude. The partial control flow graphs, called unstructured statements, are derived from syntactic constructs. The control scope of an unstructured is the smallest enclosing structured construct, whether a loop, a test or a sequence. Thus some statements, which might be seen as part of structured code, end up as nodes of an unstructured.

Note that sequences of statements are identified as such by controlizerx4.3. Each of them appears as a unique node.

Also, useless CONTINUE statements may be added as provisional landing pads and not removed. The exit node should never have successors but this may happen after some PIPS function calls. The exit node, as well as several other nodes, also may be unreachable. After clean up, there should be no unreachable node or the only unreachable node should be the exit node. Function unspaghettifyx8.3.3.1 (see Sectionx8.3.3.1) is applied by default to clean up and to reduce the control flow graphs after controlizerx4.3.

The GOTO statements are transformed in arcs but also in CONTINUE statements to preserve as many user comments as possible.

The top statement of a module returned by the controlizerx4.3 used to contain always an unstructured instruction with only one node. Several phases in PIPS assumed that this always is the case, although other program transformations may well return any kind of top statement, most likely a block. This is no longer true. The top statement of a module may contain any kind of instruction.

Here is declared the C and C99 controlizer:

new_controlizerxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code

Control restructuring eliminates empty sequences but as empty true or false branch of structured IF. This semantic property of PIPS Internal Representation of Fortran and

C code9  ^{9http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}
is enforced by libraries effects, regions, hpfc, effects-generic.
   xWARN_ABOUT_EMPTY_SEQUENCESxFALSE
   x

By unsetting this property unspaghettifyx8.3.3.1 is not applied implicitly in the controlizer phase.

   xUNSPAGHETTIFY_IN_CONTROLIZERxTRUE
   x

The next property is used to convert C for loops into C while loops. The purpose is to speed up the re-use of Fortran analyses and transformation for C code. This property is set to false by default and should ultimately disappear. But for new user convenience, it is set to TRUE by activate_language() when the language is C.

   xFOR_TO_WHILE_LOOP_IN_CONTROLIZERxFALSE

The next property is used to convert C for loops into C do loops when syntactically possible. The conversion is not safe because the effect of the loop body on the loop index is not checked. The purpose is to speed up the re-use of Fortran analyses and transformation for C code. This property is set to false by default and should disappear soon. But for new user convenience, it is set to TRUE by

activate_language() when the language is C.
   xFOR_TO_DO_LOOP_IN_CONTROLIZERxFALSE
   x

This can also explicitly applied by calling the phase described in §x8.3.3.4.

FORMAT Restructuring

To able deeper code transformation, FORMATs can be gathered at the very beginning of the code or at the very end according to the following options in the unspaghettify or control restructuring phase.

   xGATHER_FORMATS_AT_BEGINNINGxFALSE
   x
   xGATHER_FORMATS_AT_ENDxFALSE
   x

Clean Up Sequences

To display the statistics about cleaning-up sequences and removing useless CONTINUE or empty statement.

   xCLEAN_UP_SEQUENCES_DISPLAY_STATISTICSxFALSE
   x

There is a trade-off between keeping the comments associated to labels and goto and the cleaning that can be do on the control graph.

By default, do not fuse empty control nodes that have labels or comments:

   xFUSE_CONTROL_NODES_WITH_COMMENTS_OR_LABELxFALSE

Chapterx5Pedagogical phases Although this phases should be spread elsewhere in this manual, we have put some pedagogical phases useful to jump into PIPS first.

5.1 Using XML backend A phase that displays, in debug mode, statements matching an XPath expression on the internal representation:

aliasxsimple_xpath_testx'OutputxdebugxinformationxaboutxXPathxmatching'
simple_xpath_testx>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code

5.2 Prepending a comment Prepends a comment to the first statement of a module. Useful to apply post-processing after PIPS.

aliasxprepend_commentx'Prependxaxcommentxtoxthexfirstxstatementxofxaxmodule'
prepend_commentx>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code

The comment to add is selected by this property:

   xPREPEND_COMMENTx"/*␣This␣comment␣is␣added␣by␣PREPEND_COMMENT␣phase␣*/"
   x

5.3 Prepending a call This phase inserts a call to function MY_TRACK just before the first statement of a module. Useful as a pedagogical example to explore the internal representation and Newgen. Not to be used for any pratical purpose as it is bugged. Debugging it is a pedagogical exercise.

aliasxprepend_callx'InsertxaxcallxtoxMY_TRACKxjustxbeforexthexfirstxstatementxofxaxmodule'
prepend_callx>xMODULE.code
xxxxxxxxxxxxx>xMODULE.callees
xx<xPROGRAM.entities
xx<xMODULE.code

The called function could be defined by this property:

   xPREPEND_CALLx"MY_TRACK"
   x

but it is not.

5.4 Add a pragma to a module This phase prepend or appends a pragma to a module.

aliasxadd_pragmax'Prependsxorxappendxaxpragmaxtoxthexcodexofxaxmodule'
add_pragmax>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code

The pragma name can be defined by this property:

   xPRAGMA_NAMEx"MY_PRAGMA"
   x

The pragma can be append or prepend thanks to this property:

   xPRAGMA_PREPENDxTRUE

Remove labels that are not usefull

remove_useless_labelx>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code

Loop labels can be kept thanks to this property:

   xREMOVE_USELESS_LABEL_KEEP_LOOP_LABELxFALSE

Chapterx6Analyses

Analyses encompass the computations of call graphs, the memory effects, reductions, use-def chains, dependence graphs, interprocedural checks (flinter), semantics information (transformers and preconditions), continuations, complexities, convex array regions, dynamic aliases and complementary regions.

6.1 Call Graph

All lists of callees are needed to build the global lists of callers for each module. The callers and callees lists are used by pipsmake to control top-down and bottom-up analyses. The call graph is assumed to be a DAG, i.e. no recursive cycle exists, but it is not necessarily connected.

The height of a module can be used to schedule bottom-up analyses. It is zero if the module has no callees. Else, it is the maximal height of the callees plus one.

The depth of a module can be used to schedule top-down analyses. It is zero if the module has no callers. Else, it it the maximal depth of the callers plus one.

callgraphxxxxxxxxxxxxxxxxxxxxxxx>xALL.callers
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xALL.height
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xALL.depth
xxxxxxxx<xALL.callees

The following pass generates a

uDrawGraph1  ^{1http://www.informatik.uni-bremen.de/uDrawGraph}

version of the callgraph. Its quite partial since it should rely on an hypothetical all callees, direct and indirect, resource.

aliasxdvcg_filex'GraphicalxCallxGraph'
aliasxgraph_of_callsx'Forxcurrentxmodule'
aliasxfull_graph_of_callsx'Forxallxmodules'
graph_of_callsxxxxxxxxxxxxxxx>xMODULE.dvcg_file
xxxxxxxx<xALL.callees
full_graph_of_callsxxxxxxxxxx>xPROGRAM.dvcg_file
xxxxxxxx<xALL.callees

6.2 Memory Effects

The data structures used to represent memory effects and their computation are described inx[?]. Another description is available on line, in PIPS Internal Representation of Fortran

and C code2  ^{2http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}

Technical Report.

Note that the standard name in the Dragon book is likely to be Gen and Kill sets in the standard data flow analysis framework, but PIPS uses the more general concept of effect developped by P.xJouvelot and D.xGiffordx[?] and its analyses are mostly based on the abstract syntac tree (AST) rather than the control flow graph (CFG).

6.2.1 Proper Memory Effects

The proper memory effects of a statement basically are a list of variables that may be read or written by the statement. They are used to build use-def chains (seex[?] or a later edition) and then the dependence graph.

Proper means that the effects of a compound statement do not include the effects of lower level statements. For instance, the body of a loop, true and false branches of a test statement, control nodes in an unstructured statement ... are ignored to compute the proper effects of a loop, a test or an unstructured.

Two families of effects are computed : pointerxeffects are effects in which intermediary access paths may refer to different memory locations at different program points; regular effects are constant path effects, which means that their intermediary access paths all refer to unique memory locations. The same distinction holds for convex array regions (see sectionx6.11).

   properxeffectsxwithxpointsxto and properxeffectsxwithxpointerxvalues

are alternatives to compute constant path proper effects using points-to (see subsectionx6.12.3) or pointer values analyses (see subsectionx6.12.4). This is still at an experimental stage.

Summary effects (see Sectionx6.2.4) of a called module are used to compute the proper effects at the corresponding call sites. They are translated from the callee’s scope into the caller’s scope. The translation is based on the actual-to-formal binding. If too many actual arguments are defined, a user warning is issued but the processing goes on because a simple semantics is available: ignore useless actual arguments. If too few actual arguments are provided, a user error is issued because the effects of the call are not defined.

Variables private to loops are handled like regular variable.

See proper_effectsx6.2.1
See proper_effectsx6.2.1

proper_pointer_effectsxxxxxxxxxxxxxxxxxx>xMODULE.proper_pointer_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.summary_pointer_effects

proper_effectsxxxxxxxxxxxxxxxxxx>xMODULE.proper_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.summary_effects

proper_effects_with_points_tox>xMODULE.proper_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.points_to_list
xxxxxxxx<xCALLEES.summary_effects

proper_effects_with_pointer_valuesx>xMODULE.proper_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.pointer_values
xxxxxxxx<xCALLEES.summary_effects

6.2.2 Filtered Proper Memory Effects

To be continued...by whom? This phase collects information about where a given global variable is actually modified in the program.

filter_proper_effectsxxxxxxxxx>xMODULE.filtered_proper_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xCALLEES.summary_effects

6.2.3 Cumulated Memory Effects

Cumulated effects of statements are lists of read or written variables, just like the proper effects (see Sectionx6.2.1). Cumulated means that the effects of a compound statement, do loop, test or unstructured, include the effects of the lower level statements such as a loop body or a test branch.

cumulated_pointer_effectsxxx>xMODULE.cumulated_pointer_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_pointer_effects

cumulated_pointer_effects_with_points_tox>xMODULE.cumulated_pointer_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_pointer_effects
xxxxxxxx<xMODULE.points_to_list

cumulated_pointer_effects_with_pointer_valuesx>xMODULE.cumulated_pointer_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_pointer_effects
xxxxxxxx<xMODULE.points_to_list

cumulated_effectsxxxxxxxxxxxx>xMODULE.cumulated_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

cumulated_effects_with_points_toxxxxxxxx>xMODULE.cumulated_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

cumulated_effects_with_pointer_valuesxxx>xMODULE.cumulated_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

6.2.4 Summary Data Flow Information (SDFI)

Summary data flow information is the simplest interprocedural information needed to take procedure into account in a parallelizer. It was introduced in Parafrase (seex[?]) under this name, but should be called summary memory effects in PIPS context.

The summary_effectsx6.2.4 of a module are the cumulated memory effects of its top level statement (see Sectionx6.2.6), but effects on local dynamic variables are ignored (because they cannot be observed by the

callers3 ^{3Unless it accesses illegally the stack: see Tom Reps, http://pages.cs.wisc.edu/xreps} ) and subscript expressions of remaining effects are eliminated.

summary_pointer_effectsxxxxxxxxxxxxxxxxx>xMODULE.summary_pointer_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_pointer_effects

summary_effectsxxxxxxxxxxxxxxxxx>xMODULE.summary_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

6.2.5 IN and OUT Effects IN and OUT memory effects of a statement s are memory locations whose input values are used by statement s or whose output values are used by statement s continuation. Variables allocated in the statement are not part of the IN or OUT effects. Variables defined before they are used ar not part of the IN effects. OUT effects require an interprocedural

analysis4 ^{4They are not validated as of June 21, 2008 (FI).}

in_effectsx>xMODULE.in_effects
xxxxxxxxxxx>xMODULE.cumulated_in_effects
xxxxxxxxx<xPROGRAM.entities
xxxxxxxxx<xMODULE.code
xxxxxxxxx<xMODULE.cumulated_effects
xxxxxxxxx<xCALLEES.in_summary_effects
in_summary_effectsx>xMODULE.in_summary_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_effects
out_summary_effectsx>xMODULE.out_summary_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLERS.out_effects
out_effectsx>xMODULE.out_effects
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_summary_effects
xxxxxxxx<xMODULE.cumulated_in_effects

6.2.6 Proper and Cumulated References

The concept of proper references is not yet clearly defined. The original idea is to keep track of the actual objects of newgen domain reference used in the program representation of the current statement, while retaining if they correspond to a read or a write of the corresponding memory locations. Proper references are represented as effects.

For C programs, where memory accesses are not necessarily represented by objects of newgen domain reference, the semantics of this analysis is unclear.

Cumulated references gather proper references over the program code, without taking into account the modification of memory stores by the program execution.

FC: I should implement real summary references?

proper_referencesxxxxxxx>xMODULE.proper_references
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.summary_effects
cumulated_referencesxxxx>xMODULE.cumulated_references
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_references

6.2.7 Effect Properties

Filter this variable in phase filter_proper_effectsx6.2.2.

   xEFFECTS_FILTER_ON_VARIABLEx""
   x
   When set to TRUE, EFFECTS_POINTER_MODIFICATION_CHECKINGx6.2.7 enables

pointer modification checking during the computation of cumulated effects and/or RW covex array regions. Since this is still at experimentation level, it’s default value is FALSE. This property should disappear when pointer modification analyses are more mature.

   xEFFECTS_POINTER_MODIFICATION_CHECKINGxFALSE
   x

The default (and correct) behaviour for the computation of effects is to transform dereferencing paths into constant paths. When property CONSTANT_PATH_EFFECTSx6.2.7 is set to FALSE, the latter transformation is skipped. Effects are then equivalent to pointerxeffects. This property is available for backward compatibility and experimental purpose. It must be borne in mind that analyses and transformations using the resulting effects may yield uncorrect results. This property also affects the computation of convex array regions.

   xCONSTANT_PATH_EFFECTSxTRUE
   x

Since CONSTANT_PATH_EFFECTSx6.2.7 may be set to FALSE erroneously, some tests are included in conflicts testing to avoid generating wrong code. However, these tests are costly, and can be turned off by setting

TRUST_CONSTANT_PATH_EFFECTS_IN_CONFLICTSx6.2.7 to FALSE. This must be used

with care and only when there is no aliasing.

   xTRUST_CONSTANT_PATH_EFFECTS_IN_CONFLICTSxFALSE
   x

Property USER_EFFECTS_ON_STD_FILESx6.2.7 is used to control the way the user uses stdout, stdin and stderr. The default case (FALSE) means that the user does not modify these global variables. When set to TRUE, they are considered as user variables, and dereferencing them through calls to stdio functions leads to less precise effects.

   xUSER_EFFECTS_ON_STD_FILESxFALSE
   x

Property MEMORY_EFFECTS_ONLYx6.2.7 is used to restrict the action kind of an effect action to store. In other words, variable declarations and type declarations are not considered to alter the execution state when this property is set to TRUE. This is fine for Fortran code because variables cannot be declared among executable statements and because new type cannot be declared. But this leads to wrong result for C code when loop distribution or use-def elimination is performed.

Currently, PIPS does not have the capability to store default values depending on the source code language. The default value is TRUE to avoid disturbing too many phases of PIPS at the same time while environment and type declaration effects are introduced.

   xMEMORY_EFFECTS_ONLYxTRUE
   x

Some programs do measure execution times. All code placed between measurement points must not be moved out, as can happen when loops are distributed or, more generally, instructions are rescheduled. Since loops using time effects are not parallel, a clock variable is always updated when a time-related function is called. This is sufficient to avoid most problems, but not all of them because time effects of all other executed statements are kept implicit, i.e. the real time clock is not updated: and loops can still be distributed. If time measurements are key, this property must be turned on. By default, it is turned off.

   xTIME_EFFECTS_USEDxFALSE
   x

6.3 Reductions The proper reductions are computed from a code.

proper_reductionsx>xMODULE.proper_reductions
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.proper_references
xx<xCALLEES.summary_effects
xx<xCALLEES.summary_reductions

The cumulated reductions propagate the reductions in the code, upwards.

cumulated_reductionsx>xMODULE.cumulated_reductions
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.proper_references
xx<xMODULE.cumulated_effects
xx<xMODULE.proper_reductions

This pass summarizes the reductions candidates found in a module for export to its callers. The summary effects should be used to restrict attention to variable of interest in the translation?

summary_reductionsx>xMODULE.summary_reductions
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.cumulated_reductions
xx<xMODULE.summary_effects

Some possible (simple) transformations could be added to the code to mark reductions in loops, for latter use in the parallelization.

The following is NOT implemented. Anyway, should the cumulatedxreductions be simply used by the prettyprinter instead?

loop_reductionsx>xMODULE.code

xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.cumulated_reductions

6.3.1 Reduction Propagation tries to transform

{xxax=xbx+xc ; xxr x=x r x+xa ; x}

into

{xxr x=x r x+bx ; xxr x=x r x+cx ; x}

reduction_propagationx>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.proper_reductions
xx<xMODULE.dg

6.3.2 Reduction Detection tries to transform

{xxax=xbx+xc ; xxbx=xdx+xa ; x}

which hides a reduction on b into

{xxbx=xbx+xcx ; xxbx=xdx+xbx ; x}

when possible

reduction_detectionx>xMODULE.code
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.dg

6.4 Chains (Use-Def Chains)

Use-def and def-use chains are a standard data structure in optimizing compilersx[?]. These chains are used as a first approximation of the dependence graph. Chains based on convex array regions (see Sectionx6.11) are more effective for interprocedural parallelization.

If chains based on convex array regions have been selected, the simplest dependence test must be used because regions carry more information than any kind of preconditions. Preconditions and loop bound information already are included in the region predicate.

6.4.1 Menu for Use-Def Chains

aliasxchainsx'Use-DefxChains'
aliasxatomic_chainsx'Standard'
aliasxregion_chainsx'Regions'
aliasxin_out_regions_chainsx'In-OutxRegions'

6.4.2 Standard Use-Def Chains (a.k.a. Atomic Chains)

The algorithm used to compute use-def chains is original because it is based on PIPS hierarchical control flow graph and not on a unique control flow graph.

This algorithm generates inexistent dependencies on loop indices. These dependence arcs appear between DO loop headers and implicit DO loops in IO statements, or between one DO loop header and unrelated DO loop bound expressions using that index variable. It is easy to spot the problem because loop indices are not privatized. A prettyprint option,

PRETTYPRINT_ALL_PRIVATE_VARIABLESx9.2.21.5.1

must be set to true to see if the loop index is privatized or not. The problem disappears

when some loop indices are renamed.

The problem is due to the internal representation of DO loops: PIPS has no way to distinguish between initialization effects and increment effects. They have to be merged as proper loop effects. To reduce the problem, proper effects of DO loops do not include the index read effect due to the loop incrementation.

Artificial arcs are added to... (Pierre Jouvelot, help!).

atomic_chainsxxxxxxxxxxxxxxxxxxx>xMODULE.chains
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

6.4.3 READ/WRITE Region-Based Chains Such chains are required for effective interprocedural parallelization. The dependence graph is annotated with proper regions, to avoid inaccuracy due to summarization at simple statement level (see Sectionx6.11).

Region-based chains are only compatible with the Rice Fast Dependence Graph option (see Sectionx6.5.1) which has been extended to deal with

them5 5When using regions, the fast qualifier does not stand anymore, because the dependence test involves dealing with convex systems that contain much more constraints than when using the sole array indices. . Other dependence tests do not use region descriptors (their convex system), because they cannot improve the Rice Fast Dependence test based on regions.

region_chainsxxxxxxxxxxxxxxxxxxx>xMODULE.chains
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_regions

6.4.4 IN/OUT Region-Based Chains Beware : this option is for experimental use only; resulting parallel code may not be equivalent to input code (see the explanations below).

When in_out_regions_chainsx6.4.4 is selected, IN and OUT regions (see Sectionsx6.11.5 and 6.11.8) are used at call sites instead of READ and WRITE regions. For all other statements, usual READ and WRITE regions are used.

As a consequence, arrays and scalars which could be declared as local in callees, but are exposed to callers because they are statically allocated or are formal parameters, are ignored, increasing the opportunities to detect parallel loops. But as the program transformation which consists in privatizing variables in modules is not yet implemented in PIPS, the code resulting from the parallelization with in_out_regions_chainsx6.4.4 may not be equivalent to the original sequential code. The privatization here is non-standard: for instance, variables declared in commons or static should be stack allocated to avoid conflicts.

As for region-based chains (see Sectionx6.4.3), the simplest dependence test should be selected for best results.

in_out_regions_chainsxxxxxxxxxxx>xMODULE.chains
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions

The following loop in Subroutine inout cannot be parallelized legally because Subroutine foo uses a static variable, y. However, PIPS will display this loop as (potentially) parallel if the in_out option is selected for use-def chain computation. Remember that IN/OUT regions require MUST regions to obtain interesting results (see Sectionx6.11.5).

xxxxxxsubroutinexinout(a,n)
xxxxxxrealxa(n)
xxxxxx
xxxxxxdoxix=x1,xn
xxxxxxxxxcallxfoo(a(i))
xxxxxxenddo
xxxxxx
xxxxxxend
xxxxxx
xxxxxxsubroutinexfoo(x)
xxxxxxsavexy
xxxxxx
xxxxxxyx=xx
xxxxxxxx=xxx+xy
xxxxxx
xxxxxxend

6.4.5 Chain Properties

6.4.5.1 Add use-use Chains

It is possible to put use-use dependence arcs in the dependence graph. This is useful for estimation of cache memory traffic and of communication for distributed memory machine (e.g. you can parallelize only communication free loops). Beware of use-use dependence on scalar variables. You might expect scalars to be broadcasted and/or replicated on each processor but they are not handled that way by the parallelization process unless you manage to have them declared private with respect to all enclosing loops.

This feature is not supported by PIPS user interfaces. Results may be hard to interpret. It is useful to print the dependence graph.

   xKEEP_READ_READ_DEPENDENCExFALSE
   x

6.4.5.2 Remove Some Chains

It is possible to mask effects on local variables in loop bodies. This is dangerous with current version of Allen & Kennedy which assumes that all the edges are present, the ones on private variables being partially ignored but for loop distribution. In other words, this property should always be set to false.

   xCHAINS_MASK_EFFECTSxFALSE
   x

It also is possible to keep only true data-flow (Def – Use) dependences in the dependence graph. This was an attempt at mimicking the effect of direct dependence analysis and at avoiding privatization. However, direct dependence analysis is not implemented in the standard tests and spurious def-use dependence arcs are taken into account.

   xCHAINS_DATAFLOW_DEPENDENCE_ONLYxFALSE
   x

These last two properties are not consistent with PIPS current development (1995/96). It is assumed that all dependence arcs are present in the dependence graph. Phases using the latter should be able to filter out irrelevant arcs, e.g. pertaining to privatized variables.

6.5 Dependence Graph (DG)

The dependence graph is used primarily by the parallelization algorithms. A dependence graph is a refinement of use-def chains (Sectionx6.4). It is location-based and not value-based.

There are several ways to compute a dependence graph. Some of them are fast (Banerjee’s one for instance) but provide poor results, others might be slower (Rx¿œmi Triolet’s one for instance) but produce better results.

Three different dependence tests are available, all based on Fourier-Motzkin elimination improved with a heuristics for the integer domain. The fast version uses subscript expressions only (unless convex array regions were used to compute use-def chains, in which case regions are used instead). The full version uses subscript expressions and loop bounds. The semantics version uses subscript expressions and preconditions (seex6.8).

Note that, for interprocedural parallelization, precise array regions only are used by the fast dependence test if the proper kind of use-def chains has been previously selected (see Sectionx6.4.3).

There are several kinds of dependence graphs. Most of them share the same overall data structure: a graph with labels on arcs and vertices. usually, the main differences are in the labels that decorate arcs; for instance, Kennedy’s algorithm requires dependence levels (which loop actually creates the dependence) while algorithms originated from CSRD prefer DDVs (relations between loop indices when the dependence occurs). Dependence cones introduced inx[?,x?,x?,x?] are even more precisex[?].

The computations of dependence level and dependence conex[?] are both implemented in PIPS. DDV’s are not computed. Currently, only dependence levels are exploited by parallelization algorithms.

The dependence graph can be printed with or without filters (see Sectionx9.8). The standard dependence graph includes all arcs taken into account by the parallelization process (Allen & Kennedyx[?]), except those that are due to scalar private variables and that impact the distribution process only. The loop carried dependence graph does not include intra-iteration dependences and is a good basis for iteration scheduling. The whole graph includes all arcs, but input dependence arcs.

It is possible to gather some statistics about dependences by turning on property RICEDG_PROVIDE_STATISTICSx6.5.6.2 (more details in the properties). A Shell script from PIPS utilities, print-dg-statistics, can be used in combination to extract the most relevant information for a whole program.

During the parallelization phases, is is possible to ignore arcs related to states of the libc, such as the heap memory management, because thread-safe libraries do perform the updates within critical sections. But these arcs are part of the use-def chains and of the dependence graph. If they were removed instead of being ignored, use-def elimination would remove all free statements.

The main contributors for the design and development of dependence analysis are Rx¿œmi Triolet, Franx¿œois Irigoin and Yi-qing Yangx[?]. The code was improved by Corinne Ancourt and Bx¿œatrice Creusillet.

6.5.1 Menu for Dependence Tests

aliasxdgx'DependencexTest'
aliasxrice_fast_dependence_graphx'PreconditionsxIgnored'
aliasxrice_full_dependence_graphx'LoopxBoundsxUsed'
aliasxrice_semantics_dependence_graphx'PreconditionsxUsed'
aliasxrice_regions_dependence_graphx'RegionsxUsed'

6.5.2 Fast Dependence Test

Use subscript expressions only, unless convex array regions were used to compute use-def chains, in which case regions are used instead. ricexregionsxdependencexgraph is a synonym for this rule, but emits a warning if regionxchains is not selected.

rice_fast_dependence_graphxxxxxx>xMODULE.dg
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains
xxxxxxxx<xMODULE.cumulated_effects

6.5.3 Full Dependence Test

Use subscript expressions and loop bounds.

rice_full_dependence_graphxxxxxx>xMODULE.dg
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains
xxxxxxxx<xMODULE.cumulated_effects

6.5.4 Semantics Dependence Test

Uses subscript expressions and preconditions (seex6.8).

rice_semantics_dependence_graphx>xMODULE.dg
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

6.5.5 Dependence Test with Convex Array Regions

Synonym for ricexfastxdependencexgraph, except that it emits a warning when regionxchains is not selected.

rice_regions_dependence_graphxxxxxx>xMODULE.dg
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains
xxxxxxxx<xMODULE.cumulated_effects

6.5.6 Dependence Properties (Ricedg)

6.5.6.1 Dependence Test Selection

This property seems to be now obsolete. The dependence test choice is now controlled directly and only by rules in pipsmake. The procedures called by these rules may use this property. Anyway, it is useless to set it manually.

   xDEPENDENCE_TESTx"full"
   x

6.5.6.2 Statistics

Provide the following counts during the dependence test. There are three parts: numbers of dependencies and independences (fields 1-10), dimensions of referenced arrays and dependence natures (fields 11-25) and the same information for constant dependencies (fields 26-40), decomposition of the dependence test in elementary steps (fields 41-49), use and complexity of Fourier-Motzkin’s pair-wise elimination (fields 50, 51 and 52-68). array reference pairs, i.e. number of tests effected (used to be the number of use-def, def-use and def-def pairs on arrays);

number of independences found (on array reference pairs);

Note: field 1 minus field 2 is the number of array dependencies.

numbers of loop independent dependences between references in the same statement (not useful for program transformation and parallelization if statements are preserved); it should be subtracted from field 2 to compare results with other parallelizers;

numbers of constant dependences;

numbers of exact dependences;

Note: field 5 must be greater or equal to field 4.

numbers of inexact dependences involved only by the elimination of equation;

numbers of inexact dependences involved only by the F-M elimination;

numbers of inexact dependences involved by both elimination of equation and F-M elimination;

Note: the sum of fields 5 to 8 and field 2 equals field 1

number of dependences among scalar variables;

numbers of dependences among loop index variables;

dependence types detail table with the dimensions [5][3] and constant dependence detail table with the dimensions [5][3]; the first index is the array dimension (from 0 to 4 - no larger arrays has ever been found); the second index is the dependence nature (1: d-u, 2: u-d, 3: d-d); both arrays are flatten according to C rule as 5 sequences of 3 natures;

Note: the sum of fields 11 to 25 should be equal to the sum of field 9 and 2 minus field 1.

Note: the fields 26 to 40 must be less than or equal to the corresponding fields 11 to 25

numbers of independences found by the test of constant; numbers of independences found by the GCD test;

numbers of independences found by the normalize test;

numbers of independences found by the lexico-positive test for constant Di variables;

numbers of independences found during the projection on Di variables by the elimination of equation;

numbers of independences found during the projection on Di variables by the Fourier-Motzkin’s elimination;

numbers of independences found during the test of faisability of Di sub-system by the elimination of equation;

numbers of independences found during the test of faisability of Di sous-system by the Fourier-Motzkin’s elimination;

numbers of independences found by the test of lexico-positive for Di sub-system;

Note: the sum of fields 41 to 49 equals field 2

total number of Fourier-Motzkin’s pair-wise eliminations used;

number of Fourier-Motzkin’s pair-wise elimination in which the system size doesn’t augment after the elimination;

complexity counter table of dimension [17]. The complexity of one projection by F-M is the product of the number of positive inequalities and the number of negatives inequalities that contain the eliminated variable. This is an histogram of the products. Products which are less than or equal to 4 imply that the total number of inequalities does not increase. So if no larger product exists, field 50 and 51 must be equal.

The results are stored in the current workspace in MODULE.resulttestfast, MODULE.resultesttestfull, or MODULE.resulttestseman according to the test selected.

xRICEDG_PROVIDE_STATISTICSxFALSE
x

Provide the statistics above and count all array reference pairs including these involved in call statement.

   xRICEDG_STATISTICS_ALL_ARRAYSxFALSE
   x

6.5.6.3 Algorithmic Dependences

Only take into account true flow dependences (Def – Use) during the computation of SCC? Note that this is different from the CHAINSxDATAFLOWxDEPENDENCExONLY option which doesn’t compute the whole graph. Warning: this option potentially yields incorrect parallel code.

   xRICE_DATAFLOW_DEPENDENCE_ONLYxFALSE
   x

6.5.6.4 Printout

Here are the properties used to control the printing of dependence graphs in a file called modulexname.dg. These properties should not be used explicitly because they are set implicitly by the different print-out procedures available in pipsmake.rc. However, not all combinations are available from pipsmake.rc.

   xPRINT_DEPENDENCE_GRAPHxFALSE
   x

To print the dependence graph without the dependences on privatized variables

   xPRINT_DEPENDENCE_GRAPH_WITHOUT_PRIVATIZED_DEPSxFALSE
   x

To print the dependence graph without the non-loop-carried dependences:

   xPRINT_DEPENDENCE_GRAPH_WITHOUT_NOLOOPCARRIED_DEPSxFALSE
   x

To print the dependence graph with the dependence cones:

   xPRINT_DEPENDENCE_GRAPH_WITH_DEPENDENCE_CONESxFALSE
   x

To print the dependence graph in a computer friendly format defined by Deborah Whitfield (SRU):

   xPRINT_DEPENDENCE_GRAPH_USING_SRU_FORMATxFALSE
   x

6.5.6.5 Optimization

The default option is to compute the dependence graph only for loops which can be parallelized using Allen & Kennedy algorithm. However it is possible to compute the dependences in all cases, even for loop containing test, goto, etc... by setting this option to TRUE.

Of course, this information is not used by the parallelization phase which is restricted to loops meeting the A&K conditions. By the way, the hierarchical control flow graph is not exploited either by the parallelization phase.

   xCOMPUTE_ALL_DEPENDENCESxFALSE
   x

6.6 Flinter Function flinterx6.6 performs some intra and interprocedural checks about formal/actual argument pairs, use of COMMONs,... It was developed by Laurent Aniort and Fabien Coelho. Ronan Keryell added the uninitialized variable checking.

aliasxflinted_filex'FlintxView'
flinterxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.flinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.chains

In the past, flinterx6.6 used to require MODULE.summaryxeffects to check the parameter passing modes and to make sure that no module would attempt an assignment on an expression. However, this kind of bug is detected by the effect analysisx which was required by flinter.

Resource CALLEES.code is not explicitly required but it produces the global symbols which function flinterx6.6 needs to check parameter lists.

6.7 Loop statistics Computes statistics about loops in module. It computes the number of perfectly and imperfectly nested loops and gives their depths. And it gives the number of nested loops which we can treat with our algorithm.

loop_statisticsx>xMODULE.stats_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

6.8 Semantics Analysis

PIPS semantics analysis targets mostly integer scalar variables. It is a two-pass process, with a bottom-up pass computing transformersx6.8.1, and a top-down pass propagating preconditionsx6.8.5. Transformers and preconditions are specially powerful case of return and jump functionsx[?]. They abstract relations between program states with polyhedra and encompass most standard interprocedural constant propagations as well as most interval analyses. It is a powerful relational symbolic analysis.

Unlikex[?] their computations are based on PIPS Hierarchical Control Flow Graph and on syntactic constructs instead of a standard flow graph. The best presentation of this part of PIPS is inx[?].

A similar analysis is available in Parafrase-2x[]. It handles polynomial equations between scalar integer variables. SUIFx[] also performs some kind of semantics analysis.

The semantics analysis part of PIPS was designed and developed by Franx¿œois Irigoin.

6.8.1 Transformers

RK: The following is hard to read without any example for someone that knows nothing about PIPS... FI: do you want to have everything in this documentation?

A transformer is an approximate relation between the symbolic initial values of scalar variables and their values after the execution of a statement, simple or compound (seex[?] andx[?]). In abstract interpretation terminology, a transformer is an abstract command linking the input abstract state of a statement and its output abstract state.

By default, only integer scalar variables are analyzed, but properties can be set to handle boolean, string and floating point scalar

variables6 6Floating point values are combined exactly, which is not correct but still useful when dead code can be eliminated according to some parameter value.

: SEMANTICS_ANALYZE_SCALAR_INTEGER_VARIABLESx6.8.11.1
SEMANTICS_ANALYZE_SCALAR_BOOLEAN_VARIABLESx6.8.11.1
SEMANTICS_ANALYZE_SCALAR_STRING_VARIABLESx6.8.11.1
SEMANTICS_ANALYZE_SCALAR_FLOAT_VARIABLESx6.8.11.1
SEMANTICS_ANALYZE_SCALAR_COMPLEX_VARIABLESx6.8.11.1

Transformers can be computed intraprocedurally by looking at each function independently or they can be computed interprocedurally starting with the leaves of the

call tree7 7Recursive calls are not handled. Hopefully, they are detected by pipsmake to avoid looping forever. .

Intraprocedural algorithms use cumulated_effectsx6.2.3 to handle procedure calls correctly. In some respect, they are interprocedural since call statements are accepted. Interprocedural algorithms use the summary_transformerx6.8.2 of the called procedures.

Fast algorithms use a very primitive non-iterative transitive closure algorithm (two possible versions: flow sensitive or flow insensitive). Full algorithms use a transitive closure algorithm based on vector subspace (i.e. x¿œ la Karrx[?]) or one based on the discrete derivativesx[?,x?]. The iterative fix point algorithm for transformers (i.e. Halbwachs/Cousotx[?] is implemented but not used because the results obtained with transitive closure algorithms are faster and up-to-now sufficient. Property SEMANTICS_FIX_POINT_OPERATORx6.8.11.6 is set to select the transitive closure algorithm used.

Additional information, such as array declarations and array references, can be used to improve transformers. See the property documentation for:

   SEMANTICS_TRUST_ARRAY_DECLARATIONSx6.8.11.2 SEMANTICS_TRUST_ARRAY_REFERENCESx6.8.11.2

Within one procedure, the transformers can be computed in forward mode, using precondition information gathered along. Transformers can also be recomputed once the preconditions are available. In both cases, more precise transformers are obtained because the statement can be better modelized using precondition information. For instance, a non-linear expression can turn out to be linear because the values of some variables are numerically known and can be used to simplify the initial expression. See properties:

   SEMANTICS_RECOMPUTE_EXPRESSION_TRANSFORMERSx6.8.11.4
   SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXTx6.8.11.4
   SEMANTICS_RECOMPUTE_FIX_POINTS_WITH_PRECONDITIONSx6.8.11.6
   and phase refine_transformersx6.8.1.6.

Unstructured control flow graphs can lead to very long transformer computations, whose results are usually not interesting. Their sizes are limited by two properties:

   SEMANTICS_MAX_CFG_SIZE2x6.8.11.3 SEMANTICS_MAX_CFG_SIZE1x6.8.11.3

discussed below.

Default value were set in the early nineties to obtain results fast enough for live demonstrations. They have not been changed to preserve the non-regression tests. However since 2005, processors are fast enough to use the most precise options in all cases.

A transformer map contains a transformer for each statement of a module. It is a mapping from statements to transformers (type statementxmapping, which is not a NewGen file). Transformers maps are stored on and retrieved from disk by pipsdbm.

6.8.1.1 Menu for Transformers

aliasxtransformersx'Transformers'
aliasxtransformers_intra_fastx'QuickxIntra-ProceduralxComputation'
aliasxtransformers_inter_fastx'QuickxInter-ProceduralxComputation'
aliasxtransformers_intra_fullx'FullxIntra-ProceduralxComputation'
aliasxtransformers_inter_fullx'FullxInter-ProceduralxComputation'
aliasxrefine_transformersx'RefinexTransformers'

6.8.1.2 Fast Intraprocedural Transformers Build the fast intraprocedural transformers.

transformers_intra_fastxxxxxxxxx>xMODULE.transformers
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.proper_effects

6.8.1.3 Full Intraprocedural Transformers Build the improved intraprocedural transformers.

transformers_intra_fullxxxxxxxxx>xMODULE.transformers
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.proper_effects

6.8.1.4 Fast Interprocedural Transformers Build the fast interprocedural transformers.

transformers_inter_fastxxxxxxxxx>xMODULE.transformers
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xCALLEES.summary_transformer
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xPROGRAM.program_precondition

6.8.1.5 Full Interprocedural Transformers Build the improved interprocedural transformers (This should be used as default option.).

transformers_inter_fullxxxxxxxxx>xMODULE.transformers
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

xxxxxxxx<xCALLEES.summary_transformer
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xPROGRAM.program_precondition

6.8.1.6 Full Interprocedural Transformers Rebuild the interprocedural transformers using interprocedural preconditions. Intraprocedural preconditions are also used to refine all transformers.

refine_transformersxxxxxxxxx>xMODULE.transformers
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xCALLEES.summary_transformer
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xPROGRAM.program_precondition

6.8.2 Summary Transformer

A summary transformer is an interprocedural version of the module statement transformer, obtained by eliminating dynamic local, a.k.a. stack allocated, variables. The filtering is based on the module summary effects. Note: each module has a UNIQUE top-level statement.

A summary_transformerx6.8.2 is of Newgen type transformer.

summary_transformerxxxxxxxxxxxxx>xMODULE.summary_transformer
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_effects

6.8.3 Initial Precondition

All DATA initializations contribute to the global initial state of the program. The contribution of each module is computed independently. Note that variables statically initialized behave as static variables and are preserved between calls according to Fortran standard. The module initial states are abstracted by an initial precondition based on integer scalar variables only.

Note: To be extended to handle C code. To be extended to handle properly unknown modules.

initial_preconditionxxxxx>xMODULE.initial_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

All initial preconditions, including the initial precondition for the main, are combined to define the program precondition which is an abstraction of the program initial state.

program_preconditionxxxxx>xPROGRAM.program_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xALL.initial_precondition

The program precondition can only be used for the initial state of the main procedure. Although it appears below for all interprocedural analyses and it always is computed, it only is used when a main procedure is available.

6.8.4 Intraprocedural Summary Precondition A summary precondition is of type ”transformer”, but the argument list must be empty as it is a simple predicate on the initial state. So in fact it is a state predicate.

The intraprocedural summary precondition uses DATA statement for the main module and is the TRUE constant for all other modules.

intraprocedural_summary_preconditionxxxxxxxxxxxx>xMODULE.summary_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.initial_precondition

Interprocedural summary preconditions can be requested instead. They are not described in the same section in order to introduce the summary precondition resource at the right place in pipsmake.rc.

No menu is declared to select either intra- or interprocedural summary preconditions.

6.8.5 Preconditions

A precondition for a statement s in a module m is a predicate true for every state reachable from the initial state of m, in which s is executed. A precondition is of NewGen type ”transformer” (see PIPS Internal Representation of Fortran and C

code8  ^{8http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  )

and preconditions is of type statement_mapping.

Option preconditions_intrax6.8.5.2 associates a precondition to each statement, assuming that no information is available at the module entry point.

Inter-procedural preconditions may be computed with intra-procedural transformers but the benefit is not clear. Intra-procedural preconditions may be computed with inter-procedural transformers. This is faster that a full interprocedural analysis because there is no need for a top-down propagation of summary preconditions. This is compatible with code transformations like

partial_evalx8.4.2, simplify_controlx8.3.1 and dead_code_eliminationx8.3.2.

Since these two options for transformer and precondition computations are independent and that transformers_inter_fullx6.8.1.5 and preconditions_inter_fullx6.8.5.4 must be both (independently) selected to obtain the best possible results. These two options are recommended.

6.8.5.1 Menu for Preconditions

aliasxpreconditionsx'Preconditions'
aliasxpreconditions_intrax'Intra-ProceduralxAnalysis'
aliasxpreconditions_inter_fastx'QuickxInter-ProceduralxAnalysis'
aliasxpreconditions_inter_fullx'FullxInter-ProceduralxAnalysis'
aliasxpreconditions_intra_fastx'Fastxintra-ProceduralxAnalysis'

6.8.5.2 Intra-Procedural Preconditions Only build the preconditions in a module without any interprocedural propagation. The fast version uses a fast but crude approximation of preconditions for unstructured code.

preconditions_intraxxxxxxxxxxxx>xMODULE.preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.code

preconditions_intra_fastxxxxxxxxxxxx>xMODULE.preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.code

6.8.5.3 Fast Inter-Procedural Preconditions Option preconditions_inter_fastx6.8.5.3 uses the module own precondition derived from its callers as initial state value and propagates it downwards in the module statement.

The fast versions use no fix-point operations for loops.

preconditions_inter_fastxxxxxxxx>xMODULE.preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xPROGRAM.program_precondition
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xCALLEES.summary_effects
xxxxxxxx<xMODULE.summary_transformer

6.8.5.4 Full Inter-Procedural Preconditions Option preconditions_inter_fullx6.8.5.4 uses the module own precondition derived from its callers as initial state value and propagates it downwards in the module statement.

The full versions use fix-point operations for loops.

preconditions_inter_fullxxxxxxxx>xMODULE.preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xPROGRAM.program_precondition
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers

xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xCALLEES.summary_transformer
xxxxxxxx<xMODULE.summary_transformer

6.8.6 Interprocedural Summary Precondition

By default, summary preconditions are computed intraprocedurally. The interprocedural option must be explicitly activated.

An interprocedural summary precondition for a module is derived from all its call sites. Of course, preconditions must be known for all its callers’ statements. The summary precondition is the convex hull of all call sites preconditions, translated into a proper environment which is not necessarily the module’s frame. Because of invisible global and static variables and aliasing, it is difficult for a caller to know which variables might be used by the caller to represent a given memory location. To avoid the problem, the current summary precondition is always translated into the caller’s frame. So each module must first translate its summary precondition, when receiving it from the resource manager (pipsdbm) before using it.

Note: the previous algorithm was based on a on-the-fly reduction by convex hull. Each time a call site was encountered while computing a module preconditions, the callee’s summary precondition was updated. This old scheme was more efficient but not compatible with program transformations because it was impossible to know when the summary preconditions of the modules had to be reset to the infeasible (a.k.a. empty) precondition.

An infeasible precondition means that the module is never called although a main is present in the workspace. If no main module is available, a TRUE precondition is generated. Note that, in both cases, the impact of static initializations propagated by link edition is taken into account although this is prohibited by the Fortran Standard which requires a BLOCKDATA construct for such initializations. In other words, a module which is never called has an impact on the program execution and its declarations should not be destroyed.

interprocedural_summary_preconditionxxxxxxxxxxxx>xMODULE.summary_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xPROGRAM.program_precondition
xxxxxxxx<xCALLERS.preconditions
xxxxxxxx<xMODULE.callers

The following rule is obsolete. It is context sensitive and its results depends on the history of commands performed on the workspace.

summary_preconditionxxxxxxxxxxxx>xMODULE.summary_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.preconditions
xxxxxxxx<xMODULE.callers

6.8.7 Total Preconditions

Total preconditions are interesting to optimize the nominal behavior of a terminating application. It is assumed that the application ends in the main procedure. All other exits, aborts or stops, explicit or implicit such as buffer overflows and zero divide and null pointer dereferencing, are considered exceptions. This also applies at the module level. Modules nominally return. Other control flows are considered exceptions. Non-terminating modules have an empty total

precondition9 9Non-termination conditions could also be propagated backwards to provide an over-approximation of the conditions under which an application never terminates, i.e. conditions for liveness. . The standard preconditions can be refined by anding with the total preconditions to get information about the nominal behavior. Similar sources of increased accuracy are the array declarations and the array references, which can be exploited directly with properties described in sectionx6.8.11.2. These two properties should be set to true whenever possible.

Hence, a total precondition for a statement s in a module m is a predicate true for every state from which the final state of m, in which s is executed, is reached. It is an over-approximation of the theoretical total precondition. So, if the predicate is false, the final control state cannot be reached. A total precondition is of NewGen type ”transformer” (see PIPS Internal Representation of Fortran and C

code10  ^{10http://www.cri.ensmp.fr/pips/newgen/ri.htdoc}  )

and totalxpreconditions is of type statement_mapping.

The relationship with continuations (see Sectionx6.9) is not clear. Total preconditions should be more general but no must version exist.

Option total_preconditions_intrax6.8.7.2 associates a precondition to each statement, assuming that no information is available at the module return point.

Inter-procedural total preconditions may be computed with intra-procedural transformers but the benefit is not clear. Intra-procedural total preconditions may be computed with inter-procedural transformers. This is faster than a full interprocedural analysis because there is no need for a top-down propagation of summary total postconditions.

Since these two options for transformer and total precondition computations are

independent, transformers_inter_fullx6.8.1.5 and total_preconditions_interx6.8.7.3

must be both (independently) selected to obtain the best possible results.

Status:

This is a set of experimental passes. The intraprocedural part is implemented. The interprocedural part is not implemented yet, waiting for an expressed practical interest. Neither C for loops nor repeat loops are supported.

6.8.7.1 Menu for Total Preconditions

aliasxtotal_preconditionsx'TotalxPreconditions'
aliasxtotal_preconditions_intrax'TotalxIntra-ProceduralxAnalysis'
aliasxtotal_preconditions_interx'TotalxInter-ProceduralxAnalysis'

6.8.7.2 Intra-Procedural Total Preconditions Only build the total preconditions in a module without any interprocedural propagation. No specific condition must be met when reaching a RETURN statement.

total_preconditions_intraxxxxxxxxxxxx>xMODULE.total_preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_effects

xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.code

6.8.7.3 Inter-Procedural Total Preconditions Option total_preconditions_interx6.8.7.3 uses the module own total postcondition derived from its callers as final state value and propagates it backwards in the module statement. This total module postcondition must be true when the RETURN statement is reached.

total_preconditions_interxxxxxxxx>xMODULE.total_preconditions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xPROGRAM.program_postcondition
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xCALLEES.summary_effects
xxxxxxxx<xMODULE.summary_transformer

The program postcondition is only used for the main module.

6.8.8 Summary Total Precondition

The summary total precondition of a module is the total precondition of its statement limited to information observable by callers, just like a summary transformer (see Sectionx6.8.2).

A summary total precondition is of type ”transformer”.

summary_total_preconditionxxxxxxxxxxxx>xMODULE.summary_total_precondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.total_preconditions

6.8.9 Summary Total Postcondition

A final postcondition for a module is derived from all its call sites. Of course, total postconditions must be known for all its callers’ statements. The summary total postcondition is the convex hull of all call sites total postconditions, translated into a proper environment which is not necessarily the module’s frame. Because of invisible global and static variables and aliasing, it is difficult for a caller to know which variables might be used by the caller to represent a given memory location. To avoid the problem, the current summary total postcondition is always translated into the caller’s frame. So each module must first translate its summary total postcondition, when receiving it from the resource manager (pipsdbm) before using it.

A summary total postcondition is of type ”transformer”.

summary_total_postconditionxxxxxxxxxxxx>xMODULE.summary_total_postcondition
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.total_preconditions
xxxxxxxx<xMODULE.callers

6.8.10 Final Postcondition

The program postcondition cannot be derived from the source code. It should be defined explicitly by the user. By default, the predicate is always true. But you might want some variables to have specific values, e.g. KMAX==1, or signs,KMAX>1 or relationships KMAX>JMAX.

program_postconditionxxxxx>xPROGRAM.program_postcondition

6.8.11 Semantic Analysis Properties

6.8.11.1 Value types

By default, the semantic analysis is restricted to scalar integer variables as they are key variables to understand scientific code behavior. However it is possible to analyze scalar variables with other data types. Fortran LOGICAL variables are represented as 0/1 integers. Character string constants and floating point constants are represented as undefined values.

The analysis is thus limited to constant propagation for character strings and floating point values whereas integer and boolean variables are processed with a relational analysis.

Character string constants of fixed maximal length could be translated into integers but the benefit is not yet assessed because they are not much used in the benchmark and commercial applications we have studied. The risk is to increase significantly the number of overflows encountered during the analysis.

   xSEMANTICS_ANALYZE_SCALAR_INTEGER_VARIABLESxTRUE
   x
   xSEMANTICS_ANALYZE_SCALAR_BOOLEAN_VARIABLESxFALSE
   x
   xSEMANTICS_ANALYZE_SCALAR_STRING_VARIABLESxFALSE
   x
   xSEMANTICS_ANALYZE_SCALAR_FLOAT_VARIABLESxFALSE
   x
   xSEMANTICS_ANALYZE_SCALAR_COMPLEX_VARIABLESxFALSE

6.8.11.2 Array declarations and accesses

For every module, array declaration are assumed to be correct with respect to the standard: the upper bound must be greater than or equal to the lower bound. When implicit, the lower bound is one. The star upper bound is neglected.

This property is turned off by default because it might slow down PIPS quite a lot without adding any useful information because loop bounds are usually different from array bounds.

   xSEMANTICS_TRUST_ARRAY_DECLARATIONSxFALSE
   x

For every module, array references are assumed to be correct with respect to the declarations: the subscript expressions must have values lower than or equal to the upper bound and greater than or equal to the lower bound.

This property is turned off by default because it might slow down PIPS quite a lot without adding any useful information.

   xSEMANTICS_TRUST_ARRAY_REFERENCESxFALSE
   x

6.8.11.3 Flow Sensitivity

Perform “meet” operations for semantics analysis. This property is managed by pipsmake which often sets it to TRUE. See comments in pipsmake documentation to turn off convex hull operations for a module or more if they last too long.

   xSEMANTICS_FLOW_SENSITIVExFALSE
   x

Complex control flow graph may require excessive computation resources. This may happen when analyzing a parser for instance.

   xSEMANTICS_ANALYZE_UNSTRUCTUREDxTRUE
   x

To reduce execution time, this property is complemented with a heuristics to turn off the analysis of very complex unstructured.

If the control flow graph counts more than SEMANTICS_MAX_CFG_SIZE1x6.8.11.3 vertices, use effects only.

   xSEMANTICS_MAX_CFG_SIZE2x20
   x

If the control flow graph counts more than SEMANTICS_MAX_CFG_SIZE1x6.8.11.3 but less than SEMANTICS_MAX_CFG_SIZE2x6.8.11.3 vertices, perform the convex hull of its elementary transformers and take the fixpoint of it. Note that SEMANTICS_MAX_CFG_SIZE2x6.8.11.3 is assumed to be greater than or equal to

SEMANTICS_MAX_CFG_SIZE1x6.8.11.3.

   xSEMANTICS_MAX_CFG_SIZE1x20
   x

6.8.11.4 Context for statement and expression transformers

Without preconditions, transformers can be precise only for affine expressions. Approximate transformers can sometimes be derived for other expressions, involving for instance products of variables or divisions.

However, a precondition of an expression can be used to refine the approximation. For instance, some non-linear expressions can become affine because some of the variables have constant values, and some non-linear expressions can be better approximated because the variables signs or ranges are known.

To be backward compatible and to be conservative for PIPS execution time, the default value is false.

Not implemented yet.

   xSEMANTICS_RECOMPUTE_EXPRESSION_TRANSFORMERSxFALSE
   x

Intraprocedural preconditions can be computed at the same time as transformers and used to improve the accuracy of expression and statement transformers. Non-linear expressions can sometimes have linear approximations over the subset of all possible stores defined by a precondition. In the same way, the number of convex hulls can be reduced if a test branch is never used or if a loop is always entered.

   xSEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXTxFALSE
   x

The default value is false for reverse compatibility and for speed.

6.8.11.5 Interprocedural Semantics Analysis

To be refined later; basically, use callee’s transformers instead of callee’s effects when computing transformers bottom-up in the call graph; when going top-down with preconditions, should we care about unique call site and/or perform meet operation on call site preconditions ?

   xSEMANTICS_INTERPROCEDURALxFALSE
   x

This property is used internally and is not user selectable.

6.8.11.6 Fix Point Operators

CPU time and memory space are cheap enough to compute loop fix points for transformers. This property implies SEMANTICS_FLOW_SENSITIVEx6.8.11.3 and is not user-selectable.

   xSEMANTICS_FIX_POINTxFALSE
   x

The default fix point operator, called transfer, is good for induction variables but it is not good for all kinds of code. The default fix point operator is based on the transition function associated to a loop body. A computation of eigenvectors for eigenvalue 1 is used to detect loop invariants. This fails when no transition function but only a transition relation is available. Only equations can be found.

The second fix point operator, called pattern, is based on a pattern matching of elementary equations and inequalities of the loop body transformer. Obvious invariants are detected. This fix point operator is not better than the previous one for induction variables but it can detect invariant equations and inequalities.

A third fix point operator, called derivative, is based on finite differences. It was developed to handled DO loops desugared into WHILE loops as well as standard DO loops. The loop body transformer on variable values is projected onto their finite differences. Invariants, both equations and inequalities, are deduced directly from the constraints on the differences and after integration. This third fix point operator should be able to find at least as many invariants as the two previous one, but at least some inequalities are missed because of the technique used. For instance, constraints on a flip-flop variable can be missed. Unlike Cousot-Halbwachs fix point (see below), it does not use Chernikova steps and it should not slow down analyses.

This property is user selectable and its default value is derivative. The default value is the only one which is now seriously maintained.

   xSEMANTICS_FIX_POINT_OPERATORx"derivative"
   x

The next property is experimental and its default value is 1. It is used to unroll while loops virtually, i.e. at the semantics equation level, to cope with periodic behaviors such as flip-flops. It is effective only for standard while loops and the only possible value other than 1 is 2.

   xSEMANTICS_K_FIX_POINTx1
   x
   The next property SEMANTICSxPATTERNxMATCHINGxFIXxPOINT has been removed

and replaced by option pattern of the previous property.

This property was defined to select one of Cousot-Halbwachs’s heuristics and to compute fix points with inequalities and equalities for loops. These heuristics could be used to compute fix points for transformers and/or preconditions. This option implies SEMANTICS_FIX_POINTx6.8.11.6 and SEMANTICS_FLOW_SENSITIVEx6.8.11.3. It has not been implemented yet in

PIPS11 ^{11But some fix point functions are part of the C3 linear library.} because its accuracy has not yet been required, but is now badly named because there is no direct link between inequality and Halbwachs. Its default value is false and it is not user selectable.

   xSEMANTICS_INEQUALITY_INVARIANTxFALSE
   x

Because of convexity, some fix points may be improved by using some of the information carried by the preconditions. Hence, it may be profitable to recompute loop fix point transformer when preconditions are being computed.

The default value is false because this option slows down PIPS and does not seem to add much useful information in general.

   xSEMANTICS_RECOMPUTE_FIX_POINTS_WITH_PRECONDITIONSxFALSE
   x

The next property is used to refine the computation of preconditions inside nested loops. The loop body is reanalyzed to get one transformer for each control path and the identity transformer is left aside because it is useless to compute the loop body precondition. This development is experimental and turned off by default.

   xSEMANTICS_USE_TRANSFORMER_LISTSxFALSE
   x

The next property is only useful if the previous one is set to true. Instead of computing the fix point of the convex hull of the transformer list, it computes the convex hull of the derivative constraints. Since it is a new feature, it is set to false by default, but it should become the default option because it should always be more accurate, at least indirectly because the systems are smaller. The number of overflows is reduced, as well as the execution time. In practice, these improvements have not been measured. This development is experimental and turned off by default.

   xSEMANTICS_USE_DERIVATIVE_LISTxFALSE
   x

The next property is only useful if Property SEMANTICS_USE_TRANSFORMER_LISTSx6.8.11.6 is set to true. Instead of computing the precondition derived from the transitive closure of a transformer list, semantics also computes the preconditions associated to different projections of the transformer list and use as loop precondition the intersection of these preconditions. Although it is a new feature, it is set to true by default for the validation’s sake. See test case Semantics/maisonneuve09.c: it improves the accuracy, but not as much as SEMANTICS_USE_DERIVATIVE_LISTx6.8.11.6. This development is experimental and turned off by default.

   xSEMANTICS_USE_LIST_PROJECTIONxTRUE

   The string Property SEMANTICS_LIST_FIX_POINT_OPERATORx6.8.11.6 is

used to select a particular heuristic to compute an approximation of the transitive closure of a list of transformers. It is only useful if Property SEMANTICS_USE_TRANSFORMER_LISTSx6.8.11.6 is selected. The current default value is “depthxtwo”. An experimental value is “maxxdepth”.

   xSEMANTICS_LIST_FIX_POINT_OPERATORx"depth_two"
   x

Preconditions can (used to) preserve initial values of the formal parameters. This is not often useful in C because programmers usually avoid modifying scalar parameters, especially integer ones. However, old values create problems in region computation because preconditions seem to be used instead of tranformer ranges. Filtering out the initial value does reduce the precision of the precondition analysis, but this does not impact the transformer analysis. Since the advantage is really limited to preconditions and for the region’s sake, the default value is set to true. Turn it to false if you have a doubt about the preconditions really available.

The loop index is usually dead on loop exit. So keeping information about its value is useless... most of the times. However, it is preserved by default.

   xSEMANTICS_KEEP_DO_LOOP_EXIT_CONDITIONxTRUE
   x
   xSEMANTICS_FILTER_INITIAL_VALUESxTRUE
   x

6.8.11.7 Normalization level

Normalizing transformer and preconditions systems is a delicate issue which is not mathematically defined, and as such is highly empirical. It’s a tradeoff between eliminating redundant information, keeping an internal storage not too far from the prettyprinting for non-regression testing, exposing useful information for subsequent analyses,... all this at a reasonable cost.

Several levels of normalization are possible. These levels do not correspond to graduations on a normalization scale, but are different normalization heuristics. A level of 4 includes a preliminary lexicographic sort of contraints, which is very user friendly, but currently implies strings manipulations which are quite costly. It has been recently chosen to perform this normalization only before storing transformers and

preconditions to the database (SEMANTICSxNORMALIZATIONxLEVELxBEFORExSTORAGE

with a default value of 4). However, this can still have a serious impact on performances. With any other value, the normalization level is equel to 2.

   xSEMANTICS_NORMALIZATION_LEVEL_BEFORE_STORAGEx4
   x

6.8.11.8 Prettyprint Preconditions reflect by default all knowledge gathered about the current state (i.e. store). However, it is possible to restrict the information to variables actually read or written, directly or indirectly, by the statement following the precondition.

   xSEMANTICS_FILTERED_PRECONDITIONSxFALSE
   x

6.8.11.9 Debugging

Output semantics results on stdout

   xSEMANTICS_STDOUTxFALSE
   x

Debug level for semantics used to be controlled by a property. A Shell variable,

SEMANTICS_DEBUG_LEVEL, is used instead.

6.9 Continuation conditions Continuation conditions are attached to each statement. They represent the conditions under which the program will not stop in this statement. Under- and over-approximations of these conditions are computed.

continuation_conditionsx>xMODULE.must_continuation
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.may_continuation
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.must_summary_continuation
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.may_summary_continuation
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xCALLEES.must_summary_continuation
xxxxxxxx<xCALLEES.may_summary_continuation

6.10 Complexities

Complexities are symbolic approximations of the execution times of statements. They are computed interprocedurally and based on polynomial approximations of execution times. Non-polynomial execution times are represented by unknown variables which are not free with respect to the program variables. Thus non-polynomial expressions are equivalent to polynomial expressions over a larger set of variables.

Probabilities for tests should also result in unknown variables (still to be implemented). Seex[?].

A summary_complexity is the approximation of a module execution times. It is translated and used at call sites.

Complexity estimation could be refined (i.e. the number of unknown variables reduced) by using transformers to combine elementary complexities using local states, rather than preconditions to combine elementary complexities relatively to the module initial state. The same options exist for region computation. The initial versionx[?] used the initial state for combinations. The new versionx[?] delays evaluation of variable values as long as possible but does not really use local states.

The first version of the complexity estimator was designed and developed by Pierre Berthomier. It was restricted to intra-procedural analysis. This first version was enlarged and validated on real code for SPARC-2 machines by Lei Zhoux[?]. Since, it has been modified slightly by Franx¿œois Irigoin. For simple programs, complexity estimation are strongly correlated with execution times. The estimations can be used to see if program transformations are beneficial.

Known bugs: tests and while loops are not correctly handled because a fixed probably of 0.5 is systematically assumed.

6.10.1 Menu for Complexities

aliasxcomplexitiesxxxxxx'Complexities'
aliasxuniform_complexitiesxxxxxx'Uniform'
aliasxfp_complexitiesxxx'FLOPs'
aliasxany_complexitiesxx'Any'

6.10.2 Uniform Complexities Complexity estimation is based on a set of basic operations and fixed execution times for these basic operation. The choice of the set is critical but fixed. Experiments by Lei Zhou showed that it should be enlarged. However, the basic times, which also are critical, are tabulated. New sets of tables can easily be developed for new processors.

Uniform complexity tables contain a unit execution time for all basic operations. They nevertheless give interesting estimations for SPARC SS-10, especially for -O2/-O3 optimized code.

uniform_complexitiesxxxxxxxxxxxxxxxxxxxx>xMODULE.complexities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.preconditions
xxxxxxxx<xCALLEES.summary_complexity

6.10.3 Summary Complexity

Local variables are eliminated from the complexity associated to the top statement of a module in order to obtain the modules’ summary complexity.

summary_complexityxxxxxxxxxxxxxx>xMODULE.summary_complexity
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.complexities

6.10.4 Floating Point Complexities Tables for floating point complexity estimation are set to 0 for non-floating point operations, and to 1 for all floating point operations, including intrinsics like SIN.

fp_complexitiesxxxxxxxxxxxxxxxxxxxx>xMODULE.complexities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.preconditions
xxxxxxxx<xCALLEES.summary_complexity

This enables the default specification within the properties to be considered.

any_complexitiesxxxxxxxxxxxxxxxxxxxx>xMODULE.complexities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.preconditions
xxxxxxxx<xCALLEES.summary_complexity

6.10.5 Complexity properties

The following properties control the static estimation of dynamic code execution time.

6.10.5.1 Debugging

Trace the walk across a module’s internal representation:

   xCOMPLEXITY_TRACE_CALLSxFALSE
   x

Trace all intermediate complexities:

xCOMPLEXITY_INTERMEDIATESxFALSE
x

Print the complete cost table at the beginning of the execution:

xCOMPLEXITY_PRINT_COST_TABLExFALSE
x

The cost table(s) contain machine and compiler dependent information about basic execution times, e.g. time for a load or a store.

6.10.5.2 Fine Tuning

It is possible to specify a list of variables which must remain literally in the complexity formula, although their numerical values are known (this is OK) or although they have multiple unknown and unrelated values during any execution (this leads to an incorrect result).

Formal parameters and imported global variables are left unevaluated. They have relatively high priority (FI: I do not understand this comment by

Lei).

This list should be empty by default (but is not for unknown historical reasons):

xCOMPLEXITY_PARAMETERSx"IMAX␣LOOP"
x

Controls the printing of accuracy statistics:

0: do not prettyprint any statistics with complexities (to give the user a false sense of accuracy and/or to avoid cluttering his/her display); this is the default value;

1: prettyprint statistics only for loop/block/test/unstr. statements and not for basic statements, since they should not cause accuracy problems;

2: prettyprint statistics for all statements

xCOMPLEXITY_PRINT_STATISTICSx0

6.10.5.3 Target Machine and Compiler Selection

This property is used to select a set of basic execution times. These times depend on the target machine, the compiler and the compilation options used. It is shown in [?] that fixed basic times can be used to obtain accurate execution times, if enough basic times are considered, and if the target machine has a simple RISC processor. For instance, it is not possible to use only one time for a register load. It is necessary to take into account the nature of the variable, i.e. formal parameter, dynamic variable, global variable, and the nature of the access, e.g. the dimension of an accessed array. The cache can be ignored an replacer by an average hit ratio.

Different set of elementary cost tables are available:

all_1: each basic operation cost is 1;

fp_1: only floating point operations are taken into account and have cost unit 1; all other operations have a null cost.

In the future, we might add a sparc-2 table...

The different elementary table names are defined in complexity-local.h. They

presently are operation, memory, index, transcend and trigo.

The different tables required are to be found in $PIPS_LIBDIR/complexity/xyz, where xyz is specified by this property:

   xCOMPLEXITY_COST_TABLEx"all_1"
   x

6.10.5.4 Evaluation Strategy

For the moment, we have designed two ways to solve the complexity combination problem. Since symbolic complexity formulae use program variables it is necessary to specify in which store they are evaluated. If two complexity formulae are computed relatively to two different stores, they cannot be directly added.

The first approach, which is implemented, uses the module initial store as universal store for all formulae (but possibly for the complexity of elementary statements). In some way, symbolic variable are evaluated as early as possible as soon as it is known that they won’t make it in the module summary complexity.

This first method is easy to implement when the preconditions are available but it has at least two drawbacks: if a variable is used in different places with the same unknown value, each occurrence will be replaced by a different unknown value symbol (the infamous UU_xx symbols in formulae).

since variables are replaced by numerical values as soon as possible as early as possible, the user is shown a numerical execution time instead of a symbolic formulae which would likely be more useful (see property COMPLEXITY_PARAMETERSx6.10.5.2). This is especially true with interprocedural constant propagation.

The second approach, which is not implemented, delay variable evaluation as late as possible. Complexities are computed and given relatively to the stores used by each statements. Two elementary complexities are combined together using the earliest store. The two stores are related by a transformer (see Sectionx6.8.11). Such an approach is used to compute MUST regions as precisely as possible (see Sectionx6.11.9).

A simplified version of the late evaluation was implemented. The initial store of the procedure is the only reference store used as with the early evaluation, but variables are not evaluated right away. They only are evaluated when it is necessary to do so. This not an ideal solution, but it is easy to implement and reduces considerably the number of unknown values which have to be put in the formulae to have correct results.

   xCOMPLEXITY_EARLY_EVALUATIONxFALSE
   x

6.11 Convex Array Regions

Convex array regions are functions mapping a memory store onto a convex set of array elements. They are used to represent the memory effects of modules or statements. Hence, they are expressed with respect to the initial store of the module or to the store immediately preceding the execution of the statement they are associated with. The latter is now standard in PIPS. Comprehensive information about convex array regions and their associated algorithms is available in Creusillet’s PhD Dissertationx[?].

Apart from the array name and its dimension descriptors (or ϕ variables), an array region contains three additional informations:

The type of the region: READ (R) or WRITE (W) to represent the effects of statements and procedures; IN and OUT to represent the flow of array elements.

The approximation of the region: EXACT when the region exactly represents the requested set of array elements, or MAY or MUST if it is an over- or under-approximation (MUST ⊆ EXACT ⊆ MAY).

Unfortunately, for historical reasons, MUST is still used in the implementation instead of EXACT, and actual MUST regions are not computed. Moreover, the mustxregions option in fact computes exact and may regions.

MAY regions are flow-insensitive regions, whereas MUST regions are flow sensitive. Any array element touched by any execution of a statement is in the MAY region of this statement. Any array element in the MUST region of a statement is accessed by any execution of this statement.

a convex polyhedron containing equalities and inequalities: they link the ϕ variables that represent the array dimensions, to the values of the program integer scalar variables.

For instance, the convex array region:

xx

xx<A(ϕ_{1},ϕ_{2})-W-EXACT-{ϕ_{1}==I,xϕ_{1}==ϕ_{2}}>

where the region parameters ϕ_{1} and ϕ_{2} respectively represent the first and second dimensions of A, corresponds to an assignment of the element A(I,I).

Internally, convex array regions are of type effect and as such can be used to build use-def chains (see Sectionx6.4.3). Regions chains are built using proper regions which are particular READ and WRITE regions. For simple statements (assignments, calls to intrinsic functions), summarization is avoided to preserve accuracy. At this inner level of the program control flow graph, the extra amount of memory necessary to store regions without computing their convex hull should not be too high compared to the expected gain for dependence analysis. For tests and loops, proper regions contain the regions associated to the condition or the range. And for external calls, proper regions are the summary regions of the callee translated into the caller’s name space, to which are merely appended the regions of the expressions passed as argument (no summarization for this step).

Together with READ/WRITE regions and IN regions are computed their invariant

versions for loop bodies (MODULE.invxregions and MODULE.invxinxregions). For a

given loop body, they are equal to the corresponding regions in which all variables that may be modified by the loop body (except the current loop index) are eliminated from the descriptors (convex polyhedron). For other statements, they are equal to the empty list of regions.

In the following trivial example,

kx=x 0 ; xfor ( i =0;x i<N; x i++)x{x//x r e g i o n s x f o r x loop x body : x//xxxx<a [ phi1 ]−W−EXACT−{PHI1=K,K=I}>x//x i n v a r i a n t x r e g i o n s x f o r x loop x body : x//xxxx<a [ phi1 ]−W−EXACT−{PHI1=I}>xxxkx=xk+1;xxxa [ k ] x=xk ; x}

notice that the variable k which is modified in the loop body, and which appears in the loop body region polyhedron, does not appear anymore in the invariant region polyhedron.

MAY READ and WRITE region analysis was first designed by Rx¿œmi Trioletx[?] and then revisited by Franx¿œois Irigoinx[?]. Alexis Platonoffx[?] implemented the first version of region analysis in PIPS. These regions were computed with respect to the initial stores of the modules. Franx¿œois Irigoin and, mainly, Bx¿œatrice Creusilletx[?,x?,x?], added new functionalities to this first version as well as functions to compute MUST regions, and IN and OUT regions.

Array regions for C programs are currently under development.

6.11.1 Menu for Convex Array Regions

aliasxregionsx'Arrayxregions'
aliasxmay_regionsx'MAYxregions'
aliasxmust_regionsx'EXACTxorxMAYxregions'

6.11.2 MAY READ/WRITE Convex Array Regions

This function computes the MAY pointer regions in a module.

may_pointer_regionsxxxxxxxxxxxxx>xMODULE.proper_pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_pointer_regions
xxxxxxxx<xPROGRAM.entities

xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_pointer_regions

This function computes the MAY regions in a module.

may_regionsxxxxxxxxxxxxxxxxxxxxx>xMODULE.proper_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_regions

6.11.3 MUST READ/WRITE Convex Array Regions

This function computes the MUST regions in a module.

must_pointer_regionsxxxxxxxxxxxx>xMODULE.proper_pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_pointer_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_pointer_regions

This function computes the MUST pointer regions in a module using simple pointsxto information to disambiguate dereferencing paths.

must_pointer_regions_with_points_tox>xMODULE.proper_pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.pointer_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_pointer_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.points_to_list
xxxxxxxx<xCALLEES.summary_pointer_regions

This function computes the MUST regions in a module.

must_regionsxxxxxxxxxxxxxxxxxxxx>xMODULE.proper_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_regions

This function computes the MUST regions in a module.

must_regions_with_points_toxxxxx>xMODULE.proper_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_regions

6.11.4 Summary READ/WRITE Convex Array Regions

Module summary regions provides an approximation of the effects it’s execution has on its callers variables as well as on global and static variables of its callees.

summary_pointer_regionsxxxxxxxxxxxxxxxxx>xMODULE.summary_pointer_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.pointer_regions

summary_regionsxxxxxxxxxxxxxxxxx>xMODULE.summary_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions

6.11.5 IN Convex Array Regions

IN convex array regions are flow sensitive regions. They are read regions not covered (i.e. not previously written) by assignments in the local hierarchical control-flow graph. There is no way with the current pipsmake-rc and pipsmake to express the fact that IN (and OUT) regions must be calculated using must_regionsx6.11.3 (a new kind of resources, must_regionsx6.11.3, should be added). The user must be knowledgeable enough to select must_regionsx6.11.3 first.

in_regionsxxxxxxxxxxxxxxxxxxxxxx>xMODULE.in_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.cumulated_in_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.inv_in_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.inv_regions
xxxxxxxx<xCALLEES.in_summary_regions

6.11.6 IN Summary Convex Array Regions

This pass computes the IN convex array regions of a module. They contain the array elements and scalars whose values impact the output of the module.

in_summary_regionsxxxxxxxxxxxxxx>xMODULE.in_summary_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.in_regions

6.11.7 OUT Summary Convex Array Regions

This pass computes the OUT convex array regions of a module. They contain the array elements and scalars whose values impact the continuation of the module.

See Sectionx6.11.8.

out_summary_regionsxxxxxxxxxxxxx>xMODULE.out_summary_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.out_regions

6.11.8 OUT Convex Array Regions

OUT convex array regions are also flow sensitive regions. They are downward exposed written regions which are also used (i.e. imported) in the continuation of the program. They are also called exported regions. Unlike READ, WRITE and IN regions, they are propagated downward in the call graph and in the hierarchical control flow graphs of the subroutines.

out_regionsxxxxxxxxxxxxxxxxxxxxx>xMODULE.out_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.inv_regions
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.cumulated_in_regions
xxxxxxxx<xMODULE.inv_in_regions
xxxxxxxx<xMODULE.out_summary_regions

6.11.9 Properties for Convex Array Regions If MUSTxREGIONS is true, then it computes convex array regions using the algorithm described in report E/181/CRI, called T^{−1} algorithm. It provides more accurate regions, and preserve MUST approximations more often. As it is more costly, its default value is FALSE. EXACTxREGIONS is true for the moment for backward compatibility only.

   xEXACT_REGIONSxTRUE
   x
   xMUST_REGIONSxFALSE
   x

The default option is to compute regions without taking into account array bounds. The next property can be turned to TRUE to systematically add them in the region descriptors. Both options have their advantages and drawbacks.

   xREGIONS_WITH_ARRAY_BOUNDSxFALSE
   x

Property MEMORY_IN_OUT_REGIONS_ONLYx6.11.9’s default value is set to TRUE to avoid computing IN and OUT regions on non-memory effects, even if

MEMORY_EFFECTS_ONLYx6.2.7 is set to FALSE.
   xMEMORY_IN_OUT_REGIONS_ONLYxTRUE
   x

The current implementation of effects, simple effects as well as convex array regions, relies on a generic engine which is independent of the effect descriptor representation. The current representation for array regions, parameterized integer convex polyhedra, allows various patterns an provides the ability to exploit context information at a reasonable expense. However, some very common patterns such as nine-point stencils used in seismic computations or red-black patterns cannot be represented. It has been a long lasting temptation to try other representationsx[?].

A Complementary sections (see Sectionx6.13) implementation was formerly began as a set of new phases by Manjunathaiah Muniyappa, but is not maintained anymore.

And Nga Nguyen more recently created two properties to switch between regions and disjunctions of regions (she has already prepared basic operators). For the moment, they are always FALSE.

   xDISJUNCT_REGIONSxFALSE
   x
   xDISJUNCT_IN_OUT_REGIONSxFALSE
   x

Statistics may be obtained about the computation of convex array regions. When the next property (REGIONSxOPxSTATISTICS) is set to TRUE statistics are provided about operators on regions (union, intersection, projection,x). The second next property turns on the collection of statistics about the interprocedural translation.

   xREGIONS_OP_STATISTICSxFALSE
   x
   xREGIONS_TRANSLATION_STATISTICSxFALSE
   x

6.12 Alias Analysis

6.12.1 Dynamic Aliases

Dynamic aliases are pairs (formal parameter, actual parameter) of convex array regions generated at call sites. An “IN alias pair” is generated for each IN region of a called module and an “OUT alias pair” for each OUT region. For EXACT regions, the transitive, symmetric and reflexive closure of the dynamic alias relation results in the creation of equivalence classes of regions (for MAY regions, the closure is different and does not result in an equivalence relation, but nonetheless allows us to define alias classes). A set of alias classes is generated for a module, based on the IN and OUT alias pairs of all the modules below it in the callgraph. The alias classes for the whole workspace are those of the module which is at the root of the callgraph, if the callgraph has a unique root. As an intermediate phase between the creation of the IN and OUT alias pairs and the creation of the alias classes, “alias lists” are created for each module. An alias list for a module is the transitive closure of the alias pairs (IN or OUT) for a particular path through the callgraph subtree rooted in this module.

in_alias_pairsx>xMODULE.in_alias_pairs
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xCALLERS.code
xxxxxxxx<xCALLERS.cumulated_effects
xxxxxxxx<xCALLERS.preconditions
out_alias_pairsx>xMODULE.out_alias_pairs
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xCALLERS.code

xxxxxxxx<xCALLERS.cumulated_effects
xxxxxxxx<xCALLERS.preconditions
alias_listsx>xMODULE.alias_lists
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.in_alias_pairs
xxxxxxxx<xMODULE.out_alias_pairs
xxxxxxxx<xCALLEES.alias_lists
alias_classesx>xMODULE.alias_classes
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.alias_lists

6.12.2 Intraprocedural Summary Points to Analysis This phase generates synthetic points-to relations for formal parameters. It creates synthetic sinks, i.e. stubs, for formal parameters and provides an initial set of

points-to to the points_to_analysisx??.

Currently, it assumes that no sharing exists between the formal parameters and within the data structures pointed to by the formal parameters. Two properties

should control this behavior, ALIASING_ACROSS_FORMAL_PARAMETERSx6.12.5

and ALIASING_ACROSS_TYPESx6.12.5. The first one supersedes the property

ALIASING_INSIDE_DATA_STRUCTUREx6.12.5.

aliasxintraprocedural_summary_points_to_analysisxx'IntraproceduralxSummaryxPointsxToxAnalysis'
intraprocedural_summary_points_to_analysisx>xMODULE.summary_points_to_list
xxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxx<xMODULE.code

6.12.3 Points to Analysis

This function is being implemented by Amira Mensi. The points_to_analysisx?? is implemented in order to compute points-to relations, based on Emami algorithm. Emami algorithm is a top-down analysis which calcules the points-to relations by applying specific rules to each assignement pattern identified. This phase requires

another resource which is intraprocedural_summary_points_to_analysisx??.

aliasxpoints_to_analysisxx'PointsxToxAnalysis'
points_to_analysisx>xMODULE.points_to_list
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.summary_points_to_list

The pointer effects are useful, but they are recomputed for each expression and subexpression by the points-to analysis.

6.12.4 Pointer Values Analyses

Pointer values analysis is another kind of pointer analysis which tries to gather Pointer Values both in terms of other pointer values but also of memory addresses. This phase is under development.

aliasxsimple_pointer_valuesxx'PointerxValuesxAnalysis'
simple_pointer_valuesx>xMODULE.simple_pointer_values
xxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxx<xMODULE.code

6.12.5 Properties for pointer analyses The following properties are defined to ensure the safe use of points_to_analysisx??.

The property ALIASING_ACROSS_TYPESx6.12.5 specifies that two pointers of different effective types can be aliased. The default and safe value is TRUE; when it is turned to FALSE two pointers of different types are never aliased.

   xALIASING_ACROSS_TYPESxTRUE

The property ALIASING_ACROSS_FORMAL_PARAMETERSx6.12.5 is used to handle the aliasing between formal parameters and global variables of pointer type. When it is set to TRUE, two formal parameters or a formal one and a global pointer or two global pointers can be aliased. If it is turned to FALSE, such pointers are assumed to be unaliased for intraprocedural analysis and generally for root module(i.e. modules without callers). The default value is FALSE. It is the only value currently implemented.

   xALIASING_ACROSS_FORMAL_PARAMETERSxFALSE
   x

The nest property specifies that one data structure can recursively contain two pointers pointing to the same location. If it is turned to FALSE, it is assumed that two different not included memory access paths cannot point to the same memory locations. The safe value is TRUE, but parallelization is hindered. Often, the user can guarantee that data structures do not exhibit any sharing. Optimistically, FALSE is the default value.

   xALIASING_INSIDE_DATA_STRUCTURExFALSE
   x
   Property ALIASING_ACROSS_IO_STREAMSx6.12.5 can be set to FALSE to

specify that two io streams (two variables declared as FILE *) cannot be aliased, neither the locations to which they point. The safe and default value is

TRUE
   xALIASING_ACROSS_IO_STREAMSxTRUE
   x

The following string property defines the lattice of maximal elements to use when precise information is lost. Three values are possible: ”unique”, ”function” and ”area”. The first value is the default value. A unique identifier is defined to represent any set of unknown locations. The second value defines a separate identifier for each function and compilation unit. Note that compilation units require more explanation about this definition and about the conflict detection scheme. The third value, ”area”, requires a separate identifier for each area of each function or compilation unit. These abstract lcoation lattice values are further refined if the property ALIASING_ACROSS_TYPESx6.12.5 is set to FALSE. The abstract location API hides all these local maximal values from its callers. Note that the dereferencing of any such top abstract location returns the very top of all abstract locations.

The ABSTRACT_HEAP_LOCATIONSx6.12.5 specifies the modeling of the heap. The possible values are ”unique”, ”insensitive”, ”flow-sensitive” and ”context-sensitive”. Each value defines a stricly refined analysis with respect to analyses defined by previous values [This may not be a good idea, since flow and context sensitivity are orthogonal].

The default value, ”unique”, implies that the heap is a unique array. It is enough to parallelize simple loops containing pointer-based references such as ”p[i]”.

In the ”insensitive” case and all other cases, one array is allocated in each function to modelize the heap.

In the ”flow-sensitive” case, the statement numbers of the malloc() call sites are used to subscribe this array, as well as all indices of the surrounding loops [Two improvements in one property...].

In the ”contextxsensitive” case, the interprocedural translation of memory acces paths based on the abstract heap are prefixed by the same information regarding the call site: function containing the call site, statement number of the call site and indices of surrounding loops.

Note that the naming of options is not fully compatible with the usual notations in pointer analyses. Note also that the insensitive case is redundant with context sensitive case: in the later case, a unique heap associated to malloc() would carry exactly the same amount of information [flow and context sensitivity are orthogonal].

Finally, note that abstract heap arrays are distinguished according to their types if the property ALIASING_ACROSS_TYPESx6.12.5 is set to FALSE [impact on abstract heap location API]. Else, the heap array is of type unknown. If a heap abstract location is dereferenced without any point-to information nor heap aliasing information, the safe result is the top abstract location.

   xABSTRACT_HEAP_LOCATIONSx"unique"
   x
   The property POINTS_TO_UNINITIALIZED_POINTER_DEREFERENCINGx6.12.5

specifies that we are dereferencing an uninitialized pointer. The safe value is TRUE and it stops the analysis with a pipsxuserxerror. However the default value is FALSE which arises a pipsxuserxwarning and we continue the analysis, it’s due to dead code: we don’t have to stop the analysis if a dereferencing will never be executed.

   xPOINTS_TO_UNINITIALIZED_POINTER_DEREFERENCINGxFALSE
   x

The property POINTS_TO_STRICT_POINTER_TYPESx6.12.5 is used to handle pointer arithmetic. According to C standard(section 6.5.6, item 8) the following C code :

intx*p,xi;
xpx=x\&i;
xp++x;

is correct and p points to the same area, expressed by the points to analysis as i[*]. The default value is FALSE, meaning that p points to an array element. When it’s set to TRUE typing becone strict ; meaning that p points to an integer and the behavior is undefined. So the analysis stops with a pipsxuserxerror(illegal pointer arithmetic)

   xPOINTS_TO_STRICT_POINTER_TYPESxFALSE
   x

The integer property POINTS_TO_K_LIMITINGx6.12.5 specifies the maximum authorized length of an access path. Beyond this value the access path is changed into an ANYWHERE. This property is necessary while computing points to relations inside loops and it’s default value is 10.

   xPOINTS_TO_K_LIMITINGx10
   x

6.12.6 Menu for Alias Views

aliasxalias_filex'AliasxView'
aliasxprint_in_alias_pairsx'InxAliasxPairs'
aliasxprint_out_alias_pairsx'OutxAliasxPairs'
aliasxprint_alias_listsx'AliasxLists'
aliasxprint_alias_classesx'AliasxClasses'

Display the dynamic alias pairs (formal region, actual region) for the IN regions of the module.

print_in_alias_pairsx>xMODULE.alias_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.in_alias_pairs

Display the dynamic alias pairs (formal region, actual region) for the OUT regions of the module.

print_out_alias_pairsx>xMODULE.alias_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.out_alias_pairs

Display the transitive closure of the dynamic aliases for the module.

print_alias_listsx>xMODULE.alias_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.alias_lists

Display the dynamic alias equivalence classes for this module and those below it in the callgraph.

print_alias_classesx>xMODULE.alias_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.alias_classes

6.13 Complementary Sections

aliasxcompsecx'ComplementaryxSections'

A new representation of array regions added in PIPS by Manjunathaiah Muniyappa. This anlysis is not maintained anymore.

6.13.1 READ/WRITE Complementary Sections This function computes the complementary sections in a module.

complementary_sectionsx>xMODULE.compsec
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xCALLEES.summary_compsec

6.13.2 Summary READ/WRITE Complementary Sections

summary_complementary_sectionsx>xMODULE.summary_compsec
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.compsec

Chapterx7Parallelization and Distribution

7.1 Code Parallelization

PIPS basic parallelization function, rice_all_dependencex7.1.3, produces a new version of the Module code with DOALL loops exhibited using Allen & Kennedy’s algorithm. The DOALL syntactic construct is non-standard but easy to understand and usual in text book like [?]. As parallel prettyprinter option, it is possible to use Fortranx90 array syntax (see Sectionx9.4). For C, the loops can be output as for-loop decorated with OpenMP pragma.

Remember that Allen & Kennedy’s algorithm can only be applied on loops with simple bodies, i.e. sequences of assignments, because it performs loop distribution and loop regeneration without taking control dependencies into account. If the loop body contains tests and branches, the coarse grain parallelization algorithm should be used (see 7.1.6).

Loop index variables are privatized whenever possible, using a simple algorithm. Dependence arcs related to the index variable and stemming from the loop body must end up inside the loop body. Else, the loop index is not privatized because its final value is likely to be needed after the loop end and because no copy-out scheme is supported.

A better privatization algorithm for all scalar variable may be used as a preliminary code transformation. An array privatizer is also available (see Sectionx8.11.2). A non-standard PRIVATE declaration is used to specify which variables should be allocated on stack for each loop iteration. An HPF or OpenMP format can also be selected.

Objects of type parallelized_code differs from objects of type code for historic reasons, to simplify the user interface and because most algorithms cannot be applied on DOALL loops. This used to be true for pre-condition computation, dependence testing and so on... It is possible neither to re-analyze parallel code, nor to re-parse it (although it would be interesting to compute the complexity of a parallel code) right now but it should evolves. See §x7.1.8.

7.1.1 Parallelization properties

There are few properties that control the parallelization behaviour.

7.1.1.1 Properties controlling Rice parallelization TRUE to make all possible parallel loops, FALSE to generate real (vector, innermost parallel?) code:

   xGENERATE_NESTED_PARALLEL_LOOPSxTRUE
   x

Show statistics on the number of loops parallelized by pips:

   xPARALLELIZATION_STATISTICSxFALSE
   x

To select whether parallelization and loop distribution is done again for already parallel loops:

   xPARALLELIZE_AGAIN_PARALLEL_CODExFALSE
   x

The motivation is we may want to parallelize with a coarse grain method first, and finish with a fine grain method here to try to parallelize what has not been parallelized. When applying x¿œ la Rice parallelizing to parallelize some (still) sequential code, we may not want loop distribution on already parallel code to preserve cache resources, etc.

Thread-safe libraries are protected by critical sections. Their functions can be called safely from different execution threads. For instance, a loop whose body contains calls to malloc can be parallelized. The underlying state changes do no hinder parallelization, at least if the code is not sensitive to pointer values.

   xPARALLELIZATION_IGNORE_THREAD_SAFE_VARIABLESxFALSE
   x

Since this property is used to mask arcs in the dependence graph, it must be exploited by each parallelization phase independently. It is not used to derived a simplified version of the use-def chains or of the dependence graph to avoid wrong result with use-def elimination, which is based on the same graph.

7.1.2 Menu for Parallelization Algorithm Selection Entries in menu for the resource parallelized_code and for the different parallelization algorithms with may be activated or selected. Note that the nest parallelization algorithm is not debugged.

aliasxparallelized_codex'Parallelization'
aliasxrice_all_dependencex'AllxDependences'
aliasxrice_data_dependencex'TruexDependencesxOnly'
aliasxrice_crayx'CRAYxMicrotasking'
aliasxnest_parallelizationx'LoopxNestxParallelization'
aliasxcoarse_grain_parallelizationx'CoarsexGrainxParallelization'
aliasxinternalize_parallel_codex'Considerxaxparallelxcodexasxaxsequentialxone'

7.1.3 Allen & Kennedy’s Parallelization Algorithm

Use Allen & Kennedy’s algorithm and consider all dependences.

rice_all_dependencexxxxxxxxxxxxx>xMODULE.parallelized_code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.dg

7.1.4 Def-Use Based Parallelization Algorithm Several other parallelization functions for shared-memory target machines are available. Function rice_data_dependencex7.1.4 only takes into account data flow dependences, a.k.a true dependences. It is of limited interest because transitive dependences are computed. It is not equivalent at all to performing array and scalar expansion based on direct dependence computation (Brandes, Feautrier, Pugh). It is not safe when privatization is performed before parallelization.

This phase is named after the historical classification of data dependencies in output dependence, anti-dependence and true or data dependence. It should not be used for standard parallelization, but only for experimental parallelization by knowledgeable users, aware that the output code may be illegal.

rice_data_dependencexxxxxxxxxxxx>xMODULE.parallelized_code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.dg

7.1.5 Parallelization and Vectorization for Cray Multiprocessors

Function rice_crayx7.1.5 targets Cray vector multiprocessors. It selects one outermost parallel loop to use multiple processors and one innermost loop for the vector units. It uses Cray microtasking directives. Note that a prettyprinter option must also be selected independently (see Sectionx9.4).

rice_crayxxxxxxxxxxxxxxxxxxx>xMODULE.parallelized_code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.dg

7.1.6 Coarse Grain Parallelization Function coarse_grain_parallelizationx7.1.6 implements a loop parallelization algorithm based on convex array regions. It considers only one loop at a time, its body being abstracted by its invariant read and write regions. No loop distribution is performed, but any kind of loop body is acceptable whereas Allen & Kennedy algorithm only copes with very simple loop bodies.

For nasty reasons about effects that are statement addresses to effects mapping, this pass changes the code instead of producing a parallelized_code resource. It is not a big deal since often we want to modify the code again and we should use internalize_parallel_codex7.1.8 just after if its behavior were modified.

coarse_grain_parallelizationx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.inv_regions

   Function coarse_grain_parallelization_with_reductionx7.1.6 extend the

standard coarse_grain_parallelizationx7.1.6 by using reduction detection informations.

coarse_grain_parallelization_with_reductionx>xMODULE.reduction_parallel_loops
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.cumulated_reductions
xxxxxxxx<xMODULE.proper_reductions
xxxxxxxx<xMODULE.inv_regions

7.1.7 Global Loop Nest Parallelization Function nest_parallelizationx7.1.7 is an attempt at combining loop transformations and parallelization for perfectly nested loops. Different parameters are computed like loop ranges and contiguous directions for references. Loops with small ranges are fully unrolled. Loops with large ranges are strip-mined to obtain vector and parallel loops. Loops with medium ranges simply are parallelized. Loops with unknown range also are simply parallelized.

For each loop direction, the amount of spatial and temporal localities is estimated. The loop with maximal locality is chosen as innermost loop.

This algorithm still is in the development stage. It can be tried to check that loops are interchanged when locality can be improvedInternship!. An alternative for static control section, is to use the interface with PoCC (see Sectionx??).

nest_parallelizationxxxxxxxxxxxxxxxxxxxx>xMODULE.parallelized_code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.codexMODULE.dg

7.1.8 Coerce Parallel Code into Sequential Code To simplify the user interface and to display with one click a parallelized program, programs in PIPS are (parallelized code) instead of standard (code.PV:not clear As a consequence, parallelized programs cannot be further analyzed and transformed because sequential code and parallelized code do not have the same resource type. Most pipsmake rules apply to code but not to parallelized code. Unfortunately, improving the parallelized code with some other transformations such as dead-code elimination is also useful. Thus this pseudo-transformation is added to coerce a parallel code into a classical (sequential) one. Parallelization is made an internal code transformation in PIPS with this rule.

Although this is not the effective process, parallel loops are tagged as parallel and loop local variables may be added in a code resource because of a previous privatization phase.

If you display the “generated” code, it may not be displayed as a parallel one if the PRETTYPRINT_SEQUENTIAL_STYLEx9.2.21.3.2 is set to a parallel output style (such as omp). Anyway, the information is available in code.

Note this transformation may no be usable with some special parallelizations in PIPS such as WP65 or HPFC that generate other resource types that may be quite different.

internalize_parallel_codexxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xMODULE.parallelized_code

7.1.9 Detect Computation Intensive Loops Generate a pragma on each loop that seems to be computation intensive according to a simple cost model.

The computation intensity is derived from the complexity and the memory footprint. It assumes the cost model:

. executionxtime = startupxoverhead + \frac{memoryxfootprint}{bandwidth} + \frac{complexity}{frequency}

A loop is marked with pragma COMPUTATION_INTENSITY_PRAGMAx7.1.9 if the communication costs are lower than the execution cost as given by

uniform_complexitiesx6.10.2.

computation_intensityx>xMODULE.code
<xMODULE.code
<xMODULE.regions
<xMODULE.complexities

This correspond to the transfer startup overhead. Time unit is the same as in complexities.

   xCOMPUTATION_INTENSITY_STARTUP_OVERHEADx10
   x

This corresponds to the memory bandwidth in octet per time unit.

   xCOMPUTATION_INTENSITY_BANDWIDTHx100
   x

And This is the processor frequency, in operation per time unit.

   xCOMPUTATION_INTENSITY_FREQUENCYx1000
   x

This is the generated pragma.

   xCOMPUTATION_INTENSITY_PRAGMAx"pips␣intensive␣loop"
   x

Those values have limited meaning here, only their ratio have some. Having

COMPUTATION_INTENSITY_FREQUENCYx7.1.9 and COMPUTATION_INTENSITY_BANDWIDTHx7.1.9

of the same magnitude clearly limits the number of generated pragmasx

7.1.10 Limit Parallelism in Parallel Loop Nests This phase restricts the parallelism of parallel do-loop nests by limiting the number of top-level parallel do-loops to be below a given limit. The too many innermost parallel loops are replaced by sequential loops, if any. This is useful to keep enough coarse-grain parallelism and respecting some hardware or optimization constraints. For example on GPU, in CUDA there is a 2D limitation on grids of thread blocks, in OpenCL it is limited to 3D. Of course, since the phase works onto parallel loop nest, it might be interesting to use a parallelizing phase such as internalizexparallelxcode (see §x7.1.8) or coarse grain parallelization before applying limitxnestedxparallelism.

limit_nested_parallelismxxxxxxxxxx>xMODULE.code
xxxxxxxx<xMODULE.code

PIPS relies on the property NESTED_PARALLELISM_THRESHOLDx7.1.10 to determine the desired level of nested parallelism.

   xNESTED_PARALLELISM_THRESHOLDx0
   x

7.2 SIMDizer for SIMD Multimedia Instruction Set

The SAC project aims at generating efficient code for processors with SIMD extension instruction set such as VMX, SSE4, etc. which are also refered to as Superword Level Parallelism (SLP). For more information, see

https://info.enstb.org/projets/sac.

Some phases use ACCEL_LOADx7.2 and ACCEL_STOREx7.2 to generate DMA calls

and ACCEL_WORKx7.2.
   xACCEL_LOADx"SIMD_LOAD"
   x
   xACCEL_STOREx"SIMD_STORE"
   x
   xACCEL_WORKx"SIMD_"
   x

Here is yet another atomizer, based on newxatomizer (see Sectionx8.4.1.2), used to reduce complex statements to three-address code close to assembly code. There are only some minor differences with respect to newxatomizer, except that it does not break down simple expressions, that is, expressions that are the sum of a reference and a constant such as tt i+1. This is needed to generate code that could potentially be efficient, whereas the original atomizer would most of the time generate inefficient code.

aliasxsimd_atomizerx'SIMDxAtomizer'

simd_atomizerxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

   Use the SIMD_ATOMIZER_ATOMIZE_REFERENCEx7.2 property to make the SIMD

Atomizer go wild: unlike other atomizer, it will break the content of a reference. SIMD_ATOMIZER_ATOMIZE_LHSx7.2 can be used to tell the atomizer to atomize both lhs and rhs.

   xSIMD_ATOMIZER_ATOMIZE_REFERENCExFALSE
   x
   xSIMD_ATOMIZER_ATOMIZE_LHSxFALSE
   x
   The SIMD_OVERRIDE_CONSTANT_TYPE_INFERENCEx7.2 property is used by the sac

library to know if it must override C constant type inference. In C, an integer constant always as the minimum size needed to hold its value, starting from an int. In sac we may want to have it converted to a smaller size, in situation like charxb;/∗...∗/;charxax=x2x+xb;. Otherwise the result of 2+b is considered as an

int. if SIMD_OVERRIDE_CONSTANT_TYPE_INFERENCEx7.2 is set to TRUE, the result of

2+b will be a char.

   xSIMD_OVERRIDE_CONSTANT_TYPE_INFERENCExFALSE
   x

Tries to unroll the code for making the simdizing process more efficient. It thus tries to compute the optimal unroll factor, allowing to pack the most instructions

together. Sensible to SIMDIZER_AUTO_UNROLL_MINIMIZE_UNROLLx7.2.1.1 and
SIMDIZER_AUTO_UNROLL_SIMPLE_CALCULATIONx7.2.1.1.

aliasxsimdizer_auto_unrollx'SIMD-AutoxUnroll'
simdizer_auto_unrollxxxxxxxx>xMODULE.code
<xPROGRAM.simd_treematch
<xPROGRAM.simd_operator_mappings
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Similiar to simdizer_auto_unrollx7.2 but at the loop level.

Sensible to LOOP_LABELx8.1.1.

loop_auto_unrollxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Tries to tile the code to make the simdizing process more efficient.

Sensible to LOOP_LABELx8.1.1 to select the loop nest to tile.

simdizer_auto_tilexxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.code

This phase tries to pre-process reductions, so that they can be vectorized efficiently by the simdizerx7.2 phase. When multiple reduction statements operating on the same variable with the same operation are detected inside a loop body, each “instance” of the reduction is renamed, and some code is added before and after the loop to initialize the new variables and compute the final result.

aliasxsimd_remove_reductionsx'SIMDxRemovexReductions'
simd_remove_reductionsxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.simdizer_init
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_reductions
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

   xSIMD_REMOVE_REDUCTIONS_PREFIXx"RED"
   x
   xSIMD_REMOVE_REDUCTIONS_PRELUDEx""

   xSIMD_REMOVE_REDUCTIONS_POSTLUDEx""
   x

Remove useless load store calls (and more)

redundant_load_store_eliminationxxxxxx>xMODULE.code
>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.chains

   If REDUNDANT_LOAD_STORE_ELIMINATION_CONSERVATIVEx7.2 is set to false,

redundant_load_store_eliminationx7.2 will remove any statement not implied in the computation of out regions, otherwise it will not remove statement that modifies aprameters reference.

   xREDUNDANT_LOAD_STORE_ELIMINATION_CONSERVATIVExTRUE
   x

...

aliasxdeatomizerx'Deatomizer'
deatomizerxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.dg

This phase is the first phase of the if-conversion algorithm. The complete if conversion algorithm is performed by applying the three following phase:

if_conversion_initx7.2, if_conversionx7.2 and if_conversion_compactx7.2.

Use IF_CONVERSION_INIT_THRESHOLDx7.2 to control whether if conversion will occur or not: beyhond this number of call, no conversion is done.

   xIF_CONVERSION_INIT_THRESHOLDx40
   x

aliasxif_conversion_initx'If-conversionxinit'
if_conversion_initxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.summary_complexity

This phase is the second phase of the if-conversion algorithm. The complete if conversion algorithm is performed by applying the three following phase:

if_conversion_initx7.2, if_conversionx7.2 and if_conversion_compactx7.2.

   xIF_CONVERSION_PHIx"__C-conditional__"
   x

aliasxif_conversionx'If-conversion'
if_conversionxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

This phase is the third phase of the if-conversion algorithm. The complete if conversion algorithm is performed by applying the three following phase:

if_conversion_initx7.2, if_conversionx7.2 and if_conversion_compactx7.2.

aliasxif_conversion_compactx'If-conversionxcompact'
if_conversion_compactxxxxxxxxxxxxxxxxxx>xMODULE.code

xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.dg

Converts max in loop bounds into tests. Also sets variable so that simplify_controlx8.3.1 works afterwards.

loop_nest_unswitchingxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This phase tries to minimize dependencies in the code by renaming scalars when legal.

scalar_renamingxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.dg
xxxxxxxx<xMODULE.proper_effects

This function initialize a treematch used by simdizerx7.2 for simd-oriented pattern matching

simd_treematcherx>xPROGRAM.simd_treematch

This function initialize operator matchings used by simdizerx7.2 for simd-oriented pattern matching

simd_operator_mappingsx>xPROGRAM.simd_operator_mappings

simdizer_initxx>xMODULE.code
<xPROGRAM.entities
<xMODULE.code

Function simdizerx7.2 is an attempt at generating SIMD code for SIMD multimedia instruction set such as MMX, SSE2, VIS,... This transformation performs the core vectorization, transforming sequences of similar statements into vector operations.

aliasxsimdizerx'GeneratexSIMDxcode'
simdizerxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
!xMODULE.simdizer_init
<xPROGRAM.simd_treematch
<xPROGRAM.simd_operator_mappings
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

When set to true, following property tells the simdizer to try to padd arrays when it seems to be profitable

   xSIMDIZER_ALLOW_PADDINGxFALSE
   x

Skip generation of load and stores, using generic functions instead.

   xSIMDIZER_GENERATE_DATA_TRANSFERSxTRUE
   x

This phase is to be called after simdization of affectation operator. It performs type substitution from char/short array to in array using the packing from the simdization phase For example, four consecutive load from a char array could be a single load from an int array. This prove to be useful for c to vhdl compilers such as

c2h.

aliasxsimd_memory_packingx'GeneratexOptimizedxLoadxStore'
simd_memory_packingxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

7.2.1 SIMD properties This property is used to set the target register size, expressed in bits, for places where this is needed (for instance, auto-unroll with simple algorithm).

   xSAC_SIMD_REGISTER_WIDTHx64
   x

7.2.1.1 Auto-Unroll This property is used to control how the auto unroll phase computes the unroll factor. By default, the minimum unroll factor is used. It is computed by using the minimum of the optimal factor for each statement. If the property is set to FALSE, then the maximum unroll factor is used instead.

   xSIMDIZER_AUTO_UNROLL_MINIMIZE_UNROLLxTRUE
   x

This property controls how the “optimal” unroll factor is computed. Two algorithms can be used. By default, a simple algorithm is used, which simply compares the actual size of the variables used to the size of the registers to find out the best unroll factor. If the property is set to FALSE, a more complex algorithm is used, which takes into account the actual SIMD instructions.

   xSIMDIZER_AUTO_UNROLL_SIMPLE_CALCULATIONxTRUE
   x

7.2.1.2 Memory Organisation This property is used by the sac library to know which elements of multi-dimensional array are consecutive in memory. Let us consider the three following references a(i,j,k), a(i,j,k+1) and a(i+1,j,k). Then, if SIMD_FORTRAN_MEM_ORGANISATIONx7.2.1.2 is set to TRUE, it means that a(i,j,k) and a(i+1,j,k) are consecutive in memory but a(i,j,k) and a(i,j,k+1) are not. However, if SIMD_FORTRAN_MEM_ORGANISATIONx7.2.1.2 is set to FALSE, a(i,j,k) and a(i,j,k+1) are consecutive in memory but a(i,j,k) and a(i+1,j,k) are not.

   xSIMD_FORTRAN_MEM_ORGANISATIONxTRUE
   x

7.2.1.3 Pattern file This property is used by the sac library to know the path of the pattern definition file. If the file is not found, the execution fails.

   xSIMD_PATTERN_FILEx"patterns.def"
   x

7.2.2 Scalopes project This pass outlines code parts based on pragma. It can outline blocs or loops with a #pragmaxscmpxtask flag. It is based on the outline pass.

scalopragmaxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxxxxxx<xMODULE.code
xxxxxxxxxxxxxxx<xMODULE.cumulated_effects

7.2.2.1 Bufferization The goal of Bufferization is to generate a dataflow communication through buffers between modules. The communication is done by special function call generated by kernel_load_storex7.3.7.4. To keep flows consistent outside the module scalopifyx?? surround variable call with a special function too. A C file with stubs is needed.

   Note that you must also set KERNEL_LOAD_STORE_DEALLOCATE_FUNCTIONx7.3.7.4

to ”” in order to have it generate relevant code.

The goal of this pass is to keep consistent flows outside the tasks.

scalopifyxxxxxxxxxxxxxxxxxxxx>xMODULE.code
>xMODULE.callees
>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code
xxxxxxxxxxxxxxxx<xMODULE.cumulated_effects

7.2.2.2 SCMP generation The goal of the following phase is to generate SCMP tasks from ’normal’ modules. The tasks are linked and scheduled using the SCMP HAL. Sesamify take in input a module and analyze all its callees (per example the ’main’ after GPU-IFY or SCALOPRAGMA application). Each analyzed module is transformed into a SCMP task if its name begin with P4Axscmpxtask. To generate final files for SCMP the pass output need to be transform with a special python parser.

sesamifyxxxxxxxxxxxxxxxxxxxx>xMODULE.code
>xMODULE.callees
>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code
xxxxxxxxxxxxxxxx<xMODULE.cumulated_effects

7.3 Code Distribution

Different automatic code distribution techniques are implemented in PIPS for distributed-memory machines. The first one is based on the emulation of a shared-memory. The second one is based on HPF. A third one target architectures with hardware coprocessors. Another one is currently developed at IT Sud Paris that generate MPI code from OpenMP one.

7.3.1 Shared-Memory Emulation

WP65 1  ^{1http://www.cri.ensmp.fr/pips/wp65.html}  x[?,x?,x?]

produces a new version of a module transformed to be executed on a distributed memory machine. Each module is transformed into two modules. One module, wp65xcomputexfile, performs the computations, while the other one, wp65xbankxfile, emulates a shared memory.

This rule does not have data structure outputs, as the two new program generated have computed names. This does not fit the pipsmake framework too well, but is OK as long as nobody wishes to apply PIPS on the generated code, e.g. to propagate constant or eliminate dead code.

Note that use-use dependencies are used to allocate temporary arrays in local memory (i.e. in the software cache).

This compilation scheme was designed by Corinne Ancourt and Franx¿œois Irigoin. It uses theoretical results inx[?]. Its input is a very small subset of Fortran program (e.g. procedure calls are not supported). It was implemented by the designers, with help from Lei Zhou.

aliasxwp65_compute_filex'DistributedxView'
aliasxwp65_bank_filex'BankxDistributedxView'
wp65xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.wp65_compute_file
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.wp65_bank_file
xxxxxxxx!xMODULE.privatize_module
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.chains
xxxxxxxx<xMODULE.proper_effects

Name of the file for the target model:

   xWP65_MODEL_FILEx"model.rc"
   x

7.3.2 HPF Compiler

The HPF compiler2  ^{2http://www.cri.ensmp.fr/pips/hpfc.html}

is a project by itself, developed by Fabien Coelho in the PIPS framework.

A whole set of rules is used by the PIPS HPF

compiler3  ^{3http://www.cri.ensmp.fr/pips/hpfc.html}  ,

HPFC 4  ^{4http://www.cri.ensmp.fr/pips/hpfc.html}  .

By the way, the whole compiler is just a big hack according to Fabien Coelho.

7.3.2.1 HPFC Filter The first rule is used to apply a shell to put HPF-directives in an f77 parsable form. Some shell script based on sed is used. The hpfc_parserx4.2.2 must be called to analyze the right file. This is triggered automatically by the bang selection in the hpfc_closex7.3.2.5 phase.

hpfc_filterxxxxxxxxxxxxx>xMODULE.hpfc_filtered_file
xxxx<xMODULE.source_file

7.3.2.2 HPFC Initialization The second HPFC rule is used to initialize the hpfc status and other data structures global to the compiler. The HPF compiler status is bootstrapped. The compiler status stores (or should store) all relevant information about the HPF part of the program (data distribution, IO functions and so on).

hpfc_initxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.hpfc_status
xxxx<xPROGRAM.entities

7.3.2.3 HPF Directive removal This phase removes the directives (some special calls) from the code. The remappings (implicit or explicit) are also managed at this level, through copies between differently shaped arrays.

To manage calls with distributed arguments, I need to apply the directive extraction bottom-up, so that the callers will know about the callees through the hpfcxstatus. In order to do that, I first thought of an intermediate resource, but there was obscure problem with my fake calls. Thus the dependence static then dynamic directive analyses is enforced at the bang sequence request level in the hpfc_closex7.3.2.5 phase.

The hpfc_static_directivesx7.3.2.3 phase analyses static mapping directives for the specified module. The hpfc_dynamic_directivesx7.3.2.3 phase does manages realigns and function calls with prescriptive argument mappings. In order to do so it needs its callees’ required mappings, hence the need to analyze beforehand static directives. The code is cleaned from the hpfc_filterx7.3.2.1 artifacts after this phase, and all the proper information about the HPF stuff included in the routines is stored in hpfcxstatus.

hpfc_static_directivesxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.hpfc_status
xxxx<xPROGRAM.entities
xxxx<xPROGRAM.hpfc_status
xxxx<xMODULE.code
hpfc_dynamic_directivesxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.hpfc_status
xxxx<xPROGRAM.entities
xxxx<xPROGRAM.hpfc_status
xxxx<xMODULE.code
xxxx<xMODULE.proper_effects

7.3.2.4 HPFC actual compilation This rule launches the actual compilation. Four files are generated:

the host code that mainly deals with I/Os,

the SPMD node code,

and some initialization stuff for the runtime (2 files).

Between this phase and the previous one, many PIPS standard analyses are performed, especially the regions and preconditions. Then this phase will perform the actual translation of the program into a host and SPMD node code.

hpfc_compilexxxxxxxxxxx>xMODULE.hpfc_host
xxxxxxxxxxxxxxxxxxxxxxx>xMODULE.hpfc_node
xxxxxxxxxxxxxxxxxxxxxxx>xMODULE.hpfc_parameters
xxxxxxxxxxxxxxxxxxxxxxx>xMODULE.hpfc_rtinit
xxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.hpfc_status
xxxx<xPROGRAM.entities
xxxx<xPROGRAM.hpfc_status
xxxx<xMODULE.regions
xxxx<xMODULE.summary_regions
xxxx<xMODULE.preconditions
xxxx<xMODULE.code
xxxx<xMODULE.cumulated_references
xxxx<xCALLEES.hpfc_host

7.3.2.5 HPFC completion This rule deals with the compiler closing. It must deal with commons. The hpfc parser selection is put here.

hpfc_closexxxxxxxxxxxxx>xPROGRAM.hpfc_commons
xxxx!xSELECT.hpfc_parser
xxxx!xSELECT.must_regions
xxxx!xALL.hpfc_static_directives
xxxx!xALL.hpfc_dynamic_directives
xxxx<xPROGRAM.entities
xxxx<xPROGRAM.hpfc_status
xxxx<xMAIN.hpfc_host

7.3.2.6 HPFC install This rule performs the installation of HPFC generated files in a separate directory. This rule is added to make hpfc usable from wpips and epips. I got problems with the make and run rules, because it was trying to recompute everything from scratch. To be investigated later on.

hpfc_installxxxxxxxxxxxx>xPROGRAM.hpfc_installation
xxxx<xPROGRAM.hpfc_commons
hpfc_make
hpfc_run

7.3.2.7 HPFC High Performance Fortran Compiler properties

Debugging levels considered by HPFC: HPFC_{,DIRECTIVES,IO,REMAPPING}_DEBUG_LEVEL.

These booleans control whether some computations are directly generated in the output code, or computed through calls to dedicated runtime functions. The default is the direct expansion.

   xHPFC_EXPAND_COMPUTE_LOCAL_INDEXxTRUE
   x
   xHPFC_EXPAND_COMPUTE_COMPUTERxTRUE
   x
   xHPFC_EXPAND_COMPUTE_OWNERxTRUE
   x
   xHPFC_EXPAND_CMPLIDxTRUE
   x
   xHPFC_NO_WARNINGxFALSE
   x

Hacks controlx

   xHPFC_FILTER_CALLEESxFALSE
   x
   xGLOBAL_EFFECTS_TRANSLATIONxTRUE
   x

These booleans control the I/O generation.

   xHPFC_SYNCHRONIZE_IOxFALSE
   x
   xHPFC_IGNORE_MAY_IN_IOxFALSE
   x

Whether to use lazy or non-lazy communications

   xHPFC_LAZY_MESSAGESxTRUE
   x

Whether to ignore FCD (Fabien Coelho Directivesx) or not. These directives are used to instrument the code for testing purposes.

   xHPFC_IGNORE_FCD_SYNCHROxFALSE
   x
   xHPFC_IGNORE_FCD_TIMExFALSE
   x
   xHPFC_IGNORE_FCD_SETxFALSE
   x

Whether to measure and display the compilation times for remappings, and whether to generate outward redundant code for remappings. Also whether to generate code that keeps track dynamically of live mappings. Also whether not to send data to a twin (a processor that holds the very same data for a given array).

xHPFC_TIME_REMAPPINGSxFALSE
x
xHPFC_REDUNDANT_SYSTEMS_FOR_REMAPSxFALSE
x
xHPFC_OPTIMIZE_REMAPPINGSxTRUE
x
xHPFC_DYNAMIC_LIVENESSxTRUE
x
xHPFC_GUARDED_TWINSxTRUE
x

Whether to use the local buffer management. 1 MB of buffer is allocated.

xHPFC_BUFFER_SIZEx1000000
x
xHPFC_USE_BUFFERSxTRUE
x

Whether to use in and out convex array regions for input/output compiling

xHPFC_IGNORE_IN_OUT_REGIONSxTRUE
x

Whether to extract more equalities from a system, if possible.

xHPFC_EXTRACT_EQUALITIESxTRUE
x

Whether to try to extract the underlying lattice when generating code for systems with equalities.

xHPFC_EXTRACT_LATTICExTRUE
x

7.3.3 STEP: MPI code generation from OpenMP programs

RK: IT SudParis : insert your documentation here; FI: or a pointer towards you documentation

7.3.3.1 STEP Directives The step_parserx7.3.3.1 phase identifies the OpenMP constructs. The directive semantics are stored in the MODULE.stepxdirectives ressource.

step_parserxxxxxxxxxxxxxxxxx>xMODULE.step_directives
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxx<xMODULE.code

7.3.3.2 STEP Analysis

The step_analyse_initx7.3.3.2 phase init the PROGRAM.stepxcomm ressources

step_analyse_initxxxxxxxxxxxx>xPROGRAM.step_comm

The step_analysex7.3.3.2 phase triggers the convex array regions analyses to compute SEND and RECV regions leading to MPI messages and checks whether a given SEND region corresponding to a directive construct is consumed by a RECV region corresponding to a directive construct. In this case, communications can be optimized.

step_analysexxxxxxxxxxxxxxxxx>xPROGRAM.step_comm
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.step_send_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.step_recv_regions
xxx<xPROGRAM.entities
xxx<xPROGRAM.step_comm
xxx<xMODULE.step_directives
xxx<xMODULE.code
xxx<xMODULE.preconditions
xxx<xMODULE.transformers
xxx<xMODULE.cumulated_effects
xxx<xMODULE.regions
xxx<xMODULE.in_regions
xxx<xMODULE.out_regions
xxx<xMODULE.chains
xxx<xCALLEES.code

xxx<xCALLEES.step_send_regions
xxx<xCALLEES.step_recv_regions

7.3.3.3 STEP code generation Based on the OpenMP construct and analyses, new modules are generated to translate the original code with OpenMP directives. The default code transformation for OpenMP construct is driven by the STEP_DEFAULT_TRANSFORMATIONx7.3.3.3 property. The different value allowed are :

"HYBRID" : for OpenMP and MPI parallel code

"MPI" : for MPI parallel code

"OMP" : for OpenMP parallel code

   xSTEP_DEFAULT_TRANSFORMATIONx"HYBRID"
   x

The step_compilex7.3.3.3 phase generates source code for OpenMP constructs depending of the transformation desired. Each OpenMP construct could have a specific transformation define by STEP clauses (without specific clauses, the STEP_DEFAULT_TRANSFORMATIONx7.3.3.3 is used). The specific STEP clauses allowed are :

"!\$stepxhybrid" : for OpenMP and MPI parallel code

"!\$stepxno\_mpi" : for OpenMP parallel code

"!\$stepxmpi" : for MPI parallel code

"!\$stepxignore" : for sequential code

step_compilexxxxxxxxxxxxxxx>xMODULE.step_file
xxx<xPROGRAM.entities
xxx<xPROGRAM.step_comm
xxx<xMODULE.step_directives
xxx<xMODULE.code

The step_installx7.3.3.3 phase copy the generated source files in the directory specified by the STEP_INSTALL_PATHx7.3.3.3 property.

step_install
xxx<xALL.step_file

   xSTEP_INSTALL_PATHx""
   x

7.3.4 PHRASE: high-level language transformation for partial evaluation in reconfigurable logic

The PHRASE project is an attempt to automatically (or semi-automatically) transform high-level language programs into code with partial execution on some accelerators such as reconfigurable logic (such as FPGAs) or data-paths.

This phases allow to split the code into portions of code delimited by PHRASE-pragma (written by the programmer) and a control program managing them. Those portions of code are intended, after transformations, to be executed in reconfigurable logic. In the PHRASE project, the reconfigurable logic is synthesized with the Madeo tool that take SmallTalk code as input. This is why we have a SmallTalk pretty-printer (see sectionx9.10).

7.3.4.1 Phrase Distributor Initialisation

This phase is a preparation phase for the Phrase Distributor phrase_distributorx7.3.4.2: the portions of code to externalize are identified and isolated here. Comments are modified by this phase.

aliasxphrase_distributor_initx'PHRASExDistributorxinitialization'
phrase_distributor_initxxxxxxxxxxxxxxxxxx>xMODULE.code

xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This phase is automatically called by the following phrase_distributorx7.3.4.2.

7.3.4.2 Phrase Distributor

The job of distribution is done here. This phase should be applied after the initialization (Phrase Distributor Initialisation phrase_distributor_initx7.3.4.1), so this one is automatically applied first.

aliasxphrase_distributorx'PHRASExDistributor'
phrase_distributorxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.phrase_distributor_init
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.dg

7.3.4.3 Phrase Distributor Control Code

This phase add control code for PHRASE distribution. All calls to externalized code portions are transformed into START and WAIT calls. Parameters communication (send and receive) are also handled here

aliasxphrase_distributor_control_codex'PHRASExDistributorxControlxCode'
phrase_distributor_control_codexxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities

xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.dg

7.3.5 Safescale

The Safescale project is an attempt to automatically (or semi-automatically) transform sequential code written in C language for the Kaapi runtime.

7.3.5.1 Distribution init

This phase is intended for the analysis of a module given with the aim of finding blocks of code delimited by specific pragmas from it.

aliasxsafescale_distributor_initx'Safescalexdistributorxinit'
safescale_distributor_initxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

7.3.5.2 Statement Externalization

This phase is intended for the externalization of a block of code.

aliasxsafescale_distributorx'Safescalexdistributor'
safescale_distributorxxxxxxxxxxxxxxxxxx>xMODULE.code

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.safescale_distributor_init
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions

7.3.6 CoMap: Code Generation for Accelerators with DMA

7.3.6.1 Phrase Remove Dependences

aliasxphrase_remove_dependencesx'PhrasexRemovexDependences'
phrase_remove_dependencesxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.phrase_distributor_init
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.dg

7.3.6.2 Phrase comEngine Distributor

This phase should be applied after the initialization (Phrase Distributor Initialisation or phrase_distributor_initx7.3.4.1). The job of comEngine distribution is done here.

aliasxphrase_comEngine_distributorx'PHRASExcomEnginexDistributor'
phrase_comEngine_distributorxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.phrase_distributor_init
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.dg
xxxxxxxx<xMODULE.summary_complexity

7.3.6.3 PHRASE ComEngine properties This property is set to TRUE if we want to synthesize only one process on the HRE.

   xCOMENGINE_CONTROL_IN_HRExTRUE
   x

This property holds the fifo size of the ComEngine.

   xCOMENGINE_SIZE_OF_FIFOx128
   x

7.3.7 Parallelization for Terapix architecture

7.3.7.1 Isolate Statement Isolate the statement given in ISOLATE_STATEMENT_LABELx7.3.7.1 in a separated memory. Data transfer are generated using the same DMA as KERNEL_LOAD_STOREx??.

The algorithm is based on Read and write regions (no in / out yet) to compute the data that must be copied and allocated. Rectangular hull of regions are used to match allocator and data transfers prototypes. If an analysis fails, definition regions are use instead. If a sizeof is involved, EVAL_SIZEOFx8.4.2 must be set to true.

isolate_statementx>xMODULE.code
>xMODULE.callees
<xMODULE.code
<xMODULE.regions
<xPROGRAM.entities

   xISOLATE_STATEMENT_LABELx""
   x

As a side effect of isolatexstatement pass, some new variables are declared into the function. A prefix can be used for the names of those variables using the property ISOLATExSTATEMENTxVARxPREFIX. It is also possible to insert a suffix using the property ISOLATExSTATEMENTxVARxSUFFIX. The suffix will be inserted between the original variable name and the instance number of the copy.

   xISOLATE_STATEMENT_VAR_PREFIXx""
   x
   xISOLATE_STATEMENT_VAR_SUFFIXx""
   x

By default we cannot isolate a statement with some complex effects on the non local memory. But if we know we can (for example ), we can override this behaviour by setting the following property:

   xISOLATE_STATEMENT_EVEN_NON_LOCALxFALSE
   x

7.3.7.2 Delay Communications Optimize the load/store dma by delaying the stores and performing the stores as soon as possible. Interprocedural version.

It uses ACCEL_LOADx7.2 and ACCEL_STOREx7.2 to distinguish loads and stores from other calls.

The communication elimination makes the assumption that a load/store pair can always be removed.

delay_communications_interxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx!xCALLEES.delay_communications_inter
xxxxxxxx!xMODULE.delay_load_communications_inter
xxxxxxxx!xMODULE.delay_store_communications_inter

xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.dg

delay_load_communications_interxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx>xCALLERS.code
xxxxxxxx>xCALLERS.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLERS.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

delay_store_communications_interxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx>xCALLERS.code
xxxxxxxx>xCALLERS.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLERS.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

Optimize the load/store dma by delaying the stores and performing the stores as soon as possible. Intra Procedural version.

It uses ACCEL_LOADx7.2 and ACCEL_STOREx7.2 to distinguish loads and stores from other calls.

The communication elimination makes the assumption that a load/store pair can always be removed.

delay_communications_intraxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx!xMODULE.delay_load_communications_intra
xxxxxxxx!xMODULE.delay_store_communications_intra
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.dg

delay_load_communications_intraxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

delay_store_communications_intraxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

7.3.7.3 Hardware Constraints Solver if SOLVE_HARDWARE_CONSTRAINTS_TYPEx7.3.7.3 is set to VOLUME, Given a loop label, a maximum memory footprint and an unknown entity, try to find the best

value for SOLVE_HARDWARE_CONSTRAINTS_UNKNOWNx7.3.7.3 to make memory

footprint of SOLVE_HARDWARE_CONSTRAINTS_LABELx7.3.7.3 reach but not exceed SOLVE_HARDWARE_CONSTRAINTS_LIMITx7.3.7.3. If it is set to NBxPROC, it tries to find the best value for SOLVE_HARDWARE_CONSTRAINTS_UNKNOWNx7.3.7.3 to make the maximum range of first dimension of all regions accessed by SOLVE_HARDWARE_CONSTRAINTS_LABELx7.3.7.3

equals to SOLVE_HARDWARE_CONSTRAINTS_LIMITx7.3.7.3.

solve_hardware_constraintsx>xMODULE.code
<xMODULE.code
<xMODULE.regions
<xPROGRAM.entities

   xSOLVE_HARDWARE_CONSTRAINTS_LABELx""
   x
   xSOLVE_HARDWARE_CONSTRAINTS_LIMITx0
   x
   xSOLVE_HARDWARE_CONSTRAINTS_UNKNOWNx""
   x
   xSOLVE_HARDWARE_CONSTRAINTS_TYPEx""
   x

7.3.7.4 kernelize Bootstraps the kernel ressource

bootstrap_kernelsx>xPROGRAM.kernels

Add a kernel to the list of kernels known to pips

flag_kernel >xPROGRAM.kernels
<xPROGRAM.kernels

Generate unoptimized load / store information for each call to the module.

kernel_load_store >xCALLERS.code
>xCALLERS.callees
>xPROGRAM.kernels
<xPROGRAM.kernels
<xCALLERS.code
xxx <xCALLERS.regions
xxxxxxxx<xCALLERS.preconditions

The legacy kernel_load_storex7.3.7.4 approach is limited because it generates the DMA around a call, and isolate_statementx7.3.7.1 engine does not perform well in interprocedural.

The following properties are used to specify the names of runtime functions. Since they are used in Par4All, their default names begin with P4A_. To have an idea about their prototype, have a look to the Par4All accelerator runtime or in

validation/AcceleratorUtils/include/par4all.c.

Enable/disable the scalar handling by kernel load store.

   xKERNEL_LOAD_STORE_SCALARxFALSE
   x

The ISOLATE_STATEMENT_EVEN_NON_LOCALx7.3.7.1 property can be used to force the generation even with non local memory access. But beware it would not solve all the issues...

The following properties can be used to customized the allocate/load/store functions:

   xKERNEL_LOAD_STORE_ALLOCATE_FUNCTIONx"P4A_accel_malloc"
   x
   xKERNEL_LOAD_STORE_DEALLOCATE_FUNCTIONx"P4A_accel_free"
   x

The following properties are used to name the dma functions to use for scalars:

   xKERNEL_LOAD_STORE_LOAD_FUNCTIONx"P4A_copy_to_accel"
   x
   xKERNEL_LOAD_STORE_STORE_FUNCTIONx"P4A_copy_from_accel"
   x

and for 1-dimension arrays:

   xKERNEL_LOAD_STORE_LOAD_FUNCTION_1Dx"P4A_copy_to_accel_1d"
   x
   xKERNEL_LOAD_STORE_STORE_FUNCTION_1Dx"P4A_copy_from_accel_1d"
   x

and in 2 dimensions:

   xKERNEL_LOAD_STORE_LOAD_FUNCTION_2Dx"P4A_copy_to_accel_2d"

xKERNEL_LOAD_STORE_STORE_FUNCTION_2Dx"P4A_copy_from_accel_2d"
x

and in 3 dimensions:

xKERNEL_LOAD_STORE_LOAD_FUNCTION_3Dx"P4A_copy_to_accel_3d"
x
xKERNEL_LOAD_STORE_STORE_FUNCTION_3Dx"P4A_copy_from_accel_3d"
x

and in 4 dimensions:

xKERNEL_LOAD_STORE_LOAD_FUNCTION_4Dx"P4A_copy_to_accel_4d"
x
xKERNEL_LOAD_STORE_STORE_FUNCTION_4Dx"P4A_copy_from_accel_4d"
x

and in 5 dimensions:

xKERNEL_LOAD_STORE_LOAD_FUNCTION_5Dx"P4A_copy_to_accel_5d"
x
xKERNEL_LOAD_STORE_STORE_FUNCTION_5Dx"P4A_copy_from_accel_5d"
x

and in 6 dimensions:

xKERNEL_LOAD_STORE_LOAD_FUNCTION_6Dx"P4A_copy_to_accel_6d"
x
xKERNEL_LOAD_STORE_STORE_FUNCTION_6Dx"P4A_copy_from_accel_6d"
x

As a side effect of kernel load store pass, some new variables are declared into the function. A prefix can be used for the names of those variables using the property KERNELxLOADxSTORExVARxPREFIX. It is also possible to insert a suffix using the property KERNELxLOADxSTORExVARxPREFIX. The suffix will be inserted between the original variable name and the instance number of the copy.

xKERNEL_LOAD_STORE_VAR_PREFIXx"P4A_var_"
x
xKERNEL_LOAD_STORE_VAR_SUFFIXx""
x

Split a parallel loop with a local index into three parts: a host side part, a kernel part and an intermediate part. The intermediate part simulates the parallel code to the kernel from the host

kernelize >xMODULE.code
>xMODULE.callees
>xPROGRAM.kernels
!xMODULE.privatize_module
!xMODULE.coarse_grain_parallelization
<xPROGRAM.entities
<xMODULE.code
<xPROGRAM.kernels

The property KERNELIZE_NBNODESx7.3.7.4 is used to set the number of nodes for this kernel. KERNELIZE_KERNEL_NAMEx7.3.7.4 is used to set the name of generated kernel. KERNELIZE_HOST_CALL_NAMEx7.3.7.4 is used to set the name of generated call to kernel (host side).

   xKERNELIZE_NBNODESx128
   x
   xKERNELIZE_KERNEL_NAMEx""
   x
   xKERNELIZE_HOST_CALL_NAMEx""
   x
   xOUTLINE_LOOP_STATEMENTxFALSE
   x

Gather all constants from a module and put them in a single array. Relevant for Terapix code generation, and maybe for other accelerators as well

group_constantsx>xMODULE.code
<xPROGRAM.entities
<xMODULE.code
<xMODULE.regions

You may want to group constants only for a particular statement, in that case use

GROUP_CONSTANTS_STATEMENT_LABELx7.3.7.4
   xGROUP_CONSTANTS_STATEMENT_LABELx""
   x

The way variables are grouped is control by GROUP_CONSTANTS_LAYOUTx7.3.7.4, the only relevant value as of now is "terapix".

   xGROUP_CONSTANTS_LAYOUTx""
   x

The name of the variable holding constants can be set using

GROUP_CONSTANTS_HOLDERx7.3.7.4.

   xGROUP_CONSTANTS_HOLDERx"caillou"
   x

You may want to skip loop bounds from the grouping

   xGROUP_CONSTANTS_SKIP_LOOP_RANGExFALSE
   x

You may want to skip litterals too.

   xGROUP_CONSTANTS_LITERALxTRUE
   x

Perform various checks on a Terapix microcode to make sure it can be synthesized. GROUP_CONSTANTS_HOLDERx7.3.7.4 is used to differentiate mask and image.

normalize_microcode >xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xCALLERS.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xCOMPILATION_UNIT.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.cumulated_effects

normalize array access in a loop nest for terapixification.

This pass is meaningless for any other target :(.

terapix_warmupx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

converts divide operator into multiply operator using formula a/cste = a ∗ (1/b) ≃ a ∗ (128/cste)/128

terapix_remove_dividex>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Use this property for accuracy of divide to multiply conversion.

   xTERAPIX_REMOVE_DIVIDE_ACCURACYx4
   x

7.3.7.5 Generating communications This phase computes the mapping of data on the accelarators. It records the set of data that have to be copied on the GPU before each statement in the module, and the set of data that have to be copied back from the GPU after the execution of each statement.

Then according to this information, the copy-in and copy-out transfers are generated using same properties as KERNEL_LOAD_STOREx??:

aliasxkernel_data_mappingx"Kernelxdataxmapping"
kernel_data_mappingx>xMODULE.kernel_copy_in
xxxx>xMODULE.kernel_copy_out
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xPROGRAM.kernels
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.callees
xxxxxxxx<xMODULE.callers
xxxxxxxx<xCALLEES.kernel_copy_out
xxxxxxxx<xCALLEES.kernel_copy_in

This phase wrap argument at call site with an access function. The wrapper name is controlled with WRAP_KERNEL_ARGUMENT_FUNCTION_NAMEx7.3.7.5. Currently the purpose of this is to insert call to a runtime to resolve addresses in accelerator memory corresponding to addresses in host memory.

   xWRAP_KERNEL_ARGUMENT_FUNCTION_NAMEx"P4A_runtime_host_ptr_to_accel_ptr"

aliasxwrap_kernel_argumentx"wrap_kernel_argument"
wrap_kernel_argumentx>xCALLERS.code
xxx>xCALLERS.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.code
xxxxxxxx<xCALLERS.callees
xxxxxxxx<xMODULE.callers

7.3.8 Code distribution on GPU This phase generate GPU kernels from perfect parallel loop nests. GPU_IFY_ANNOTATE_LOOP_NESTSx7.3.8 property triggers automatically the annotation

of the loop nest (see GPU_LOOP_NEST_ANNOTATEx??).
   xGPU_IFY_ANNOTATE_LOOP_NESTSxFALSE
   x

aliasxgpu_ifyx'Distributex//xloopxnestsxonxGPU'
gpu_ifyxxxxxxxxxxxxxxxxxxxx>xMODULE.code
>xMODULE.callees
>xPROGRAM.entities
!xMODULE.privatize_module
<xPROGRAM.entities
<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

For example from

xxxfor ( i x=x 1 ; x i x<=x 499; x i x+=x 1)xxxxxxxfor ( j x=x 1 ; x j x<=x 499; x j x+=x 1)xxxxxxxxxxsave [ i ] [ j ] x=x 0 . 2 5 ∗ ( space [ i −1][ j ]+ space [ i +1][ j ]+ space [ i ] [ j −1]+space [ i ] [ j +1]);

it generates something like

xxxp4axkernelxlauncherx0 ( save , x space ) ; xxxxx [ …] xxxxvoidx p4axkernelxlauncherx0 ( f l o a t x t x save [ 5 0 1 ] [ 5 0 1 ] , x f l o a t x t x space [ 5 0 1 ] [ 5 0 1 ] ) xxxx{xxxxxxint x i ; xxxxxxint x j ; xxxxfor ( i x=x 1 ; x i x<=x 499; x i x+=x 1)xxxxxxxfor ( j x=x 1 ; x j x<=x 499; x j x+=x 1)xxxxxxxxxxxp4axkernelxwrapperx0 ( save , x space , x i , x j ) ; xxxx}xxxxxvoidx p4axkernelxwrapperx0 ( f l o a t x t x save [ 5 0 1 ] [ 5 0 1 ] , x f l o a t x t x space [ 5 0 1 ] [ 5 0 1 ] , x int x i , x int x j )xxxx{xxxxxx i x=xP4Axpvx0 ( i ) ; xxxxxx j x=xP4Axpvx1 ( j ) ; xxxxxxp4axkernelx0 ( save , x space , x i , x j ) ; xxxx}xxxxvoidx p4axkernelx0 ( f l o a t x t x save [ 5 0 1 ] [ 5 0 1 ] , x f l o a t x t x space [ 5 0 1 ] [ 5 0 1 ] , x intxxxxxxxxxxxxxxxxxxxxxxi , x int x j ) x{xxxxxxsave [ i ] [ j ] x=x 0 . 2 5 ∗ ( space [ i −1][ j ]+ space [ i +1][ j ]+ space [ i ] [ j −1]+space [ i ] [ j +1]);xxxx}

The launcher, wrapper and kernel prefix names to be used during the generation:

   xGPU_LAUNCHER_PREFIXx"p4a_launcher"
   x
   xGPU_WRAPPER_PREFIXx"p4a_wrapper"
   x
   xGPU_KERNEL_PREFIXx"p4a_kernel"
   x

This boolean property control wherever the outliner use the original function name as a suffix instead of only numerical suffix.

   xGPU_OUTLINE_SUFFIX_WITH_OWNER_NAMExTRUE
   x

For Fortran output you may need to have these prefix name in uppercase.

Indeed, each level of outlining can be enabled or disabled according to the following properties:

   xGPU_USE_LAUNCHERxTRUE
   x
   xGPU_USE_WRAPPERxTRUE
   x
   xGPU_USE_KERNELxTRUE
   x

Each generated function can go in its own source file according to the following properties:

   xGPU_USE_KERNEL_INDEPENDENT_COMPILATION_UNITxFALSE
   x
   xGPU_USE_LAUNCHER_INDEPENDENT_COMPILATION_UNITxFALSE
   x
   xGPU_USE_WRAPPER_INDEPENDENT_COMPILATION_UNITxFALSE
   x

By default they are set to FALSE for languages like CUDA that allow kernel and host

codes mixed in a same file but for OpenCL it is not the case.

When the original code is in Fortran it might be useful to wrap the kernel launcher in an independent C file. The GPU_USE_FORTRAN_WRAPPERx7.3.8 can be used for that purpose. The name of the function wrapper can be configured using the property GPU_FORTRAN_WRAPPER_PREFIXx7.3.8. As specified before it is safe to use prefix name in uppercase.

   xGPU_USE_FORTRAN_WRAPPERxFALSE
   x
   xGPU_FORTRAN_WRAPPER_PREFIXx"P4A_FORTRAN_WRAPPER"

The phase generates a wrapper function to get the iteration coordinate from intrinsics functions instead of the initial loop indices. Using this kind of wrapper is the normal behaviour but for simulation of an accelerator code, not using a wrapper is useful.

The intrinsics function names to get an i^{th} coordinate in the iteration space are defined by this GNU x¿œ la printf format:

   xGPU_COORDINATE_INTRINSICS_FORMATx"P4A_vp_%d"
   x

where %d is used to get the dimension number. Here vp stands for virtual processor

dimension and is a reminiscence from PompC and HyperC...

Please, do not use this feature for buffer-overflow attack...

Annotates loop nests with comments and guards for further generation of CUDA calls.

aliasxgpu_loop_nest_annotatex'Decoratexloopxnestsxwithxiterationxspacesxandxaddxiterationxclamping'
gpu_loop_nest_annotate xxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

To annotate only outer parallel loop nests, set the following variable to true:

   xGPU_LOOP_NEST_ANNOTATE_PARALLELxTRUE
   x

Parallelize annotated loop nests based on the sentinel comments.

gpu_parallelize_annotated_loop_nestxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This phase promote sequential code in GPU kernels to avoid memory transfers.

gpu_promote_sequential >xMODULE.code
>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code

7.3.9 Task generation for SCALOPES project The goal of the following phase is to generate several tasks from one sequential program. Each task is generated as an independent main program. Then the tasks are linked and scheduled using the SCMP HAL.

scalopifyxxxxxxxxxxxxxxxxxxxx>xMODULE.code
>xMODULE.callees
>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code
xxxxxxxxxxxxxxxx<xMODULE.cumulated_effects

sesamifyxxxxxxxxxxxxxxxxxxxx>xMODULE.code
>xMODULE.callees
>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code
xxxxxxxxxxxxxxxx<xMODULE.cumulated_effects

   Phase sesamxbuffersxprocessing is to be run after isolatexstatement has

been applied to all tasks statements. It then produces a header file to be included by the future sesam application individual tasks. This header file describes how kernel and server tasks use the sesam buffers.

sesam_buffers_processingxxxx>xMODULE.sesam_buffers_file
xxxxxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxxxxx<xMODULE.code
xxxxxxxxxxxxxx<xMODULE.cumulated_effects

The next two properties are used by phase sesamxbuffersxprocessing to detect kernel tasks statements in the input module and to generate server tasks names in the output header file.

   xSCALOPES_KERNEL_TASK_PREFIXx"P4A_sesam_task_"
   x
   xSCALOPES_SERVER_TASK_PREFIXx"P4A_sesam_server_"

Chapterx8Program Transformations

A program transformation is a special phase which takes a code as input, modifies it, possibly using results from several different analyses, and puts back this modified code as result.

A rule describing a program transformation will never be chosen automatically by pipsmake to generate some code since every transformation rule contains a cycle for the MODULE.code resource. Since the first rule producing code, described in this file, is controlizerx4.3 and since it is the only non-cyclic rule, the internal representation always is initialized with it.

As program transformations produce nothing else, pipsmake cannot guess when to apply these rules automatically. This is exactly what the user want most of the time: program transformations are under explicit control by the user. Transformations are applied when the user pushes one of wpips transformation buttons or when (s)he enters an apply command when running

tpips1  ^{1http://www.cri.ensmp.fr/pips/line-interface.html}  ,

or by executing a Perform Shell script. See the introduction for pointers to the user interfaces.

Unfortunately, it is sometime nice to be able to chain several transformations without any user interaction. No general macro mechanism is available in pipsmake, but it is possible to impose some program transformations with the ’!’ command.

User inputs are not well-integrated although a user_query rule and a string resource could easily be added. User interaction with a phase are performed directly without notifying pipsmake to be more flexible and to allow dialogues between a transformation and the user.

8.1 Loop Transformations

8.1.1 Introduction

Most loop transformations require the user to give a valid loop label to locate the loop to be transformed. This is done interactively or by setting the following property to the valid label:

   xLOOP_LABELx""
   x

Put a label on unlabelled loops for further interactive processing. Unless FLAG_LOOPS_DO_LOOPS_ONLYx8.1.1 is set to false, only do loops are considered.

flag_loopsxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xx>xMODULE.loops
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

   xFLAG_LOOPS_DO_LOOPS_ONLYxTRUE
   x

Display label of all modules loops

print_loops >xMODULE.loops_file
<xMODULE.loops

8.1.2 Loop range Normalization Use intermediate variables as loop upper and lower bound when they are not affine.

linearize_loop_rangex>xMODULE.code
xxxx<xPROGRAM.entities
<xMODULE.code

8.1.3 Loop Distribution

Function distributerx8.1.3 is a restricted version of the parallelization function rice* (see Sectionx7.1.3).

Distribute all the loops of the module.

Allen & Kennedy’s algorithmx[?] is used in both cases. The only difference is that distributerx8.1.3 does not produce DOALL loops, but just distributes loops as much as possible.

aliasxdistributerx'DistributexLoops'
distributerxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

Partial distribution distributes the statements of a loop nest except the isolated statements,that have no dependences at the common level l, are gathered in the same l-th loop.

   xPARTIAL_DISTRIBUTIONxFALSE
   x

8.1.4 Statement Insertion Check if the statement flagged by STATEMENT_INSERTION_PRAGMAx8.1.4 can be safely inserted in the current control flow. This pass should be reserved to internal use only, another pass should create and insert a flagged statement and then call this one to verify the validity of the insertion

statement_insertionx>xMODULE.code
xxxx<xPROGRAM.entities
xxxx<xALL.code
xxxx>xALL.code
<xMODULE.regions
<xMODULE.out_regions

   xSTATEMENT_INSERTION_PRAGMAx"pips␣inserted␣statement␣to␣check"
   x
   xSTATEMENT_INSERTION_SUCCESS_PRAGMAx"pips␣inserted␣statement"

   xSTATEMENT_INSERTION_FAILURE_PRAGMAx"pips␣inserted␣statement␣to␣remove"
   x

8.1.5 Loop Expansion Prepare the loop expansion by creating a new statement (that may be invalid) for further processing by statement_insertionx8.1.4. Use STATEMENT_INSERTION_PRAGMAx8.1.4 to identify the created statement. Otherwise LOOP_LABELx8.1.1 and LOOP_EXPANSION_SIZEx8.1.5 have the same meaning as in

loop_expansionx8.1.5

loop_expansion_initx >xMODULE.code
xxxx<xPROGRAM.entities
xxxx<xMODULE.code

Extends the range of a loop given by LOOP_LABELx8.1.1 to fit a size given by

LOOP_EXPANSION_SIZEx8.1.5. An offset can be set if LOOP_EXPANSION_CENTERx8.1.5

is set to True. The new loop is guarded to prevent illegal iterations, further transformations can elaborate on this.

loop_expansionx >xMODULE.code
xxxx<xPROGRAM.entities
xxxx<xMODULE.code
<xMODULE.cumulated_effects

   xLOOP_EXPANSION_SIZEx""
   x
   xLOOP_EXPANSION_CENTERxFALSE
   x

Extends the dimension of all declared arrays so that no access is illegal.

array_expansionx>xPROGRAM.entities
xxxx<xPROGRAM.entities
<xMODULE.code
<xMODULE.regions

8.1.6 Loop Fusion

This pass fuses as many loops as possible in a greedy manner. The loops must appear in a sequence and have exactly the same loop bounds and if possible the same loop indices. We’ll always try first to fuse loops where there is a dependence between their body. We expect that this policy will maximize possibilities for further optimizations.

Property LOOP_FUSION_GREEDYx8.1.6 allows to control whether it’ll try to fuse as many loop as possible even without any reuse. This will be done in a second pass.

Property LOOP_FUSION_MAXIMIZE_PARALLELISMx8.1.6 is used to control if loop fusion has to preserve parallelism while fusing. If this property is true, a parallel loop is never fused with a sequential loop.

   Property LOOP_FUSION_KEEP_PERFECT_PARALLEL_LOOP_NESTSx8.1.6 prevents to

lose parallelism when fusing outer loops from a loop nests without being able to fuse inner loops.

Property LOOP_FUSION_MAX_FUSED_PER_LOOPx8.1.6 limit the number of fusion per loop. A negative value means that no limit will be enforced.

The fusion legality is checked in the standard way by comparing the dependence graphs obtained before and after fusion.

This pass is still in the experimental stage. It may have side effects on the source code when the fusion is attempted but not performed in case loop indices are different.

aliasxFusionx'FusionxLoops'
loop_fusionxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.dg

   xLOOP_FUSION_MAXIMIZE_PARALLELISMxTRUE

   xLOOP_FUSION_GREEDYxFALSE
   x
   xLOOP_FUSION_KEEP_PERFECT_PARALLEL_LOOP_NESTSxTRUE
   x
   xLOOP_FUSION_MAX_FUSED_PER_LOOPx-1
   x

8.1.7 Index Set Splitting

Index Set Splittingx[?] splits the loop referenced by property LOOP_LABELx8.1.1 into two loops. The first loop ends at an iteration designated by property INDEX_SET_SPLITTING_BOUNDx8.1.7 and the second start thereafter. It currently only works for do loops. This transformation is always legal. Index set splitting in combination with loop unrolling could be used to perform loop peeling.

aliasxindex_set_splittingx'IndexxSetxSplitting'
index_set_splittingxxxxxx>xMODULE.code
xxxxxxxx>xPROGRAM.entities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Index Set Splitting requires the following globals to be set :

LOOP_LABELx8.1.1 is the loop label

     INDEX_SET_SPLITTING_BOUNDx8.1.7 is the splitting bound
     xINDEX_SET_SPLITTING_BOUNDx""
     x

   Additionnaly, INDEX_SET_SPLITTING_SPLIT_BEFORE_BOUNDx8.1.7 can be

used to accurately tell to split the loop before or after the bound given in

INDEX_SET_SPLITTING_BOUNDx8.1.7
   xINDEX_SET_SPLITTING_SPLIT_BEFORE_BOUNDxFALSE

8.1.8 Loop Unrolling

8.1.8.1 Regular Loop Unroll Unroll requests a loop label and an unrolling factor from the user. Then it unrolls the specified loop as specified. The transformation is very general, and it is interesting to run partial_evalx8.4.2, simplify_controlx8.3.1 and dead_code_eliminationx8.3.2 after this transformation. When the number of iterations cannot be proven to be a multiple of the unrolling factor, the extra iterations can be executed first or last (see LOOP_UNROLL_WITH_PROLOGUEx8.1.8.1).

Labels in the body are deleted. To unroll nested loops, start with the innermost loop.

This transformation is always legal.

aliasxunrollx'LoopxUnroll'
unrollxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Use LOOP_LABELx8.1.1 and UNROLL_RATEx8.1.8.1 if you do not want to unroll interactively You can also set LOOP_UNROLL_MERGEx8.1.8.1 to use the same declarations among all the unrolled statement (only meaningful in C).

   xUNROLL_RATEx0
   x
   xLOOP_UNROLL_MERGExFALSE
   x

The unrolling rate does not always divide exactly the number of iterations. So an extra loop must be added to execute the remaining iterations. This extra loop can be executed with the first iterations (prologue option) or the last iterations (epilogue option). Property LOOP_UNROLL_WITH_PROLOGUEx8.1.8.1 can be set to FALSE to use the epilogue when possible. The current implementation of the unrolling with prologue is general, while the implementation of the unrolling with epilogue is restricted to loops with a statically knonw increment of one. The epilogue option may reduce misalignments.

   xLOOP_UNROLL_WITH_PROLOGUExTRUE
   x

Another option might be to require unrolling of the prologue or epilogue loop when possible.

8.1.8.2 Full Loop Unroll A loop can also be fully unrolled if the range is numerically known. “Partial Eval” may be usefully applied first.

This is only useful for small loop ranges.

Unrolling can be interactively applied and the user is requested a loop label:

aliasxfull_unrollx'FullxLoopxUnrollx(Interactive)'
full_unrollxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Or directives can be inserted as comments for loops to be unrolled with:

aliasxfull_unroll_pragmax'FullxLoopxUnrollx(Pragma)'
full_unroll_pragmaxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

The directive is a comment containing the string Cxxx just before a loop to fully unroll (it is reserved to Fortran right now and should be generalized).

Full loop unrolling is applied one loop at a time by default. The user must specify the loop label. This default feature can be turned off and all loops with constant loop bounds and constant increment are fully unrolled.

Use LOOP_LABELx8.1.1 to pass the desired label if you do not want to give it interactively

Property FULL_LOOP_UNROLL_EXCEPTIONSx8.1.8.2 is used to forbid loop unrolling when specific user functions are called in the loop body. The function names are separated by SPACEs. The default value is the empy set, i.e. the empry string.

   xFULL_LOOP_UNROLL_EXCEPTIONSx""
   x

8.1.9 Loop Fusion This pass applies unconditionnally a loop fusion between the loop designated by the property LOOP_LABELx8.1.1 and the following loop. They must have the same loop index and the same iteration set. No legality check is performed.

force_loop_fusionx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
<xMODULE.code

8.1.10 Strip-mining

Strip-mine requests a loop label and either a chunk size or a chunk number. Then it strip-mines the specified loop, if it is found. Note that the DO/ENDDO construct is not compatible with such local program transformations.

aliasxstrip_minex'StripxMining'
strip_minexxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Behavior of strip mining can be controlled by the following properties:

LOOP_LABELx8.1.1 selects the loop to strip mine

STRIP_MINE_KINDx8.1.10 can be set to 0 (fixed-size chunks) or 1 (fixed number of chunks). Negative value is used for interactive prompt.

STRIP_MINE_FACTORx8.1.10 controls the size of the chunk or the number of chunk depending on STRIP_MINE_KINDx8.1.10. Negative value is used for interactive prompt.

   xSTRIP_MINE_KINDx-1

   xSTRIP_MINE_FACTORx-1
   x

8.1.11 Loop Interchange

loop_interchangex8.1.11 requests a loop label and exchange the outer-most loop with this label and the inner-most one in the same loop nest, if such a loop nest exists.

Presently, legality is not checked.

aliasxloop_interchangex'LoopxInterchange'
loop_interchangexxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Property LOOP_LABELx8.1.1 can be set to a loop label instead of using the default interactive method.

8.1.12 Hyperplane Method

loop_hyperplanex8.1.12 requests a loop label and a hyperplane direction vector and applies the hyperplane method to the loop nest starting with this loop label, if such a loop nest exists.

Presently, legality is not checked.

aliasxloop_hyperplanex'HyperplanexMethod'
loop_hyperplanexxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.1.13 Loop Nest Tiling

loop_tilingx8.1.13 requests from the user a numerical loop label and a numerical partitioning matrix and applies the tiling method to the loop nest starting with this loop label, if such a loop nest exists.

The partitioning matrix must be of dimension n × n where n is the loop nest depth. The default origin for the tiling is 0, but lower loop bounds are used to adjust it and decrease the control overhead. For instance, if each loop is of the usual kind, DOxIx=x1,xN, the tiling origin is point (1, 1,...). The code generation is performed according to the PPoPP’91 paper but redundancy elimination may results in different loop bounds.

Presently, legality is not checked. There is no decision procedure to select automatically an optimal partitioning matrix. Since the matrix must be numerically known, it is not possible to generate a block distribution unless all loop bounds are numerically known. It is assumed that the loop nest is fully parallel.

Jingling Xue published an advanced code generation algorithm for tiling

in Parallel Processing Letters (http://cs.une.edu.au/~xue/pub.html).

aliasxloop_tilingx'Tiling'
loop_tilingxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This transformations prompts the user for a partition matrix. Alternatively, this matrix can be provided through the LOOP_TILING_MATRIXx8.1.13 property. The format of the matrix is a00 a01 a02,a10 a11 a12,a20 a21 a22

   xLOOP_TILING_MATRIXx""
   x

Likewise, one can use the LOOP_LABELx8.1.1 property to specify the targeted loop.

8.1.14 Symbolic Tiling Tiles a loop nest using a partitioning vector that can contain symbolic values. The tiling only works for parallelepiped tiles. Use LOOP_LABELx8.1.1 to specify the loop to tile. Use SYMBOLIC_TILING_VECTORx8.1.14 as a comma-separated list to specify tile sizes. Use SYMBOLIC_TILING_FORCEx8.1.14 to bypass condition checks. Consider using loop_nest_unswitchingx7.2 if generated max disturbs further analyses

symbolic_tilingx>xMODULE.code
!xMODULE.coarse_grain_parallelization
<xPROGRAM.entities
<xMODULE.code
<xMODULE.cumulated_effects

   xSYMBOLIC_TILING_VECTORx""
   x
   xSYMBOLIC_TILING_FORCExFALSE
   x

8.1.15 Loop Normalize

The loop normalization consists in transforming all the loops of a given module into a normal form. In this normal form, the lower bound and the increment are equal to one (1).

   Property LOOP_NORMALIZE_PARALLEL_LOOPS_ONLYx8.1.15 control whether we

want to normalize only parallel loops or all loops. If we note the initial DO loop as:

       DO I = lower, upper, incre

...

                                                               ENDDO

the transformation gives the folowing code:

       DO NLC = 0, (upper - lower + incre)/incre - 1, 1
                                             I = incre*NLC + lower

...

                                                               ENDDO
       I =xincre * MAX((upper - lower + incre)/incre, 0) + lower

The normalization is done only if the initial increment is a constant number. The normalization produces two assignment statements on the initial loop index. The first one (at the beginning of the loop body) assigns it to its value function of the new index and the second one (after the end of the loop) assigns it to its final value.

aliasxloop_normalizex'LoopxNormalize'
loop_normalizexxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

If the increment is 1, the loop is considered already normalized. To have a 1-increment loop normalized too, set the following property

   xLOOP_NORMALIZE_ONE_INCREMENTxFALSE
   x

This is useful to have iteration spaces that begin at 0 for GPU for example.

The loop normalization has been defined in some days only Fortran was available, so having loops starting at 1 like the default for arrays too make sense in Fortran.

Anyway, no we could generalize for C (starting at 0 is more natural) or why not from any other value that can be chosen with the following property:

   xLOOP_NORMALIZE_LOWER_BOUNDx1
   x

If you are sure the final assignment is useless, you can skip it with the following property.

   xLOOP_NORMALIZE_SKIP_INDEX_SIDE_EFFECTxFALSE
   x
   xxLOOP_NORMALIZE_PARALLEL_LOOPS_ONLYxFALSE
   x

8.1.16 Guard Elimination and Loop Transformations Youcef Bouchebaba’s implementation of unimodular loop transformationsx

guard_eliminationxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.1.17 Tiling for sequences of loop nests Tiling for sequences of loop nests

Youcef Bouchebaba’s implementation of tiling for sequences of loop nests x

aliasxtiling_sequencex'Tilingxsequencexofxloopxnests'

tiling_sequencexxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.2 Redundancy Elimination

8.2.1 Loop Invariant Code Motion

This is a test to implement a loop-invariant code motion. This phase hoist loop-invariant code out of the loop.

A side effect of this transformation is that the code is parallelized too with some loop distribution. If you don’t want this side effect, you can check sectionx8.4.9 which does a pretty nice job too.

The original algorithm used is described in Chapters 12, 13 and 14 of Julien Zory’s PhD dissertationx[?].

invariant_code_motionxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.codexMODULE.dg

Note: this pass deals with loop invariant code motion while the icm pass deals with expressions.

8.2.2 Partial Redundancy Elimination In essence, a partial redundancy [?] is a computation that is done more than once on some path through a flowgraph. We implement here a partial redundancy elimination transformation for logical expressions such as bound checks by using informations given by precondition analyses.

This transformation is implemented by Thi Viet Nga Nguyen.

See also the transformation in §xsec:comm-subexpr-elim-1, the partial evaluation, and so on.

aliasxpartial_redundancy_eliminationx'PartialxRedundancyxElimination'
partial_redundancy_eliminationxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions

8.3 Control-Flow Optimizations

8.3.1 Dead Code Elimination

Alias for simplify_controlx8.3.1.

Function simplify_controlx8.3.1 is used to delete non-executed code, such as empty loop nests or zero-trip loops, for example after strip-mining or partial evaluation.

Preconditions are used to find always true conditions in tests and to eliminate such tests. In some cases, tests cannot be eliminated, but test conditions can be simplified. One-trip loops are replaced by an index initialization and the loop body. Zero-trip loops are replaced by an index initialization. Effects in bound computations are preserved.

A lot of dead code can simply be eliminated by testing its precondition feasibility. A very simple and fast test may be used if the preconditions are normalized when they are computed, but this slows down the precondition computation. Or non-normalized preconditions are stored in the database and an accurate and slow feasibility test must be used. Currently, the first option is used for assignments, calls, IOs and IF statements but a stronger feasibility test is used for loops.

FORMAT statements are suppressed because they behave like a NOP command. They should be gathered at the beginning or at the end of the module using

property GATHER_FORMATS_AT_BEGINNINGx4.3 or GATHER_FORMATS_AT_ENDx4.3.

The property must be set before the control flow graph of the module is computed.

The cumulated effects are used in debug mode to display information.

The simplify_controlx8.3.1 phase also performs some If Simplifications and Loop Simplificationsx[?].

This function was designed and implemented by Ronan Keryell.

aliasxsimplify_controlx'SimplifyxControl'
simplify_controlxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.preconditions

This pass is the same as simplify_controlx8.3.1. It is used under this obsolete name in some validation scripts. The name has been preserved for backward compatibility.

suppress_dead_codexxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.preconditions

This pass is very similar to simplify_controlx8.3.1, but it does not require the preconditions. Only local information is used. It can be useful to clean up input code with constant tests, e.g. 3>4, and constant loop bounds. It can also be used after partial_evalx8.4.2 to avoid recomputing the preconditions yet another time.

aliasxsimplify_control_directlyx'SimplifyxControlxDirectly'
simplify_control_directlyxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

8.3.1.1 Dead Code Elimination properties

It is sometimes useful to display statistics on what has been found useless and removed in a function, this property controls the statistics display:

   xDEAD_CODE_DISPLAY_STATISTICSxTRUE

8.3.2 Dead Code Elimination (a.k.a. Use-Def Elimination)

Function dead_code_eliminationx8.3.2 deletes statements whose def references are all dead, i.e. are not used by later executions of statements. It was developed by Ronan Keryell. The algorithm compute the set of live statements without fix-point. An initial set of live statements is extended with new statements reached thru use-def chains, control dependences and....

The initial set of live statements contains IO statements, RETURN, STOP,...

Note that use-def chains are computed intraproceduraly and not interproceduraly. Hence some statements may be preserved because they update a formal parameter although this formal parameter is no longer used by the callers.

The dependence graph may be used instead of the use-def chains, but Ronan Keryell, designer and implementer of the initial Fortran version, did not produce convincing evidence of the benefit... The drawback is the additional CPU time required.

This pass was extended to C by Mehdi Amini in 2009-2010, but it is not yet stabilized. For C code, this pass requires that effects are calculated with property MEMORY_EFFECTS_ONLY set to FALSE because we need that the DG includes arcs for declarations as these latter are separate statements now.

CLEAN_DECLARATIONSx?? is automatically done at the end, this is why cumulated effects are needed.

Comments from Nga Nguyen: According tox[?] p. 595, andx[?] p. 592, a variable is dead if it is not used on any path from the location in the code where it is defined to the exit point of the routine in the question; an instruction is dead if it computes only values that are not used on any executable path leading from the instruction. The transformation that identifies and removes such dead code is called dead code elimination. So in fact, the Use-def elimination pass in PIPS is a Dead code elimination pass and the Suppress dead code pass (see Sectionx8.3.1) does not have a standard name. It could be If and loop simplification pass.

The following properties are intended to force some functions to be kept by the algorithm, DEAD_CODE_ELIMINATION_KEEP_FUNCTIONSx8.3.2 expect a space separated

list of function names while DEAD_CODE_ELIMINATION_KEEP_FUNCTIONSx8.3.2 expect

a space separated list of prefix for function name.

   xDEAD_CODE_ELIMINATION_KEEP_FUNCTIONSx""
   x
   xDEAD_CODE_ELIMINATION_KEEP_FUNCTIONS_PREFIXx""
   x

aliasxdead_code_eliminationx'DeadxCodexElimination'
dead_code_eliminationxxxxxxxxxx>xMODULE.code

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.chains

For backward compatibility, the previous pass name is preserved.

aliasxuse_def_eliminationx'Use-Defxelimination'
use_def_eliminationxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.chains

8.3.3 Control Restructurers

Two control restructurers are available: unspaghettifyx8.3.3.1 which is used by default in conjunction with controlizerx4.3 and restructure_controlx8.3.3.2 which must be explicitly

applied2 ^{2A property can be used to force the call to restructurer by the controlizerx4.3.}

8.3.3.1 Unspaghettify

The unspaghettifier is a heuristic to clean up and to simplify the control graphs of a module. It is useful because the controlizer (see Sectionx4.3) or some transformation phases can generate some spaghetti code with a lot of useless unstructured code which can confuse some other parts of PIPS. Dead code elimination, for example,

uses unspaghettifyx8.3.3.1.

This control restructuring transformation can be automatically applied in the

controlizerx4.3 phase (see Sectionx4.3) if the UNSPAGHETTIFY_IN_CONTROLIZERx4.3

property is true.

To add flexibility, the behavior of unspaghettifyx8.3.3.1 is controlled

by the properties UNSPAGHETTIFY_TEST_RESTRUCTURINGx8.3.3.1 and
UNSPAGHETTIFY_RECURSIVE_DECOMPOSITIONx8.3.3.1 to allow more restructuring

from restructure_controlx8.3.3.2 to be added in the controlizerx4.3 for example.

This function was designed and implemented by Ronan Keryell.

aliasxunspaghettifyx'UnspaghettifyxthexControlxGraph'

unspaghettifyxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

To display the statistics about unspaghettifyx8.3.3.1 and control graph restructuring restructure_controlx8.3.3.2.

   xUNSPAGHETTIFY_DISPLAY_STATISTICSxTRUE
   x

The following option enables the use of IF/THEN/ELSE restructuring when applying unspaghettify:

   xUNSPAGHETTIFY_TEST_RESTRUCTURINGxFALSE
   x

It is assumed as true for restructure_controlx8.3.3.2. It recursively implement TEST restructuring (replacing IF/THEN/ELSE with GOTOs with structured IF/THEN/ELSE without any GOTOs when possible) by applying pattern matching methods.

The following option enables the use of control graph hierarchisation when applying unspaghettify:

   xUNSPAGHETTIFY_RECURSIVE_DECOMPOSITIONxFALSE
   x

It is assumed as true for restructure_controlx8.3.3.2. It implements a recursive decomposition of the control flow graph by an interval graph partitioning method.

The restructurer can recover some while loops if this property is set:

   xUNSPAGHETTIFY_WHILE_RECOVERxFALSE
   x

8.3.3.2 Restructure Control restructure_controlx8.3.3.2 is a more complete restructuring phase that is useful to improve the accuracy of various PIPS phases.

It is implemented by calling unspaghettifyx8.3.3.1 (§x8.3.3.1)

with the properties UNSPAGHETTIFY_TEST_RESTRUCTURINGx8.3.3.1 and
UNSPAGHETTIFY_RECURSIVE_DECOMPOSITIONx8.3.3.1 set to TRUE.

Other restructuring methods are available in PIPS with the TOOLPACK’s restructurer (see Sectionx8.3.4).

aliasxrestructure_controlx'RestructurexthexControlxGraph'
restructure_controlxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.3.3 For-loop recovering This control-flow transformation try to recover for-loops from while-loops. Useful to be run after transformations

aliasxrecover_for_loopx'Recoverxfor-loopsxfromxwhile-loops'
recover_for_loopxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

This phase cannot be called from inside the control restructurer since it needs many higher-level analysis. This is why it is in a separate phase.

8.3.3.4 For-loop to do-loop transformation Since in PIPS some transformations and analysis are more precise for Fortran code, this is a transformation than try to transform the C-like for-loops into Fortran-like do-loops.

Don’t worry about the C-code output: the prettyprinter output do-loop as for-loop if the C-output is selected. The do-loop construct is interesting since the iteration set is computed at the loop entry (for example it is not sensible to the index modification from the inside of the loop) and this simplifies abstract interpretation a lot.

This transformation transform for example a

for x ( i x=x lb ; x i x<xub ; x i x+=x s t r i d e )xxxbody ;

into a

dox i x=xlb , xubx−x 1 , x s t r i d e xxxbodyxendxdo

aliasxfor_loop_to_do_loopx'For-loopxtoxdo-loopxtransformation'
for_loop_to_do_loopxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.3.5 For-loop to while-loop transformation Since in PIPS some transformations and analysis may not be implemented for C for-loop but may be implemented for while-loop, it is interesting to have this for-loop to while-loop desugaring transformation.

This transformation transforms a for x ( i n i t ; xcond ; xupdate )xxxbody ;

into a

{xxx i n i t ; xxxwhile ( cond ) x{xxxxxbody ; xxxxxupdate ; xxx}x}

Since analysis are more precise on do-loops, you should apply a for_loop_to_do_loopx8.3.3.4 transformation first , and only after, apply this for_loop_to_while_loopx8.3.3.5 transformation that will transform the remaining for-loops into while loops.

aliasxfor_loop_to_while_loopx'For-loopxtoxwhile-loopxtransformation'
for_loop_to_while_loopxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.3.6 Do-while to while-loop transformation Some transformations only work on while loops, thus it is useful to have this transformation that transforms a

dox{xxxbody ; x}xwhilex ( cond ) ;

into a

{xxxbody ; x}xwhilex ( cond ) x{xxxbody ; x}

It is a transformation useful before while-loop to for-loop recovering for example (see §x8.3.3.3).

aliasxdowhile_to_whilex'Do-whilextoxwhile-loopxtransformation'
dowhile_to_whilexxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.3.7 Spaghettify

spaghettifyx8.3.3.7 is used in the context of the PHRASE project while creating “Finite State Machine”-like code portions in order to synthesize them in reconfigurable units.

This phases transform structured code portions (eg. loops) in unstructured statements.

spaghettifyx8.3.3.7 transforms the module in a unstructured code with hierarchical unstructured portions of code corresponding to the old control flow structures.

To add flexibility, the behavior of spaghettifyx8.3.3.7 is controlled by the properties

DESTRUCTURExTESTS

DESTRUCTURExLOOPS

DESTRUCTURExWHILELOOPS

DESTRUCTURExFORLOOPS

to allow more or less destruction power.

aliasxspaghettifyx'SpaghettifyxthexControlxGraph'

spaghettifyxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Thoses properties allow to fine tune spaghettifyx8.3.3.7 phase

   xDESTRUCTURE_TESTSxTRUE
   x
   xDESTRUCTURE_LOOPSxTRUE
   x
   xDESTRUCTURE_WHILELOOPSxTRUE
   x
   xDESTRUCTURE_FORLOOPSxTRUE
   x

8.3.3.8 Full Spaghettify The spaghettifyx8.3.3.7 is used in context of PHRASE project while creating“Finite State Machine”-like code portions in order to synthesize them in reconfigurable units.

This phases transforms all the module in a unique flat unstructured statement.

Whereas the spaghettifyx8.3.3.7 transforms the module in a unstructured code with hierarchical unstructured portions of code corresponding to the old structures, the full_spaghettifyx8.3.3.8 transform the code in a sequence statement with a beginning statement, a unique and flattened unstructured (all the unstructured and sequences are flattened), and a final statement.

aliasxfull_spaghettifyx'SpaghettifyxthexControlxGraphxforxthexentirexmodule'

full_spaghettifyxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.4 Control Structure Normalisation (STF)

Transformation stfx8.3.4 is a C interface to a Shell script used to restructure a Fortran program using ISTST (via the combined tool fragment ISTLY = ISTLX/ISTYP and then ISTST) from TOOLPACKx[?,x?].

Be careful, since TOOLPACK is written in Fortran, you need the Fortran runtime libraries to run STF if is has not been statically compiled...

Known bug/feature: stfx8.3.4 does not change resource code like other transformations, but the source file. Transformations applied before stfx8.3.4 are lost. This should be changed in the near future.

This transformation is now assumed redundant with respect to the native PIPS control restructurers that deal with other languages too.

aliasxstfx'RestructurexwithxSTF'
stfxxxxxxxxxxxxxxxxxxxxxx>xMODULE.source_file
xxxxxxxx<xMODULE.source_file

8.3.5 Trivial Test Elimination

Function suppress_trivial_testx8.3.5 is used to delete the branch TRUE of trivial test instruction. After apply suppress_trivial_testx8.3.5, the condition of the new test instruction is the condition correspondent to the branch FALSE of the test initial.

This function was designed and implemented by Trinh Quoc Anh.

aliasxsuppress_trivial_testx'TrivialxTestxElimination'
suppress_trivial_testxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.6 Finite State Machine Generation

Theses phases are used for PHRASE project.

NB: The PHRASE project is an attempt to automatically (or semi-automatically) transform high-level language for partial evaluation in reconfigurable logic (such as FPGAs or DataPaths).

This library provides phases allowing to build and modify ”Finite State Machine”-like code portions which will be later synthesized in reconfigurable units. This was implemented by Sylvain Gux�œrin.

8.3.6.1 FSM Generation This phase tries to generate finite state machine from arbitrary code by applying rules numeroting branches of the syntax tree and using it as state variable for the finite state machine.

This phase recursively transforms each UNSTRUCTURED statement in a WHILE-LOOP statement controlled by a state variable, whose different values are associated to the different statements.

To add flexibility, the behavior of fsm_generationx8.3.6.1 is controlled by the property FSMIZE_WITH_GLOBAL_VARIABLEx8.3.6.5 which controls the fact that the same global variable (global to the current module) must be used for each FSMized statements.

aliasxfsm_generationx'FSMxGeneration'
fsm_generationxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

To generate a hierarchical finite state machine, apply first spaghettifyx8.3.3.7 (§x8.3.3.7) and then fsm_generationx8.3.6.1.

To generate a flat finite state machine, apply first full_spaghettifyx8.3.3.8 (§x8.3.3.8) and then fsm_generationx8.3.6.1 or use the aggregate phase

full_fsm_generationx8.3.6.2.

8.3.6.2 Full FSM Generation This phase tries to generate a flat finite state machine from arbitrary code by applying rules numeroting branches of the syntax tree and using it as state variable for the finite state machine.

This phase transform all the module in a FSM-like code, which is a WHILE-LOOP statement controlled by a state variable, whose different values are associated to the different statements.

In fact, this phase do nothing but rely on pipsmake to apply the succession of the 2 phases full_spaghettifyx8.3.3.8 and fsm_generationx8.3.6.1 (§x8.3.6.1)

aliasxfull_fsm_generationx'FullxFSMxGeneration'
full_fsm_generationxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxx!xMODULE.full_spaghettify
xxxxxxxx!xMODULE.fsm_generation
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.6.3 FSM Split State This phase is not yet implemented and do nothing right now...

This phase transform a state of a FSM-like statement and split it into n new states where the portion of code to execute is smaller.

NB: Phase full_spaghettifyx8.3.3.8 must have been applied first !

aliasxfsm_split_statex'FSMxsplitxstate
fsm_split_statexxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.6.4 FSM Merge States This phase is not yet implemented and do nothing right now...

This phase transform 2 or more states of a FSM-like statement and merge them into a new state where the portion of code to execute is bigger.

NB: Phase full_spaghettifyx8.3.3.8 must have been applied first !

aliasxfsm_merge_statesx'FSMxmergexstates
fsm_merge_statesxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.3.6.5 FSM properties

Control the fact that the same global variable (global to the current module) must be used for each FSMized statements.

   xFSMIZE_WITH_GLOBAL_VARIABLExFALSE
   x

8.3.7 Control Counters

A code instrumentation that adds local integer counters in tests and loops to know how many times a path is taken. This transformation may help some semantical analyses.

aliasxadd_control_countersx'Controlxcounters
add_control_countersxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.4 Expression Transformations

8.4.1 Atomizers

Atomizer produces, or should produce, three-address like instructions, in Fortran. An atomic instructions is an instruction that contains no more than three variables, such as A = B op C. The result is a program in a low-level Fortran on which you are able to use all the others passes of PIPS.

Atomizers are used to simplify the statement encountered by automatic distribution phases. For instance, indirect addressing like A(B(I))x=x... is replaced

by T=B(I);A(T)x=x....

8.4.1.1 General Atomizer

aliasxatomizerx'Atomizer'
atomizerxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.dg

8.4.1.2 Limited Atomizer

This pass performs subscripts atomization so that they can be converted in reference for more accruate analysis.

simplify_subscriptsx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This pass performs a conversion from complex to real.

SIMPLIFY_COMPLEX_USE_ARRAY_OF_STRUCTSx8.4.1.2 controls the new layout

simplify_complexx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

   xSIMPLIFY_COMPLEX_USE_ARRAY_OF_STRUCTSxTRUE
   x

Split structures in separated variables when possible, that is remove the structure variable and replaces all fields by different variables.

split_structuresx>xMODULE.code
xxxx<xPROGRAM.entities
xxxx<xMODULE.code

Here is a new version of the atomizer using a small atomizer from the HPF compiler (see Sectionx7.3.2).

aliasxnew_atomizerx'NewxAtomizer'
new_atomizerxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

An atomizer is also used by WP65 (see Sectionx7.3.1)

8.4.1.3 Atomizer properties

This transformation only atomizes indirect references of array access functions.

   xATOMIZE_INDIRECT_REF_ONLYxFALSE
   x

By default, simple array accesses such as X(I+2) are atomized, although it is not necessary to generate assembly code:

   xATOMIZE_ARRAY_ACCESSES_WITH_OFFSETSxTRUE
   x

The purpose of the default option is to maximise common subexpression elimination.

Once a code has been atomized, you can use this transformation to generate two address code only It can be useful for asm generation

generate_two_addresses_codex>xMODULE.code
<xMODULE.code
<xMODULE.cumulated_effects
<xPROGRAM.entities

Set following property to false if you want to split dereferencing:

   xGENERATE_TWO_ADDRESSES_CODE_SKIP_DEREFERENCINGxTRUE
   x

8.4.2 Partial Evaluation

Function partial_evalx8.4.2 produces code where numerical constant expressions or subexpressions are replaced by their value. Using the preconditions, some variables are evaluated to a integer constant, and replaced wherever possible. They are not replaced in user function calls because Fortran uses a call-by-reference mechanism and because they might be updated by the function. For the same conservative reason, they are not replaced in intrinsics calls.

Note that symbolic constants were left unevaluated because they already are constant. However it was found unfriendly by users because the principle of least surprise was not enforced: symbolic constants were sometimes replaced in the middle of an expression but not when the whole expression was a reference to a symbolic constant. Symbolic integer constants are now replaced by their values systematically.

   Transformations simplify_controlx8.3.1 and dead_code_eliminationx8.3.2

should be performed after partial evaluation. It is sometimes important to run more than one partial evaluation in a row, because the first partial evaluation may linearize some initially non-linear expressions. Perfect Club benchmark ocean is a case in point.

Comments from Nga Nguyen: According tox[?] andx[?], the name of this optimization should be Constant-Expression Evaluation or Constant Folding for integer values. This transformation produces well error message at compile time indicating potential error such as division by zero.

aliasxpartial_evalx'PartialxEval'
partial_evalxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.preconditions

PIPS 3  ^{3http://www.cri.ensmp.fr/pips}

default behavior in various places is to evaluate symbolic constants. While meaningful, this approach is not source-to-source compliant, so one can set property EVAL_SYMBOLIC_CONSTANTx8.4.2 to FALSE to prevent some of those evaluations.

   xEVAL_SYMBOLIC_CONSTANTxTRUE
   x

One can also set PARTIAL_EVAL_ALWAYS_SIMPLIFYx8.4.2 to TRUE in order to force distribution, even when it does not seem profitable

   xPARTIAL_EVAL_ALWAYS_SIMPLIFYxFALSE
   x

Likewise, one can turn following property to true if he wants to use hard-coded value for size of types

   xEVAL_SIZEOFxFALSE
   x

This function was implemented initially by Bruno Baron.

8.4.3 Reduction Detection Phase Reductions detects generalized instructions and replaces them by calls to a run-time library supporting parallel reductions. It was developed by Pierre Jouvelot in CommonLISP, as a prototype, to show than NewGen data structures were language-neutral. Thus it by-passes some of pipsmake/dbm facilities.

This phase is now obsolete, although reduction detection is critical for code restructuring and optimization... A new reduction detection phase was implemented by Fabien Coelho. Have a look at §x6.3 but it does not include a code transformation. Its result could be prettyprinted in an HPF style (FC: implementation?).

old_reductionsxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

8.4.4 Reduction Replacement replace_reduction_with_atomicx8.4.4 replace all reduction in loop that are marked as

parallel with reduction by coarse_grain_parallelization_with_reductionx7.1.6.

The property ATOMIC_OPERATION_PROFILEx8.4.4 control the set of atomic operations and operand allowed. At that time only “cuda” is supported.

flag_parallel_reduced_loops_with_atomicx8.4.4 flag as parallel all loops that
were detected by coarse_grain_parallelization_with_reductionx7.1.6.

The property ATOMIC_OPERATION_PROFILEx8.4.4 control the set of atomic operations and operand allowed. At that time only “cuda” is supported.

   xATOMIC_OPERATION_PROFILEx"cuda"
   x

replace_reduction_with_atomicx>xMODULE.code
xxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.reduction_parallel_loops
xxxxxxxx<xMODULE.cumulated_reductions

flag_parallel_reduced_loops_with_atomicx>xMODULE.code
>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.reduction_parallel_loops
xxxxxxxx<xMODULE.cumulated_reductions

Flag loops with openmp directives, taking into account reductions.

flag_parallel_reduced_loops_with_openmp_directivesx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.reduction_parallel_loops
xxxxxxxx<xMODULE.cumulated_reductions

8.4.5 Forward Substitution

CSE)

Scalars can be forward substituted. The effect is to undo already performed optimizations such as invariant code motion and common subexpression elimination, or manual atomization. However we hope to do a better job automatically!

aliasxforward_substitutex'ForwardxSubstitution'
forward_substitutexxxxxx>xMODULE.code

xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.dg
xxxxxxxx<xMODULE.cumulated_effects

   One can set FORWARD_SUBSTITUTE_OPTIMISTIC_CLEANx8.4.5 to TRUE in order to

clean (without check) forward - substituted assignments. Use cautiously !

   xFORWARD_SUBSTITUTE_OPTIMISTIC_CLEANxFALSE
   x

8.4.6 Expression Substitution This transformation is quickly developed to fulfill the need of a simple pattern matcher in pips. The user provide a module name through EXPRESSION_SUBSTITUTION_PATTERNx8.4.6 property and all expression similar to those contained in EXPRESSION_SUBSTITUTION_PATTERNx8.4.6 will be substituted to a call to this module. It is a kind of simple outlining transformations, it proves to be useful during simdization to recognize some idioms. Note that the pattern must contain only a single return instruction!

This phase was developed by Serge Guelton during his PhD.

aliasxexpression_substitutionx'ExpressionxSubstitution'
expression_substitutionx>xMODULE.code
xxxxxxxx>xMODULE.callee
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xALL.code

Set RELAX_FLOAT_ASSOCIATIVITYx8.4.6 to TRUE if you want to consider all floating point operations

as really associative4 4Floating point computations are not associative in real hardware because of finite precision and rounding errors. For example (10^{50} ⊖ 10^{−60}) ⊕ 1 = 1 but 10^{50} ⊕ (−10^{−60} ⊕ 1) = 0. :

   xRELAX_FLOAT_ASSOCIATIVITYxFALSE
   x

This property is used to set the one-liner module used during expression substitution. It must be the name of a module already loaded in pips and containing only one return instruction (the instruction to be matched).

   xEXPRESSION_SUBSTITUTION_PATTERNx""
   x

8.4.7 Rename operator This transformation replaces all language operators by function calls.

rename_operatorx>xMODULE.code
xxxxxxxxxxxxxxxx<xMODULE.code
xxxxxxxxxxxxxxxx<xPROGRAM.entities

Function name is deduced from operator name, operator arguments type and a common prefix. Each function name is built using the pattern [PREFIX][OPxNAME][SUFFIX] (eg: int + int will lead to opxaddi). The replacement function must have been declared, otherwise a warning is asserted and the operator is ignored.

For instance, the following code:

float x foo ( float xa , x float xb)x{xxxxxreturnxax+xb ; x}

would become using the default configuration:

float x foo ( float xa , x float xb)x{xxxxxreturnxopxaddf ( a , xb ) ; x}

OPxNAME is given by the following table:

11post++11postxinc
11 ++pre11incxpre
11 post−−11postxdec
11 −−pre11decxpre
11  +11plus
11unary +11unxplus
11  −11minus
11unary −11unxminus

11

 11 *11mul
 11 /11div
 11 %11mod

11 =11assign
11 *=11mulxup
11 /=11divxup
11%=11modxup
11+=11plusxup

11−=11minusxup
11 <=11leq

11 <11lt

11 >=11geq

11 >11gt
11 ==11eq

11 !=11neq

11

Using the property RENAME_OPERATOR_OPSx8.4.7, it is possible to give a restrictive list of operator name on which operator renaming should be applied. Every operator not listed in this list will be ignored.

  xRENAME_OPERATOR_OPSx"plus␣minus␣mul␣div␣mod␣un_plus␣un_minus␣assign␣mul_up␣div_up␣mod_up␣plus_up␣minus_up"
  x

Assuming that all arguments of the operator have the same type. SUFFIX is deduced using the following table:

11char11c 11short11s 11 int11i 11

11 long11l 11 float11f 11double11d 11

11  xBool11b
11 xComplex11C
11xImaginary11I

11

Using the property RENAME_OPERATOR_SUFFIXESx8.4.7, it is possible to give a restrictive list of suffix on which operator renaming should be applied. Every type not listed in this list will be ignored.

  xRENAME_OPERATOR_SUFFIXESx"f␣d␣C␣I"
  x

The PREFIX is a common prefix defined by the property RENAME_OPERATOR_PREFIXx8.4.7 which is applied to each operators. It can be used to choose between multiple implementations of the same operator. The default value is opx.

  xRENAME_OPERATOR_PREFIXx"op_"
  x

In Pips, C For loop like for(i=0;xix<xn;xi++) is represented by a Fortran-like range-based Do loop doxix=x1,n−1. Thus, the code:

for ( i =0;x i x<xn ; x i++)

will be rewritten :

for ( i =0;x i x<=x opxsubi (n , 1 ) ; x i++)

If you want it to be rewritten :

for ( o p x a s s i g n i (&i , 0 ) ; x o p x l e q i ( i , opxsubi (n , 1 ) ) ; x o p x i n c i ( i , 1 ) )

   you should set the property RENAME_OPERATOR_REWRITE_DO_LOOP_RANGEx8.4.7 to

TRUE. This is not the default behaviour, because in most case you don’t want to rewrite For loop like this.

   xRENAME_OPERATOR_REWRITE_DO_LOOP_RANGExFALSE
   x

Some operators (=, +=, x) takes a modifiable lvalue. In this case, the expected function signature for a type T is Tx(T∗,xT). For instance, the code:

float xa , xb ; xax+=xb ;

would be rewritten:

float xa , xb ; xopxaddxupf(&a , xb ) ;

8.4.8 Array to pointer conversion This transformation replaces all arrays in the module by equivalent linearized arrays. Eventually using array/ pointer equivalence.

linearize_arrayx>xMODULE.code
xxxxxxxxxxxxxxxxx>xCOMPILATION_UNIT.code
x>xCALLERS.code
xxxxxxxxx>xPROGRAM.entities
<xPROGRAM.entities
<xMODULE.code
xxxxxxxx<xCOMPILATION_UNIT.code
<xCALLERS.code

This transformation replaces all arrays in the module by equivalent linearized arrays. This only makes the arrays starting their index from one.

linearize_array_fortranx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxx>xCALLERS.code
xxxxxxxx>xPROGRAM.entities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLERS.code

Use LINEARIZE_ARRAY_USE_POINTERSx8.4.8 to control whether arrays are declared as 1D arrays or pointers. Pointers are accessed using dereferencement and arrays using subscripts. This property does not apply to the fortran case.

   xLINEARIZE_ARRAY_USE_POINTERSxFALSE
   x

Use LINEARIZE_ARRAY_MODIFY_CALL_SITEx8.4.8 to control whether the call site is modified or not.

   xLINEARIZE_ARRAY_MODIFY_CALL_SITExTRUE
   x
   Use LINEARIZE_ARRAY_CAST_AT_CALL_SITEx8.4.8 to control whether a cast is

inserted at call sites. Turning it on break further effects analysis, but without the cast it might break compilation or at least generate warnings for type mismatch. This property does not apply to the fortran case.

   xLINEARIZE_ARRAY_CAST_AT_CALL_SITExFALSE
   x

Use LINEARIZE_ARRAY_VLA_ONLYx8.4.8 to limit this pass to C99 VLA array.

   xLINEARIZE_ARRAY_VLA_ONLYxFALSE
   x

8.4.9 Expression Optimizations

8.4.9.1 Expression optimization using algebraic properties This is an experimental section developed by Julien Zory as PhD workx[?]. This phase aims at optimizing expression evaluation using algebraic properties such as associativity, commutativity, neutral elements and so forth.

This phase restructure arithmetic expressions in order (1) to decrease the number of operations (e.g. through factorization), (2) to increase the ILP by keeping the corresponding DAG wide enough, (3) to facilitate the detection of composite instructions such as multiply-add, (4) to provide additional opportunities for (4a) invariant code motion (ICM) and (4b) common subexpression elimination (CSE).

Large arithmetic expressions are first built up via forward substitution when the programmer has already applied ICM and CSE by hand.

The optimal restructuring of expressions depends on the target defined by a combination of the computer architecture and the compiler. The target is specified by a string property called EOLE_OPTIMIZATION_STRATEGYx8.4.9.1 which can take values such as "P2SC" for IBM Power-2 architecture and XLFx4.3. To activate all sub-transformations such as ICM and CSE set it to "FULL". See properties for more information about values for this property and about other properties controlling the behavior of this phase.

The current implementation is still shaky and does not handle well expressions of mixed types such as X+1 where 1 is implictly promoted from integer to real.

Warning: this phase relies on an external (and unavailable) binary. To

make it work, you can set EOLE_OPTIMIZATION_STRATEGYx8.4.9.1 to "CSE"

or "ICM", or even ICMCSE to have both. This will only activate common subexpressions elimination or invariant code motion. Since it is a quite common use case, they have been defined as independent phase too. Seex8.4.9.2.

aliasxoptimize_expressionsx'OptimizexExpressions'
optimize_expressionsxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.code
aliasxinstruction_selectionx'SelectxInstructions'
instruction_selectionx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

EOLE: Evaluation Optimization of Loops and Expressions. Julien Zory stuff integrated within pipsx[?]. It relies on an external tool named eole. The version and options set can be controlled from the following properties. The status is experimental. See the optimize_expressionsx8.4.9.1 pass for more details about the advanced transformations performed.

   xEOLEx"newgen_eole"
   x
   xEOLE_FLAGSx"-nfd"
   x
   xEOLE_OPTIONSx""
   x
   xEOLE_OPTIMIZATION_STRATEGYx"P2SC"
   x

8.4.9.2 Common subexpression elimination

Here are described 2 interesting cases of the one in §x8.4.9.1.

Run common sub-expression elimination to factorize out some redundant expressions in the code.

   One can use COMMON_SUBEXPRESSION_ELIMINATION_SKIP_ADDED_CONSTANTx8.4.9.2 to skip
expression of the form a+2 and COMMON_SUBEXPRESSION_ELIMINATION_SKIP_LHSx8.4.9.2

to prevent elimination of left hand side of assignment.

The heuristic used for common subexpression elimination is described in Chapter 15 of Julien Zory’s PhD dissertationx[?].

aliasxcommon_subexpression_eliminationx'CommonxSubexpressionxElimination'
common_subexpression_eliminationx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.code
aliasxicmx'InvariantxCodexMotion'
icmx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.code

Note: the icm deals with expressions while the invariant_code_motion deals with loop invariant code.

The following property is used in sac to limit the subexpressions: When set to true, only subexpressions without ”+constant” terms are eligible.

   xCOMMON_SUBEXPRESSION_ELIMINATION_SKIP_ADDED_CONSTANTxFALSE
   x
   xCOMMON_SUBEXPRESSION_ELIMINATION_SKIP_LHSxTRUE
   x

Performs invariant code motion over sub expressions

8.5 Hardware Accelerator Generate code from a FREIA application possibly targeting hardware accelerator, such as SPoC, Terapix, or GPGPU. I’m unsure about the right granularity (now it is at the function level) and the resource which is produced (should it be an accelerated file?). The current choice does not allow to easily mix different accelerators.

8.5.1 FREIA Software Generate code for a software FREIA implementation, by applying various optimizations at the library API level, but without generating accelerated functions.

freia_aipo_compilerxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

The following properties are generic to all FREIA accelerator targets.

Whether to label arcs in dag dot output with the image name, and to label nodes with the statement number, and whether to filter out unused scalar nodes.

   xFREIA_DAG_LABEL_ARCSxFALSE

xFREIA_DAG_LABEL_NODESxTRUE
x
xFREIA_DAG_FILTER_NODESxTRUE
x

Whether to compile lone operations, i.e. operations which do not belong to a sequence.

xFREIA_COMPILE_LONE_OPERATIONSxTRUE
x

Whether to normalize some operations:

xFREIA_NORMALIZE_OPERATIONSxTRUE
x

Whether to simplify the DAG using algebraic properties.

xFREIA_SIMPLIFY_OPERATIONSxTRUE
x

Whether to remove dead image operations in the DAG. Should always be beneficial.

xFREIA_REMOVE_DEAD_OPERATIONSxTRUE
x

Whether to remove duplicate operations in the DAG, including algebraic optimizations with commutators. Should be always beneficial to terapix, but it may depend for spoc.

xFREIA_REMOVE_DUPLICATE_OPERATIONSxTRUE
x

Whether to remove useless image copies from the expression DAG.

xFREIA_REMOVE_USELESS_COPIESxTRUE
x

Whether to move image copies within an expression DAG outside as external copies, if possible.

xFREIA_MOVE_DIRECT_COPIESxTRUE
x

Whether to merge identical arguments, especially kernels, when calling an accelerated function:

xFREIA_MERGE_ARGUMENTSxTRUE
x

Whether to attempt to reuse initial images if possible, instead of keeping possibly newly introduced temporary images.

xFREIA_REUSE_INITIAL_IMAGESxTRUE
x

Try to allow shuffling image pointers, but this is not allowed by default because it may lead to wrong code as the compiler currently ignores the information and mixes up images.

   xFREIA_ALLOW_IMAGE_SHUFFLExFALSE
   x

Whether to assume that casts are simple image copies. Default is to keep a cast as cast, which is not accelerated.

   xFREIA_CAST_IS_COPYxFALSE
   x

Whether to cleanup freia returned status, as the code is assumed correct when compiled.

   xFREIA_CLEANUP_STATUSxTRUE
   x

Assume this pixel size in bits:

   xFREIA_PIXEL_SIZEx16
   x

If set to a non-zero value, assume this image size when generating code. If zero, try generic code. In particular, the height is useful to compute a better imagelet size when generating code for the Terapix hardware accelerator.

   xFREIA_IMAGE_HEIGHTx0
   x
   xFREIA_IMAGE_WIDTHx0
   x

8.5.2 FREIA SPoC FREIA Compiler for SPoC target. Consider applying freia_unroll_while beforehand.

freia_spoc_compilerxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxx>xMODULE.spoc_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
freia_unroll_while >xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Default depth of the target SPoC accelerator:

   xHWAC_SPOC_DEPTHx8
   x

8.5.3 FREIA Terapix FREIA compiler for Terapix target.

freia_terapix_compilerxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.terapix_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

Number of processing elements (PE) for the Terapix accelerator:

   xHWAC_TERAPIX_NPEx128
   x

Default size of memory, in pixel, for the Terapix accelerator (RAMPE is RAM of PE):

   xHWAC_TERAPIX_RAMPEx1024
   x

Terapix DMA bandwidth. How many terapix cycles to transfer an imagelet row (size of which is necessarily the number of pe):

   xHWAC_TERAPIX_DMABWx32
   x

Terapix 2D global RAM (GRAM) width and height:

   xHWAC_TERAPIX_GRAM_WIDTHx64
   x
   xHWAC_TERAPIX_GRAM_HEIGHTx32
   x

Whether and how to further cut the dag for terapix. Expected values, by order of compilation costs, are: none, compute, enumerate.

   xHWAC_TERAPIX_DAG_CUTx"compute"
   x

Whether input and output memory transfers overlap one with the other, that we have a full duplex DMA.

   xHWAC_TERAPIX_OVERLAP_IOxFALSE

Note that it is already assumed that computations overlap with communications. This adds the information that host-accelerator loads and stores run in parallel. This has two impacts: the communication apparent time is reduced thanks to the overlapping, which is good, but the imagelet memory cannot be reused for inputs because it is still live while being stored, which is bad for memory pressure.

Use this maximum size (height) of an imagelet if set to non-zero. It may be useful to set this value to the image height (if known) so that compiler generates code for smaller imagelets, so that the runtime is not surprised. This is rather use of debug to impose an imagelet size.

   xHWAC_TERAPIX_IMAGELET_MAX_SIZEx0
   x

8.5.4 FREIA OpenCL FREIA compiler for OpenCL target, which may run on both multi-core and GPU.

freia_opencl_compilerxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxxx>xMODULE.opencl_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects

Whether we should attempt to generate merged OpenCL image operations. If not, the result will be simular to simple AIPO compilation, no actual helper functions will be generated.

   xHWAC_OPENCL_MERGE_OPERATIONSxTRUE
   x

Whether merged OpenCL image operations should include reductions as well. Added to help debugging the code.

   xHWAC_OPENCL_MERGE_REDUCTIONSxTRUE
   x

Whether to generate OpenCL code for one operation on its own. It is not interesting to do so because it is just equivalent to the already existing AIPO implementation, but it can be useful for debug.

   xHWAC_OPENCL_COMPILE_ONE_OPERATIONxFALSE

8.6 Function Level Transformations

8.6.1 Inlining

Inlining is a well known technique. Basically, it replaces a function call by the function body. The current implementation does not work if the function has static declarations, access global variables x. Actually it (seems to) work(s) for pure, non-recursive functions xand not to work for any other kind of call.

Property INLINING_CALLERSx8.6.1 can be set to define the list of functions where the call sites have to be inlined. By default, all call sites of the inlined function are inlined.

Only for C because of pipsmake output declaration !

inliningxxxxxx>xCALLERS.c_source_file
xxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxxxxxxxx>xMODULE.callers
!xMODULE.split_initializations
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.code
xxxxxxxx<xCALLERS.printed_file
<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx*xALL.restructure_control
*xALL.remove_useless_label

Use following property to control how generated variables are initialized

   xINLINING_USE_INITIALIZATION_LISTxTRUE
   x

Use following property to control whether inlining should ignore stubs:

   xINLINING_IGNORE_STUBSxTRUE
   x

Use following property to control whether inlining should ignore stubs:

   xINLINING_IGNORE_STUBSxTRUE
   x

Set following property to TRUE to add comments on inlinied statements to keep track of their origin.

   xINLINING_COMMENT_ORIGINxFALSE
   x

Same as inlining but always simulate the by-copy argument passing

Only for C because of pipsmake output declaration !

inlining_simplexxxxxx>xCALLERS.c_source_file
xxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxxxxxxxxxxxxxxx>xMODULE.callers
!xMODULE.split_initializations
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.code
xxxxxxxx<xCALLERS.printed_file
<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx*xALL.restructure_control
*xALL.remove_useless_label

Regenerate the ri from the ri ...

Only for C because of pipsmake output declaration !

recompile_modulex>xMODULE.c_source_file
<xMODULE.code

The default behavior of inlining is to inline the given module in all call sites. Use INLINING_CALLERSx8.6.1 property to filter the call sites: only given module names will be considered.

   xINLINING_CALLERSx""
   x

8.6.2 Unfolding Unfolding is a complementary transformation of inliningx8.6.1. While inlining inlines all call sites to a given module in other modules, unfolding inlines recursively all call sites in a given module, thus unfolding the content of the module. An unfolded source code does not contain any call anymore. If you run it recursievly, you should set INLINING_USE_INITIALIZATION_LISTx8.6.1 to false.

Only for C because of output declaration in pipsmake rule!

unfoldingxxxxxx>xMODULE.c_source_file
xxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxx>xPROGRAM.entities
!xCALLERS.split_initializations
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.printed_file
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xCALLEES.code
xxxxxxxx*xALL.restructure_control
*xALL.remove_useless_label

Same as unfolding, but cumulated effects are not used, and the resulting code always simulates the by-copy argument passing.

Only for C because of output declaration in pipsmake rule!

unfolding_simplexxxxxx>xMODULE.c_source_file
xxxxxxxxxxxxxxxxxxxxxx>xMODULE.callees
xxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
!xCALLERS.split_initializations
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.printed_file
xxxxxxxx<xCALLEES.code
*xALL.restructure_control
*xALL.remove_useless_label

Use UNFOLDING_CALLEESx8.6.2, to specify which modules you want to inline in the unfolded module. The unfolding will be performed as long as one of the module in UNFOLDING_CALLEESx8.6.2 is called. More than one module can be specified, they are separated by blank spaces.

   xUNFOLDING_CALLEESx""
   x

The default behavior of the unfoldingx8.6.2 pass is to recursively inline all callees from the current module or from the argument modules of the pass, as long as a callee remains. You can use UNFOLDING_FILTERx8.6.2 to inline all call sites to a module not present in the space separated module list defined by the string property:

   xUNFOLDING_FILTERx""
   x

By default this list is empty and hence all call sites are inlined.

8.6.3 Outlining This documentation is a work in progress, as well as the documented topicSerge? Still true? What do you mean?.

Outlining is the opposite transformation of inliningx8.6.1. It replaces some statements in an existing module by a call site to a new function whose execution is equivalent to the execution of the replaced statements. The body of the new function is similar to the piece of code replaced in the existing module. The user is prompted for various pieces of information in order to perform the outlining:

a new module name,

the statement number of the first outlined statement,

number of statements to outline.

The statements are a subset of a sequence. They are counted in the sequenceSerge: I

invent...(FI).

   OUTLINE_WRITTEN_SCALAR_BY_REFERENCEx8.6.3 controls whether we pass

written scalar by reference or not. This property might lead to incorrect code !

outlinexxxxxx>xMODULE.code
!xMODULE.privatize_module
xxxxxxxx>xPROGRAM.entities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.code

The property OUTLINE_SMART_REFERENCE_COMPUTATIONx8.6.3 is used to limit the

number of entities passed by reference. With it, a[0][0] is passed as an a[n][m] entity, without it it is passed as an int or int∗ depending on the cumulated read/write memory effects of the outlined statementsSerge: but cumulated effects are always required?.

If you need to pass the upper bound expression of a particular loop as a parameter, which is used in Ter@pix code generation (see Sectionx???), set OUTLINE_LOOP_BOUND_AS_PARAMETERx8.6.3 to the loop labelSerge: a few words of motivation?.

The property OUTLINE_MODULE_NAMEx8.6.3 is used to specify the new module name. The user is prompted if it is set to its default value, the empty string.

But first the pass scansSerge: unconditionally? the code for any statement flagged with the pragma defined by the string property OUTLINE_PRAGMAx8.6.3Serge: What happens when it is set to the empty strin?.

If set, the string property OUTLINE_LABELx8.6.3 is used to choose the statementSerge: you outline a set of statements; is it reduced to a singleton in that case? to outline.

The boolean property OUTLINE_ALLOW_GLOBALSx8.6.3 controls whether global variables whose initial values are not used are passed as parameters or notSerge: why is it called “globals”? It seems that this makes sense for any local variable.... It is suggested to addressed this issue with a previous privatization pass.

   Finally, the boolean property OUTLINE_INDEPENDENT_COMPILATION_UNITx8.6.3

can be set to true to outline the new module into a newly created compilation unit. It is named after the OUTLINE_MODULE_NAMEx8.6.3. All necessary types, global variables and functionsSerge? are declared into this new compilation unitSerge: Consistency betweeen properties? Name conflicts?.

   xOUTLINE_MODULE_NAMEx""
   x
   xOUTLINE_PRAGMAx"pips␣outline"
   x
   xOUTLINE_LABELx""
   x
   xOUTLINE_ALLOW_GLOBALSxFALSE
   x
   xOUTLINE_SMART_REFERENCE_COMPUTATIONxFALSE
   x
   xOUTLINE_LOOP_BOUND_AS_PARAMETERx""
   x
   xOUTLINE_INDEPENDENT_COMPILATION_UNITxFALSE
   x
   xOUTLINE_WRITTEN_SCALAR_BY_REFERENCExTRUE

8.6.4 Cloning

Procedures can be cloned to obtain several specialized versions. The call sites must be updated to refer to the desired version.

User assisted cloning.See examples in clone validation suite. RK: terse; to be improved by FC

aliasxclonex'ManualxClone'
clonexxxxxxxxxxxxxxxxxxx>xCALLERS.code
xxxxxxxxxxxxxxxxxxxxxxxx>xCALLERS.callees
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.user_file
xxxxxxxx<xCALLERS.callees
xxxxxxxx<xCALLERS.code

aliasxclone_substitutex'ManualxClonexSubstitution'
clone_substitutexxxxxxxx>xCALLERS.code
xxxxxxxxxxxxxxxxxxxxxxxx>xCALLERS.callees
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.user_file
xxxxxxxx<xCALLERS.callees
xxxxxxxx<xCALLERS.code

Cloning of a subroutine according to an integer scalar argument. The argument is specified through integer property TRANSFORMATION_CLONE_ON_ARGUMENTx8.6.4. If set to 0, a user request is performed.

aliasxclone_on_argumentx'ClonexOnxArgument'
clone_on_argumentxxxxxxx>xCALLERS.code
xxxxxxxxxxxxxxxxxxxxxxxx>xCALLERS.callees
xxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callers
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx<xMODULE.user_file
xxxxxxxx<xCALLERS.callees
xxxxxxxx<xCALLERS.preconditions
xxxxxxxx<xCALLERS.code

Not use assisted version of cloning it just perform the cloning without any substitution Use the CLONE_NAMEx8.6.4 property if you want a particular clone name. It’s up to another phase to perform the substitution.

aliasxclone_onlyx'SimplexClone'
clone_only
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.user_file

There are two cloning properties. Cloning on an argument. If 0, a user request is performed.

   xTRANSFORMATION_CLONE_ON_ARGUMENTx0
   x

Clone name can be given using the CLONExNAME properties Otherwise, a new one is generated

   xCLONE_NAMEx""
   x

8.7 Declaration Transformations

8.7.1 Declarations cleaning Clean the declarations of unused variables and commons and so. It is also a code transformation, since not only the module entity are updated by the process, but also the declaration statements, some useless writes...

Clean the declarations of unused variables and commons and so.

aliasxclean_declarationsx'CleanxDeclarations'
clean_declarationsxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
<xMODULE.cumulated_effects

In C, dynamic variables which are allocated and freed but otherwise never used can be removed. This phase removes the calls to the dynamic allocation functions (malloc and free or user defined equivalents), and remove their declarations.

Clean unused local dynamic variables by removing malloc/free calls.

clean_unused_dynamic_variablesx>xMODULE.code
<xPROGRAM.entities
<xMODULE.code

It may be a regular expression instead of a function name?

   xDYNAMIC_ALLOCATIONx"malloc"
   x
   xDYNAMIC_DEALLOCATIONx"free"
   x

Detecting and forcing variables in the register storage class can help subsequent analyses, as they cannot be referenced by pointers.

force_register_declarationsx>xPROGRAM.entities
xxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxx<xPROGRAM.entities
xxxxxxxxx<xMODULE.code

Whether to allow arrays to be qualified as registers:

   xFORCE_REGISTER_ARRAYxTRUE
   x

Whether to allow pointers to be qualified as registers:

   xFORCE_REGISTER_POINTERxTRUE
   x

Whether to allow formal parameters to be qualified as registers:

   xFORCE_REGISTER_FORMALxTRUE
   x

8.7.2 Array Resizing One problem of Fortran code is the unnormalized array bound declarations. In many program, the programmer put an asterisk (assumed-size array declarator), even 1 for every upper bound of last dimension of array declaration. This feature affects code quality and prevents others analyses such as array bound checking, alias analysis. We developed in PIPS two new methods to find out automatically the proper upper bound for the unnormalized and assumed-size array declarations, a process we call array resizing. Both approaches have advantages and drawbacks and maybe a combination of these ones is needed.

To have 100% resized arrays, we implement also the code instrumentation task, in the top-down approach.

Different options to compute new declarations for different kinds of arrays are described in properties-rc.tex. You can combine the two approaches to have a better results by using these options.

How to use these approaches: after generating new declarations in the logfile, you have to use the script $PIPSxROOT/Src/Script/misc/arrayxresizingxinstrumentation.pl to replace the unnormalized declarations and add new assignments in the source code.

8.7.2.1 Top Down Array Resizing The method uses the relationship between actual and formal arguments from parameter-passing rules. New array declarations in the called procedure are computed with respect to the declarations in the calling procedures. It is faster than the first one because convex array regions are not needed.

This phase is implemented by Thi Viet Nga Nguyen (seex[?]).

aliasxarray_resizing_top_downx'TopxDownxArrayxResizing'
array_resizing_top_downxxxxxxxxx>xMODULE.new_declarations
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xCALLERS.code
xxxxxxxx<xCALLERS.new_declarations
xxxxxxxx<xCALLERS.preconditions

8.7.2.2 Bottom Up Array Resizing The approach is based on an convex array region analysis that gives information about the set of array elements accessed during the execution of code. The regions READ and WRITE of each array in each module are merged and a new value for the upper bound of the last dimension is calculated and then it will replace the 1 or *.

This function is firstly implemented by Trinh Quoc Anh, and ameliorated by Corinne Ancourt and Thi Viet Nga Nguyen (seex[?]).

aliasxarray_resizing_bottom_upx'BottomxUpxArrayxResizing'
array_resizing_bottom_upxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions

8.7.2.3 Array Resizing Statistic We provide here a tool to calculate the number of pointer-type A(,1) and assumed-size A(,*) array declarators as well as other information.

aliasxarray_resizing_statisticx'ArrayxResizingxStatistic'
array_resizing_statisticxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.7.2.4 Array Resizing properties This phase is firstly designed to infer automatically new array declarations for assumed-size (A(*)) and one (A(1) or also called ugly assumed-size) array declarators. But it also can be used for all kinds of array : local or formal array arguments, unnormalized or all kinds of declarations. There are two different approaches that can be combined to have better results.

Top-down Array Resizing There are three different options:

Using information from the MAIN program or not (1 or 0). If you use this option, modules that are never called by the MAIN program are not taken into account. By default, we do not use this information (0).

Compute new declarations for all kinds of formal array arguments, not only assumed-size and one declarations (1 or 0). By default, we compute for assumed-size and one only (0).

Compute new declarations for assumed-size array only, not for ugly assumed-size (one) array (1 or 0). By default, we compute for both kinds (0).

So the combination of the three above options gives us a number from 0 to 7 (binary representation : 000, 001,..., 111). You must pay attention to the order of options. For example, if you want to use information from MAIN program to compute new declarations for assumed-size and one array declarations, both of them, the option is 4 (100). The default option is 0 (000).

xARRAY_RESIZING_TOP_DOWN_OPTIONx0
x

Bottom-up Array Resizing There are also three different options:

Infer new declarations for arrays with declarations created by the top-down approach or not (1 or 0). This is a special option because we want to combine the two approaches: apply top-down first and then bottom-up on the instrumented arrays (their declarations are of from: IxPIPSxMODULExARRAY). By default, we do not use this option (0).

Compute new declarations for all kinds of array arguments, not only assumed-size and one declarations (1 or 0). By default, we compute for assumed-size and one only (0).

Compute new declarations for local array arguments or not (1 or 0). By default, we compute for formal array arguments only (0).

So the combination of the three above options gives us a number from 0 to 7 (binary representation : 000, 001,..., 111). You must pay attention to the order of options. There are some options that exclude others, such as the option to compute new declarations for instrumented array (IxPIPSxMODULExARRAY). The default option is 0 (000).

xARRAY_RESIZING_BOTTOM_UP_OPTIONx0
x

8.7.3 Scalarization Scalarization is the process of replacing array references with references to scalar copies of the array elements wherever appropriate. Expected benefits include lower memory footprint and access time because registers can be used instead of temporary stack variables or memory accesses, and hence, shorter execution times, as long as the register pressure is not so high that spill code is generated.

Scalarizing a given array reference is subject to two successive criteria, a Legality criterion and a Profitability criterion:

The Legality criterion is evaluated first. It tries and determines if replacing the reference might lead to breaking dependence arcs, due to hidden references to the element, e.g. “get(A,i)” instead of “A[i]”. Also, one and only one array element must be accessed at each iteration. If these two conditions are not met, no scalarization takes place.

The Profitability criterion is then evaluated, to try and eliminate cases where scalarization would yield no satisfactory performance gains, e.g. when a scalarized reference has to be immediately copied back into the original reference. This is performed at the source level and depends on the effective register allocation and code generation.

The legality test is based on convex array regions, and not on the dependence graph as is the Carr’s algorithm. Currently, loop carried dependence arcs prevent scalarization by PIPS, although some can be processed by Carr’s algorithm. See non-regression tests Transformations/scalarization30 to 36.

This transformation is useful 1) to improve the readability of the source code with constructs similar to let x be ..., 2) to improve the modelizations of the execution, time or energy, by using source instructions closer to the machine instruction, 3) to perform an optimization at the source level because the code generator does not include a powerful (partially) redundant load elimination, and 4) to be a useful pass in a fully source-to-source compiler. This transformation is useful to reduce the expansion caused by the different atomizer passes.

The new scalar variables use the default prefix ___scalar__and are thus easily identified, but a new prefix can be user defined with

PropertyxSCALARIZATION_PREFIXx8.7.3. IfSCALARIZATION_PREFIXx8.7.3 is the

empty string, the names of the scalarized variables are used.

If needed according to the IN and OUT convex array regions, the new variables are initialized, e.g. __scalar0__x=xA[i], and/or copied back into the initial array,

e.g. A[i]x=x__scalar0__.

Scalarization is currently applicable both to Fortran and C code, but the code generation slightly differs because local declarations are possible with C. However, this may destroy perfect loop nests required by other passes. Property

SCALARIZATION_PRESERVE_PERFECT_LOOP_NESTx8.7.3 can be used to preserve C

perfect loop nests.

Pass scalarizationx8.7.3 uses the read and written convex array regions to decide if the scalarization is possible, the IN and OUT regions to decide if it is useful to initialize the scalar copy or to restore the value of the array element.

aliasxscalarizationx'Scalarization'
scalarizationxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions

Since OUT regions are computed interprocedurally, strange code may result when a small or not so small function without any real output is scalarized. The problem can be fixed by adding a PRINT or a printf to force an OUT region, or by setting

Property SCALARIZATION_FORCE_OUTx8.7.3 to true.

Also, it may be useful to use Property SEMANTICS_TRUST_ARRAY_DECLARATIONSx6.8.11.2

and/or SEMANTICS_TRUST_ARRAY_REFERENCESx6.8.11.2 to make sure that as

many loops as possible are entered. If not, loop bounds may act like guards, which prevents PIPS from hoisting a reference out of a loop, although this is puzzling for programmers because they expect all loops to be entered at least once...

As explained above, Property SCALARIZATION_PREFIXx8.7.3 is used to select the names of the new scalar variables. If it is set to the empty string, "", the scalarized variable name is used as prefix, which improves readability.

   xSCALARIZATION_PREFIXx""
   x
   Also, as explained above, Property SCALARIZATION_PRESERVE_PERFECT_LOOP_NESTx8.7.3

is used to control the way new scalar variables are declared and initialized in C. The current default value is FALSE because the locality of declarations is better for automatic loop parallelization, but this could be changed as a privatization pass should do as well while preserving perfect loop nests. Note that initializations may have to be placed in such a way that a perfect loop nest is nevertheless destroyed, even with this property set to true.

   xSCALARIZATION_PRESERVE_PERFECT_LOOP_NESTxFALSE
   x

Property SCALARIZATION_FORCE_OUTx8.7.3 forces the generation of a copy-out statement when it is useless according to the OUT region, for instance when dealing with a library function.

   xSCALARIZATION_FORCE_OUTxFALSE
   x

Numerical property SCALARIZATION_THRESHOLDx8.7.3 is used to decide profitability: the estimated complexity of the scalarized code must be less than the initial complexity. Its minimal value is 2. It can be set to around 5 to forbid scalarization in sequences with no loop benefit.

   xSCALARIZATION_THRESHOLDx2
   x
   Property SCALARIZATION_STRICT_MEMORY_ACCESSESx8.7.3 is used to

control the insertion of new memory accesses. A memory access may be moved out of a loop, which is the best case for performance, but it then is no longer control dependent on the loop bounds. A new access is thus added if the compiler cannot prove that the loop is always entered. However, the burden of the proof may be too much, if only because nothing can be proven when the loop is sometimes entered and sometimes not. Also, the memory access may be always perfectly legal. The default value is FALSE, going for performance before safety. This property is pretty hard to understand, as well as its impact. See sequence06, 07 and 08 in the validaiton suite of the scalarization pass.

   xSCALARIZATION_STRICT_MEMORY_ACCESSESxFALSE
   x

This pass was designed by Franxois Irigoin and implemented by Laurent Daverio and Franxois Irigoin.

Similar to scalarizationx8.7.3, but with a different criterion: if an array is only accessed with numerical constant subscript expressions, it is replaced by a set of scalars and all its references are replaced by references to the corresponding scalars.

constant_array_scalarizationx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This pass may be useful to make C source code more palatable to C to VHDL converter that prefer dealing with scalars than arrays. It is also useful to propagate constants contained in an array since the semantics passes only analyze scalar variables.

This pass was designed and implemented by Serge Guelton.

Pass scalarizationx8.7.3 may be costly because it relies on array regions analyses and uses them to check its legality criteria. The next phase alleviates these drawbacks.

This Pass solely relies on proper and cumulated effets, and as such may fail to scalarize some accesses. However, it is expected to give good results in current cases, especially after loop_fusionx8.1.6.

It basically uses the same algorithm as scalar privatization, but performs on the dependence graph rather than the chains graph for more precision about array dependences. Several legality criteria are then tested to ensure the safety of the transformation. In particular, it is checked that candidate references are not accessed through hidden references (for instance in calls), and that only one kind of reference is scalarized in the loop.

aliasxquick_scalarizationx'QuickxScalarization'
quick_scalarizationxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.dg

8.7.4 Induction Variable Substitution Induction substitution is the process of replacing scalar variables by a linear expression of the loop indices.

aliasxinduction_substitutionx'Inductionxvariablexsubstitution'
induction_substitutionx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

This pass was designed and implemented by Mehdi Amini.

8.7.5 Strength Reduction Reduce the complexity of expression computation by generating induction variables when possible. E.g.

for ( i =0; i<n ; i++)xxxa [ i ]=2;

Would become

for ( i =0; i<n ; i++)x{xxx∗a=2;xxxa++;x}

strength_reductionx>xMODULE.code
xxxxxxxxxxxxxxxxxxx>xPROGRAM.entities
xxxx<xMODULE.code
xxxx<xMODULE.cumulated_effects
xxxx<xMODULE.transformers

8.7.6 Flatten Code The goal of this program transformation is to enlarge basic blocks as much as possible to increase the opportunities for optimization.

This transformation has been developed in PIPS for heterogeneous computing and is combined with inlining to increase the size of the code executed by an external accelerator while reducing the externalization

overhead5  ^{5FREIA project}  .

Other transformations, such as partial evaluation and dead code elimination (including use-def elimination) can be applied to streamline the resulting code further.

The transformation flatten_codex8.7.6 firstly moves declarations up in the abstract syntax tree, secondly remove useless braces and thirdly fully unroll loops when there iteration counts are known and the FLATTEN_CODE_UNROLL property is true. Unrolling can also be controlled using Property FULL_LOOP_UNROLL_EXCEPTIONSx8.1.8.2.

Inlining(s), which must be performed explicitly by the user with tpips or another PIPS interface, can be used first to create lots of opportunities. The basic block size increase is first due to brace removals made possible when declarations have been moved up, and then to loop unrollings. Finally, partial evaluation, dead code elimination and use-def based elimination can also straighten-out the code and enlarge basic blocks by removing useless tests or assignments.

The code externalization and adaptation for a given hardware accelerator is performed by another phase, see for instance Sectionx8.5.

Initially developed in August 2009 by Laurent Daverio, with help from Fabien Coelho and Franx¿œois Irigoin.

aliasxflatten_codex'FlattenxCode'
flatten_codex>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

If the following property is set, loop unrolling is applied too for loops with static bounds.

   xFLATTEN_CODE_UNROLLxTRUE
   x

8.7.7 Split Update Operator Split C operators such as ax+=xb, ax*=xb, ax>>=xb, etc. into their expanded form

such as ax=xax+xb.

Note that if you have side effects in the destination, since the destination is evaluated twice, it is not equivalent in the general case.

split_update_operatorx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.7.8 Split Initializations (C code) The purpose of this transformation is to separate the initialization part from the declaration part in C code in order to make static code analyses simpler.

This transformation recurses through all variable declarations, and creates a new statement each time an initial value is specified in the declaration, if the initial value can be assigned. The declarations are modified by eliminating the initial value, and a new assignment statement with the initial value is added to the source code.

This transformation can be used, for instance, to improve reduction detection (see TRAC ticket 181).

Note that C array and structure initializations, which use braces, cannot be converted into assignments. In such cases, the initial declaration is left untouchedFI-¿SG: improved?.

aliasxsplit_initializationsx'SplitxInitializations'
split_initializationsx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This transformation uses the C89_CODE_GENERATION property to generate either C89 or C99 code.

8.7.9 Set Return Type The purpose of this transformation is to change the return type of a function. The new type will be a typedef whose name is controlled by

SET_RETURN_TYPE_AS_TYPEDEF_NEW_TYPEx8.7.9. The corresponding typedef must

exist in the symbol table.

This transformation loops over the symbols in the symbol table, and for each of them which is a typedef, compare the local name to the property

SET_RETURN_TYPE_AS_TYPEDEF_NEW_TYPEx8.7.9. This approach is unsafe because

there can be differents typedef with the same name in different compilation units, resulting in differents entries in the symbol table for a same local name. The return type can also be incoherent with the return statement, thus it is not safe to run it on a non void function.

However this pass has been created for special need in par4all, and considering previously described restrictions, it does the job.

   xSET_RETURN_TYPE_AS_TYPEDEF_NEW_TYPEx"P4A_accel_kernel_wrapper"
   x

aliasxset_return_type_as_typedefx'Setxreturnxtypexasxtypedef'
set_return_type_as_typedefx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.7.10 Cast at Call Sites The purpose of this transformation is to force parameters at call sites to be casted as expected according to the prototype of the functions.

aliasxcast_at_call_sitesx'Callxparametersxatxcallxsites'
cast_at_call_sitesx>xCALLERS.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.callers
xxxxxxxx<xCALLERS.code

8.8 Array Bound Checking Array bound checking refers to determining whether all array references are within their declared range in all of their uses in a program. These array bound checks may be analysed intraprocedurally or interprocedurally, depending on the need for accuracy.

There are two versions of intraprocedural array bounds checking: array bound check bottom up, array bound check top down. The first approach relies on checking every array access and on the elimination of redundant tests by advanced dead code elimination based on preconditions. The second approach is based on exact convex array regions. They are used to prove that all accessed in a compound statement are correct.

These two dynamic analyses are implemented for Fortran. They are described in Nga Nguyen’s PhD (seex[?]). They may work for C code, but this has not been validated.

8.8.1 Elimination of Redundant Tests: Bottom-Up Approach This transformation takes as input the current module, adds array range checks (lower and upper bound checks) to every statement that has one or more array accesses. The output is the module with those added tests.

If one test is trivial or exists already for the same statement, it is no need to be generated in order to reduce the number of tests. As Fortran language permits an assumed-size array declarator with the unbounded upper bound of the last dimension, no range check is generated for this case also.

Associated with each test is a bound violation error message and in case of real access violation, a STOP statement will be put before the current statement.

This phase should always be followed by the partial_redundancy_eliminationx8.2.2 for logical expression in order to reduce the number of bound checks.

aliasxarray_bound_check_bottom_upx'EliminationxofxRedundantxTests'
array_bound_check_bottom_upxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.8.2 Insertion of Unavoidable Tests This second implementation is based on the array region analyses phase which benefits some interesting proven properties:

If a MAY region correspond to one node in the control flow graph that represents a block of code of program is included in the declared dimensions of the array, no bound check is needed for this block of code.

If a MUST region correspond to one node in the control flow graph that represents a block of code of program contains elements which are outside the declared dimensions of the array, there is certainly bound violation in this block of code. An error can be detected just in compilation time.

If none of these two properties are satisfied, we consider the approximation of region. In case of MUST region, if the exact bound checks can be generated, they will be inserted before the block of code. If not, like in case of MAY region, we continue to go down to the children nodes in the control flow graph.

The main advantage of this algorithm is that it permits to detect the sure bound violations or to tell that there is certainly no bound violation as soon as possible, thanks to the context given by preconditions and the top-down analyses.

aliasxarray_bound_check_top_downx'InsertionxofxUnavoidablexTests'
array_bound_check_top_downxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions

8.8.3 Interprocedural Array Bound Checking This phase checks for out of bound errors when passing arrays or array elements as arguments in procedure call. It ensures that there is no bound violation in every array access in the callee procedure, with respect to the array declarations in the caller procedure.

aliasxarray_bound_check_interproceduralx'InterproceduralxArrayxBoundxChecking'
array_bound_check_interproceduralxxxxxxxxxxxxx>xMODULE.code

xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions

8.8.4 Array Bound Checking Instrumentation We provide here a tool to calculate the number of dynamic bound checks from both initial and PIPS generated code.

These transformations are implemented by Thi Viet Nga Nguyen (seex[?]).

aliasxarray_bound_check_instrumentationx'ArrayxBoundxCheckingxInstrumentation'
array_bound_check_instrumentationx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Array bounds checking refers to determining whether all array reference are within their declared range in all of its uses in a program. Here are array bounds checking options for code instrumentation, in order to compute the number of bound checks added. We can use only one property for these two case, but the meaning is not clear. To be changed ?

   xINITIAL_CODE_ARRAY_BOUND_CHECK_INSTRUMENTATIONxTRUE
   x
   xPIPS_CODE_ARRAY_BOUND_CHECK_INSTRUMENTATIONxFALSE
   x

In practice, bound violations may often occur with arrays in a common block. The standard is violated, but programmers think that they are not dangerous because the allocated size of the common is not reached. The following property deals with this kind of bad programming practice. If the array is a common variable, it checks if the reference goes beyond the size of the common block or not.

   xARRAY_BOUND_CHECKING_WITH_ALLOCATION_SIZExFALSE
   x

The following property tells the verification phases (array bound checking, alias checking or uninitialized variables checking) to instrument codes with the STOP or the PRINT message. Logically, if a standard violation is detected, the program will stop immediately. Furthermore, the STOP message gives the partial redundancy elimination phase more information to remove redundant tests occurred after this STOP. However, for the debugging purposes, one may need to display all possible violations such as out-of-bound or used-before-set errors, but not to stop the program. In this case, a PRINT message is chosen. By default, we use the STOP message.

   xPROGRAM_VERIFICATION_WITH_PRINT_MESSAGExFALSE
   x

8.9 Alias Verification

8.9.1 Alias Propagation

Aliasing occurs when two or more variables refer to the same storage location at the same program point. Alias analysis is critical for performing most optimizations correctly because we must know for certain that we have to take into account all the ways a location, or the value of a variable, may (or must) be used or changed. Compile-time alias information is also important for program verification, debugging and understanding.

In Fortran 77, parameters are passed by address in such a way that, as long as the actual argument is associated with a named storage location, the called subprogram can change the value of the actual argument by assigning a value to the corresponding formal parameter. So new aliases can be created between formal parameters if the same actual argument is passed to two or more formal parameters, or between formal parameters and global parameters if an actual argument is an object in common storage which is also visible in the called subprogram or other subprograms in the call chain below it.

Both intraprocedural and interprocedural alias determinations are important for program analysis. Intraprocedural aliases occur due to pointers in languages like LISP, C, C++ or Fortran 90, union construct in C or EQUIVALENCE in Fortran. Interprocedural aliases are generally created by parameter passing and by access to global variables, which propagates intraprocedural aliases across procedures and introduces new aliases.

The basic idea for computing interprocedural aliases is to follow all the possible chains of argument-parameters and nonlocal variable-parameter bindings at all call sites. We introduce a naming memory locations technique which guarantees the correctness and enhances the precision of data-flow analysis. The technique associates sections, offsets of actual parameters to formal parameters following a certain call path. Precise alias information are computed for both scalar and array variables. The analysis is called alias propagation.

This analysis is implemented by Thi Viet Nga Nguyen (seex[?]).

alias_propagationxxxxxxxxxxx>xMODULE.alias_associations
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLERS.alias_associations
xxxxxxxx<xCALLERS.code

8.9.2 Alias Checking

With the call-by-reference mechanism in Fortran 77, new aliases can be created between formal parameters if the same actual argument is passed to two or more formal parameters, or between formal parameters and global parameters if an actual argument is an object in common storage which is also visible in the called subprogram or other subprograms in the call chain below it.

Restrictions on association of entities in Fortran 77 (Section 15.9.3.6 [?]) say that neither aliased formal parameters nor the variable in the common block may become defined during execution of the called subprogram or the others subprograms in the call chain.

This phase uses information from the alias_propagationx8.9.1 analysis and computes the definition informations of variables in a program, and then to verify statically if the program violates the standard restriction on alias or not. If these informations are not known at compile-time, we instrument the code with tests that check the violation dynamically during execution of program.

This verification is implemented by Thi Viet Nga Nguyen (seex[?]).

aliasxalias_checkx'AliasxCheck'
alias_checkxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.alias_associations
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xALL.code

This is a property to control whether the alias propagation and alias checking phases use information from MAIN program or not. If the current module is never called by the main program, we do no alias propagation and alias checking for this module if the property is on. However, we can do nothing with modules that have no callers at all, because this is a top-down approach.

   xALIAS_CHECKING_USING_MAIN_PROGRAMxFALSE
   x

8.10 Used Before Set This analysis checks if the program uses a variable or an array element which has not been assigned a value. In this case, anything may happen: the program may appear to run normally, or may crash, or may behave unpredictably. We use IN regions that give a set of read variables not previously written. Depending on the nature of the variable: local, formal or global, we have different cases. In principle, it works as follows: if we have a MUST IN region at the module statement, the corresponding variable must be used before being defined, a STOP is inserted. Else, we insert an initialization function and go down, insert a verification function before each MUST IN at each sub-statements.

This is a top-down analysis that process a procedure before all its callees. Information given by callers is used to verify if we have to check for the formal parameters in the current module or not. In addition, we produce information in the resource MODULE.ubs to tell if the formal parameters of the called procedures have to be checked or not.

This verification is implemented by Thi Viet Nga Nguyen (seex[?]).

aliasxused_before_setx'UsedxBeforexSet'
used_before_setxxx>xMODULE.ubs
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xCALLERS.ubs

8.11 Miscellaneous transformations The following warning paragraphs should not be located here, but the whole introduction has to be updated to take into account the merger with properties-rc.tex, the new content (the transformation section has been exploded) and the new passes such as gpips. No time right now. FI.

All PIPS transformations assume that the initial code is legal according to the language standard. In other words, its semantics is well defined. Otherwise, it is impossible to maintain a constant semantics through program transformations. So uninitialized variables, for instance, can lead to codes that seem wrong, because they are likely to give different outputs than the initial code. But this does not matter as the initial code output is undefined and could well be the new output,

Also, remember that dead code does not impact the semantics in an observable way. Hence dead code can be transformed in apparently weird ways. For instance, all loops that are part of a dead code section can be found parallel, although they are obviously sequential, because all the references will carry an unfeasible predicate. In fact, reference A(I), placed in a dead code section, does not reference the memory and does not have to be part of the dependence graph.

Dead code can crop out in many modules when a whole application linked with a library is analyzed. All unused library modules are dead for PIPS.

On the other hand, missing source modules synthesized by PIPS may also lead to weird results because they are integrated in the application with empty definitions. Their call sites have no impact on the application semantics.

8.11.1 Type Checker

Typecheck code according to Fortran standard + double-complex. Typechecking is performed interprocedurally for user-defined functions. Insert type conversions where implicitly needed. Use typed intrinsics instead of generic ones. Precompute constant conversions if appropriate (e.g. 16 to 16.0E0). Add comments about type errors detected in the code. Report back how much was done.

type_checkerxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.code

Here are type checker options. Whether to deal with double complex or to refuse them. Whether to add a summary of errors, conversions and simplifications as a comment to the routine. Whether to always show complex constructors.

   xTYPE_CHECKER_DOUBLE_COMPLEX_EXTENSIONxFALSE
   x
   xTYPE_CHECKER_LONG_DOUBLE_COMPLEX_EXTENSIONxFALSE
   x
   xTYPE_CHECKER_ADD_SUMMARYxFALSE
   x
   xTYPE_CHECKER_EXPLICIT_COMPLEX_CONSTANTSxFALSE
   x

8.11.2 Scalar and Array Privatization

Variable privatization consists in discovering variables whose values are local to a particular scope, usually a loop iteration.

Three different privatization functions are available. The quick privatization is restricted to loop indices and is included in the dependence graph computation (see Sectionx6.5). The scalar privatization should be applied before any serious parallelization attempt. The array privatization is much more expensive and is still mainly experimental.

You should keep in mind that, although they modify the internal repesentation of the code, scalar and array privatizations are only latent program transformations, and no actual local variable declaration is generated. This is the responsibility of code generation phases, which may use this information differently depending on their target.

8.11.2.1 Scalar Privatization

Privatizer detects variables that are local to a loop nest and marks these variables as private. A variable is private to a loop if the values assigned to this variable inside the loop cannot reach a statement outside the loop body.

Note that illegal code, for instance code with uninitialized variables, can lead to surprising privatizations, which are still correct since the initial semantics is unspecified.

aliasxprivatize_modulex'PrivatizexScalars'
privatize_modulexxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities

xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.chains

Use informations from privatize_modulex8.11.2.1 to change C variable declarations. For instance

int x i , j ; xfor ( i =0; i <10; i++)xxxxxxxxxfor ( j =0; j <10; j++)xxxxxxxxx …

becomes

int x i ; xfor ( i =0; i <10; i++)x{xxxxxxxxxint x j ; xxxxxxxxxfor ( j =0; j <10; j++)xxxxxxxxx … x}

localize_declarationx>xMODULE.code
!xMODULE.privatize_module
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

   xLOCALIZE_DECLARATION_SKIP_LOOP_INDICESxFALSE
   x

8.11.2.2 Array Privatization

Array privatization aims at privatizing whole arrays (array_privatizerx8.11.2.2) or sets of array elements (array_section_privatizerx8.11.2.2) instead of scalar variables only. The algorithm, developed by Bxatrice Creusilletx[?], is very different from the algorithm used for solely privatizing scalar variables and relies on IN and OUT regions analyses. Of course, it also privatizes scalar variables, although the algorithm is much more expensive and should be used only when necessary.

Array sections privatization is still experimental and should be used with great care. In particular, it is not compatible with the next steps of the parallelization process, i.e. dependence tests and code generation, because it does not modify the code, but solely produces a new region resource.

Another transformation, which can also be called a privatization, consists in declaring as local to a procedure or function the variables which are used only locally. This happens quite frequently in old Fortran codes where variables are declared as SAVEd to avoid allocations at each invocation of the routine. However, this prevents parallelization of the loop surrounding the calls. The function which performs this transformation is called declarations_privatizerx8.11.2.2.

aliasxarray_privatizerx'PrivatizexScalarsx&xArrays'
aliasxarray_section_privatizerx'ScalarxandxArrayxSectionxPrivatization'
aliasxdeclarations_privatizerx'DeclarationxPrivatization'

array_privatizerxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
array_section_privatizerxxxxxxxxxxxxx>xMODULE.code
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.privatized_regions
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.copy_out_regions
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions

xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions
declarations_privatizerxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.out_regions

Several privatizability criterions can be applied for array section privatization, and its not yet clear which one should be used. The default case is to remove potential false dependences between iterations. The first option, when set to false, removes this constraint. It is useful for single assignment programs, to discover what section is really local to each iteration.

When the second option is set to false, copy-out is not allowed, which means only array regions that are not further reused in the program continuation can be privatized.

   xARRAY_PRIV_FALSE_DEP_ONLYxTRUE
   x
   xARRAY_SECTION_PRIV_COPY_OUTxTRUE
   x

8.11.3 Scalar and Array Expansion

Variable expansion consists in adding new dimensions to a variable so as to parallelize surrounding loops. There is no known advantage for expansion against privatization, but expansion is used when parallel loops must be distributed, for instance to generate SIMD code.

It is assumed that the variables to be expanded are the private variables. So this phase only is useful if a privatization has been performed earlier.

8.11.3.1 Scalar Expansion

Loop private scalar variables are expanded

aliasxvariable_expansionx'ExpandxScalar'
variable_expansionxxxxxxxxxxxxxxxxxxxx>xMODULE.code
!xMODULE.privatize_module
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

Uses LOOP_LABELx8.1.1 to select a particular loop, then finds all reduction in this loop and performs variable expension on all reduction variables.

reduction_variable_expansionxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_reductions
xxxxxxxx<xMODULE.code

A variant of atomization that splits expressions but keep as much reduction as possible. E.g: r+=a+b becomes r+=a ; r+=b;

reduction_atomizationxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.cumulated_reductions
xxxxxxxx<xMODULE.code

8.11.3.2 Array Expansion

Not implemented yet.

8.11.4 Freeze variables

Function freeze_variablesx8.11.4 produces code where variables interactively specified by the user are transformed into constants. This is useful when the functionality of a code must be reduced. For instance, a code designed for N dimensions could be reduced to a 3-D code by setting N to 3. This is not obvious when N changes within the code. CA? More information? The variable names are requested from the PIPS user? This is useful to specialize a code according to specific input

data6  ^{6See the CHiLL tool.}  .

aliasxfreeze_variablesx'FreezexVariables'
freeze_variablesxxxxxxxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.cumulated_effects

8.11.5 Manual Editing The window interfaces let the user edit the source files, because it is very useful to demonstrate PIPS. As with stfx8.3.4, editing is not integrated like other program transformations, and previously applied transformations are lost. Consistency is however always preserved.

A general edit facility fully integrated in pipsmake is planned for the (not so) near future. Not so near because user demand for this feature is low.

Since tpips can invoque any Shell command, it is also possible to touch and edit source files.

8.11.6 Transformation Test This is plug to implement quickly a program transformation requested by a user. Currently, it is a full loop distribution suggested by Alain Darte to compare different implementations, namely Nestor and PIPS.

aliasxtransformation_testx'TransformationxTest'
transformation_testxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

8.12 Extensions Transformations

8.12.1 OpenMP Pragma

The following transformation reads the sequential code and generates OpenMP pragma as an extension to statements. The pragmas produced are based on the information previously computed by differents phases and already stores in the pips internal representation of the sequential code. It might be interesting to use the phase internalizexparallelxcode (see §x7.1.8) before to apply ompifyxcode in order to maximize the number of parallel information available.

ompify_codexxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xMODULE.cumulated_reductions
xxxxxxxx<xMODULE.code

As defined in the ri, the pragma can be of different types. The following property can be set to str or expr. Obviously, if the property is set to str then pragmas would be generated as strings otherwise pragmas would be generated as expressions.

   xPRAGMA_TYPEx"expr"
   x

The PIPS phase OMPxLOOPxPARALLELxTHRESHOLDxSET allows to add the OpenMP if clause to all the OpenMP pragmas. Afterwards, the number of iterations in the loop is evaluated dynamically and compared to the defined threshold. The loop is parallelized only if the threshold is reached.

omp_loop_parallel_threshold_setxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xMODULE.code

The OMPxLOOPxPARALLELxTHRESHOLDxVALUE property , is used as a parameter by the PIPS phase OMPxLOOPxPARALLELxTHRESHOLDxSET. The number of iteration of the parallel loop will be compared to that value in an omp if clause. The OpenMP run time will decide dynamicaly to parallelize the loop if the number of iteration is above this threshold.

   xOMP_LOOP_PARALLEL_THRESHOLD_VALUEx0
   x

The OMPxIFxCLAUSExRECURSIVE property , is used as a parameter by the PIPS phase OMPxLOOPxPARALLELxTHRESHOLDxSET. If set to TRUE the number of iterations of the inner loops will be used to test if the threshold is reached. Otherwise only the nunber of iteration of the processed loop will be used.

   xOMP_IF_CLAUSE_RECURSIVExTRUE
   x

Compiler tends to produce many parallel loops which is generally not optimal for performance. The following transformation merges nested omp pragma in a unique omp pragma.

omp_merge_pragmaxxxxxxxxxxxxx>xMODULE.code
xxxxxxxx<xMODULE.code

PIPS merges the omp pragma on the inner or outer loop depending on the property OMPxMERGExPOLICY. This string property can be set to either outer

or inner.
   xOMP_MERGE_POLICYx"outer"
   x

The OMPxMERGExPRAGMA phase with the inner mode can be used after the phase limitxnestedxparallelism (see §x7.1.10). Such a combinaison allows to fine choose the loop depth you really want to parallelize with OpenMP.

The merging of the if clause of the omp pragma follows its own rule. This clause can be ignore without changing the output of the program, it only changes the program perfomances. Then three policies are offered to manage the if clause merging. The if clause can simply be ignored. Or the if clauses can be merged alltogether using the boolean opertaion or or and. When ignored, the if clause can be later regenerated using the appropriated PIPS phase : OMPxLOOPxPARALLELxTHRESHOLDxSET. To summarize, remenber that the property can be set to ignore or or and

   xOMP_IF_MERGE_POLICYx"ignore"

Chapterx9Output Files (Prettyprinted Files)

PIPS results for any analysis and/or transformations can be displayed in several different formats. User views are the closest one to the initial user source code. Sequential views are obtained by prettyprinting the PIPS internal representation of modules. Code can also be displayed graphically or using Emacs facilities (through a property). Of course, parallelized versions are available. At the program level, call graph and interprocedural control flow graphs, with different degrees of ellipse, provide interesting summaries.

Dependence graphs can be shown, but they are not user-friendly. No filtering interface is available. They mainly are useful for debugging and for teaching purposes.

9.1 Parsed Printed Files (User View) These are files containing a pretty-printed version of the parsed code, before the controlizer is applied. It is the code display closest to the user source code, because arcs in control flow graphs do not have to be rewritten as GOTO statements. However, it is inconsistent with the internal representation of the code as soon a a code transformation has been applied.

Bug: the inconsistence between the user view and the internal code representation presently is not detected. Solution: do not use user views.

The Fortran statements may be decorated with preconditions or transformers or complexities or any kind of effects, including convex array regions,... depending on the prettyprinter selected used to produce this file.

Transformers and preconditions require cumulated effects to build the module value basis.

9.1.1 Menu for User Views

aliasxparsed_printed_filex'UserxView'
aliasxprint_sourcex'Basic'
aliasxprint_source_transformersx'WithxTransformers'
aliasxprint_source_preconditionsx'WithxPreconditions'
aliasxprint_source_total_preconditionsx'WithxTotalxPreconditions'
aliasxprint_source_regionsx'WithxRegions'
aliasxprint_source_in_regionsx'WithxINxRegions'
aliasxprint_source_out_regionsx'WithxOUTxRegions'
aliasxprint_source_complexitiesx'WithxComplexities'
aliasxprint_source_proper_effectsx'WithxProperxEffects'
aliasxprint_source_cumulated_effectsx'WithxCumulatedxEffects'
aliasxprint_source_in_effectsx'WithxINxEffects'

aliasxprint_source_out_effectsx'WithxOUTxEffects'
aliasxprint_source_continuation_conditionsx'WithxContinuationxConditions'

9.1.2 Standard User View Display the code without any decoration.

print_sourcexxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code

9.1.3 User View with Transformers Display the code decorated with the transformers.

print_source_transformersxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.1.4 User View with Preconditions Display the code decorated with the preconditions.

print_source_preconditionsxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.cumulated_effects

9.1.5 User View with Total Preconditions Display the code decorated with the total preconditions.

print_source_total_preconditionsxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.cumulated_effects

9.1.6 User View with Continuation Conditions Display the code decorated with the continuation conditions.

print_source_continuation_conditionsxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.must_continuation
xxxxxxxx<xMODULE.may_continuation
xxxxxxxx<xMODULE.must_summary_continuation

xxxxxxxx<xMODULE.may_summary_continuation
xxxxxxxx<xMODULE.cumulated_effects

9.1.7 User View with Convex Array Regions Display the code decorated with the regions.

print_source_regionsxxxxxxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.1.8 User View with Invariant Convex Array Regions Display the code decorated with the regions.

print_source_inv_regionsxxxxxxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.inv_regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.1.9 User View with IN Convex Array Regions Display the code decorated with the IN regions.

print_source_in_regionsxxxxxxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.1.10 User View with OUT Convex Array Regions Display the code decorated with the OUT regions.

print_source_out_regionsxxxxxxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.1.11 User View with Complexities

Display the code decorated with the complexities.

print_source_complexitiesxxxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.complexities
xxxxxxxx<xMODULE.summary_complexity

9.1.12 User View with Proper Effects Display the code decorated with the proper effects.

print_source_proper_effectsxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xxMODULE.proper_effects

9.1.13 User View with Cumulated Effects Display the code decorated with the cumulated effects.

print_source_cumulated_effectsxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.1.14 User View with IN Effects Display the code decorated with its IN effects.

print_source_in_effectsxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_effects
xxxxxxxx<xMODULE.in_summary_effects

9.1.15 User View with OUT Effects Display the code decorated with its OUT effects.

print_source_out_effectsxxxxxxx>xMODULE.parsed_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_effects
xxxxxxxx<xMODULE.out_summary_effects

9.2 Printed File (Sequential Views) These are files containing a pretty-printed version of the internal representation,

code.

The statements may be decorated with the result of any analysis, e.g.complexities, preconditions, transformers, convex array regions,x depending on the pretty printer used to produce this file.

To view C programs, it is a good idea to select a C pretty printer, for example in

tpips with:

setpropertyxPRETTYPRINT_C_CODExTRUE

Transformers and preconditions (and regions?) require cumulated effects to build the module value basis.

9.2.1 Html output This is intended to be used with PIPS IR Navigator (tm).

Produce a html version of the internal representation of a PIPS Module. The property HTML_PRETTYPRINT_SYMBOL_TABLEx9.2.1 control whether the symbol table should be included in the output.

html_prettyprintx>xMODULE.html_ir_file
xxxxxxxxx<xPROGRAM.entities
xxxxxxxxx<xMODULE.code

Produce a html version of the symbol table, it’s module-independent, it’ll produce the same output for each module (the symbol table is global/unique).

html_prettyprint_symbol_tablex>xPROGRAM.html_ir_file
xxxxxxxxx<xPROGRAM.entities
xxxxxxxxx<xMODULE.code

   xHTML_PRETTYPRINT_SYMBOL_TABLExFALSE
   x

9.2.2 Menu for Sequential Views

aliasxprinted_filex'SequentialxView'
aliasxprint_codex'StatementsxOnly'
aliasxprint_code_transformersx'Statementsx&xTransformers'
aliasxprint_code_complexitiesx'Statementsx&xComplexities'
aliasxprint_code_preconditionsx'Statementsx&xPreconditions'
aliasxprint_code_total_preconditionsx'Statementsx&xTotalxPreconditions'
aliasxprint_code_regionsx'Statementsx&xRegions'
aliasxprint_code_regionsx'Statementsx&xInvariantxRegions'
aliasxprint_code_complementary_sectionsx'Statementsx&xComplementaryxSections'
aliasxprint_code_in_regionsx'Statementsx&xINxRegions'
aliasxprint_code_out_regionsx'Statementsx&xOUTxRegions'
aliasxprint_code_privatized_regionsx'Statementsx&xPrivatizedxRegions'
aliasxprint_code_proper_effectsx'Statementsx&xProperxEffects'
aliasxprint_code_in_effectsx'Statementsx&xINxEffects'
aliasxprint_code_out_effectsx'Statementsx&xOUTxEffects'
aliasxprint_code_cumulated_effectsx'Statementsx&xCumulatedxEffects'
aliasxprint_code_proper_reductionsx'Statementsx&xProperxReductions'
aliasxprint_code_cumulated_reductionsx'Statementsx&xCumulatedxReductions'
aliasxprint_code_static_controlx'Statementsx&xStaticxControls'
aliasxprint_code_continuation_conditionsx'Statementsx&xContinuationxConditions'
aliasxprint_code_proper_regionsx'Statementsx&xProperxRegions'
aliasxprint_code_proper_referencesx'Statementsx&xProperxReferences'
aliasxprint_code_cumulated_referencesx'Statementsx&xCumulatedxReferences'
aliasxprint_initial_preconditionx'InitialxPreconditions'
aliasxprint_code_points_to_listx'Statementsx&xPointsxTo'
aliasxprint_code_simple_pointer_valuesx'Statementsx&xSimplexPointerxValues'

9.2.3 Standard Sequential View

Display the code without any decoration.

print_codexxxxxxxxxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

9.2.4 Sequential View with Transformers Display the code statements decorated with their transformers, except for loops, which are decorated with the transformer from the loop entering states to the loop body states. The effective loop transformer, linking the input to the output state of a loop, is recomputed when needed and can be deduced from the precondition of the next statement after the

loop1 1PIPS design maps statement to decorations. For one loop statement, we need two transformers: one transformer to propagate the loop precondition as loop body precondition and a second transformer to propagate the loop precondition as loop postcondition. The second transformer can be deduced from the first one, but not the first one from the second one, and the second transformer is not used to compute the loop postcondition as it is more accurate to use the body postcondition. It is however computed to derive a compound statement transformer, e.g. the loop is part of block, which is part of a module statement, and then junked. .

print_code_transformersxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.2.5 Sequential View with Initial Preconditions

print_initial_preconditionxx>xMODULE.printed_file
xxxxxxxx<xMODULE.initial_precondition
xxxxxxxx<xPROGRAM.entities
print_program_preconditionxx>xPROGRAM.printed_file

xxxxxxxx<xPROGRAM.program_precondition
xxxxxxxx<xPROGRAM.entities

9.2.6 Sequential View with Complexities Display the code decorated with the complexities.

print_code_complexitiesxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.complexities
xxxxxxxx<xMODULE.summary_complexity

9.2.7 Sequential View with Preconditions Display the code decorated with the preconditions.

print_code_preconditionsxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.2.8 Sequential View with Total Preconditions Display the code decorated with the total preconditions.

print_code_total_preconditionsxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.summary_total_precondition
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.2.9 Sequential View with Continuation Conditions Display the code decorated with the continuation preconditions.

print_code_continuation_conditionsxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parsed_code
xxxxxxxx<xMODULE.must_continuation
xxxxxxxx<xMODULE.may_continuation
xxxxxxxx<xMODULE.must_summary_continuation
xxxxxxxx<xMODULE.may_summary_continuation
xxxxxxxx<xMODULE.cumulated_effects

9.2.10 Sequential View with Convex Array Regions

9.2.10.1 Sequential View with Plain Pointer Regions Display the code decorated with the pointer regions.

print_code_pointer_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.pointer_regions
xxxxxxxx<xMODULE.summary_pointer_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.2 Sequential View with Proper Pointer Regions Display the code decorated with the proper pointer regions.

print_code_proper_pointer_regionsxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_pointer_regions
xxxxxxxx<xMODULE.summary_pointer_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.3 Sequential View with Invariant Pointer Regions Display the code decorated with the invariant read/write pointer regions.

print_code_inv_pointer_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.inv_pointer_regions
xxxxxxxx<xMODULE.summary_pointer_regions

xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.4 Sequential View with Plain Convex Array Regions Display the code decorated with the regions.

print_code_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.5 Sequential View with Proper Convex Array Regions Display the code decorated with the proper regions.

print_code_proper_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.6 Sequential View with Invariant Convex Array Regions Display the code decorated with the invariant read/write regions.

print_code_inv_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.inv_regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.7 Sequential View with IN Convex Array Regions Display the code decorated with the IN regions.

print_code_in_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.8 Sequential View with OUT Convex Array Regions Display the code decorated with the OUT regions.

print_code_out_regionsxxxxxxxxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.2.10.9 Sequential View with Privatized Convex Array Regions Display the code decorated with the privatized regions.

print_code_privatized_regionsxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.privatized_regions
xxxxxxxx<xMODULE.copy_out_regions

9.2.11 Sequential View with Complementary Sections Display the code decorated with complementary sections.

print_code_complementary_sectionsx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.compsec
xxxxxxxx<xMODULE.summary_compsec

9.2.12 Sequential View with Proper Effects Display the code decorated with the proper pointer effects.

print_code_proper_pointer_effectsxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_pointer_effects

Display the code decorated with the proper effects.

print_code_proper_effectsxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

Display the code decorated with the proper references.

print_code_proper_referencesxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_references

9.2.13 Sequential View with Cumulated Effects Display the code decorated with the cumulated effects.

print_code_cumulated_pointer_effectsxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_pointer_effects
xxxxxxxx<xMODULE.summary_pointer_effects

Display the code decorated with the cumulated effects.

print_code_cumulated_effectsxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

Display the code decorated with the cumulated references.

print_code_cumulated_referencesxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_references

9.2.14 Sequential View with IN Effects Display the code decorated with its IN effects.

print_code_in_effectsxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_effects
xxxxxxxx<xMODULE.in_summary_effects

9.2.15 Sequential View with OUT Effects Display the code decorated with its OUT effects.

print_code_out_effectsxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_effects
xxxxxxxx<xMODULE.out_summary_effects

9.2.16 Sequential View with Proper Reductions Display the code decorated with the proper reductions.

print_code_proper_reductionsx>xMODULE.printed_file
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.proper_reductions

9.2.17 Sequential View with Cumulated Reductions Display the code decorated with the cumulated reductions.

print_code_cumulated_reductionsx>xMODULE.printed_file
xx<xPROGRAM.entities
xx<xMODULE.code
xx<xMODULE.cumulated_reductions
xx<xMODULE.summary_reductions

9.2.18 Sequential View with Static Control Information Display the code decorated with the static control.

print_code_static_controlxxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.static_control

9.2.19 Sequential View with Points-To Information Display the code decorated with the points to information.

print_code_points_to_listxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.summary_points_to_list
xxxxxxxx<xMODULE.points_to_list

9.2.20 Sequential View with Simple Pointer Values Displays the code with simple pointer values relationships.

print_code_simple_pointer_valuesxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.simple_pointer_values

Displays the code with simple gen pointer values and kill sets.

print_code_simple_gen_kill_pointer_valuesxxxxxx>xMODULE.printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.simple_gen_pointer_values
xxxxxxxx<xMODULE.simple_kill_pointer_values

9.2.21 Prettyprint properties

9.2.21.1 Language

PIPS can handle many different languages. By default the PrettyPrinter uses the native language as an output but it is also possible to prettyprint Fortran code as C code. Possible values for the PRETTYPRINTxLANGUAGE property are: native

F95 F77 C.

   xPRETTYPRINT_LANGUAGEx"native"
   x

9.2.21.2 Layout

When prettyprinting semantic information (preconditions, transformers and regions), add a line before and after each piece of information if set to TRUE. The resulting code is more readable, but is larger.

   xPRETTYPRINT_LOOSExTRUE
   x

By default, each prettyprinted line of Fortran or C code is terminated by its statement number in columns 73-80, unless no significative statement number is available. This feature is used to trace the origin of statements after program transformations and parallelization steps.

This feature may be inconvenient for some compilers or because it generates large source files. It may be turned off.

Note that the statement number is equal to the line number in the function file, that is the source file obtained after PIPS

preprocessing2 2PIPS preprocessing usually includes the standard C or Fortran preprocessing phase but also breaks down user files into compilation units and function files, a.k.a. initial files in Fortran and source files in C.

and filtering3 3Filtering is applied on Fortran files only to perform file includes. It is implemented in Perl., and not the user file, which is the file submitted by the user and which may contain several functions.

Note also that some phases in pips may add new statement that are not present in the original file. In this case the number of the statement that requires such a transformation, is used for the added statement.

   xPRETTYPRINT_STATEMENT_NUMBERxTRUE
   x

Note: this default value is overriden to FALSE by activate_language() for C and Fortranx95.

The structured control structure is shown by using an indentation. The default value is 3.

   xPRETTYPRINT_INDENTATIONx3

Some people prefer to use a space after a comma to separate items in lists such as declaration lists or parameter lists in order to improve readability. Other people would rather pack more information per line. The default option is chosen for readability.

   xPRETTYPRINT_LISTS_WITH_SPACESxTRUE
   x

Depending on the user goal, it may be better to isolate comments used to display results of PIPS analyses from the source code statement. This is the default option.

   xPRETTYPRINT_ANALYSES_WITH_LFxTRUE
   x

This feature only exists for the semantics analyses.

9.2.21.3 Target Language Selection

Parallel output style

How to print, from a syntactic point of view, a parallel do loop. Possible values

are: do doall f90 hpf cray craft cmf omp.
   xPRETTYPRINT_PARALLELx"do"
   x

Default sequential output style

How to print, from a syntactic point of view, a parallel do loop for a sequential code. Of course, by default, the sequential output is sequential by definition, so the default value is "do".

But we may interested to change this behaviour to display after an application of internalize_parallel_codex7.1.8 the parallel code that is hidden in the sequential code. Possible values are: do doall f90 hpf cray craft cmf

omp.

By default, parallel information is displayed with am OpenMP flavor since it is widely used nowadays.

   xPRETTYPRINT_SEQUENTIAL_STYLEx"omp"

9.2.21.4 Display Analysis Results

Add statement effects as comments in output; not implemented (that way) yet.

   xPRETTYPRINT_EFFECTSxFALSE
   x

The next property, PRETTYPRINT_IO_EFFECTSx9.2.21.4, is used to control the computation of implicit statement IO effects and display them as comments in output. The implicit effects on the logical unit are simulated by a read/write action to an element of the array TOP-LEVEL:LUNS(), or to the whole array when the element is not known at compile time. This is the standard behavior for PIPS. Some phases, e.g. hpfc, may turn this option off, but it is much more risky than to filter out abstract effects. Furthermore, the filtering is better because it takes into account all abstract effects, not only IO effects on logical units. PIPS users should definitely not turn off this property as the semantic equivalence between the inout and the output program is no longer guaranteed.

   xPRETTYPRINT_IO_EFFECTSxTRUE
   x

To transform C source code properly, variable and type declarations as well as variable and type references must be tracked alhtough standard use and def information is restricted to memory loads and stores because the optimizations are performed at a lower level. Fortranx77 analyses do not need information about variable declarations and there is not possibility of type definition. So the added information about variable declarations and references may be pure noise. It is possible to get rid of it by setting this property to TRUE, which is its default value before August 2010. For C code, it is better to set it to FALSE. For the time being, the default value cannot depend on the code language.

   xPRETTYPRINT_MEMORY_EFFECTS_ONLYxFALSE
   x

Transform DOALL loops into sequential loops with an opposed increment to check validity of the parallelization on a sequential machine. This property is not implemented.

   xPRETTYPRINT_REVERSE_DOALLxFALSE
   x

It is possible to print statement transformers as comments in code. This property is not intended for PIPS users, but is used internally. Transformers can be

prettyprinted by using activate and PRINT_CODE_TRANSFORMERS

   xPRETTYPRINT_TRANSFORMERxFALSE
   x

It is possible to print statement preconditions as comments in code. This property is not intended for PIPS users, but is used internally. Preconditions can be

prettyprinted by using activate and PRINT_CODE_PRECONDITIONS
   xPRETTYPRINT_EXECUTION_CONTEXTxFALSE
   x

It is possible to print statement with convex array region information as comments in code. This property is not intended for PIPS users, but is used internally. Convex array regions can be prettyprinted by using activate and

PRINT_CODE_REGIONS or PRINT_CODE_PROPER_REGIONS
   xPRETTYPRINT_REGIONxFALSE
   x

By default, convex array regions are printed for arrays only, but the internal representation includes scalar variables as well. The default option can be overriden with this property.

   xPRETTYPRINT_SCALAR_REGIONSxFALSE
   x

9.2.21.5 Display Internals for Debugging

All these debugging options should be set to FALSE for normal operation, when the prettyprinter is expected to produce code as close as possible to the input form. When they are turned on, the output is closer to the PIPS internal representation.

Sequences are implicit in Fortran and in many programming languages but they are internally represented. It is possible to print pieces of information gathered about sequences by turning on this property.

   xPRETTYPRINT_BLOCKSxFALSE

To print all the C blocks (the {x} in C, you can set the following property:

   xPRETTYPRINT_ALL_C_BLOCKSxFALSE
   x

This property is a C-specialized version of PRETTYPRINT_BLOCKS, since in C you can represent the blocks. You can combine this property with a PRETTYPRINT_EMPTY_BLOCKS set to true too. Right now, the prettyprint of the C block is done in the wrong way, so if you use this option, you will have redundant blocks inside instructions, but you will have all the other hidden blocks too...

To print unstructured statements:

   xPRETTYPRINT_UNSTRUCTUREDxFALSE
   x

Print all effects for all statements regardless of PRETTYPRINT_BLOCKSx9.2.21.5 and

PRETTYPRINT_UNSTRUCTUREDx9.2.21.5.
   xPRETTYPRINT_ALL_EFFECTSxFALSE
   x

Print empty statement blocks (false by default):

   xPRETTYPRINT_EMPTY_BLOCKSxFALSE
   x

Print statement ordering information (false by default):

   xPRETTYPRINT_STATEMENT_ORDERINGxFALSE
   x

The next property controls the print out of DO loops and CONTINUE statement. The code may be prettyprinted with DO label and CONTINUE instead of DO-ENDDO, as well as with other useless CONTINUE (This property

encompasses a virtual PRETTYPRINTxALLxCONTINUExSTATEMENTS). If set to

FALSE, the default option, all useless CONTINUE statements are NOT prettyprinted (ie. all those in structured parts of the code). This mostly is a debugging option useful to understand better what is in the internal representation.

Warning:

if set to TRUE, generated code may be wrong after some code transformations like distribution...

   xPRETTYPRINT_ALL_LABELSxFALSE
   x

Print code with DO label as comment.

   xPRETTYPRINT_DO_LABEL_AS_COMMENTxFALSE
   x

Print private variables without regard for their effective use. By default, private variables are shown only for parallel DO loops.

   xPRETTYPRINT_ALL_PRIVATE_VARIABLESxFALSE

Non-standard variables and tests are generated to simulate the control effect of Fortran IO statements. If an end-of-file condition is encountered or if an io-error is raised, a jump to relevant labels may occur if clauses ERR= or END= are defined in the IO control list. These tests are normally not printed because they could not be compiled by a standard Fortran compiler and because they are redundant with the IO statement itself.

   xPRETTYPRINT_CHECK_IO_STATEMENTSxFALSE
   x

Print the final RETURN statement, although this is useless according to Fortran standard. Note that comments attached to the final return are lost if it is not printed. Note also that the final RETURN may be part of an unstructured in which case the previous property is required.

   xPRETTYPRINT_FINAL_RETURNxFALSE
   x

The internal representation is based on a standard IF structure, known as block if in Fortran jargon. When possible, the prettyprinter uses the logical if syntactical form to save lines and to produce an output assumed closer to the input. When statements are decorated, information gathered by PIPS may be lost. This property can be turned on to have an output closer to the internal representation. Note that edges of the control flow graphs may still be displayed as logical if since they never carry any useful

information4  4Information is carried by the vertices (i.e. nodes). A CONTINUE statement is generated to have an attachment node when some information must be stored and displayed.  .

   xPRETTYPRINT_BLOCK_IF_ONLYxFALSE
   x

Effects give data that may be read and written in a procedure. These data are represented by their entity name. By default the entity name used is the shortest

nom-ambiguous one. The PRETTYPRINT_EFFECT_WITH_FULL_ENTITY_NAMEx9.2.21.5.1

property can be used to force the usage of full entity name (module name + scope + local name).

   xPRETTYPRINT_EFFECT_WITH_FULL_ENTITY_NAMExFALSE
   x

In order to have information on the scope of commons, we need to know the common in which the entity is declared if any. To get this information the PRETTYPRINT_WITH_COMMON_NAMESx9.2.21.5.1 property has to set to TRUE.

   xPRETTYPRINT_WITH_COMMON_NAMESxFALSE
   x

By default, expressions are simplified according to operator precedences. It is possible to override this prettyprinting option and to reflect the abstract tree with redundant parentheses.

   xPRETTYPRINT_ALL_PARENTHESESxFALSE

By default, the C prettyprinter uses a minimum of braces to improve readability. However, gcc advocates the use of more braces to avoid some ambiguities about else clauses. In order to run succesfully gcc with options -Wall and -Werror, it is possible to force the print-out of all possible braces.

   xPRETTYPRINT_ALL_C_BRACESxFALSE
   x

The previous property leads to hard to read source code. Property PRETTYPRINT_GCC_C_BRACESx9.2.21.5.1 is used to print only a few additional braces required by gcc to avoid ambiguous else warning messages.

   xPRETTYPRINT_GCC_C_BRACESxFALSE
   x

9.2.21.6 Declarations

By default in Fortran (and not in C), module declarations are preserved as huge strings to produce an output as close as possible to the input (see field decls_text in type code). However, large program transformations and code generation phases, e.g. hpfc, require updated declarations.

Regenerate all variable declarations, including those variables not declared in the user program. By default in Fortran, when possible, the user declaration text is used to preserve comments.

   xPRETTYPRINT_ALL_DECLARATIONSxFALSE
   x

If the prettyprint of the header and the declarations are done by PIPS, try to display the genuine comments. Unfortunately, there is no longer order relation between the comments and the declarations since these are sorted by PIPS. By default, do not try to display the comments when PIPS is generating the header.

   xPRETTYPRINT_HEADER_COMMENTSxFALSE
   x

How to regenerate the common declarations. It can be none, declaration, or include.

   xPRETTYPRINT_COMMONSx"declaration"
   x

DATA declarations are partially handled presently.

   xPRETTYPRINT_DATA_STATEMENTSxTRUE
   x

Where to put the dimension information, which must appear once. The default is associated to the type information. It can be associated to The type, or preferably to the common if any, or maybe to a dimension statement, which is not implemented.

   xPRETTYPRINT_VARIABLE_DIMENSIONSx"type"
   x

9.2.21.7 FORESYS Interface

Print transformers, preconditions and regions in a format accepted by Foresys and Partita. Not maintained.

   xPRETTYPRINT_FOR_FORESYSxFALSE
   x

9.2.21.8 HPFC Prettyprinter

To deal specifically with the prettyprint for hpfc

   xPRETTYPRINT_HPFCxFALSE
   x

9.2.21.9 Interface to Emacs

The following property tells PIPS to attach various Emacs properties for interactive purpose. Used internally by the Emacs pretyyprinter and the epip user interface.

   xPRETTYPRINT_ADD_EMACS_PROPERTIESxFALSE
   x

9.3 Printed Files with the Intraprocedural Control Graph These are files containing a pretty-printed version of code to be displayed with its intraprocedural control graph as a graph, for example using the

uDrawGraph5  ^{5http://www.informatik.uni-bremen.de/uDrawGraph}

program (formerly known as daVinci) or dot/GraphViz tools. More concretely, use

some scripts like pips_unstructured2daVinci or pips_unstructured2dot to

display graphically these .pref-graph files.

The statements may be decorated with complexities, preconditions, transformers, regions,x depending on the printer used to produce this file.

9.3.1 Menu for Graph Views

aliasxgraph_printed_filex'ControlxGraphxSequentialxView'
aliasxprint_code_as_a_graphx'GraphxwithxStatementsxOnly'
aliasxprint_code_as_a_graph_transformersx'GraphxwithxStatementsx&xTransformers'
aliasxprint_code_as_a_graph_complexitiesx'GraphxwithxStatementsx&xComplexities'
aliasxprint_code_as_a_graph_preconditionsx'GraphxwithxStatementsx&xPreconditions'
aliasxprint_code_as_a_graph_total_preconditionsx'GraphxwithxStatementsx&xTotalxPreconditions'
aliasxprint_code_as_a_graph_regionsx'GraphxwithxStatementsx&xRegions'
aliasxprint_code_as_a_graph_in_regionsx'GraphxwithxStatementsx&xINxRegions'
aliasxprint_code_as_a_graph_out_regionsx'GraphxwithxStatementsx&xOUTxRegions'
aliasxprint_code_as_a_graph_proper_effectsx'GraphxwithxStatementsx&xProperxEffects'
aliasxprint_code_as_a_graph_cumulated_effectsx'GraphxwithxStatementsx&xCumulatedxEffects'

9.3.2 Standard Graph View Display the code without any decoration.

print_code_as_a_graphxxxxxxxxxxxxxxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

9.3.3 Graph View with Transformers Display the code decorated with the transformers.

print_code_as_a_graph_transformersxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.3.4 Graph View with Complexities Display the code decorated with the complexities.

print_code_as_a_graph_complexitiesxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.complexities
xxxxxxxx<xMODULE.summary_complexity

9.3.5 Graph View with Preconditions Display the code decorated with the preconditions.

print_code_as_a_graph_preconditionsxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.3.6 Graph View with Preconditions Display the code decorated with the preconditions.

print_code_as_a_graph_total_preconditionsxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.3.7 Graph View with Regions Display the code decorated with the regions.

print_code_as_a_graph_regionsxxxxxxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.3.8 Graph View with IN Regions Display the code decorated with the IN regions.

print_code_as_a_graph_in_regionsxxxxxxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.3.9 Graph View with OUT Regions Display the code decorated with the OUT regions.

print_code_as_a_graph_out_regionsxxxxxxxxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.3.10 Graph View with Proper Effects Display the code decorated with the proper effects.

print_code_as_a_graph_proper_effectsxxxxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.proper_effects

9.3.11 Graph View with Cumulated Effects Display the code decorated with the cumulated effects.

print_code_as_a_graph_cumulated_effectsxxxx>xMODULE.graph_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.3.12 ICFG properties

This prettyprinter is NOT a call graph prettyprinter (see Sectionx6.1). Control flow information can be displayed and every call site is shown, possibly with some annotation like precondition or region

This prettyprinter uses the module codes in the workspace database to build the ICFG.

Print IF statements controlling call sites:

   xICFG_IFsxFALSE
   x

Print DO loops enclosing call sites:

xICFG_DOsxFALSE
x

It is possible to print the interprocedural control flow graph as text or as a graph using daVinci format. By default, the text output is selected.

xICFG_DVxFALSE
x

To be destroyed:

xICFG_CALLEES_TOPO_SORTxFALSE
x
xICFG_DECORx0
x
xICFG_DRAWxTRUE
x

ICFG default indentation when going into a function or a structure.

xICFG_INDENTATIONx4
x

Debugging level (should be ICFG_DEBUG_LEVEL and numeric instead of boolean!):

xICFG_DEBUGxFALSE
x

Effects are often much too numerous to produce a useful interprocedural control flow graph.

The integer property RW_FILTERED_EFFECTSx9.3.12 is used to specify a filtering criterion.

  0: READ_ALL,

  1: WRITE_ALL,

  2: READWRITE_ALL,

  3: READ_END,

  4: WRITE_END,

  5: READWRITE_END, .
xRW_FILTERED_EFFECTSx0

9.3.13 Graph properties

9.3.13.1 Interface to Graphics Prettyprinters

To output a code with a hierarchical view of the control graph with markers instead of a flat one. It purposes a display with a graph browser such as

daVinci6  ^{6http://www.informatik.uni-bremen.de/~davinci}  :
   xPRETTYPRINT_UNSTRUCTURED_AS_A_GRAPHxFALSE
   x

and to have a decorated output with the hexadecimal addresses of the control nodes:

   xPRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH_VERBOSExFALSE
   x

9.4 Parallel Printed Files File containing a pretty-printed version of a parallelized_code. Several versions are available. The first one is based on Fortran-77, extended with a DOALL construct. The second one is based on Fortran-90. The third one generates CRAY Research directives as comments if and only if the correspondent parallelization option was selected (see Sectionsubsection-parallelization).

No one knows why there is no underscore between parallel and printed...

9.4.1 Menu for Parallel View

aliasxparallelprinted_filex'ParallelxView'
aliasxprint_parallelized77_codex'Fortranx77'
aliasxprint_parallelizedHPF_codex'HPFxdirectives'
aliasxprint_parallelizedOMP_codex'OMPxdirectives'
aliasxprint_parallelized90_codex'Fortranx90'
aliasxprint_parallelizedcray_codex'FortranxCray'

9.4.2 Fortran 77 Parallel View Output a Fortran-77 code extended with DOALL parallel constructs.

print_parallelized77_codexxxxxxx>xMODULE.parallelprinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parallelized_code

9.4.3 HPF Directives Parallel View Output the code decorated with HPF directives.

print_parallelizedHPF_codexxxxx>xMODULE.parallelprinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parallelized_code

9.4.4 OpenMP Directives Parallel View Output the code decorated with OpenMP (OMP) directives.

print_parallelizedOMP_codexxxxx>xMODULE.parallelprinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parallelized_code

9.4.5 Fortran 90 Parallel View Output the code with some Fortran-90 array construct style.

print_parallelized90_codexxxxxxx>xMODULE.parallelprinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parallelized_code

9.4.6 Cray Fortran Parallel View Output the code decorated with parallel Cray directives. Note that the Cray parallelization algorithm should have been used in order to match Cray directives for parallel vector processors.

print_parallelizedcray_codexxxxx>xMODULE.parallelprinted_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.parallelized_code
xxxxxxxx<xMODULE.cumulated_effects

9.5 Call Graph Files

This kind of file contains the sub call

graph7  ^{7It is not a graph but a tree.}  of

a module. Of course, the call graph associated to the MAIN module is the program call graph.

Each module can be decorated by summary information computed by one of PIPS analyses.

If one module has different callers, its sub call tree is replicated once for each

caller8  ^{8In the ICFG , the replication would occur for each call site.}  .

No fun to read, but how could we avoid it with a text output? But it is useful to check large analyses.

The resource defined in this section is callgraph_file (note the missing underscore between call and graph in callgraph...). This is a file resource to be displayed, which cannot be loaded in memory by pipsdbm.

Note that the input resource lists could be reduced to one resource, the decoration. pipsmake would deduce the other ones. There is no need for a transitive closure, but some people like it that way to make resource usage verification possible...RK: explain... FI: no idea; we would like to display any set of resources, but the sets are too numerous to have a phase for each.

9.5.1 Menu for Call Graphs Aliases for call graphs must de different from aliases for interprocedural control flow graphs (ICFG). A simple trick, a trailing SPACE character, is used.

aliasxcallgraph_filex'CallgraphxView'
aliasxprint_call_graphx'Calls'
aliasxprint_call_graph_with_complexitiesx'Callsx&xComplexities'
aliasxprint_call_graph_with_preconditionsx'Callsx&xPreconditions'
aliasxprint_call_graph_with_total_preconditionsx'Callsx&xTotalxPreconditions'
aliasxprint_call_graph_with_transformersx'Callsx&xTransformers'
aliasxprint_call_graph_with_proper_effectsx'Callsx&xProperxeffects'
aliasxprint_call_graph_with_cumulated_effectsx'Callsx&xCumulatedxeffects'
aliasxprint_call_graph_with_regionsx'Callsx&xRegions'
aliasxprint_call_graph_with_in_regionsx'Callsx&xInxRegions'
aliasxprint_call_graph_with_out_regionsx'Callsx&xOutxregions'

9.5.2 Standard Call Graphs To have the call graph without any decoration.

print_call_graphxxxxxxxxxxxxxxxxxxxxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file

9.5.3 Call Graphs with Complexities To have the call graph decorated with the complexities.

print_call_graph_with_complexitiesxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.summary_complexity
xxxxxxxx<xMODULE.complexities

9.5.4 Call Graphs with Preconditions To have the call graph decorated with the preconditions.

print_call_graph_with_preconditionsxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.5.5 Call Graphs with Total Preconditions To have the call graph decorated with the total preconditions.

print_call_graph_with_total_preconditionsxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.5.6 Call Graphs with Transformers To have the call graph decorated with the transformers.

print_call_graph_with_transformersxxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.5.7 Call Graphs with Proper Effects To have the call graph decorated with the proper effects.

print_call_graph_with_proper_effectsxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.proper_effects

9.5.8 Call Graphs with Cumulated Effects To have the call graph decorated with the cumulated effects.

print_call_graph_with_cumulated_effectsxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.5.9 Call Graphs with Regions To have the call graph decorated with the regions.

print_call_graph_with_regionsxxxxxxxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.5.10 Call Graphs with IN Regions To have the call graph decorated with the IN regions.

print_call_graph_with_in_regionsxxxxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.5.11 Call Graphs with OUT Regions To have the call graph decorated with the OUT regions.

print_call_graph_with_out_regionsxxxxxxxx>xMODULE.callgraph_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.callgraph_file
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

This library is used to display the calling relationship between modules. It is different from the interprocedural call flow graph, ICFG (see Sectionx9.3.12). For example: if A calls B twice, in callgraph, there is only one edge between A and B; while in ICFG (see next section)), there are two edges between A and B, since A contains two call sites.

The call graph is derived from the modules declarations. It does not really the parsed code per se, but the code must have been parsed to have up-to-date declarations in the symbol table.

Because of printout limitations, the call graph is developed into a tree before it is printed. The sub-graph of a module appears as many times as is has callers. The resulting printout may be very long.

There is no option for the callgraph prettyprinter except for debugging.

Debugging level (should be CALLGRAPH_DEBUG_LEVEL and numeric!)

   xCALLGRAPH_DEBUGxFALSE
   x

9.6 DrawGraph Interprocedural Control Flow Graph Files (DVICFG) This is the file ICFG with format of graph

uDrawGraph9  ^{9http://www.informatik.uni-bremen.de/uDrawGraph}

(formerly daVinci). This should be generalized to be less tool-dependent.

9.6.1 Menu for DVICFG’s

aliasxdvicfg_filex'DVICFGxView'
aliasxprint_dvicfg_with_filtered_proper_effectsx'GraphicalxCallsx&xFilteredxproperxeffects'

9.6.2 Minimal ICFG with graphical filtered Proper Effects Display the ICFG graphically decorated with the write proper effects filtered for a variable.

print_dvicfg_with_filtered_proper_effectsxxxxxxxxxxx>xMODULE.dvicfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.dvicfg_file
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xCALLEES.summary_effects

9.7 Interprocedural Control Flow Graph Files (ICFG) This kind of file contains a more or less precise interprocedural control graph. The graph can be restricted to call sites only, to call sites and enclosing DO loops or to call sites, enclosing DO loops and controlling IF tests. This abstraction option is orthogonal to the set of decorations, but pipsmake does not support this orthogonality. All combinations are listed below.

Each call site can be decorated by associated information computed by one of PIPS analyses.

9.7.1 Menu for ICFG’s Note: In order to avoid conflicts with callgraph aliases, a space character is appended at each alias shared with call graph related functions (Guillaume Oget).

aliasxicfg_filex'ICFGxView'
aliasxprint_icfgx'Callsx'
aliasxprint_icfg_with_complexitiesx'Callsx&xComplexitiesx'
aliasxprint_icfg_with_preconditionsx'Callsx&xPreconditionsx'
aliasxprint_icfg_with_total_preconditionsx'Callsx&xTotalxPreconditionsx'
aliasxprint_icfg_with_transformersx'Callsx&xTransformersx'
aliasxprint_icfg_with_proper_effectsx'Callsx&xProperxeffectsx'
aliasxprint_icfg_with_filtered_proper_effectsx'Callsx&xFilteredxproperxeffectsx'
aliasxprint_icfg_with_cumulated_effectsx'Callsx&xCumulatedxeffectsx'
aliasxprint_icfg_with_regionsx'Callsx&xRegionsx'
aliasxprint_icfg_with_in_regionsx'Callsx&xInxRegionsx'
aliasxprint_icfg_with_out_regionsx'Callsx&xOutxregionsx'
aliasxprint_icfg_with_loopsx'Callsx&xLoops'
aliasxprint_icfg_with_loops_complexitiesx'Callsx&xLoopsx&xComplexities'
aliasxprint_icfg_with_loops_preconditionsx'Callsx&xLoopsx&xPreconditions'
aliasxprint_icfg_with_loops_total_preconditionsx'Callsx&xLoopsx&xTotalxPreconditions'
aliasxprint_icfg_with_loops_transformersx'Callsx&xLoopsx&xTransformers'
aliasxprint_icfg_with_loops_proper_effectsx'Callsx&xLoopsx&xProperxeffects'
aliasxprint_icfg_with_loops_cumulated_effectsx'Callsx&xLoopsx&xCumulatedxeffects'
aliasxprint_icfg_with_loops_regionsx'Callsx&xLoopsx&xRegions'
aliasxprint_icfg_with_loops_in_regionsx'Callsx&xLoopsx&xInxRegions'
aliasxprint_icfg_with_loops_out_regionsx'Callsx&xLoopsx&xOutxregions'

aliasxprint_icfg_with_controlx'Callsx&xControl'
aliasxprint_icfg_with_control_complexitiesx'Callsx&xControlx&xComplexities'
aliasxprint_icfg_with_control_preconditionsx'Callsx&xControlx&xPreconditions'
aliasxprint_icfg_with_control_total_preconditionsx'Callsx&xControlx&xTotalxPreconditions'
aliasxprint_icfg_with_control_transformersx'Callsx&xControlx&xTransformers'
aliasxprint_icfg_with_control_proper_effectsx'Callsx&xControlx&xProperxeffects'
aliasxprint_icfg_with_control_cumulated_effectsx'Callsx&xControlx&xCumulatedxeffects'
aliasxprint_icfg_with_control_regionsx'Callsx&xControlx&xRegions'
aliasxprint_icfg_with_control_in_regionsx'Callsx&xControlx&xInxRegions'
aliasxprint_icfg_with_control_out_regionsx'Callsx&xControlx&xOutxregions'

9.7.2 Minimal ICFG Display the plain ICFG, without any decoration.

print_icfgxxxxxxxxxxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file

9.7.3 Minimal ICFG with Complexities Display the ICFG decorated with complexities.

print_icfg_with_complexitiesxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_complexity
xxxxxxxx<xMODULE.complexities

9.7.4 Minimal ICFG with Preconditions Display the ICFG decorated with preconditions. They are expressed in the callee name space to evaluate the interest of cloning, depending on the information available to the callee at a given call site.

print_icfg_with_preconditionsxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.5 Minimal ICFG with Preconditions Display the ICFG decorated with total preconditions. They are expressed in the callee name space to evaluate the interest of cloning, depending on the information available to the callee at a given call site.

print_icfg_with_total_preconditionsxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.6 Minimal ICFG with Transformers Display the ICFG decorated with transformers.

print_icfg_with_transformersxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects

9.7.7 Minimal ICFG with Proper Effects Display the ICFG decorated with the proper effects.

print_icfg_with_proper_effectsxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.proper_effects

9.7.8 Minimal ICFG with filtered Proper Effects Display the ICFG decorated with the write proper effects filtered for a variable.

print_icfg_with_filtered_proper_effectsxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xCALLEES.summary_effects

9.7.9 Minimal ICFG with Cumulated Effects Display the ICFG decorated with cumulated effects.

print_icfg_with_cumulated_effectsxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.7.10 Minimal ICFG with Regions Display the ICFG decorated with regions.

print_icfg_with_regionsxxxxxxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.11 Minimal ICFG with IN Regions Display the ICFG decorated with IN regions.

print_icfg_with_in_regionsxxxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities

xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.12 Minimal ICFG with OUT Regions Display the ICFG decorated with OUT regions.

print_icfg_with_out_regionsxxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.13 ICFG with Loops Display the plain ICFG with loops, without any decoration.

print_icfg_with_loopsxxxxxxxxxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file

9.7.14 ICFG with Loops and Complexities Display the ICFG decorated with loops and complexities.

print_icfg_with_loops_complexitiesxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_complexity
xxxxxxxx<xMODULE.complexities

9.7.15 ICFG with Loops and Preconditions Display the ICFG decorated with preconditions.

print_icfg_with_loops_preconditionsxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.16 ICFG with Loops and Total Preconditions Display the ICFG decorated with total preconditions.

print_icfg_with_loops_total_preconditionsxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file

xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.17 ICFG with Loops and Transformers Display the ICFG decorated with transformers.

print_icfg_with_loops_transformersxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects

9.7.18 ICFG with Loops and Proper Effects Display the ICFG decorated with proper effects.

print_icfg_with_loops_proper_effectsxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.proper_effects

9.7.19 ICFG with Loops and Cumulated Effects Display the ICFG decorated with cumulated effects.

print_icfg_with_loops_cumulated_effectsxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.7.20 ICFG with Loops and Regions Display the ICFG decorated with regions.

print_icfg_with_loops_regionsxxxxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.21 ICFG with Loops and IN Regions Display the ICFG decorated with IN regions.

print_icfg_with_loops_in_regionsxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions

xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.22 ICFG with Loops and OUT Regions Display the ICFG decorated with the OUT regions.

print_icfg_with_loops_out_regionsxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.23 ICFG with Control Display the plain ICFG with loops, without any decoration.

print_icfg_with_controlxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file

9.7.24 ICFG with Control and Complexities Display the ICFG decorated with the complexities.

print_icfg_with_control_complexitiesxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_complexity
xxxxxxxx<xMODULE.complexities

9.7.25 ICFG with Control and Preconditions Display the ICFG decorated with the preconditions.

print_icfg_with_control_preconditionsxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.26 ICFG with Control and Total Preconditions Display the ICFG decorated with the preconditions.

print_icfg_with_control_total_preconditionsxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.summary_total_postcondition
xxxxxxxx<xMODULE.total_preconditions
xxxxxxxx<xMODULE.cumulated_effects

9.7.27 ICFG with Control and Transformers Display the ICFG decorated with the transformers.

print_icfg_with_control_transformersxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.summary_transformer
xxxxxxxx<xMODULE.cumulated_effects

9.7.28 ICFG with Control and Proper Effects Display the ICFG decorated with the proper effects.

print_icfg_with_control_proper_effectsxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.proper_effects

9.7.29 ICFG with Control and Cumulated Effects Display the ICFG decorated with the cumulated effects.

print_icfg_with_control_cumulated_effectsxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects

9.7.30 ICFG with Control and Regions Display the ICFG decorated with the regions.

print_icfg_with_control_regionsxxxxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.regions
xxxxxxxx<xMODULE.summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.31 ICFG with Control and IN Regions Display the ICFG decorated with the IN regions.

print_icfg_with_control_in_regionsxxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.in_regions
xxxxxxxx<xMODULE.in_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.7.32 ICFG with Control and OUT Regions Display the ICFG decorated with the OUT regions.

print_icfg_with_control_out_regionsxxxxx>xMODULE.icfg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xCALLEES.icfg_file
xxxxxxxx<xMODULE.out_regions
xxxxxxxx<xMODULE.out_summary_regions
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.transformers
xxxxxxxx<xMODULE.cumulated_effects

9.8 Dependence Graph File

This file shows the dependence graph.

Known bug: there is no precise relationship between the dependence graph seen by the parallelization algorithm selected and any of its view...

Two formats are available: the default format which includes dependence cone and a SRU format which packs all information about one arc on one line and which replaces the dependence cone by the dependence direction vector (DDV). The line numbers given with this format are in fact relative (approximatively...) to the statement line in the PIPS output. The SRU format was defined with researchers at Slippery Rock University (PA). The property

PRINT_DEPENDENCE_GRAPH_USING_SRU_FORMATx6.5.6.4

is set to FALSE by default.

9.8.1 Menu For Dependence Graph Views

aliasxdg_filex'DependencexGraphxView'
aliasxxxprint_effective_dependence_graphxxxx'Default'
aliasxxxprint_loop_carried_dependence_graphx'LoopxCarriedxOnly'
aliasxxxprint_whole_dependence_graphxxxxxxxx'Allxarcs'
aliasxxxprint_chains_graphxxxxxxxxxxxxxxxxxx'Chains'
aliasxxxprint_dot_chains_graphxxxxxxxxxxxxxx'Chainsx(forxdot)'
aliasxxxprint_dot_dependence_graphxxxxxxxxxx'Dependencexgraphx(forxdot)'
aliasxxxprint_filtered_dependence_graphxxxxx'FilteredxArcs'
aliasxxxprint_filtered_dependence_daVinci_graphxxx'FilteredxArcsxOutputxtoxuDrawGraph'
aliasxxximpact_checkxxxxxxxxxxxxxxxxxxxxxxxx'Checkxaliasximpact'

9.8.2 Effective Dependence Graph View Display dependence levels for loop-carried and non-loop-carried dependence arcs due to non-privatized variables. Do not display dependence cones.

print_effective_dependence_graphxxxxxxxxxx>xMODULE.dg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.3 Loop-Carried Dependence Graph View Display dependence levels for loop-carried dependence arcs only. Ignore arcs labeled by private variables and do not print dependence cones.

print_loop_carried_dependence_graphxxxxxxxxxx>xMODULE.dg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.4 Whole Dependence Graph View Display dependence levels and dependence polyhedra/cones for all dependence arcs, whether they are loop carried or not, whether they are due to a private variable (and ignored by parallelization algorithms) or not. Dependence cones labeling arcs are printed too.

print_whole_dependence_graphxxxxxxxxxx>xMODULE.dg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.5 Filtered Dependence Graph View Same as print_whole_dependence_graphx9.8.4 but it’s filtered by some variables. Variables to filter is a comma separated list set by user via property “EFFECTSxFILTERxONxVARIABLE”.

print_filtered_dependence_graphxxxxxxxxxx>xMODULE.dg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.6 Filtered Dependence daVinci Graph View

Same as print_filtered_dependence_graphx9.8.5 but its output is

uDrawGraph10  ^{10http://www.informatik.uni-bremen.de/uDrawGraph}

format.

print_filtered_dependence_daVinci_graphxxxxxxxxxx>xMODULE.dvdg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.7 Filtered Dependence Graph View Check impact of alias on the dependance graph.RK: What is that? FI: Maybe, we should sign how contributions? See validation?

impact_checkxxxx>xMODULE.code
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.alias_associations
xxxxxxxx<xMODULE.cumulated_effects
xxxxxxxx<xMODULE.summary_effects
xxxxxxxx<xMODULE.proper_effects
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.summary_precondition
xxxxxxxx<xMODULE.dg
xxxxxxxx<xALL.code

9.8.8 Chains Graph View Display the chains graph in a textual format. The following properties control the output :

   PRINT_DEPENDENCE_GRAPHx6.5.6.4 PRINT_DEPENDENCE_GRAPH_WITHOUT_PRIVATIZED_DEPSx6.5.6.4
PRINT_DEPENDENCE_GRAPH_WITHOUT_NOLOOPCARRIED_DEPSx6.5.6.4
PRINT_DEPENDENCE_GRAPH_WITH_DEPENDENCE_CONESx6.5.6.4
PRINT_DEPENDENCE_GRAPH_USING_SRU_FORMATx6.5.6.4

print_chains_graphxxxxxx>xMODULE.dg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains

9.8.9 Chains Graph Graphviz Dot View Display the chains graph in graphviz dot format.

print_dot_chains_graphxx>xMODULE.dotdg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.chains

9.8.10 Dependence Graph Graphviz Dot View Display the dependence graph in graphviz dot format.

Using pyps, some convenient functions are provide, for instance :

importxpypsexxxwx=xworkspace ( …) xxw. fun . myxfunctionxname . viewxdg ( )

which will produce in current directory a file named myxfunctionxname.png.

print_dot_dependence_graphxxxxxxxxxx>xMODULE.dotdg_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.dg

9.8.11 Properties for Dot output Here are the properties available to tune the Dot output, read dot documentation for available colors, style, shape, etc.

xPRINT_DOTDG_STATEMENTxTRUE
x

Print statement code and not only ordering inside nodes.

xxxPRINT_DOTDG_TOP_DOWN_ORDEREDxTRUE
x

Add a constraint on top-down ordering for node instead of free dot placement.

xPRINT_DOTDG_CENTEREDxFALSE
x

Should dot produce a centered graph ?

xPRINT_DOTDG_TITLEx""
x
xPRINT_DOTDG_TITLE_POSITIONx"b"
x

Title and title position (t for top and b for bottom) for the graph.

xPRINT_DOTDG_BACKGROUNDx"white"
x

Main Background.

xPRINT_DOTDG_NODE_SHAPEx"box"
x

Shape for statement nodes.

xPRINT_DOTDG_NODE_SHAPE_COLORx"black"
x
xPRINT_DOTDG_NODE_FILL_COLORx"white"
x
xPRINT_DOTDG_NODE_FONT_COLORx"black"
x
xPRINT_DOTDG_NODE_FONT_SIZEx"18"

   xPRINT_DOTDG_NODE_FONT_FACEx"Times-Roman"
   x

Color for the shape, background, and font of each node.

   xPRINT_DOTDG_FLOW_DEP_COLORx"red"
   x
   xPRINT_DOTDG_ANTI_DEP_COLORx"green"
   x
   xPRINT_DOTDG_OUTPUT_DEP_COLORx"blue"
   x
   xPRINT_DOTDG_INPUT_DEP_COLORx"black"
   x

Color for each type of dependence

   xPRINT_DOTDG_FLOW_DEP_STYLEx"solid"
   x
   xPRINT_DOTDG_ANTI_DEP_STYLEx"solid"
   x
   xPRINT_DOTDG_OUTPUT_DEP_STYLEx"solid"
   x
   xPRINT_DOTDG_INPUT_DEP_STYLEx"dashed"
   x

Style for each type of dependence

9.9 Fortran to C prettyprinter A basic and experimental C dumper to output a Fortran program in C code. It is not the same as the default pretty printer that is normaly used to pretty print C code in C. This pass is mainly use inside PIPS and Par4All to be able to generate call to CUDA kernels from a fortran code. The kernel is supposed not to use I/O intrinsics (such as WRITE, READ), they are not handle at the moment (and not usefull in the CUDA context) by the crough printer. However it is still possible to print the C code with the name of the fortran intrinsic using the property CROUGHxPRINTxUNKNOWNxINTRINSIC.

print_croughxx>xMODULE.crough
xxxxxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxxxxx<xMODULE.code
xxxxxxxxxxxxxx<xMODULE.summary_effects

Display the crough output of a fortran function.

print_c_codexx>xMODULE.c_printed_file
xxxxxxxxxxxxxx<xMODULE.crough

Once C version of fortran code has been generated, ones might like to call this C functions from fortran code. A convenient way to do this is to use an interface in the fortran code. PIPS can generate the interface module for any function using the following pass.

print_interfacexx>xMODULE.interface
xxxxxxxxxxxxxxxxx<xPROGRAM.entities
xxxxxxxxxxxxxxxxx<xMODULE.code

9.9.1 Properties for Fortran to C prettyprinter By default the crough pass fails if it encounters a fortran intrinsic that cannot be translated to C. However it is still possible to print the C code with the name of the fortran intrinsic using the following property.

   xCROUGH_PRINT_UNKNOWN_INTRINSICxFALSE
   x

By default the crough pass tries to match the best C type for any Fortran type. Here is the matches between Fortran and C variables:

INTEGER is matched to int.

INTEGER*4 is matched to int.

INTEGER*8 is matched to long long int.

REAL is matched to float.

REAL*4 is matched to float.

REAL*8 is matched to double.

However, many Fortran compilers (ifort, gfortran) allow to change the type size at compile time. It is possible to do the same by setting the property CROUGHxUSERxDEFINEDxTYPE to TRUE. In such a case the include file specified by the property CROUGHxINCLUDExFILE is included by any file generated using crough. It has to define (using #define or typedef) the two types defined by the properties CROUGHxINTEGERxTYPE and CROUGHxREALxTYPE. Obviously those types are used in the generated C file to declare variables that has the types INTEGER or REAL in the original Fortan file. When choosing that solution all INTEGER and REAL (including INTEGER*4, INTEGER*8, REAL*4 and REAL*8) variables will be set to the same user defined types.

   xCROUGH_USER_DEFINED_TYPExFALSE
   x
   xCROUGH_INCLUDE_FILEx"p4a_crough_types.h"
   x
   xCROUGH_INTEGER_TYPEx"p4a_int"
   x
   xCROUGH_REAL_TYPEx"p4a_real"
   x

Is is possible to prettyprint function parameters that are arrays as pointers using the property CROUGHxARRAYxPARAMETERxASxPOINTER

   xCROUGH_ARRAY_PARAMETER_AS_POINTERxFALSE
   x

When PRETTYPRINTxCxFUNCTIONxNAMExWITHxUNDERSCORE is set to TRUE, an underscore is added at the end of the module name. This is needed when translating only some part of a Fortran Program to C. This property must be used with great care, so that only interface function names are changed : the function names in subsequent calls are not modified. An other solution to call a C function from a fortran program is to use/declare an interface in the fortran source code (This feature is part of the Fortran 2003 standard but many Fortran95 compilers support it). The property CROUGHxFORTRANxUSESxINTERFACE can be set to TRUE when the Fotran code integrates interfaces. In such a case, the unmodified scalar function parameters (by the function or any of its callees) are expected to be passed by values, the other parameters are passed by pointers. Finally when using interfaces it is also possible to pass all the scalar variables by values using the propety CROUGHxSCALARxBYxVALUExINxFCTxDECL. Now, let’s talk about function called from the fortran code PIPS has to print in C. The problem on how to pass scalars (by value or by pointer) also exists. At the moment PIPS is less flexible for function call. One of the solution has to be choosen using the property CROUGHxSCALARxBYxVALUExINxFCTxCALL.

   xPRETTYPRINT_C_FUNCTION_NAME_WITH_UNDERSCORExFALSE
   x
   xCROUGH_FORTRAN_USES_INTERFACExFALSE
   x
   xCROUGH_SCALAR_BY_VALUE_IN_FCT_DECLxFALSE
   x
   xCROUGH_SCALAR_BY_VALUE_IN_FCT_CALLxFALSE
   x

If the property DOxRETURNxTYPExASxTYPEDEF is set to TRUE the crough phase additionaly does the same thing that the phase setxreturnxtypexasxtypedef does (cf section x2). In such a case the same property SETxRETURNxTYPExASxTYPEDEFxNEWxTYPE is taken into account. This is only posible for the SUBROUTINES and the FUNCTIONS but not for the PROGRAMS

   xDO_RETURN_TYPE_AS_TYPEDEFxFALSE
   x

Using the property INCLUDExFILESxLIST, it is possible to insert some #include statement before to output the code. The INCLUDExFILESxLIST is a string interpreted as coma (and/or blank) separated list of files.

   xCROUGH_INCLUDE_FILE_LISTx""
   x

9.10 Prettyprinters Smalltalk

This pass is used by the phrase project, which is an attempt to automatically (or semi-automatically) transform high-level language application into control code with reconfigurable logic accelerators (such as fpgas or data-paths with alu).

This pass is used in context of PHRASE project for synthetisation of reconfigurable logic for a portion of initial code. This function can be viewed as a SmallTalk pretty-printer of a subset of Fortran or C.

It is used as input for the Madeo synthesis tools from UBO/AS that is written in SmallTalk and take circuit behaviour in SmallTalk.

It is an interesting language fusion...

aliasxprint_code_smalltalkx'SmalltalkxPretty-Printer'
print_code_smalltalkxxxxxxxx>xMODULE.smalltalk_code_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

9.11 Prettyprinter for the Polyhderal Compiler Collection (PoCC)

This pass is used for printing pragmas scop and endscop which delimit the static control parts (SCoP) of the code. Instrumented code can be an input for any PoCC compiler.

aliasxpocc_prettyprinterx'pocc_prettyprinter'
pocc_prettyprinterxxxxxx>xxxxMODULE.code
xxxx<xPROGRAM.entities
xxxx<xMODULE.code
xxxx<xMODULE.static_control

This pass is used for outlining the static control parts (SCoP) computed by the previous pass, pocc prettyprinted. Instrumented code can be an input for any PoCC compiler.

aliasxscop_outlinerx'scop_outliner'

scop_outlinerxxxxxx>xxxxxMODULE.code
xxxx>xMODULE.callees
xxxx<xPROGRAM.entities
xxxx<xMODULE.code
xxxx<xMODULE.cumulated_effects

For the outlinig of the control static parts, function prefix names to be used during the generation:

   xSCOP_PREFIXx"SCoP"
   x

To generalize the outlining for other purposes, the two delimiter pragma used can be redefined using the next two properties:

   xPRAGMA_BEGIN_OUTLININGx"scop"
   x
   xPRAGMA_END_OUTLININGx"endscop"
   x

which maybe redundant with property EXTERNALIZED_CODE_PRAGMA_BEGINx?? of libraries phrase and safescale. But both of these libraries are currently not maintained and not tested.

Because of user function calls are not allowed in PoCC static control parts, whereas they are generally accepted in PIPS (see Arnauld Leservot’s PhD), we introduce a property to control the impact of user calls. This property could be called POCC_COMPATIBILIRY if there were a set of limiting rules to apply for PoCC, but user calls are the only current

issue11 11The PLUTO compiler does not support intrinsics calls either, althoug it is part of the PoCC collection.

So the property is called STATIC_CONTROLIZE_ACROSS_USER_CALLSx?? and its

default value is TRUE.

   xSTATIC_CONTROLIZE_ACROSS_USER_CALLSxTRUE
   x

9.12 Prettyprinter for CLAIRE

This pass is used for the DREAM-UP project. The internal representation of a C or Fortran program is dumped as CLAIRE objects, either DATAxARRAY or TASK. CLAIRE is an object-oriented language used to develop constraint solvers.

The only type constructor is array. Basic types must be storable on a fixed number of bytes.

The code structure must be a sequence of loop nests. Loops must be perfectly nested and parallel. Each loop body must be a single array assignment. The right-hand side expression must be a function call.

If the input code does not meet these conditions, a user error is generated.

This pass is used for the specification input and transformation in the XML format which can further be used by number of application as input. This function can be viewed as a XML pretty-printer of a subset of C and Fortran programs.

aliasxprint_xml_codex'XmlxPretty-Printer'
print_xml_codexxxxxx>xMODULE.xml_printed_file
xxxx<xPROGRAM.entities
xxxx<xMODULE.code
xxxx<xMODULE.complexities
xxxx<xMODULE.preconditions
xxxx<xMODULE.regions

This phase was developped for the DREAM-UP/Ter@ops project to generate models of functions used for automatic mapping by APOTRES []. It generates XML code like the printxxmlxcode pass, but the input contains explicitly loops to scan motifs. It is useless for other purposes. RK: gnih? FI: to be deleted? CA: more to say?

aliasxprint_xml_code_with_explicit_motifx'XmlxPretty-Printerxwithxexplicitxmotif'
print_xml_code_with_explicit_motifxxxxxxx>xMODULE.xml_printed_file
xxxxxxxx<xPROGRAM.entities
xxxx<xMODULE.code

This pass is used in the DREAM-UP project for module specification input and transformation (?)x[]. This function can be viewed as a CLAIRE pretty-printer of a subset of Fortran.

aliasxprint_claire_codex'ClairexPretty-Printer'
print_claire_codexxxxxxxx>xMODULE.claire_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code
xxxxxxxx<xMODULE.preconditions
xxxxxxxx<xMODULE.regions

This pass generates CLAIRE code like the printxclairexcode pass, but the input contains explicitly loops to scan motifs.

aliasxprint_claire_code_with_explicit_motifx'ClairexPretty-Printerxwithxexplicitxmotif'
print_claire_code_with_explicit_motifxxxxxxx>xMODULE.claire_printed_file
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

This pass was developped for the Ter@ops project to generate models of functions and application used for automatic mapping by SPEAR. It generates XML code.

aliasxprint_xml_applicationx'TeraopsxXmlxPretty-Printer'
print_xml_applicationxxxxxx>xMODULE.xml_printed_file
xxxx<xPROGRAM.entities
xxxx<xMODULE.code
xxxx<xMODULE.proper_effects
xxxx<xMODULE.cumulated_effects
xxxx<xMODULE.summary_effects
xxxx<xMODULE.regions
xxxx<xCALLEES.summary_effects

Chapterx10Feautrier Methods (a.k.a. Polyhedral Method) This part of PIPS was implemented at Centre d’x¿œtudes Atomiques, Limeil-Brx¿œvannes, by Benox¿œt de Dinechin, Arnauld Leservot and Alexis Platonoff.

Unfortunately, this part is no longer used in PIPS right now because of some typing issues in the code. To be fixed when somebody needs it.

10.1 Static Control Detection static_controlizex10.1 transforms all the loops in order to have steps equal to one. Only loops with constant step different than one are normalized. Normalized loop counters are instantiated as a new kind of entity: NLC. This entity is forwarded in the inner statements. It also gets the structural parameters and makes new ones when it is possible (“NSP”). It detects enclosing loops, enclosing tests and the static_control property for each statement. Those three informations are mapped on statements. Function static_controlizex10.1 also modifies code (>xMODULE.code). It is not specified here for implementation bug purpose.

The definition of a static control program is given inx[?].

aliasxstatic_controlizex'StaticxControlize'
static_controlizexxxxxxxxxxxxxxx>xMODULE.static_control
xxxxxxxx<xPROGRAM.entities
xxxxxxxx<xMODULE.code

See the alias print_code_static_controlx9.2.18 and function print_code_static_controlx9.2.18 in Sectionx9.1 and so on.

10.2 Scheduling

Function scheduling computes a schedule, called Base De Temps in French, for each assignment instruction of the program. This computation is based on the Array Data Flow Graph (seex[?,x?]).

The output of the scheduling is of the following form: (the statements are named in the same manner as in the array DFG)

W: Statement examined

pred: Conditions for which the following schedule is valid dims: Time at which the execution of W is schedule, in function of the loop

counters of the surrounding loops.

10.3 Code Generation for Affine Schedule Function reindexing transforms the code using the schedule (bdt) and the mapping (plc) (seex[?,x?]). The result is a new resource named reindexed_code.

10.4 Prettyprinters for CM Fortran How to get a pretty-printed version of reindexed_code ? Two prettyprinters are available. The first one produces CM Fortran and the result is stored in a file suffixed by .fcm. The second one produces CRAFT Fortran and the result is stored in a file suffixed by .craft.

Use the polyhedric method to parallelize the code and display the reindexed code in a CMF (parallel Fortran extension from TMC, Thinking Machine Corporation) style.

Use the polyhedric method to parallelize the code and display the reindexed code in a CRAFT (parallel Fortran used on the Cray T3 serie) style.

Chapterx11User Interface Menu Layouts For presentation issues, it is useful to select only the features that are needed by a user and to display them in a comprehensive order. For that purpose, a layout description mechanism is used here to pick among the PIPS phases described above.

For each menu, the left part before the arrow, ->, is the menu item title and the right part is the PIPS procedure to be called when the item is selected. For the view menu (sectionx11.1, there is two display methods to view resources separated by a comma, the first one is the method for wpips, the second one is the one used in epip, followed by the icon to use.

Use a blank line to insert a menu separator.

11.1 View menu The view menu is displayed according to the following layout and methods (wpips method, epip method, icon name for the frame):

View

xxprinted_filex->xwpips_display_plain_file,epips-display-fortran-file,sequential
xxparsed_printed_filex->xwpips_display_plain_file,epips-display-fortran-file,user
xxalias_filex->xwpips_display_plain_file,epips-display-plain-file,-
xxgraph_printed_filex->xwpips_display_graph_file_display,epips-display-graph-file,-
xxdg_filex->xwpips_display_plain_file,epips-display-plain-file,DG
xxadfg_filex->xwpips_display_plain_file,epips-display-plain-file,-
xxbdt_filex->xwpips_display_plain_file,epips-display-plain-file,-
xxplc_filex->xwpips_display_plain_file,epips-display-plain-file,-
xxcallgraph_filex->xwpips_display_plain_file,epips-display-xtree-file,callgraph
xxdvcg_filex->xwpips_display_graph_file_display,epips-display-graph-file,callgraph
xxicfg_filex->xwpips_display_plain_file,epips-display-plain-file,ICFG
xxwp65_compute_filex->xwpips_display_WP65_file,epips-display-distributed-file,WP65_PE
xxparallelprinted_filex->xwpips_display_plain_file,epips-display-fortran-file,parallel
xxflinted_filex->xwpips_display_plain_file,epips-display-plain-file,-

11.2 Transformation menu The transformation menu is displayed as here:

Transformations

xxdistributer
xxfull_unroll
xxunroll
xxloop_interchange
xxloop_normalize
xxstrip_mine
xxloop_tiling
xxtiling_sequence
xxprivatize_module
xxarray_privatizer
xxdeclarations_privatizer
xxrestructure_control
xxunspaghettify
xxsimplify_control
xxsimplify_control_directly
xxpartial_eval
xxdead_code_elimination
xxstf
xxfreeze_variables
xxpartial_redundancy_elimination
xxarray_bound_check_bottom_up
xxarray_bound_check_top_down
xxarray_bound_check_interprocedural
xxarray_resizing_bottom_up
xxarray_resizing_top_down
xxalias_check
xxatomizer
xxnew_atomizer
xxclone
xxclone_substitute
xxclone_on_argument
xxclean_declarations
xxunsplit
xxstatic_controlize

At the end of this menu is added a special entry in wpips, the “Edit” line that allows the user to edit the original file. It is seen as a very special transformation, since the user can apply whatever transformation (s)he wants...

Chapterx12Conclusion New functionalities can easily be added to PIPS. The new function names must be declared somewhere in this file as well as the resources required and produced. Then, make must be run in the Documentation directory and the pipsmake library must be recompiled and PIPS interfaces (pips, tpips, wpips) linked with the new C modules.

It is much more difficult to add a new type of resources, because PIPS database manager, pipsdbm, is not as automatized as pipsmake. This is explained inx[?].

Chapterx13Known Problems

pipsmake behavior may be erratic if files are accessed across a nfs network of non-synchronized workstations (see for instance UNIX rdate command or better ntp daemon).

STOP statements in subroutines (i.e. control effects and control dependencies) are not taken into account when parallelizing the caller.

Index (, 133

Abort, 8

Abstract Syntax Tree, 18 Alias Analysis, 73 Alias Checking, 159 Alias Classes, 73 Alias Propagation, 158 Allen & Kennedy Algorithm, 81 Allen&Kennedy, 80 Alternate Return, 22 Analysis, 33, 179 Analysis (Semantics), 49 Array access, 156 Array Expansion, 164 Array Privatization, 161, 162 Array Region, 67, 72, 77 ARRAYxPRIVxFALSExDEPxONLY, 162 ARRAYxSECTIONxPRIVxCOPYxOUT, 162 Assigned GO TO, 24 AST, 18 Atomic Chains, 40 Atomization, 131 ATOMIZExINDIRECTxREFxONLY, 131 Atomizer, 84, 130 atomizer, 130 Automatic Distribution, 90

Buffer overflow, 156

C3 Linear Library, 7

Call Graph, 33, 190 Callees, 19 CFG, 28 CHAINSxDATAFLOWxDEPENDENCExONLY, 43 CHAINSxMASKxEFFECTS, 43 checkpoint, 7 CLEANxUPxSEQUENCESxDISPLAYxSTATISTICS, 30 Cloning, 146 CM Fortran, 180 Code Distribution, 97 Code Prettyprinter, 179 Common subexpression elimination, 131, 133, 137 common subexpression elimination, 138 compilation unit, 25 Complementary Sections, 77 Complementary Sections (Summary), 78 Complex Constant, 13 Complexity, 63, 65, 170 Complexity (Floating Point), 64 Complexity (Summary), 64 Complexity (Uniform), 64 COMPLEXITYxCOSTxTABLE, 66 COMPLEXITYxEARLYxEVALUATION, 66 COMPLEXITYxINTERMEDIATES, 65 COMPLEXITYxPARAMETERS, 65 COMPLEXITYxPRINTxCOSTxTABLE, 65 COMPLEXITYxPRINTxSTATISTICS, 65 COMPLEXITYxTRACExCALLS, 65 COMPUTExALLxDEPENDENCES, 48 Computed GO TO, 24 Control Counters, 129 Control Flow Graph, 28 Control Restructurer, 122, 127 Control Simplification, 120 Controlizer, 28 correctness, 21 Craft, 180 Cray, 81 Cray Fortran, 180 CSE, 131, 137 Cumulated Effects, 35, 37

DaVinci, 189

Dead Code, 121 Dead Code Elimination, 120 Dead code elimination, 121 DEADxCODExDISPLAYxSTATISTICS, 121 Debug, 182 Debug (Complexity), 65 Debug (Semantics), 63 Debugging, 7 Declaration, 184 Def-Use Chains, 40, 47 Dependence Graph, 43, 47, 202 Dependence Test, 45 dependence test xxxxfast, 44 xxxxfull, 44 xxxxregions, 45 xxxxsemantics, 45 Dependence test statistics, 45 DEPENDENCExTEST, 45 DESTRUCTURExFORLOOPS, 126 DESTRUCTURExLOOPS, 126 DESTRUCTURExTESTS, 126 DESTRUCTURExWHILELOOPS, 126 DG, 43, 202 DG Prettyprinter, 47 DISJUNCTxINxOUTxREGIONS, 72 DISJUNCTxREGIONS, 72 Distribution, 79, 90 Distribution (Loop), 111 Distribution init, 98 DREAM-UP, 210 Dynamic Aliases, 73

Effect, 34

Effects (Cumulated), 35, 37 Effects (IN), 36 Effects (Memory), 37 Effects (OUT), 36 Effects (Proper), 34 EFFECTSxPRINTxSDFI, 37 Emacs, 185 Emulated Shared Memory, 90 Entity, 18 ENTRY, 22 EOLE, 137 EOLExFLAGS, 137 EOLExOPTIONS, 137 EXACTxREGIONS, 72 Expansion, 164 Expression, 59

Final Postcondition, 58

Finite State Machine Generation, 128 Fix Point, 60 Floating Point Complexity, 64 Flow Sensitivity, 59 Foresys, 184 Format (Fortran), 30 Fortran (Cray), 180 Fortran 90, 21, 180 Forward substitution, 133 freeze variables, 164 FSM Generation, 129 FSMIZExWITHxGLOBALxVARIABLE, 129 FUSExCONTROLxNODESxWITHxCOMMENTSxORxLABEL, 30

GATHERxFORMATSxATxBEGINNING, 30

GATHERxFORMATSxATxEND, 30 General Loop Interchange, 116 GENERATExNESTEDxPARALLELxLOOPS, 80 GLOBALxEFFECTSxTRANSLATION, 93 GO TO (Assigned), 24 GO TO (Computed), 24

hCFG, 28

Hierarchical Control Flow Graph, 28 Hollerith, 12 HPF, 91, 93, 180, 185 HPFC, 91 HPFCxBUFFERxSIZE, 93 HPFCxDYNAMICxLIVENESS, 93 HPFCxEXPANDxCMPLID, 93 HPFCxEXPANDxCOMPUTExCOMPUTER, 93 HPFCxEXPANDxCOMPUTExLOCALxINDEX, 93 HPFCxEXPANDxCOMPUTExOWNER, 93 HPFCxEXTRACTxEQUALITIES, 93 HPFCxEXTRACTxLATTICE, 93 HPFCxFILTERxCALLEES, 93 HPFCxGUARDEDxTWINS, 93 HPFCxIGNORExFCDxSET, 93 HPFCxIGNORExFCDxSYNCHRO, 93 HPFCxIGNORExFCDxTIME, 93 HPFCxIGNORExINxOUTxREGIONS, 93 HPFCxIGNORExMAYxINxIO, 93 HPFCxLAZYxMESSAGES, 93 HPFCxNOxWARNING, 93 HPFCxOPTIMIZExREMAPPINGS, 93 HPFCxREDUNDANTxSYSTEMSxFORxREMAPS, 93 HPFCxSYNCHRONIZExIO, 93 HPFCxTIMExREMAPPINGS, 93 HPFCxUSExBUFFERS, 93 Hyperplane Method, 116

ICFG, 188

ICFGxCALLEESxTOPOxSORT, 188 ICFGxDEBUG, 188 ICFGxDECOR, 188 ICFGxDOs, 188 ICFGxDRAW, 188 ICFGxDV, 188 ICFGxIFs, 188 ICFGxINDENTATION, 188 If Simplification, 120 Implicit None, 13 IN Effects, 36 IN Regions, 70 IN Summary Regions, 71 Include, 12, 13 Index Set Splitting, 113 Initial Precondition, 52 Inlining, 142 INLININGxCALLERS, 142 Input File, 11 Interprocedural, 60 Intraprocedural Summary Precondition, 52 Invariant code motion, 133, 137 invariant code motion, 119 IR, 18

Kaapi, 98

KEEPxREADxREADxDEPENDENCE, 42

Logging, 6, 8

Loop Distribution, 111 Loop fusion, 113 Loop Interchange, 116 Loop Normalize, 118 Loop Simplification, 120 Loop Unrolling, 114 LOOPxLABEL, 110

MAY Region, 69

Memory Effect, 34 Memory Effects, 37 MEMORYxEFFECTSxONLY, 37 Missing Code, 15 Missing file, 12 Module, 18 MPI, 95 MUST Region, 69 MUSTxREGIONS, 72

NewGen, 7 NOxUSERxWARNING, 10

OpenGPU, 209

OpenMP, 95, 165 Optimization, 137 OUT Effects, 36 OUT Regions, 71 OUT Summary Regions, 71

Parallelization, 79–81

PARALLELIZATIONxSTATISTICS, 80 Parsed Code, 19 PARSERxACCEPTxANSIxEXTENSIONS, 21 PARSERxACCEPTxARRAYxRANGExEXTENSION, 21 PARSERxEXPANDxSTATEMENTxFUNCTIONS, 24 PARSERxFORMALxLABELxSUBSTITUTExPREFIX, 22 PARSERxLINEARIZExLOOPxBOUNDS, 22 PARSERxRETURNxCODExVARIABLE, 22 PARSERxSIMPLIFYxLABELLEDxLOOPS, 22 PARSERxSUBSTITUTExALTERNATExRETURNS, 22 PARSERxSUBSTITUTExASSIGNEDxGOTO, 24 PARSERxSUBSTITUTExENTRIES, 22 PARSERxTYPExCHECKxCALLxSITES, 21 PARSERxWARNxFORxCOLUMNSx73x80, 20 Partial Evaluation, 131 PARTIALxDISTRIBUTION, 111 PHRASE, 97, 128, 208 Phrase comEngine Distributor, 99 Phrase Distributor, 97 Phrase Distributor Control Code, 97 Phrase Distributor Initialisation, 97 Phrase Remove Dependences, 98 Pipsdbm, 8 PIPSDBMxNOxFREExONxQUIT, 8 Pipsmake, 7 Pointer Values Analyses, 74 Points to Analysis, 74 Postcondition (Final), 58 Precondition, 53, 58 Precondition (Initial), 52 Precondition (Summary), 52, 54 Preprocessing, 12, 13 PRETTYPRINTxADDxEMACSxPROPERTIES, 185 PRETTYPRINTxALLxCxBLOCKS, 182 PRETTYPRINTxALLxDECLARATIONS, 184 PRETTYPRINTxALLxEFFECTS, 182 PRETTYPRINTxALLxLABELS, 182 PRETTYPRINTxALLxPARENTHESES, 182 PRETTYPRINTxALLxPRIVATExVARIABLES, 182 PRETTYPRINTxANALYSESxWITHxLF, 179 PRETTYPRINTxBLOCKxIFxONLY, 182 PRETTYPRINTxBLOCKS, 182 PRETTYPRINTxCxCODE, 179 PRETTYPRINTxCHECKxIOxSTATEMENTS, 182 PRETTYPRINTxCOMMONS, 184 PRETTYPRINTxDOxLABELxASxCOMMENT, 182 PRETTYPRINTxEFFECTS, 180 PRETTYPRINTxEMPTYxBLOCKS, 182 PRETTYPRINTxEXECUTIONxCONTEXT, 180 PRETTYPRINTxFINALxRETURN, 182 PRETTYPRINTxFORxFORESYS, 184 PRETTYPRINTxHEADERxCOMMENTS, 184 PRETTYPRINTxHPFC, 185 PRETTYPRINTxINDENTATION, 179 PRETTYPRINTxINTERNALxRETURN, 182 PRETTYPRINTxIOxEFFECTS, 180 PRETTYPRINTxLISTSxWITHxSPACES, 179 PRETTYPRINTxLOOSE, 179 PRETTYPRINTxMEMORYxEFFECTSxONLY, 180 PRETTYPRINTxPARALLEL, 180 PRETTYPRINTxREGENERATExALTERNATExRETURNS, 22 PRETTYPRINTxREGION, 180 PRETTYPRINTxREVERSExDOALL, 180 PRETTYPRINTxSCALARxREGIONS, 180 PRETTYPRINTxSTATEMENTxNUMBER, 179 PRETTYPRINTxSTATEMENTxORDERING, 182 PRETTYPRINTxTRANSFORMER, 180 PRETTYPRINTxUNSTRUCTURED, 182 PRETTYPRINTxUNSTRUCTUREDxASxAxGRAPH, 189 PRETTYPRINTxUNSTRUCTUREDxASxAxGRAPHxVERBOSE, 189 PRETTYPRINTxVARIABLExDIMENSIONS, 184 PRETTYPRINTxWITHxCOMMONxNAMES, 182 Prettyprinter, 167 Prettyprinter (Code), 179 Prettyprinter (DG), 47 Prettyprinter (HPF), 185 Prettyprinter Claire, 210 Prettyprinter PoCC, 209 Prettyprinters Smalltalk, 208 PRINTxDEPENDENCExGRAPH, 47 PRINTxDEPENDENCExGRAPHxUSINGxSRUxFORMAT, 47 PRINTxDEPENDENCExGRAPHxWITHxDEPENDENCExCONES, 47 PRINTxDEPENDENCExGRAPHxWITHOUTxNOLOOPCARRIEDxDEPS, 47 PRINTxDEPENDENCExGRAPHxWITHOUTxPRIVATIZEDxDEPS, 47 Privationzation (Array), 162 Privatization, 161, 162 Program Transformation, 110 Proper Effects, 34 Reduction Detection, 132

Reduction Parallelization, 164 Region, 67 Region (Array), 72 Region (Summary), 70 Regions (IN), 70 Regions (OUT), 71 REGIONSxOPxSTATISTICS, 72 REGIONSxTRANSLATIONxSTATISTICS, 72 REGIONSxWITHxARRAYxBOUNDS, 72 RESTRUCTURExWHILExRECOVER, 123 Restructurer, 122 Return (Alternate), 22 RI, 18 RICExDATAFLOWxDEPENDENCExONLY, 47 RICEDGxPROVIDExSTATISTICSxFALSE, 45 RICEDGxSTATISTICSxALLxARRAYS, 45

Safescale, 98

Scalar Expansion, 164 Scalar Privatization, 161 Scheduling, 212 SDFI, 36 Semantics, 58 Semantics Analysis, 49 SEMANTICSxANALYZExSCALARxBOOLEANxVARIABLES, 58 SEMANTICSxANALYZExSCALARxFLOATxVARIABLES, 58 SEMANTICSxANALYZExSCALARxINTEGERxVARIABLES, 58 SEMANTICSxANALYZExSCALARxSTRINGxVARIABLES, 58 SEMANTICSxANALYZExUNSTRUCTURED, 59 SEMANTICSxFILTEREDxPRECONDITIONS, 62 SEMANTICSxFIXxPOINT, 60 SEMANTICSxFIXxPOINTxOPERATOR, 60 SEMANTICSxFLOWxSENSITIVE, 59 SEMANTICSxINEQUALITYxINVARIANT, 60 SEMANTICSxINTERPROCEDURAL, 60 SEMANTICSxNORMALIZATIONxLEVELxBEFORExSTORAGE, 62 SEMANTICSxRECOMPUTExFIXxPOINTSxWITHxPRECONDITIONS, 60 SEMANTICSxSTDOUT, 63 SEMANTICSxTRUSTxARRAYxDECLARATIONS, 58 SEMANTICSxTRUSTxARRAYxREFERENCES, 58 Sequential View, 172 Simplify Control, 120 SLP, 84 Software Caching, 90 Source File, 15 Spaghettifier, 126 Specialize, 164 Splitting, 12 SSE, 84 Statement externalization, 98 Statement Function, 24 Statement number, 179 Statistics (Dependence test), 45 STF, 127 Strip-Mining, 116 Summary Complementary Sections, 78 Summary Complexity, 64 Summary Precondition, 54 Summary Region, 70 Summary Regions (IN), 71 Summary Regions (OUT), 71 Summary Total Postcondition, 57 Summary Total Precondition, 57 Summary Transformer, 52 Superword parallelism, 84 Symbol table, 20

Terapix, 99

Thread-safe library, 80 Three Address Code, 131 Three-Address Code, 130 Tiling, 117 Top Level, 8 Total Postcondition (Summary), 57 Total Precondition, 55 Total Precondition (Summary), 57 Tpips, 10 TPIPSxISxAxSHELL, 10 Transformation, 110 TRANSFORMATIONxCLONExONxARGUMENT, 146 Transformer, 49, 58, 59 Transformer (Summary), 52 Trivial Test Elimination, 127 Type Checking, 15, 21 TypeChecker, 161

Uniform Complexity, 64

Unreachable Code Elimination, 120 Unspaghettify, 123 UNSPAGHETTIFYxDISPLAYxSTATISTICS, 123 UNSPAGHETTIFYxRECURSIVExDECOMPOSITION, 123 UNSPAGHETTIFYxTESTxRESTRUCTURING, 123 Use-Def Chains, 40 Use-Def Elimination, 121 Use-Use Chains, 40 User File, 11 Variable, 18 Vectorization, 81 WARNxABOUTxEMPTYxSEQUENCES, 10 Warning, 10 WARNINGxONxSTATxERROR, 10 WP65, 90