Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
AU2011305837B2 - Systems and methods for compiler-based vectorization of non-leaf code - Google Patents
[go: Go Back, main page]

AU2011305837B2 - Systems and methods for compiler-based vectorization of non-leaf code - Google Patents

Systems and methods for compiler-based vectorization of non-leaf code Download PDF

Info

Publication number
AU2011305837B2
AU2011305837B2 AU2011305837A AU2011305837A AU2011305837B2 AU 2011305837 B2 AU2011305837 B2 AU 2011305837B2 AU 2011305837 A AU2011305837 A AU 2011305837A AU 2011305837 A AU2011305837 A AU 2011305837A AU 2011305837 B2 AU2011305837 B2 AU 2011305837B2
Authority
AU
Australia
Prior art keywords
function
dependency
compiler
called function
vector
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Ceased
Application number
AU2011305837A
Other versions
AU2011305837A1 (en
Inventor
Jeffry E. Gonion
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Apple Inc
Original Assignee
Apple Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US12/888,644 external-priority patent/US8621448B2/en
Priority claimed from US12/888,658 external-priority patent/US8949808B2/en
Application filed by Apple Inc filed Critical Apple Inc
Publication of AU2011305837A1 publication Critical patent/AU2011305837A1/en
Application granted granted Critical
Publication of AU2011305837B2 publication Critical patent/AU2011305837B2/en
Ceased legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/45Exploiting coarse grain parallelism in compilation, i.e. parallelism between groups of instructions
    • G06F8/456Parallelism detection

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

Systems and methods for the vectorization of software applications are described. In some embodiments, source code dependencies can be expressed in ways that can extend a compiler's ability to vectorize otherwise scalar functions. For example, when compiling a called function, a compiler may identify dependencies of the called function on variables other than parameters passed to the called function. The compiler may record these dependencies, e.g., in a dependency file. Later, when compiling a calling function that calls the called function, the same (or another) compiler may reference the previously-identified dependencies and use them to determine whether and how to vectorize the calling function. In particular, these techniques may facilitate the vectorization of non-leaf loops. Because non-leaf loops are relatively common, the techniques described herein can increase the amount of vectorization that can be applied to many applications.

Description

WO 2012/039937 PCT/US2011/050713 TITLE: SYSTEMS AND METHODS FOR COMPILER-BASED VECTORIZATION OF NON-LEAF CODE BACKGROUND OF THE DISCLOSURE 5 Field of the Invention [00011 This disclosure relates to computer systems, and, more particularly, to systems and methods for enabling the universal vectorization of software applications. 10 Description of the Related Art 100021 The typical software development paradigm is well known, A computer programmer writes source code in a high-level programming language (e.g., Basic, C++, etc.). At some point, the programmer uses a compiler to transform the source code into object code. After being 15 transformed into executable code (e.g., after linking or other compile-time or run-time processing), the resulting object code can then be executed by a computer or computing device. 100031 Computers now have multiple processing units and are capable of executing instructions in parallel. To take advantage of this architecture, modem compilers may attempt to 20 "parallelize" or "vectorize" certain software functions so that, instead of having a single processing unit sequentially execute one instruction at a time, multiple processing units can execute instructions siniultaneously. [00041 During the compilation process, the compiler analyzes a software function to 25 determine if there are any obstacles to vectorization. One such obstacle, for example, is the presence of a true data dependency. This happens when a present instruction refers to the data obtained through the execution of a preceding instruction, In that case, the latter instruction can only be carried out after the former, and therefore the two instructions cannot be executed in parallel. Another potential obstacle is the presence of a function call, For instance, if a function 30 to be compiled makes a call to an external function, then the compiler may not be able to vectorize the calling function, 1 1001053592_2.docx SUMMARY [0005] The present disclosure provides systems and methods for enabling the universal vectorization of software applications. To that end, systems and methods disclosed herein provide the expression of dependencies and/or interfaces that extend a 5 compiler's ability to vectorize functions. [0005A] In a first aspect, there is provided a method including: performing, by one or more computers: identifying a calling function during a process of compiling source code including the calling function, the calling function including a call to a previously compiled called function; accessing a persistent dependency database to retrieve an 10 expressed dependency associated with the previously-compiled called function, wherein the expressed dependency is generated and persistently store into the persistent dependency database during compilation of the previously-compiled called function, wherein the expressed dependency is accessible across distinct compiler invocations, and wherein the expressed dependency indicates whether the previously-compiled called 15 function only reads a data item, only writes the data item, or both reads and writes the data item; and generating a determination of whether the calling function interacts with the previously-compiled called function based, at least in part, upon the expressed dependency and without accessing source code of the previously-compiled called function. 20 [0005B] In a second aspect, there is provided a computer-readable storage medium having program instructions stored therein that, in response to execution by a computer system, cause the computer system to perform operations that implement a method according to the first aspect. [0005C] In a third aspect, there is provided a system including: one or more memories 25 that, during operation, store instructions; and one or more processors that, during operation, retrieve instructions from the one or more memories and execute the instructions to cause the system to perform operations that implement a method according to the first aspect. [0006] In a non-limiting embodiment, a compiler may examine memory and/or data 30 dependencies within a function (a "called function") during its compilation, and express 2 1001053592_2.docx those dependencies in a dependency database, such as, e.g., a dependency file. Once compiled, the called function may become, for example, a library function or the like. At a later point in time, another function (a "calling function") may be created such that it makes a call to the called function. During compilation of the calling function, the 5 compiler may access the dependency file associated with the called function and may identify its dependencies. Based on the called function's dependencies, the compiler can make a decision as to whether to vectorize the calling function. [0007] Additionally or alternatively, the compiler may decide to vectorize only a portion of the calling function. The visibility provided by the use of dependency files 10 may allow the compiler to vectorize a higher percentage of functions than would otherwise be possible. [0008] For example, the implementation of dependency files allows the vectorization of functions that include non-leaf loops - i.e. , loops that make calls to external functions for which source code is not visible. Because the vast majority of software functions 15 today include one or more non-leaf loops, these systems and methods can increase the amount of vectorization that can be applied to any application. [0009] In another non-limiting embodiment, a compiler may generate both scalar and vector versions of a function from a single source code description. A scalar version of the function may use a scalar interface as originally specified by the source code. 20 Meanwhile, a vector version of the function may implement a vector interface to the function, accepting vector parameters and generating vector return values. [0010] For instance, the vector interface may be exposed in the dependency file associated with the function. The presence of this alternative vector interface allows the compiler to make vector function calls from within vectorized loops, for example, rather 25 than making multiple serialized scalar function calls from within a vectorized loop. [0011] Various combinations of the technologies disclosed herein also permit the vectorization of functions that do not contain loops, which is contrary to accepted wisdom and 2a WO 2012/039937 PCT/US2011/050713 yet provides numerous advantages., Particularly, these techniques may increase the amount of overall vectorization in software applications. BRIEF DESCRIPTION OF THE DRAWINGS 5 [00121 FIG. I is a block diagram illustrating a computer system operable to implement techniques for enabling universal vectorization of software applications according to certain embodiments. [00131 FIG. 2 is a block diagram illustrating a compiler that, when executed by a computer 10 system, may generate executable code according to certain embodiments. [00141 FIG. 3 shows a flow diagram illustrating a method of expressing a dependency in a dependency database according to certain embodiments. [00151 FIG. 4 shows a flow diagram illustrating a method of vectorizing a function according to certain embodiments. 15 [00161 FIG. 5 shows a flow diagram illustrating a full function vectorization method according to certain embodiments. [00171 FIG. 6 shows a flow diagram illustrating a method of using a vectorized function according to certain embodiments, 100181 While being susceptible to various modifications and alternative forms, specific 20 embodiments discussed in this specification are shown by way of example in the drawings and will herein be described in detail. It should be understood, however, that the drawings and detailed description are not intended to limit the disclosure to the particular forn disclosed, but on the contrary, the intention is to cover all modifications, equivalents and alternatives falling within the spirit and scope of the present disclosure as defined by the appended claims. 25 DETA] LED DESCRIPTION Introduction [00191 The following specification first discusses an illustrative computer system or device. The specification also describes an illustrative compiler that may be configured to execute and/or 30 generate executable code for the computer system. Then, the specification presents several techniques for enabling non-leaf loop and full function vectorization. An Illustrative Computer System 3 WO 2012/039937 PCT/US2011/050713 [00201 FIG. I depicts an illustrative computer system operable to implement techniques for enabling universal vectorization of software applications according to certain embodiments. In this non-limiting example, computer system 100 includes one or more processors 110a-11On coupled to memory 120 via I/O interface 130. Computer system 100 also includes network 5 interface 140 and storage interface 150 coupled to I/O interface 130. Storage interface 150 connects external storage device 155 to i/O interface 130. Further, network interface 140 may connect system 100 to a network (not shown) or to another computer system (not shown). [00211 In some embodiments, computer system 100 may be a single processor system including only one processor 110 a. In other embodiments, computer system 100 may include 10 two or more processors I iOa-i 10in. Processors 110a-1 IOn may include any processor capable of executing instructions. For example, processors 110a-1IOn may be general-purpose or embedded processors implementing any suitable instruction set architectures (ISAs), such as, for example, the x86, PowerPCTM, SIPARCT', or MIPSTM ISAs. In an embodiment, processors 110 a-I IOn may include various features of the Macroscalar processors described in U.S. Patent 15 No. 7,617,496 and U.S. Patent No. 7,395,419. [00221 System memory 120 may be configured to store instructions and data accessible by processors 110a-110n. For example, system memory 120 may be as static random access memory (SRAM), synchronous dynamic RAM (SDRAM), nonvolatile/Flash-type memory, or any other any suitable type of memory technology. A portion of the program instructions and/or 20 data implementing desired functions or applications described in detail below may be shown stored within system memory 120. Additionally or alternatively, a portion of those program instructions and/or data may be stored in storage device 155, in a cache memory within one or more processors 110 a-1On, or may arrive from a network via network interface 140. [00231 I/O interface 130 is operable to manage data traffic between processors 110 a- I1On, 25 system memory 120, and any device in or attached to the system, including network interface 140, storage interface 150 or other peripheral interfaces. For example, i/O interface 130 may convert data or control signals from one component into a format suitable for use by another component. In some embodiments, I/O interface 130 may include support for devices attached through various types of peripheral buses, such as the Peripheral Component Interconnect (PCI) 30 bus or the Universal Serial Bus (USB), for example. Also, in some embodiments some or all of the functionality of I/O interface 130 may be incorporated into processors I Ia- Iin. 4 WO 2012/039937 PCT/US2011/050713 [00241 Network interface 140 is configured to allow data to be exchanged between computer system 100 and other devices attached to a network, such as other computer systems, for example. For example, network interface 140 may support communication via wired or wireless general data networks, telecommunications/telephony networks, storage area networks such as 5 Fibre Channel SANs, and the like. 100251 Storage interface 150 is configured to allow computer system 100 to interface with a storage device such as storage device 155. Storage interface 150 may support standard storage interfaces such as one or more suitable versions of the Advanced Technology Attachment Packet Interface (ATAPI) standard (which may also be referred to as Integrated Drive Electronics 10 (IDE)), the Small Computer System Interface (SCSI) standard, the IEEE 1394 "Firewire" standard, the USB standard, or another standard or proprietary interface suitable for interconnecting a mass storage device with computer system 100. For example, storage device 155 may include magnetic, optical or solid state media that may be fixed or removable. Storage device 155 may also correspond to a hard disk drive or drive array, a CD or DVD drive, or a 15 nonvolatile memory (e.g., Fla sh)-based device, [00261 System memory 120 and storage device 155 represent illustrative embodiments of a computer-accessible or computer-readable storage medium configured to store program instructions and data. In other embodiments, program instructions and/or data may be received, sent or stored upon different types of computer-accessible media. In general, a computer 20 accessible medium or storage medium may include any type of mass storage media or memory media such as magnetic or optical media. A computer-accessible medium or storage medium may also include any volatile or non-volatile media such as RAM (e.g. SDRAM, DDR SDRAM, RDRAM, SRAM, etc.), ROM, or the like, whether included in computer system 100 as system memory 120 or another type of memory. Program instructions and data stored via a computer 25 accessible medium may be transmitted by transmission media or signals such as electrical, electromagnetic, or digital signals, which may be conveyed via a communication medium such as a network and/or a wireless link, such as may be implemented via network interface 140. [00271 Typically, computer system 100 may take the form of a desktop or laptop computer. As will be readily understood in light of this disclosure, however, computer system 100 may be 30 any suitable device capable of executing software. For example, computer system 100 may be a tablet computer, a phone, or the like.
WO 2012/039937 PCT/US2011/050713 An Illustrative Compiler 100281 Generally speaking, a compiler may correspond to a software application (e.g., one or more modules of computer-executable instructions) that is configured to translate or transform source code, which may be represented in a high-level programming language such as C, C++ or any other suitable programming language, into object code. The language in which the source code is expressed may be referred to as the source code language or simply the source language. Typically, object code may be represented in the fonn of instructions and data suitable for processing by a target computing architecture, although in some embodiments, additional processing (e.g., linking) may be performed on generated object code to transform object code 1 0 into machine-executable code. In various embodiments, such additional processing may be performed by a compiler or by separate applications. 100291 Object code may be represented in machine-readable form (e.g., binary form), in human-readable form (e.g., assembly language) that may require additional processing to generate machine-readable code, or in a combination of human- and machine-readable forms. 15 The target architecture for the object code may be the same as the ISA implemented by processors I 0a- 1i0n on which the compiler is configured to execute. However, in some instances, a compiler may be configured to generate object code for a different ISA than the ISA on which the compiler executes (a "cross-compiler"). 100301 FIG, 2 depicts an illustrative compiler that, when executed by computer system 100 or 20 another suitable computer system, may generate executable code according to certain embodiments. Compiler 200 includes front end 220 and back end 230, which may in turn include optimizer 240 and code generator 250. As shown, front end 220 receives source code 210 and back end 230 produces object code such as, for example, scalar object code 260, vectorized object code 270, or a combination thereof. Compiler 200 may also produce 25 dependency database 280 associated with one or more of object codes 260 and/or 270. 100311 While source code 210 is typically written in a high-level programming language, source code 210 may alternatively correspond to a machine-level language such as assembly language. For example, compiler 200 may be configured to apply its optimization techniques to assembly language code in addition to code written in higher-level programming languages. 30 Also, compiler 200 may include a number of different instances of front end 220, each configured to process source code 21 0 written in a different respective language and to produce a 6 WO 2012/039937 PCT/US2011/050713 similar intermediate representation for processing by back end 230. In such embodiments, compiler 200 may effectively function as a multi-language compiler. 100321 In an embodiment, front end 220 may be configured to perform preliminary processing of source code 210 to determine whether the source is lexically and/or syntactically correct, and to perform any transformation suitable to ready source code 210 for further processing by back end 230. For example, front end 220 may be configured to process any compiler directives present within source code 210, such as conditional compilation directives that may result in some portions of source code 210 being included in the compilation process while other portions are excluded. Front end 220 may also be variously configured to convert source code 210 into 10 tokens (e.g., according to whitespace and/or other delimiters defined by the source language), determine whether source code 210 includes any characters or tokens that are disallowed for the source language, and determine whether the resulting stream of tokens obeys the rules of syntax that define well-formed expressions in the source language. In different situations, front end 220 may be configured to perform different combinations of these processing activities, may omit 15 certain actions described above, or may include different actions, depending on the implementation of front end 220 and the source language to which front end 220 is targeted. For example, if a source language does not provide a syntax for defining compiler directives, front end 220 may omit a processing action that includes scanning source code 210 for compiler directives. 20 100331 If fi-ont end 220 encounters errors during processing of source code 210, it may abort processing and report the errors (e.g., by writing error information to a log file or to a display). Otherwise, upon sufficiently analyzing the syntactic and semantic content of source code 210, front end 220 may provide a intermediate representation of source code 210 to back end 230. Generally speaking, this intermediate representation may include one or more data structures that 25 represent the structure and semantic content of source code 210, such as syntax trees, graphs, symbol tables or other suitable data structures. The intermediate representation may be configured to preserve information identifying the syntactic and semantic features of source code 210, and may also include additional annotation information generated through the parsing and analysis of source code 210. For example, the intermediate representation may include control 30 flow graphs that explicitly identify the control relationships among different blocks or segments of source code 210. Such control flow information may be employed by back end 230 to determine, for example, how functional portions of source code 210 may be rearranged (e.g., by 7 WO 2012/039937 PCT/US2011/050713 optimizer 240) to improve performance while preserving necessary exec ution-ordering relationships within source code 210. 100341 Back end 230 may generally be configured to transform the intermediate representation into one or more of scalar code 260, vectorized code 270, or a combination of 5 both. Specifically, in the illustrated embodiment, optimizer 240 may be configured to transform the intermediate representation in an attempt to improve some aspect of the resulting scalar code 260 or vectorized code 270. For example, optimizer 240 may be configured to analyze the intermediate representation to identify memory or data dependencies. In some embodiments, optimizer 240 may be configured to perform a variety of other types of code optimization such as 10 vectorization, loop optimization (e.g., loop fusion, loop unrolling, etc.), data flow optimization (e.g., common subexpression elimination, constant folding, etc.), or any other suitable optimization techniques. Optimizer 240 may also be configured to generate dependency database 280. As described in greater detail below, dependency database 280 may express an indication of a memory and/or data dependency within source code 210. Additionally or 15 alternatively, in connection with the vectorization of source code 210, dependency database 280 may expose a vector interface associated with vectorized object code 270. 100351 Code generator 250 may be configured to process the intermediate representation, as transformed by optimizer 206, in order to produce scalar code 260, vectorized code 270, or a combination of both types of code. For example, code generator 250 may be configured to 20 generate vectorized machine instructions defined by the ISA of the target architecture such that execution of the generated instructions by a processor implementing the target architecture (e.g. one of processors 1 IOa-1 IOn, or a different processor) may implement the functional behavior specified by source code 210. In an embodiment, code generator 250 may also be configured to generate instructions corresponding to operations that may not have been inherent in source code 25 210, but which may have been added by optimizer 240 during the optimization process. [00361 In other embodiments, compiler 200 may be partitioned into more, fewer or different components than those shown. For example, compiler 200 may include a linker (not shown) configured to take one or more object files or libraries as input and combine them to produce a single-usually executable-file. Alternatively, the linker may be an entity separate from 30 compiler 200. As rioted above, any of the components of compiler 200, and any of the methods or techniques performed thereby including those described below with respect to FIGs. 3-6, may 8 WO 2012/039937 PCT/US2011/050713 be implemented partially or entirely as software code stored within a suitable computer accessible storage medium. 100371 Source code 210 may represent, for example, a software function or algorithm. The resulting object code 260 and/or 270 may be, for example, a library or external function that can 5 be called by other functions. Illustrative techniques employed by compiler 200 during operation, and in particular during its vectorization operation, are discussed in more detail below. Vectorization of Non-Leaf Loops [00381 Many modern computers have the capability of performing some type of parallel processing of a computational workload by concurrently executing two or more different 10 operations. For example, a superscalar processor may allow a computer to attempt to execute multiple independent instructions at once. Another technique generally referred to as "vector computing" (which may be considered to be a special case of parallel computing) allows a computer to attempt to execute a single instruction that operates on multiple data items at once. Various examples of vector computing can be found in the single instruction, multiple data 15 (SIMD) instruction sets now available in various processors, including, for example, IBM's AltiVecTM and SPETM instruction set extensions for PowerPCTM processors and Intel's -ariants of MMXTM and SSETM instruction set extensions. Such SIMD instructions are examples of vector instructions that may be targeted by a vectorizing compiler, although other types of vector instructions or operations (including variable-length vector operations, predicated vector 20 operations, vector operations that operate on combinations of vectors and scalars/immediates) are also possible and contemplated. 100391 Generally speaking, the process of transforming source code into vectorized object code may be referred to as "vectorization." When performed using a compiler (as opposed to, for example, vectorizing source code by hand), vectorization may be referred to as "compiler auto 25 vectorization. One particular type of auto-vectorization is loop auto-veetorization. Loop auto vectorization may convert procedural loops that iterate over multiple data items into code that is capable of concurrently processing multiple data items within separate processing units (e.g processors I I a-Il0n of computer system 100 in FIG. 1, or separate functional units within a processor). For example, to add together two arrays of numbers A/ and B/J, a procedural loop 30 may iterate through the arrays, adding a pair of array elements during each iteration. When compiling such a loop, a vectorizing compiler might take advantage of the fact that the target processor implements vector operations capable of concurrently processing a fixed or variable 9 WO 2012/039937 PCT/US2011/050713 number of vector elements, For example, the compiler might auto-vectorize the array-addition loop so that at each iteration, multiple elements of arrays Afl and B/J/ are concurrently added, reducing the number of iterations needed to complete the addition. A typical program spends a significant amount of its execution time within such loops. As such, auto-vectorization of loops 5 can generate performance improvements without programmer intervention. [00401 In some embodiments, compiler auto-vectorization is limited to leaf loops---- i.e., loops that do not make calls to other functions. Vectorization of non-leaf loops-i.e., those that make calls to other functions-is ordinarily very difficult because the side-effects of external functions calls are usually opaque, especially when their source-code is unavailable for inter-procedural 10 analysis, such as is the case with libraries, for example. For purposes of illustration, consider the following loop: for(x:=O; x<size; +-+x) 15 A[x]=x; foo (x) [00411 To vectorize this loop, compiler 200 may determine whether function fboo interacts 20 with (e.g., reads or writes) array A/j. Here, three possibilities exist: (1) function Jboo does not interact with Aji; (2) function fboo does interact with A[]; or (3) function foo might interact with A[] (e.g., depending on a compile-time or run-time condition,foo may or may not interact with .4/). The case where function foo might interact with A/] presents similar problems as the case where function fboo does in fact interact with A[ In the case where there is no 25 interaction between fooO and A[/, then the vectorizabie code below is equivalent to the loop above: for (x=O; x<size; ++x) A[x] = x; 30 for (x:=O; x<size; ++x) f oo (x) ; 100421 This example shows that, in the process of vectorizing the non-leaf loop, compiler 200 35 would benefit from knowing the memory that function accesses and/or whether that memory is read and/or written. Because the majority of loops typically contain function calls within them, 10 WO 2012/039937 PCT/US2011/050713 the vectorization of non-leaf loops and the functions called by them is preferred for high degrees of vectorization. To enable this level of vectorization, various embodiments of the techniques and systems described herein increase the compile-time visibility of dependencies and potential dependencies across libraries and modules that may have been previously compiled. For 5 example, this information may be available when the calling function is compiled, independently of when (or where) the library or module was originally compiled. Accordingly, certain techniques described herein establish an illustrative compiler infrastructure to create this visibility and explore the types of vectorization enabled by it. Dependency Databases 10 [00431 When compiling code that calls an external function, it may be desirable to determine the interface of the external function (e.g,, the number and/or types of parameters the external function takes, and/or the number and/or types of results it returns). For example, such interface information may be useful in determining whether the calling code has correctly implemented the external function. Externally callable functions may typically expose their interface definitions 15 in header files. However, such header files may not expose the details of variables that are not part of an external function's interface to a calling function, but which may nevertheless affect code vectorization. For example, in the loop illustrated above, vectorization of the for-loop may depend on how functionfboo interacts with array AfJ. However, becausefboo does not take A[/ as a parameter, the header file corresponding to boo may not adequately indicate this 20 dependency to compiler 200, 100441 A dependency database, which may also be referred to herein as a "persistent dependency database," may describe the dependencies of externally callable functions in a library. That is, a dependency database may expose to a calling function various dependencies of a called function that are not necessarily apparent from the called function's interface alone. 25 This database may be accessed when functions that call a library are compiled. Generally speaking, a dependency database may persistently store indications of the dependencies of callable code such that the dependencies are visible across compiler invocations. For example, in some embodiments, a dependency database may be implemented as a dependency file (analogous to a header file) that includes human-readable and/or machine-readable content indicative of 30 various dependencies. In other embodiments, a dependency database may be implemented using other techniques, such as by using a table-based relational database, semi-structured data (e.g., fonnatted using Extensible Markup Language (XMLF)), or any other suitable technique. For simplicity of exposition, the following discussion makes reference to an embodiment that
II
WO 2012/039937 PCT/US2011/050713 employs a dependency file. However, it should be noted that this is merely an non-liniting example of a dependency database. [0045] In an embodiment, compiler 200 automatically accesses a dependency file (if it exists) upon inclusion of a corresponding header file (e.g., stdib.h). This mechanism may allow 5 vectorizing compilers such as, for example, Macroscalar compilers to compile existing code without modification while having the advantage of knowing the dependencies of external libraries. Compiler 200 may then generate dependency files automatically when libraries are compiled. [00461 Infonnation contained in a dependency file may form an Application Compiler 10 Interface (ACI) that provides information which compiler 200 can use to understand the constraints of a function. Specifically, dependency files may express information about variables that are not normally within the scope of a calling function. For example, the variables expressed in a dependency file may include data items that are not parameters of the called function (that is, such variables may not be defined by a called function's programming interface as parameters of 15 the called function). Through the use of dependency files, a calling function may become aware of whether a called function reads or writes function-static or file-static variables, for example. Dependency files may also allow compiler 200 to differentiate between variables that share the same name but have different scopes. [00471 As a non-limiting example, when a library std/ib is compiled, a compiler would 20 ordinarily only generate object file stdib.o. Using the techniques described herein, compiler 200 may also generate dependency file std/ib.dJ, for example, at compile-time. Dependency file stdlib.d exposes memory dependencies associated with public functions defined in stdibi.h. Other programs that include stclib.h from their source code may trigger compiler 200 to search for the associated dependency file stdlib.d in corresponding locations. This dependency file may 25 be distributed and installed along with stdlit.h and std/ib.o. In one implementation, the absence of a dependency file would mean that no additional information about the library is available, which might be the default state for legacy libraries and would not cause any compile errors. [00481 Dependency databases may enable vectorization of non-leaf loops by exposing the data dependency characteristics of a previously-compiled library function (or any function in a 30 program) in a manner that is visible to compiler 200 when the code that calls the library function is compiled. This information may be made available without revealing the source-code for the library. 100491 In some embodiments, the dependency information may be generated at compile-time of the library. For example, for each function that is compiled, compiler 200 may note the types 35 of accesses to function static variables, file static variables, global variables, and/or pointers WO 2012/039937 PCT/US2011/050713 passed in to the function being compiled. Compiler 200 may then record which symbols were read or written, and export this information in the form of a dependency file that can be accessed and used at the compile-time of other code that references the library. 100501 As another non-limiting example, if the function fooQ is defined in file foo.c and its 5 interface is defined in the header file foo.h, then at the compile time of fbo.c, the memory dependency characteristics of function fbo() may be stored into dependency file foo.hd. (It is noted that any suitable naming convention for dependency files may be employed.) A calling function that uses function foo( may include header file /bo.h, but may have no access to file foo.c. At the time thatfboh is referenced during compilation of the calling function, compiler 10 200 may automatically search for the dependency file /oo.hd to see whether it exists, Because the existence of dependency file foo.hd is optional, the absence of this file may imply that the dependency characteristics of functions defined in file foo.h are unknown, thus suggesting compiler 200 should make pessimistic assumptions when vectorizing the calling function. If the dependency file exists, however, compiler 200 can use the dependency information in this file to 15 make more accurate and aggressive assumptions using the dependency characteristics contained therein during vectorization of the calling function, [00511 Referring to FIG. 3, a flowchart representing a method of expressing a dependency in a dependency file is depicted according to certain embodiments. In block 300, com piler 200 receives a function to be compiled. For example, compiler 200 may receive the function when 20 processing source code for compilation, such as during compilation of a library that includes the function. In block 310, compiler 200 analyzes the function and identifies an expressed dependency within the function. This expressed dependency may be, for example, a memory or data dependency associated with a data item that is not a parameter of the called function. More generally, an expressed dependency of a function with respect to a particular data item may 25 indicate whether the function only reads the particular data item, only writes the particular data item, or both reads and writes the particular data item. In various embodiments, analysis of the function may include activities such as performing a lexical, syntactic, and/or sernanic analysis of the function, Analysis may also include generating a parse tree, symbol table, intermediate code representation, and/or any other suitable data structure or representation that is indicative of 30 some aspect of the operations and/or data references of the code being compiled. 100521 In block 320, compiler 200 stores an indication of the expressed dependency in a dependency database associated with the function. For example, during analysis of the function, compiler 200 may identify variables used by the function that are not necessarily local or private to that function, and thus are capable of being read or written by code that is external to the 35 function. Such variables may be examples of expressed dependencies that compiler 200 might 13 WO 2012/039937 PCT/US2011/050713 identify, and compiler 200 may store indications of these variables within a dependency database. (It is noted that in some embodiments, compiler 200 may also identify and indicate dependencies that are local or private to the function.) In various embodiments, the indication of an expressed dependency may include information that identifies the expressed dependency, such 5 as a name of the variable depended upon. The indication may also include information that characterizes the expressed dependency, such as information regarding whether the function reads or writes the variable, and/or information regarding the data type or scope of the variable (e.g., whether the variable is global, private, static, etc.). As will be readily apparent in light of this disclosure, the dependency file may be created or tipdated in any suitable format such as, for 10 example, Extensible Markup Language (XML), or the like. Moreover, in some embodiments, dependencies may be indicated in a negative fashion instead of or in addition to an affirmative fashion. For example, a dependency file may explicitly indicate that a given variable is not dependent on external code, in addition to or instead of indicating those expressed dependencies that do exist. 15 [00531 For instance, consider the example below, whereftnc].c is to be compiled: / --- File funcl.c int. A[100C] ; // Global array A int F[1000] ; // Global array F 20 #include <fool.h> int func l(int b) f int x, C; C = 0; 25 for (x:=0; x<100; ++x) c = c + fool(x) + A[x+b] F[x] = c } 30 return (c) [00541 In this case,fa-nc1.c makes a call to external functionf/bol.c, shown below: 14 WO 2012/039937 PCT/US2011/050713 // --- File fool.c int fool (int d) f static int e = 0; 5 e = e + d; return (e) } [00551 The source code for called ftmnctionfbol.c is reproduced for illustration purposes only, 10 It is understood that, so long as a dependency database (in this example, a dependency file) exists forfio]oc, its source code need not be available during compilation of calling function fancl.c. In this example, the expressed dependency information stored in the dependency file fool.hd, which may have been generated at the time when file fool.c is compiled, may express the fact that the function static variable "e" is both read and written. As such, one non-limiting example 15 of a corresponding dependency file is shown below: --- File fool.hd function fool (void) 20 read e; write e; 1 [00561 At the compile time of filejfunc1.c, the inclusion of header file fbol.h may cause the 25 dependency file fbol.hd to be read by compiler 200. This information informs the compiler of the expressed dependencies of called function fboI: i.e., that static variable "e" is read and written. This also allows compiler 200 to detect that even though they are used in calling functionfanc]Q, global variables "A" and "F" are not referenced by called functionfboio. This knowledge allows compiler 200 to vectorize the loop in function funciQ, because it can 30 determine that parallelism will not cause incorrect operation. In this case, the loop in func1i would callf6oo10 once for each element in the vector being processed. 100571 If function fiolO wrote to global "A," then compiler 200 might not vectorize the loop in funcI(, or it might use the information to vectorize only a portion of the function. In this instance, the compiler may, for example, serialize the call to ftmnction fool and the memory 35 reference to "A.," while allowing the rest of the loop to execute in a parallel manner. 15 WO 2012/039937 PCT/US2011/050713 [00581 Referring to FIG. 4, a flowchart representing an embodiment of a method of vectorizing a function is depicted. In block 400, compiler 200 identifies a calling function. In a non-limiting embodiment, the calling function may include a non-leaf loop, in which case the calling function may include a call to an external or called function. Referring to the code 5 example just given, compiler 200 may process the finc .c source code and identify the fitncl0 function as a calling function that includes a non-leaf for loop that calls thefboolQ function, [00591 In block 410, compiler 200 may attempt to access a dependency database associated with the called function. In some instances, a dependency database (e.g., a dependency file) may be explicitly indicated to compiler 200, for example via a command-line parameter, a compiler 10 directive embedded within source code, or via another suitable technique. In other instances, compiler 200 may attempt to infer the name of a dependency file from other data according to a naming convention. For example, if a header file is included within source code, compiler 200 may search for a dependency file that is derived from the name of the header file, In some embodiments, compiler 200 may search for dependency files based on the name of the called 15 function. 100601 If the dependency database exists, it may indicate an expressed dependency within the called function. This expressed dependency may be, for example, a memory or data dependency associated with an data item that is not a parameter of the called function, as discussed above. In some instances, compiler 200 may check a number of different naming conventions to determine 20 whether or not a dependency file exists. [00611 In block 420, compiler 200 then determines whether the calling function interacts with the called function based, at least in part, on the expressed dependency (or the absence of a dependency). For example, upon accessing the dependency file associated with functionfbolQ, compiler 200 may determine that fool() depends on variable "e" but not variables "A" or "F." 25 Thus, compiler 200 may determine that calling functionfanc 1 does interact with called function foolQ, at least with respect to variable "e." [00621 In block 430, dependent upon the determination of whether the calling function interacts with the called function, compiler 200 may determine whether to vectorize at least a portion of the calling function, For example, based on the expressed dependency information 30 discussed above, compiler 200 may attempt to vectorize calling functionfanc]0, by generating vector code that concurrently operates on multiple data items (e.g., array elements) and/or multiple loop iterations. 100631 In various embodiments, a dependency database may express various types of information that may be useful to compiler 200 in determining whether to vectorize a function. 35 Examples include tracking reads and writes to data objects, pointers, pointed-to data objects, 16 WO 2012/039937 PCT/US2011/050713 known offsets within pointed-to objects, unknown offsets into pointed-to objects (which may effectively constitute a reference to the entire object), variable offsets within objects (both pointed-to and data objects, which may enable run-time dependency analysis using the variable in question), and known offsets into objects of unknown offset into a higher-level object (e.g, 5 when an unknown number of known offsets are referenced, but other offsets remain unreferenced). [00641 Known offset information may enable compiler 200 to vectorize without generating additional dependency-checking instructions, while variable offset information may be used to generate dependency-checking instructions that analyze the variable dependencies at run-tine, 10 which may allow increased vector parallelism to be achieved while still maintaining program correctness. 100651 As explained above, a dependency database may express information about a called function that is useful to compiler 200 when vectorizing a calling function. In that regard, a dependency database may store information such as the type of memory access, the addressing 15 mode, and/or additional qualifiers. 100661 In some embodiments, memory accesses by a function generally fall into two types: reads and writes. Thus, as shown in the examples given above, a dependency database may explicitly store indications of whether a data item is read or written. 100671 Addressing modes describe memory accesses within a called function as viewed by the 20 calling function. Some embodiments may define three addressing modes: constant, variable, and unknown, though alternative embodiments are possible and contemplated. Each of these three addressing modes may be determined by whether addressing can be established by the compiler at compile time, by the calling function at run time, or by the called function at run time, respectively. In addition, some embodiments may define two orthogonal qualifiers to the 25 addressing modes: public and private. These designate whether the associated variable is visible to external modules. [00681 According to some embodiments, constant addressing describes addressing that can be resolved from outside the module at compile time. This includes references to named variables, named structure elements within a named structure, or array indexes that can be resolved at 30 compile time. For example, g (a named variable), str.g (a named structure element within a named structure), h[5] (an array indexed by a constant), and str/5I.i (a named structure element within a named array of structures indexed by a constant) represent examples of constant addressing. These examples can represent either static or global variables. (Automatic storage is usually temporal-for example, allocated upon entry to a module and deallocated upon the 17 WO 2012/039937 PCT/US2011/050713 module's exit -and thus not generally visible outside of the module.) The example below illustrates dependencies for a function that uses constant addressing: function foo(void) 5 { write public h5] read public g; } ; 10 [00691 In some embodiments, variable addressing describes addressing that is not constant but also not modified by the called function. Therefore, it may be evaluated by the calling function at run time, Examples include references to pointed-to objects and to arrays where the addressing may be observed by the calling function. Consider the function below: 15 static int A [1000] ; // file-static variable, not exported void assignA (int g, int x) { A[g] = A [x]; 20 100701 This function would export the following dependencies to the dependency file, declaring that the function writes Afg/ and reads Afx7-both variably-addressed arrays: void assignA(g,x) 25 { write private A [g]; read private A [x] 30 [00711 In this example, dependency checking (which may also be referred to as hazard checking) may be unnecessary if the function assignA) is called only once per iteration of the calling loop. The called function assignA( may determine whether g and x overlap and may partition the vector accordingly, for example, using Macroscalar techniques. 35 100721 Consider the situation where an external loop invokes assign ( twice per iteration: 18 WO 2012/039937 PCT/US2011/050713 for (x::: ... { assignA (gl,x) ; azssigLA (g2,y) ; 5 } 100731 Although hazards may exist between gi versus x, or g2 versus v, these dependencies are pertinent to a single invocation of the function. In this particular instance, the calling loop may check for potential hazards only between g] versus Y, and g 2 versus .V, which it can 10 recognize from the information in the dependency file. 100741 In some embodiments, unknown addressing is similar to variable addressing as described above, but typically applies to situations where the rin-time addressing cannot be evaluated by the calling function. This may happen, for example, in situations where the called function modifies the values of address variables in a manner that is not visible to the calling 1 5 function using information from the dependency file. [00751 Additional qualifiers "public" and "private" may designate whether a linker exports a symbol to allow the variable to be inspected by calling functions. For example, the references to A[] in the next to last example given above are designated "private,"' because AJ] is declared as a file-static variable not exported to functions that call assignAO. In this example, compiler 200 20 can determine from the dependency information how the assignAb function addresses Af], but may not be able to generate code that actually reads values of Afr. Ftll-Function Vectorization 100761 As described in detail above, compiler auto-vectorization may be employed to generate vectorized code from nonvectorized source code in a manner that may be transparent to 25 progrannners or other users. Such compiler auto-vectorization may enable source code to take advantage of performance improvements offered by vector computing hardware with little or no programmer intervention, [00771 However, if non-leaf functions (i.e., functions that call other functions) are to be effectively vectorized, it may be desirable to provide versions of called functions that expose a 30 vector interface to the calling function, rather than the scalar interface that might be represented in the original source code. [00781 Moreover, an application developer might wish to target an application to a variety of computing platforms, not all of which may offer vector resources. For example, a mobile version of a processor family might omit vector operations to reduce die size and power consumption, 19 WO 2012/039937 PCT/US2011/050713 whereas a desktop version of the same processor family might be developed to emphasize processing power over power consumption. In this scenario, in order to execute on the mobile processor, an application might need to be compiled using only scalar functions, whereas the application might use either scalar or vector functions when executing on the desktop processor. 5 However, as with the auto-vectorization described above, it may be desirable to allow the application to efficiently execute on vector and non-vector platforms while reducing or eliminating programmer intervention. [00791 Correspondingly, when vectorizing a function, a compiler according to some embodiments described herein may generate both scalar and vector versions of the function from 10 a single source code description. The function may be, for example, a library function, though more generally, it may correspond to any callable procedure or method. In some embodiments, the scalar version of the function may use a scalar interface as originally specified by the source code. Meanwhile, the vector version of the function may implement a vector interface to the function, accepting vector parameters and/or generating vector return values. By generating both 15 scalar and vector versions of the function, the compiler may enable code to be more flexibly tailored to the available resources, either at compile or run time. Moreover, by generating a vectorized version of a called function and exposing the resulting vector interface to calling functions, the compiler may facilitate the vectorization of calling functions, thus propagating opportunities for vectorization hierarchically upwards from leaf functions. 20 [00801 The vector interface may be expressed, for example, in a dependency database associated with the function, such as a dependency file. For example, consider the following function shell, in which internal details of the function have been omitted: int foo (int A) 25 { int B; // function code return(B); } 30 100811 A scalar interface for this function may be represented (e.g., within a dependency file) as: 20 WO 2012/039937 PCT/US2011/050713 int foo (int A) This representation reflects that according to this version, foo takes a scalar parameter and returns a scalar result. [00821 The same function, when vectorized to perform operations on multiple data items at a time, for example, may become: 10 Vector foo (Vector A) Vector B; // function code return(B); 15 100831 As such, a vector interface for this function may be represented (e.g., within a dependency file) as: Vector foo(Vector A) 20 Unlike the prior representation, this representation indicates that this version of fooQ takes a vector parameter and returns a vector result, [00841 Referring to FIG. 5, a flowchart representing an embodiment of a full-function vectorization method is depicted. In block 500, compiler 200 receives a function to be compiled. 25 in block 510, compiler 200 may compile a scalar version of the function. In block 520, compiler 200 may compile a vector version of the function. And in block 530, compiler 200 may express a vector interface associated with the vector version of the function in a dependency database, 100851 The presence of this alternate vector interface allows compiler 200 to make vector function calls from within vectorized loops, rather than making multiple serialized scalar 30 function-calls from within a vectorized loop. For example, consider the following loop within a calling function that makes a call to external functionfooQ: 21 WO 2012/039937 PCT/US2011/050713 for(x:::O; x<512; ++x) C Ex] =D [x] foo (C); 5 } [00861 Iffooo had only a scalar interface, the opportunities for vectorizing this loop might be limited, e.g., to vectorization of the assignment. However, the presence of a vector version of foo() may increase opportunities for loop vectorization. For example, a vectorized version of the 10 above loop might callfooO using vector parameters and might receive vector results, enabling more concurrent execution and reducing serialization within the loop. Furthermore, unlike previous approaches, this technology permits the vectorization of functions that do not contain loops. This may increase the amount of overall vectorization in applications. 100871 Loops in both versions of a function may be vectorized. Generally speaking, 15 "horizontal" vectorization may refer to a type of vectorization in which iterations of a loop are mapped to corresponding elements of a vector. "Vertical" vectorization may refer to a type of vectorization in which the iterative nature of a loop may be preserved (i.e., as opposed to being mapped to vector elements as in horizontal vectorization), but in which scalar variables are replaced with vector variables, such that each iteration concurrently operates on more data than 20 the scalar version of the code. [0088] Loops in the scalar version of the function can be vectorized horizontally using Macroscalar techniques, while loops in the vector version of the function can be vectorized either horizontally or vertically. This may increase the opportunities for vectorization in applications. In addition to the performance and efficiency benefits of vectorizing function calls, this 25 technology may increase the number of loops that are vertically vectorized in an application, thus reducing the overhead caused. when loops are horizontally vectorized. [00891 Referring to FIG. 6, a flowchart representing an embodiment of a method of using a vectorized function is depicted. In block 600, compiler 200 identifies a calling function that makes a call to called function. For example, the calling function may include a loop that makes 30 the call to a function within a pre-compiled library. In block 610, compiler 200 accesses a dependency database associated with the called function. In block 620, compiler 200 checks the dependency database to determine whether a vector variant of the called function is available. In one implementation, when the vector version is available, compiler 200 compiles the calling function to utilize the vector variant of the called function in bock 630. If the vector version is 2)2 WO 2012/039937 PCT/US2011/050713 not available, compiler 200 compiles the calling function to utilize the scalar version (e.g., by iteratively calling the scalar version of the function). [00901 For example, consider again the following loop: 5 for(x=O; x<512; ++x) C [x] =D [x] foo (C); 10 100911 When this loop is vectorized, the compiler may check a dependency database associated with foo( to determine whether a vector interface associated with fioO exists. If fboo's vector interface does not exist, then compiler 200 may only partially vectorize the loop, for example by vectorizing the assignment while leaving the function call in a scalar format. 15 100921 If, on the other hand, fboo has a vectorized interface expressed in its dependency database, then in some instances, compiler 200 may vectorize the loop in its entirety (e.g., by replacing or otherwise transforming both the assignment and the function call into vector operations). [00931 When the compiler checks /boo's dependency database to determine whether a 20 vectorized interface exists for the called function, the compiler may additionally or alternatively examine any memory dependencies associated with the called function that may be expressed the same (or another) dependency database associated with/foo0. [00941 In some implementations, addressing for each dimension of an array may be tracked independently to minimize uncertainty. This concept may apply to all aggregate data types in 25 general, such as strictures and arrays. The following example illustrates in greater detail how a compiler, such as compiler 200, for example, may use dependency database information to enable vectorization, and may employ vector versions of functions in place of scalar versions when possible (it being noted that in other embodiments, a dependency database may be used independently of determining whether vector function interfaces exist, and vice versa). 30 23 WO 2012/039937 PCT/US2011/050713 typedef strict f int a; int b; 5 int c; int *ptr; } myStruct; myStruct g; 10 int bar (myStruct &p, int j p.ptr[p.b+j] 0; return(p.b > 15 void foo(int i) { for (int x:::i; x<i+200; ++x) if (bar (g, x)); 20 ++g.,a; [00951 In this example, function baro would export dependencies (e.g,, via a dependency file generated by compiler 200 when function baro is compiled, as discussed above) indicating that 25 it writes to p.ptr/j, and reads frompb and j: 24 WO 2012/039937 PCT/US2011/050713 typedef strict f int a; int b; 5 int c; int *ptr; } myStruct; int bar (ryStruct *p, int j) 10 { read p. b; read D.ptr; write p.ptr[p.b+j]; 15 100961 It should be noted that, in this particular case, it may be unnecessary to identify references to parameters as "public" or "private." Also, it may be unnecessary to declare that the function reads from p orj, since at least in this example it can be assumed that a function uses its own parameters. The type definition of myStruct can be included in the dependency database to 20 expose it to functions that call fioo, but may not necessarily be exposed to the definition of nyStruct through header file inclusion. [00971 During compilation, compiler 200 may compile function baro without vectorizing it because there is no loop over which to vectorize. In doing so, it may produce a scalar version of baro having the following interface: 25 int bar (myStruct *p, tin j) [00981 In this example, baro may take a single instance of a pointer to a structure and a single integer as parameters, and return a single integer as a result. Thus, this version of baro is scalar 30 in its inputs and outputs. [00991 However, compiler 200 may also compile a vector function, with the following interface that can also be exported in the dependency database: 25 WO 2012/039937 PCT/US2011/050713 Vector bar(Vector p, Vector j, Vector pred) [00100] In this example, the predicate vector pred designates which vector elements should be 5 processed by this function. For example, assuming that vectors include a defined number of elements, a predicate vector may contain a vector having the same defined number of bits, each bit corresponding to a respective element. Each bit may serve as a Boolean predicate that determines whether its corresponding vector element should be processed (e.g., "yes" if the predicate bit is "1" and "no" if it is "0," or vice versa). Predicates allow the calling function to 10 make conditional function calls and takes care of the tail of the loop if it does not terminate on a vector-length boundary. It is noted that other embodiments may employ different types of predicate formats, such as non-Boolean predicates. [00101] Also, in this example, vector p is a vector of pointers to structures, although in this example they all point to the same instance. Vector j is a vector of simple integers. The 15 compiler can infer this type information from the scalar function declaration. [001021 One possible vector variant of function barO calculates p.b+j for each element of the input vectors, and writes these results into the appropriate array indexes ofp.ptr. It also returns a vector of results based on the comparison of p.b andj. In this particular example, the compiler vertically vectorized the function. That is, because baro contains no loop, there are no loop 20 iterations to be transformed into vector elements, as would be the case in horizontal vectorization. Instead, the vectorized version of baro may concurrently operate on different elements of the vector inputs. 1001031 During the compilation offoocompiler 200 may read the dependency information about the function baro, which may not necessarily be located in the same source file, and 25 determine that called function bar() has no dependencies on g.a, even though the calling function is passing a pointer to the structure g. Because it has this information, compiler 200 can horizontally vectorize the loop in functionfboo. Furthermore, compiler 200 can make a single function call to the vector variant of baro for each vector processed, rather than calling the scalar variant in every iteration of the loop. Finally, compiler 200 may create a vector variant offio 30 with a vector interface. In this particular case vertical vectorization may not be applied since the full extent of x cannot be analyzed for dependencies. Horizontal vectorization of the loop may be applied, and it is contained within another loop that iterates over the vector elements that were passed to the vector variant of finctionfboo. 35 [001041 Under these assumptions, functionfboo might export the following dependencies: 26 WO 2012/039937 PCT/US2011/050713 void foo(int j) readwrite public g.a; read public g.b; read public g.ptr; write public g .ptr [@]; 10 [001051 (The @ symbol represents unknown addressing.) Because function baro exported the dependency "write p.ptr/n.b+jf," compiler 200 could tell that structure member ptrf/ is written to as a function of x, Thus, compiler 200 may report to callers off/oo( that the index that is written to is unknown, since it cannot be determined by callers offboo. 15 Additional Implementation Techniques [001061 This section describes additional non-limiting compiler techniques that may be used to implement non-leaf and full-function vectorization. The description below is based on Macroscalar compiler technology, but a person of ordinary skill in the art will recognize in light of this disclosure that other compiler technologies may be used. 20 1001071 The previous example illustrated that addressing can include mathematical expressions. This is generally true as long as the expression does not involve a function call, and contains only terms that are visible to the calling function. This can include indirect addressing, such as when look-up tables are used in the calculation of indexes into other arrays. [001081 Indirect addressing is one situation where configuring the compiler and linker to 25 export static arrays as public can help vectorize more loops. Consider the following example: 27 WO 2012/039937 PCT/US2011/050713 int foo(int i) { static int A[1001 = {..; return (B [A [i ]) 5 } void bar (void) { for (x=0; x<100; ++x) 10 { t = B[.x]; B[t]= foo(x) } } 15 1001091 The dependencies generated forfboo may differ depending on whether the compiler and linker are configured to export static symbols publicly. In the examples that follow, the first dependency file expresses private static variables and the second dependency file expresses public static variables: 20 int foo (int i) { read Private Aui]; read public B [@] 25 int foo(int i) { static int A:[100]; 30 read public A[i]; read public B [A [x]] [001101 Note that the type declaration of A may be necessary in the depende-ncy file when it is 35 exported publicly. When static variables are private, the addressing of B{/ is unknown, since it cannot be determined from outside the function. Since hazard checking is not possible the vectorization of the loop in baro may not be performed. When the tools are configured to export 28 WO 2012/039937 PCT/US2011/050713 static variables publicly, however, the compiler can emit instructions that read the contents of A/x], and check for hazards between B/[x] and B/tj, thus enabling vectorization of the loop. 100111] Naturally, when static variables are publicly exported and addressed externally, the opportunity for name conflicts arise. To help avoid such conflicts, static variables can be name 5 mangled with the function and file in which they are declared. 1001121 Some hazards involve memory operations that occur conditionally, or involve addressing that may differ based upon conditional calculations. To support the vectorization of loops that call functions involving conditional dependencies, a mechanism may be provided to express how the condition affects the dependencies. 10 [001131 For example, consider the following code: if (A[x] < c) d = B[x]; [001141 This code may be expressed in a dependency database as: 15 read public A[x]; read public c; A [xl < c ? read public B [x; A[x] < c ? writ-e public d; 20 1001151 Conditional expressions may also exist in the calculation of the address. For example, consider the following code: if (A [x"] < c) 25 d = B[x] else e =: B[x+C]; [001161 This code may be expressed in a dependency database as: 30 29 WO 2012/039937 PCT/US2011/050713 read public A[x]; read public c; A[x] < c ? write public d : write public e; A [x] < c ? read public B [xl : read public B [x+c]; 5 [001171 Alternatively, the latter conditional expression above may be expressed as: read public B[ A[x] < c ? x : x+c 10 [001181 In some cases, unknowns may creep into the dependency expression. In this case, one illustrative example may be: A [x] < c ? read public B [x] : read public B[@]; 15 1001191 This expression may inform the compiler about a specific dependency on B if the condition is true and an unknown dependency on B when the condition is false. [001201 Unknowns that creep into the conditional expression may cause unconditional 20 dependencies that behave as if the condition is both true and false. For example: A[x] < B[@] ? read public f : read public g; [001211 May be expressed as: 25 read public f; read public g; [001221 And: 30 read public A[ x > @ ? x : x+y]; 1001231 May be expressed as: 35 30 WO 2012/039937 PCT/US2011/050713 read public A[x]; read public A[x+y]; 1001241 Because calling functions are typically able to evaluate unknown conditions, they may make the conservative assumption that both possible indexes into AfI are accessed. [001251 In some implementations, circular dependencies may also be expressed in a dependency database. For example, consider the function below: 10 if (A[x] > b) b = A[x] [001261 In one implementation, this function may be expressed as: read public A[x]; 15 read public b; A[x] > b ? writ-e public b; 1001271 Where pointers or references are passed to a function (also referred to as "passing by reference"), it is possible for the function to modify its calling parameters. This differs from 20 modifications of parameters passed by value, for example, because modifications of parameters passed by reference may affect the operation of the calling function. Modifications of parameters passed by reference may be recorded in the same manner that modifications of static and global storage are recorded, Modifications of parameters passed by value may be treated as modifications of local automatic storage. In some instances, they may not be recorded because 25 they are invisible to the calling function. [001281 In some implementations, functions that meet a set of criteria may be called speculatively in cases where software speculation would be necessary to vectorize the calling loop. Accordingly, speculation-safe indicators may be expressed in the dependency file and may serve as indications that the corresponding code may be safely called in a speculative manner. In 30 one non-limiting example, vector functions that are capable of being called speculatively may fall into one of two categories: type-A and type-B. Type-A functions may be vector-functions having the normal vector interface described herein. For instance, type-A functions may be called speculatively with no harmful side effects if they meet the following criteria. First, the function accesses no memory other than local automatic non-array storage. Second, the function 31 WO 2012/039937 PCT/US2011/050713 does not call any other functions that are not also type-A functions. Examples of type-A functions might be transcendentals or other iterative convergence algorithms. 1001291 In addition to any return values specified by the source code, type-B functions may return a predicate vector that indicates which elements were processed. In an embodiment, the 5 criteria for speculatively calling type-B functions may be as follows. First, any reads from non local storage or local array storage use first-faulting read instructions. Second, the function does not write to non-local storage or static local storage. Third, the function does not call any functions that are not also type-A or type-B functions. [001301 Calling a type-A function from a loop may be similar to calling a non-speculative 10 function, Typically, no special action is necessary on the part of the calling loop when speculatively calling a type-A function. Calling a type-B function, however, may require the calling loop to check the return vector in order to determine which elements were processed, and adjust the behavior of the calling loop in response. 1001311 A compiler such as compiler 200 may choose to have all callers of type-B vector 15 functions adjust their behavior to accommodate the number of elements that were actually processed, regardless of whether software speculation is used in the calling loop. Alternatively, compiler 200 may create two vector-functions for each type-B function; one speculative and one non-speculative, The criterion for type-B loops can be generally designed to ensure that those loops that qualify are few and small, and thus the code-size impact for this approach may be 20 negligible. [001321 Type-A and type-B vector functions may be identified by their declaration in the dependency database, as shown below. In one implementation, the absence of a designator implies the function may not be called speculatively. 25 int func (int a) A read public b; // local-static write public c; // local-static 30 int func2 (int a) B read public d; // non-local }; 35 32 WO 2012/039937 PCT/US2011/050713 [001331 Aliasing can sometimes be a problem for vectorizing compilers. While Macroscalar architecture addresses the problem through run-time alias analysis, there is an overhead to this approach. Overhead in Macroscalar programs contributes to the serial component in Amdahl's law, which can limit the benefits of wider vectors. Moreover, aliasing with external or static 5 variables can affect behavior across function calls. Therefore, in one implementation, compile time alias analysis is performed and an aliasing indicator is exported to a dependency file. [001341 For instance, one approach may be to separate aliasing events into two categories such as, for example, inbound and outbound aliasing. From the perspective of the called function, inbound aliasing may refer to addresses that come into a function, such as those passed-in as 10 parameters, read from external variables, or calculated by the function by taking the address of an external variable, Meanwhile, outbound aliasing may refer to pointers that the function puts out. These can be return values-i.e., values that the function writes into external variables or de referenced pointers. 1001351 Further, at least two types of aliasing can be tracked. "Copies aliasing" may indicate 15 that the pointer mayv be a copy of another pointer and might alias anything the pointer can alias, "Points aliasing" may indicate that a pointer is likely to affect another variable. Alias information in the dependency file is an affirmative expression of the possible existence of an alias. It need not be used, for example, when the compiler simply cannot tell whether two pointers reference the same memory due to lack of information. 20 [001361 The declaration of aliasing for variables may be similar to the declaration of aliasing for return values, For example, consider the function below: static int s; static void *ptr, *ptr2; 25 static void *A[1000]; void foo (int x, int y) A[x] = (void*) s; A [y] (void*) &s; 30 ptri = &A[s] ptr2 = As]; 100137] In one implementation, this function may express the following dependencies: 35 33) WO 2012/039937 PCT/US2011/050713 void foo(int x, int y) read public s; write public Aix] copies s; 5 write public A Ey] points s; write public ptrl points A Es] ; read public A[s]; write public ptr2 copies AFs]; 10 1001381 The foregoing distinguishes between points and copies for clarity, although it may be possible to combine these two concepts in an alternate syntax. As with other dependency information, aliasing information typically propagates upward through the chain of calling functions, 15 [001391 The values returned by a function may also result in aliasing, for example, through the return value itself, or through information returned by modifying passed-by-reference variables. These can also be tracked in the dependency file, For example, consider the function below: static float gVar; 20 mt *foo(float *ptrl, float **ptr2) *-ptr2 = &gVar; return ((int*) pt r1) 25 [001401 In one implementation, this function may export the following dependencies: int *foo(float *ptri, float **ptr2) 30 write *ptr2 points gVar; return copies ptri; }; 1001411 The dependency declaration may inform the calling loop that the pointer returned by 35 foo0 might be a copy of the pointer that was passed in. This allows the calling loop to take measures to ensure correct operation of the loop regardless of the aliasing that occurs. 34 WO 2012/039937 PCT/US2011/050713 Furthermore, this knowledge can also enable the compiler to better leverage ANSI aliasing rules when faced with code that is no ANSI-C compliant. 1001421 As another consideration, the casting of pointers may affect address calculations. For 5 example, consider the function below: void ZeroInt(char *ptr, int x) 10 *((int*)ptr + x) = 0; return; 1001431 In one implementation, this function may export the following dependencies: 15 void ZeroInt(char *ptr, int x) write *((int*)ptr+x); } 20 1001441 Calls via function pointers may not ordinarily be vectorized due to the fact that it is unknown at compile-time what function will be called or whether the called function supports a vector interface. Functions that call other functions via pointers may not export dependency information, which can be a reflection on the uncertainty of the dependencies on the pointed-to 25 function. This may cause the compiler to view such functions as scalar functions with unknown dependencies. [001451 In one implementation, a versioning scheme allows dependencies to be expressed using best practices at any point in time. For example, an embodiment may permit backward compatibility with dependency-files generated by older compilers, whereas another embodiment 30 may permit bi-directional compatibility that enables older compilers to also read files generated by newer compilers. In cases where backward compatibility is the only requirement, then a version designator for the dependency file is used to inform older compilers that a given file is unreadable and should be ignored. 35 WO 2012/039937 PCT/US2011/050713 [001461 Bi-directional compatibility may be implemented as follows, Assume, for example, that compiler version I does not support calculations in array indices but complier version 2 does. A write to Bi/xi+yj, may be expressed by a version-I compiler as: 5 #1 int foo (int x, int y) write public B [@]; } ; 10 1001471 On the other hand, a version-2 compiler may additionally export the same function using a version- 2 syntax: #2 int foo(int x, int y) f 15 write public B [x+y]i; 1001481 With this approach, not only can a version-2 compiler read version-i files, but it can also allow version-2 declarations to override version-i declarations. A version-i compiler would 20 know to ignore any declarations that were greater than version-1, giving it as much dependency information as it is capable of understanding. This is a significant capability as compiler technology matures. 1001491 Generally speaking, if developers are required to make changes to software to enable vectorization, then relatively little code may become vectorized. To address this problem, the 25 techniques described herein provide the ability to perform large-scale vectorization without requiring developers to modify their source code. [001501 Although the embodiments above have been described in considerable detail, numerous variations and modifications will become apparent to those skilled in the art once the specification is fully appreciated. It is intended that the following claims be interpreted to 30 embrace all such variations and modifications. 36

Claims (20)

1. A method including: performing, by one or more computers: 5 identifying a calling function during a process of compiling source code including the calling function, the calling function including a call to a previously-compiled called function; accessing a persistent dependency database to retrieve an expressed dependency associated with the previously-compiled called 10 function, wherein the expressed dependency is generated and persistently store into the persistent dependency database during compilation of the previously-compiled called function, wherein the expressed dependency is accessible across distinct compiler invocations, and wherein the expressed dependency indicates 15 whether the previously-compiled called function only reads a data item, only writes the data item, or both reads and writes the data item; and generating a determination of whether the calling function interacts with the previously-compiled called function based, at least in part, 20 upon the expressed dependency and without accessing source code of the previously-compiled called function.
2. The method of claim 1, wherein the call to the previously-compiled called function occurs within a loop of the calling function. 25
3. The method of claim 1, wherein the performing further includes: determining from the persistent dependency database that a vector version of the previously-compiled called function exists; and within the calling function, transforming a call to a scalar version of the 30 previously-compiled called function into a call to the vector version of the previously-compiled called function. 37 1001053592_2.docx
4. The method of claim 1, wherein the performing further includes determining whether to vectorize at least a portion of the calling function based on one or more of the following items indicated by the persistent dependency database: whether 5 the variable is read or written by the calling function, whether the variable is public or private to the calling function, or an addressing mode associated with the variable.
5. The method of claim 1, wherein the performing further includes: compiling source code corresponding to a called function; 10 during compiling, identifying an expressed dependency of the called function on the data item, wherein the expressed dependency indicates whether the called function only reads the data item, only writes the data item, or both reads and writes the data item; and storing an indication of the expressed dependency in the persistent dependency 15 database.
6. The method of claim 5, wherein storing the indication of the expressed dependency includes, in addition to storing a name of the variable, storing an indication of one or more of the following in the persistent dependency database: whether the 20 variable is public or private to the called function, or an addressing mode associated with the variable.
7. The method of claim 5, wherein the performing further includes generating a vector version of the called function having a vector interface and storing an 25 indication of the vector interface in the persistent dependency database.
8. The method of claim 5, wherein the performing further includes creating the persistent dependency database at compile time of the called function. 30
9. The method of claim 5, wherein storing the indication includes expressing one or more of the following: an addressing mode associated with the data item within 38 1001053592_2.docx the called function, a public or private qualifier associated with the data item within the called function, a speculation-safe indicator associated with the called function, or an aliasing indicator associated with the data item within the called function. 5 10. The method of claim 5, wherein storing the indication includes expressing one or more of the following: an indication of whether the called function reads or writes to a known offset within a pointed-to object, an indication of whether the called function reads or writes to a variable offset within an object, or an indication of whether the called function reads or writes to an unknown offset within an object.
10
11. The method of claim 5, wherein the data item is not a parameter passed in to the called function via the called function's programming interface.
12. The method of claim 1, wherein the performing further includes 15 vectorizing code within the calling function based at least in part on the determination.
13. The method of claim 12, wherein vectorizing code within the calling function further includes vectorizing a loop within the calling function based at least in part on the determination. 20
14. The method of claim 12, wherein vectorizing code within the calling function further includes modifying the call to reference a vector version of the called function. 25
15. The method of claim 1, wherein the operations further include: dependent upon the determination of whether the calling function interacts with the previously-compiled called function, determining whether to vectorize at least a portion of the calling function based, at least in part, upon the expressed dependency; and 30 in response to determining to vectorize at least a portion of the calling function, generating vector code that, when executed, causes a vector operation to 39 1001053592_2.docx be concurrently performed on multiple data items referenced within the calling function.
16. The method of claim 15, wherein the determining operation determines to 5 vectorize at least a portion of the calling function despite source code for the previously compiled called function being unavailable.
17. The method of claim 1, wherein the calling function includes a non-leaf loop, the non-leaf loop including the call to the previously-compiled called function. 10
18. The method of claim 17, wherein the performing further includes: vectorizing a first portion of the non-leaf loop; and serializing a second portion of the non-leaf loop. 15
19. A computer-readable storage medium having program instructions stored therein that, in response to execution by a computer system, cause the computer system to perform operations that implement a method according to any one of claims 1-18.
20. A system including: 20 one or more memories that, during operation, store instructions; and one or more processors that, during operation, retrieve instructions from the one or more memories and execute the instructions to cause the system to perform operations that implement a method according to any one of claims 1-18. 40
AU2011305837A 2010-09-23 2011-09-07 Systems and methods for compiler-based vectorization of non-leaf code Ceased AU2011305837B2 (en)

Applications Claiming Priority (5)

Application Number Priority Date Filing Date Title
US12/888,644 US8621448B2 (en) 2010-09-23 2010-09-23 Systems and methods for compiler-based vectorization of non-leaf code
US12/888,658 US8949808B2 (en) 2010-09-23 2010-09-23 Systems and methods for compiler-based full-function vectorization
US12/888,658 2010-09-23
US12/888,644 2010-09-23
PCT/US2011/050713 WO2012039937A2 (en) 2010-09-23 2011-09-07 Systems and methods for compiler-based vectorization of non-leaf code

Publications (2)

Publication Number Publication Date
AU2011305837A1 AU2011305837A1 (en) 2013-03-28
AU2011305837B2 true AU2011305837B2 (en) 2015-05-14

Family

ID=44937720

Family Applications (1)

Application Number Title Priority Date Filing Date
AU2011305837A Ceased AU2011305837B2 (en) 2010-09-23 2011-09-07 Systems and methods for compiler-based vectorization of non-leaf code

Country Status (9)

Country Link
KR (1) KR101573586B1 (en)
CN (1) CN103119561B (en)
AU (1) AU2011305837B2 (en)
BR (1) BR112013008640A2 (en)
DE (1) DE112011103190T5 (en)
GB (1) GB2484000A (en)
MX (1) MX2013003339A (en)
TW (1) TWI446267B (en)
WO (1) WO2012039937A2 (en)

Families Citing this family (19)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US9298456B2 (en) * 2012-08-21 2016-03-29 Apple Inc. Mechanism for performing speculative predicated instructions
US9348589B2 (en) 2013-03-19 2016-05-24 Apple Inc. Enhanced predicate registers having predicates corresponding to element widths
US9817663B2 (en) 2013-03-19 2017-11-14 Apple Inc. Enhanced Macroscalar predicate operations
US9830134B2 (en) * 2015-06-15 2017-11-28 Qualcomm Incorporated Generating object code from intermediate code that includes hierarchical sub-routine information
CN106371838B (en) * 2016-08-31 2019-10-18 福建联迪商用设备有限公司 A method and system for maintaining software package dependencies
CN108733432B (en) * 2017-04-14 2021-12-21 创新先进技术有限公司 Method for realizing private method in programming environment, calling method and device thereof
US10379825B2 (en) * 2017-05-22 2019-08-13 Ab Initio Technology Llc Automated dependency analyzer for heterogeneously programmed data processing system
US10318259B2 (en) * 2017-05-31 2019-06-11 Intel Corporation Technology to use control dependency graphs to convert control flow programs into data flow programs
CN111566616B (en) * 2017-11-03 2023-12-12 相干逻辑公司 Programming flow for multiprocessor systems
CN109240666B (en) * 2018-06-22 2020-08-25 北京大学 Method and system for function call code generation based on call stack and dependency path
US11809871B2 (en) 2018-09-17 2023-11-07 Raytheon Company Dynamic fragmented address space layout randomization
CN112799671B (en) * 2019-11-13 2024-10-18 北京配天技术有限公司 Function analysis method and computer equipment thereof
US11366648B2 (en) * 2020-05-28 2022-06-21 Red Hat, Inc. Compiling monoglot function compositions into a single entity
CN112214221B (en) * 2020-10-10 2023-04-28 上海上讯信息技术股份有限公司 Method and equipment for constructing Linux system
CN113342319B (en) * 2021-05-24 2024-03-22 重庆长安汽车股份有限公司 Method and system for automatically generating software code for CAN fault diagnosis
CN113536316B (en) * 2021-06-17 2023-08-11 深圳开源互联网安全技术有限公司 Method and device for detecting component dependency information
CN114327480A (en) * 2021-12-27 2022-04-12 上海市数字证书认证中心有限公司 Software compilation preprocessing method, device, equipment and storage medium
CN116700729B (en) * 2023-04-27 2025-02-18 珠海市芯动力科技有限公司 Code compilation method and related device
CN116700731B (en) * 2023-05-12 2024-09-24 珠海市芯动力科技有限公司 Code compilation method and related device

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0785506A1 (en) * 1996-01-17 1997-07-23 Nec Corporation Optimizing compiler using interprocedural dataflow analysis

Family Cites Families (9)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2002073333A (en) * 2000-08-25 2002-03-12 Hitachi Ltd Analysis display method of data dependence of procedure call destination
JP2004246776A (en) * 2003-02-17 2004-09-02 Ricoh Co Ltd Automatic variable sharing compiler, automatic variable sharing linker and program development support system
US7617496B2 (en) 2004-04-23 2009-11-10 Apple Inc. Macroscalar processor architecture
US7395419B1 (en) 2004-04-23 2008-07-01 Apple Inc. Macroscalar processor architecture
US7506331B2 (en) 2004-08-30 2009-03-17 International Business Machines Corporation Method and apparatus for determining the profitability of expanding unpipelined instructions
JP2009129179A (en) * 2007-11-22 2009-06-11 Toshiba Corp Program parallelization support apparatus and program parallelization support method
US8255884B2 (en) 2008-06-06 2012-08-28 International Business Machines Corporation Optimized scalar promotion with load and splat SIMD instructions
US8418161B2 (en) * 2008-11-24 2013-04-09 International Business Machines Corporation System and method for loading a called class file table with data indicating a highest version of a class file
CN101477472B (en) * 2009-01-08 2011-11-16 上海交通大学 Multi-core multi-threading construction method for hot path in dynamic binary translator

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0785506A1 (en) * 1996-01-17 1997-07-23 Nec Corporation Optimizing compiler using interprocedural dataflow analysis

Non-Patent Citations (2)

* Cited by examiner, † Cited by third party
Title
KUNRONG CHEN ET AL: "RIPPLES: tool for change in legacy software", PROCEEDINGS IEEE INTENATIONAL CONFERENCE ON SOFTWARE MAINTENANCE, ICSM-2001, FLORENCE, ITALY, NOV 7 - 9, 2001 *
XIAO NONG ET AL: "A parallelizing translator for object-oriented large-grain data flow model", SYSTEM THEORY, 1996, PROCEEDINGS OF THE TWENTY-EIGHTH SOUTHEASTERN SYMPOSIUM ON BATON ROUGE. LA, USA 31 MARCH-2 APRIL 1996, *

Also Published As

Publication number Publication date
CN103119561A (en) 2013-05-22
BR112013008640A2 (en) 2016-06-21
WO2012039937A3 (en) 2012-09-20
GB2484000A (en) 2012-03-28
DE112011103190T5 (en) 2013-06-27
CN103119561B (en) 2016-03-09
AU2011305837A1 (en) 2013-03-28
TW201224933A (en) 2012-06-16
GB201116429D0 (en) 2011-11-02
TWI446267B (en) 2014-07-21
WO2012039937A2 (en) 2012-03-29
MX2013003339A (en) 2013-06-24
KR20130096738A (en) 2013-08-30
KR101573586B1 (en) 2015-12-01

Similar Documents

Publication Publication Date Title
AU2011305837B2 (en) Systems and methods for compiler-based vectorization of non-leaf code
US8949808B2 (en) Systems and methods for compiler-based full-function vectorization
US8621448B2 (en) Systems and methods for compiler-based vectorization of non-leaf code
US9529574B2 (en) Auto multi-threading in macroscalar compilers
Midkiff Automatic parallelization: an overview of fundamental compiler techniques
JP5893038B2 (en) Compile-time boundary checking for user-defined types
JP4183399B2 (en) Multiple language compilation method and system
US9747089B2 (en) Automatic conversion of sequential array-based programs to parallel map-reduce programs
Schardl et al. Tapir: Embedding recursive fork-join parallelism into llvm’s intermediate representation
KR20130137652A (en) Extensible data parallel semantics
Grosse-Kunstleve et al. Automatic Fortran to C++ conversion with FABLE
Zhang et al. Regcpython: A register-based python interpreter for better performance
US10884720B2 (en) Memory ordering annotations for binary emulation
Schommer et al. Embedded program annotations for WCET analysis
Psaroudakis et al. Analytics with smart arrays: Adaptive and efficient language-independent data
Bowen et al. Extending RAJA Parallel Programming Abstractions with Just-In-Time Optimization
Gay et al. Yada: Straightforward parallel programming
Honorio et al. Using barrier elision to improve transactional code generation
Smith et al. Localizing globals and statics to make c programs thread-safe
Prabhu Just in time compilation for high performance computing
Poulsen et al. EPG source code instrumentation tools-user manual
Chevalier-Boisvert On the fly type specialization without type analysis
Erhardt et al. A Control-Flow-Sensitive Analysis and Optimization Framework for the KESO Multi-JVM
Bauer et al. Sequoia++ User Manual
Balaš Advanced Optimizations in Dynamic Language Compiler

Legal Events

Date Code Title Description
FGA Letters patent sealed or granted (standard patent)
MK14 Patent ceased section 143(a) (annual fees not paid) or expired