450 likes | 603 Views
LAO Getting Started. Plan. Architecture Tests XCC Coding Rules Information To Start Use Cases. Linear Assembly Optimizer. Gather a set of packages Two possible modes: Mode LAO: CDT ECL PRO Mode JIT: CDT ECL Hierarchy: LAO > Packages > Libraries > Modules
E N D
Plan • Architecture • Tests • XCC • Coding Rules • Information To Start • Use Cases
Linear Assembly Optimizer • Gather a set of packages • Two possible modes: • Mode LAO: • CDT • ECL • PRO • Mode JIT: • CDT • ECL • Hierarchy: LAO > Packages > Libraries > Modules • Repository: svn+ssh://stmicro.lipforge.ens-lyon.fr/svnroot/ecc/lao/trunk/LAO
LAO Structure • LAO • PACK1/ ; A package • PACK2/ • Makefile ; Package makefile • DOC/ ; Documentation • LIB1/ ; A library • LIB2/ • Makefile ; Library makefile • 0/ ; Input files for (self-)tests (MyModule.0) (e.g. foo.0) • 1/ ; Expected output files for tests (MyModule.1) (e.g. foo.1) • MyTarget1/ ; MyTarget1 specific expected output • MyTarget2/ • LIB2.xcc ; Global interface of the library • Module1 ; (Module1.xcc) (e.g. foo.xcc) • Module2 • MyTarget1/ ; Contains targeting of modules for MyTarget1 when needed • MyModule.xcc ; One file per module with a targeting (e.g. foo.xcc) • MyTarget2/
Packages Properties • GNU like • configure • automake
Available Packages • CDT: Compiler Development Tools: Utilities package • BSL: Basic Services Library (memory, etc.) • CCL: C Container Library (list, set, etc.) • CAL: Combinatorial Algorithm Library (dominator graph, etc.) • ECL: Embedded Compiler Libraries: IR + optimizations • AIR: Assembler Intermediate Representation • MDS: Target machine description library configured by the MDS • LIR: Layered Intermediate Representation • PFA: Program Flow Analyses (Liveness, SSA Form) • CGO: Code Generator Optimizations • JIT: Just-In-Time compiler • PRO: Heavy optimization and Open64 bridge • GRA: Register Allocation • XFA: Extra Flow Analyses • SCD: Scheduling algorithms • O64: Open64 interface and LAO compilation driver
Makefile – LAO • extract: extract CDT, ECL and PRO • install: installation (see next slide) • clean: Remove built files • distclean: Remove built files and files created by configure • build: all + install • MyTarget: If MyTarget does not exist, it tries to parse a file named MyTarget.def and launch make build with that definition • Note: LAO builds directly in the sources • Note: To do an optimized compiler: make speed (cf. speed.def) • Note: To do a development compiler: make debug (cf. debug.def)
Makefile – LAO • install: Create the following structure • export/ • lib/ ; For Open64 • lao.so • include/ ; For Open64 • MyTarget1/ • lao_....h ; Should not diff with files under Open64 svn • MyTarget2/ • lao_....h • include/ ; include file to use LAO as a library • bin/ • lib/ • share/ • doc/ ; Documentation of LAO (extracted from xcc files)
Makefile – Package • all: Build all libraries • check: Build and run self tests • clean: Remove built files • install: Copy libraries at a defined prefix
Makefile - Library • all: Launch xccgen on all xcc files • clean: Remove built files • check: Build and run self tests • refs: Update references. I.e. move generated output file into 1/ directory • again: Check that used libraries are up-to-date. E.g. make clean again check • This is configure process of LAO which create the makefile
Tests • Embedded directly in .xcc (//@XCC_.c) • Test locally a module • Tests process (make check) • xccgen tool extracts the tests code in a file • host compiler compile the test file • host execute test file with input file • comparison is done between output and expected output • status (fail or pass) is printed • To sum up: • xccgen MyModule.xcc # extract a test file: MyModule_.c • gcc MyModule_.c -o MyModule.tst # produce executable (simplified command) • MyModule.tst < 0/MyModule.0 > MyModule.1 # execution • (diff MyModule.1 1/MyModule.1 && echo PASS) || echo FAIL # status
Self Tests • Used to ensure that a modification in LAO will not break its integration in Open64 • Create a LAO IR and call some optimizations on it • Output must be conformed to what it is kept in svn • Structure: • Working Copy/ • LAO/ • CDT/ ; Created by make extract • ECL/ ; Idem • PRO/ ; Idem • Makefile • LAO_INPUT/ ; In svn, contains all the sources of the self tests • LAO_TRACE/ ; Created by hand. This directory will contain the traces of the self tests. It also contains the optimization to be passed (cf. next slides)
Self Tests – Makefile • Self Tests are available for PRO module only • refs: Move generated output into related references directories • tests: Build and run all self tests • Use makefile variables to specify: • Input directory: LAO_INPUT (default ../../LAO_INPUT) • Trace directory: LAO_TRACE (default ../../LAO_TRACE). • Use LAO options overrideable both by: • Environment variables • Created files named MyOption=MyValue in directory specified by LAO_TRACE • inputs: Create input files from input.c files (compilation) • traces: Create trace files from input files (execution)
Self Tests – Remarks • Three classes of optimizations: • Register allocation • Scheduling • Other • All the input tests have not a call to the three classes of optimization. For instance, the allocation phase is not always available • Overrideable options for LAO optimizations are listed in: • ECL/LIR/Configure.xcc • ECL/LIR/Optimize.xcc • ... • E.g.: FORCE_SCHEDULING=MyMask, LIR_TRACE=MyFileDescriptor • You can directly do: ‘make foo.trace’, the condition is: a foo.input.c file must exist
Files • XCC: eXtra C Comment • One xcc file = one module • Merge of • Interface • Implementation • Test • Documentation (see share/doc/CDT/WLMDoc.html after make install)
Commands • Embedded in C command • Start with @ • /*@cmd */ • //@cmd • Two kind of commands • Dispatcher • “Structure helper” • Dispatcher command • XCCMyExtension • Extract next paragraph in MyModuleMyExtension • A paragraph is a sequence of text which stops at \n\n • no dispatch imply .c for a paragraph • Structure helper: Valid only in between the two braces of a C struct code
Processing – Dispatching Preprocessing: xccgen .c Implementation .xcc dispatch _.h Private Interface .h Public Interface _.c Test .wlm Documentation
Processing – C Structure • Generate several typedef (assume struct MyStruct_): • MyStruct_: Define the type for the structure • MyStruct: Define the type of a pointer to the structure • const_MyStruct: Define the type of a pointer to the constant structure • Generate getter and setter for all structure fields using macro. E.g. int FIELD: • Getter: MyStruct_FIELD(this) ((this)->FIELD) • Setter: MyStruct__FIELD(this) (&(this)->FIELD) • Process structure helper and generate related code
Structure Helper • args MyArgs: Specify additional arguments to be set on generated constructor and size function for the structure by xccgen • ctor MyContribution: Add MyContribution code to the constructor function of the structure. All the contributions set with that command are emitted from top to bottom in the constructor (MyStruct_Ctor(this + @args)). • dtor MyContribution: Add MyContribution code to the destructor function of the structure. All the contributions set with that command are emitted from top to bottom in the constructor (MyStruct_Dtor(this)). • size MyContribution: Add MyContribution code to function used to get the size of the structure. This size will be used by operation like malloc (MyStruct_Size(@args)) • copy MyContribution: Contribution for the function to copy that structure (MyStruct_Copy(this, const that)). • decl MyContribution: Contribution to do forward declaration. E.g. to emit declaration of utility functions used by the constructor. • access MyField MyCode: Define getter code. Allow to create virtual fields or override default xccgen generation. (Produce #define MyStruct_MyField(this) MyCode). • mutate MyField MyCode: Define setter code. Allow to create virtual fields or override default xccgen generation. (Produce #define MyStruct__MyField(this) MyCode).
XCCGEN Common Error • Dispatching: • /*@XCC.h*/ => MyModule.h*/ // ERROR • //@XCC.h => MyModule.h // OK • /*@XCC.h */ => MyModule.h // OK • Paragraph//@XCC.hstruct MyStruct {int32_t FIELD1;int32_t FIELD2;}; // => End of the paragraph in the structure: end of the structure dispatched in .c file Compilation error
Example (1) – foo.xcc //@XCC_.h struct MyStruct_ { //@args Memory memory, CodeRegion codeRegion //@ctor TemporaryTable globalTable = //@ctor CodeRegion_globalTable(codeRegion); //@ctor Procedure procedure = //@ctor CodeRegion_procedure(codeRegion); //@ctor Temporary_ *dedicated = //@ctor Procedure_dedicated(procedure); Memory MEMORY; //@ctor *MyStruct__MEMORY(this) = memory; //@access VIRTUALFIELD MyStruct_MEMORY(this)+12 //@decl void MyStruct_ctor_(MyStruct this, //@decl Temporary_ *dedicated, bool doIt); //@ctor MyStruct_ctor_(this, dedicated, true); //@size sizeof(MyStruct_) };
Example (2) //@XCC_.h • Next paragraph will be dispatched in foo_.h typedef struct MyStruct_ MyStruct_, *MyStruct;typedef const struct MyStruct_ *const_MyStruct; struct MyStruct_ { //@args Memory memory, CodeRegion codeRegion • Specify additional arguments of constructor and size functions //@ctor TemporaryTable globalTable = • First contribution to constructor • Generate prototype with arguments specified by @args MyStructMyStruct_Ctor(MyStruct this, Memory memory, CodeRegion codeRegion) {// Add the contributionTemporaryTable globalTable =
Example (3) • New contributions to constructor • CodeRegion_globalTable(codeRegion); • Procedure procedure = • CodeRegion_procedure(codeRegion); • Temporary_ *dedicated = • Procedure_dedicated(procedure); //@ctor CodeRegion_globalTable(codeRegion); //@ctor Procedure procedure = //@ctor CodeRegion_procedure(codeRegion); //@ctor Temporary_ *dedicated = //@ctor Procedure_dedicated(procedure); Memory MEMORY • Field detection • Emit field in the structure • Memory MEMORY; • Emit getter/setter • #define MyStruct_MEMORY(this) ((this)->MEMORY) • #define MyStruct__MEMORY(this) (&(this)->MEMORY) //@ctor *MyStruct__MEMORY(this) = memory; • New contribution to constructor • *MyStruct__MEMORY(this) = memory;
Example (4) //@access VIRTUALFIELD MyStruct_MEMORY(this)+12 • Definition of a getter on a virtual field • #define MyStruct_VIRTUALFIELD(this) MyStruct_MEMORY(this)+12 //@decl void MyStruct_ctor_(MyStruct this, //@decl Temporary_ *dedicated, bool doIt); • Contributions to declarations • void MyStruct_ctor_(MyStruct this, • Temporary_ *dedicated, bool doIt); ////@ctor MyStruct_ctor_(this, dedicated, true); • New contribution to constructor • MyStruct_ctor_(this, dedicated, true); //@size sizeof(MyStruct_) • Contribution to size function • Generate prototype with arguments specified by @args • size_t • MyStruct_Size(Memory memory, CodeRegion codeRegion) { • return • sizeof(MyStruct_) // My contribution
Example (5) }; • End of the structure • Emit in foo_.h file with that order: • Structure definition • Macros • Declarations • Generated functions
Final result without comments Example (6) struct MyStruct_ { Memory MEMORY; }; typedef struct MyStruct_ MyStruct_, *MyStruct; typedef const struct MyStruct_ *const_MyStruct; #define MyStruct_MEMORY(this) ((this)->MEMORY) #define MyStruct__MEMORY(this) (&(this)->MEMORY) #define MyStruct_VIRTUALFIELD(this) MyStruct_MEMORY(this)+12 void MyStruct_ctor_(MyStruct this, Temporary_ *dedicated, bool doIt); MyStruct MyStruct_Ctor(MyStruct this, Memory memory, CodeRegion codeRegion) { TemporaryTable globalTable = CodeRegion_globalTable(codeRegion); Procedure procedure = CodeRegion_procedure(codeRegion); Temporary_ *dedicated = Procedure_dedicated(procedure); *MyStruct__MEMORY(this) = memory; MyStruct_ctor_(this, dedicated, true); return this; } size_t MyStruct_Size(Memory memory, CodeRegion codeRegion) { return sizeof(MyStruct_) ; }
“Enhanced” C89 • Write “enhanced” C89 • Mix declaration and code is forbidden • Use standard C library (e.g. alloca is forbidden) and standard type (stdint.h, stdbool.h) • Usage of GNU extension is fordidden • Only rely on C89 norm (behavior, syntax, …) • Exceptions • C99 comments allow (//) • static inline • restrict
Lexical Conventions (1) • Lines length ≤ 90 characters • Indent with space (2) • <TAB> is forbidden except in comment • Use K&R recommended layout:if (cond1) { ...} else if (cond2) { ...} else { ...}
Lexical Conventions (2) • Control expression must check a logical valueif (pointer) // forbiddenif (pointer != NULL) // OK • Attach the opening ‘(‘ of a function call to the function namefoo (bar) // forbiddenfoo(bar) // OK • Use ‘, ‘ to separate function arguments • Function definitions have the function name and the return type on two linesstatic intfoo(int bar)
Lexical Convention (3) • When an expression does not fit on a single line, break it up according to these rules: • Break after a comma. • Break before an operator. • Prefer higher-level breaks to lower-level breaks. • Align the new line with the beginning of the expression at the same level on the previous line.if ( cond1 && ( cond 2 || cond 3)) { ...}for (iter1 = val1, iter2 = val2;
Identifier Names (1) • Type name • BackColor • Should be prefixed by module name// Module.htypedef int (*ModuleCompare)(int, int);typedef struct { int16_t REAL; int16_t IMAG;} ModuleComplex; • Function name • Simple function: backColor. • Object function: Object_backColor • External linkage function: Module_backColor
Identifier Names (2) • Structure: • Structure name: struct MyStruct_ • Field name: BACKCOLOR • Related function: MyStruct_someFunc • Enumeration: All enumeration values should start with the name of the enumerationtypedef enum { ModuleFlag_Opened, ModuleFlag_Closed, ModuleFlag_} ModuleFlag; • Variable: backColor • Macro: Namespace_BACKCOLOR
Useful Interfaces (1) • Create temporaries • Procedure (ECL/LIR) • SSAForm (ECL/PFA) • Create operations • Selector (ECL/LIR) • BasicBlock (ECL/LIR) • Create basic blocks • Procedure (ECL/LIR) • SSA Creation/Destruction • SSAForm (ECL/PFA)
Useful Interfaces (2) • Browse basic blocks’ succs/preds • CodeRegion (ECL/LIR) • Browse basic blocks • CodeRegion (ECL/LIR) • Browse basic blocks’ operations • BasicBlock (ECL/LIR) • Browse operations’ arguments/results • Operation (ECL/LIR)
Convention (1) • Constructor • initializes structure’s members • MyStruct_make • Performs memory allocation • Call constructor • Return a pointer to new “object” • MyStruct_kill • Call destructor • Performs memory release
Convention (2) • Result of module analysis available between • MyStruct_make • MyStruct_kill • Use functions to access/mutate fields members, or at least generated macros • MyStruct_myField • MyStruct_MYFIELD
Start With LAO • Create your working directory (WD) • Checkout LAO in your working directory • svn co svn+ssh://stmicro.lipforge.ens-lyon.fr/svnroot/ecc/lao/trunk/LAO • Enter LAO directory and retrieve packages • cd LAO; make extract • Build LAO • make debug • Test LAO • make check
Create Self Test References • Retrieve and build LAO (cf. previous slide) • Go to WD and extract tests bed • svn co svn+ssh://stmicro.lipforge.ens-lyon.fr/svnroot/ecc/lao/trunk/LAO_INPUT • Create a directory for the traces • mkdir LAO_TRACE • Set the optimizations options you want • E.g. touch LAO_TRACE/FORCE_CONVERSION=127 • Create References • make refs –C LAO/PRO • Note: To test against references • make tests –C LAO/PRO
New Module • Create MyModule.xcc file • Add it to the repository • svn add MyModule.xcc • Add it in the build process • Add MyModule.c on the lines of the library you belong to in Makefile.am of your package • Launch automake (version 1.9.6) • Ensure it works • Commit your changes (at least adding of your file and makefile modification)
Use Liveness Information For My Optimization • Call Liveness_make • Set live in and live out attributes on basic blocks • Do your optimization • Call Liveness_kill • Kill live in and live out attributes on basic blocks