WO2021140568A1 - 関数生成プログラム、関数生成方法、及び情報処理装置 - Google Patents

関数生成プログラム、関数生成方法、及び情報処理装置 Download PDF

Info

Publication number
WO2021140568A1
WO2021140568A1 PCT/JP2020/000184 JP2020000184W WO2021140568A1 WO 2021140568 A1 WO2021140568 A1 WO 2021140568A1 JP 2020000184 W JP2020000184 W JP 2020000184W WO 2021140568 A1 WO2021140568 A1 WO 2021140568A1
Authority
WO
WIPO (PCT)
Prior art keywords
function
instruction
code
mnemonic
file
Prior art date
Application number
PCT/JP2020/000184
Other languages
English (en)
French (fr)
Inventor
川上健太郎
齋藤盛幸
Original Assignee
富士通株式会社
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
Application filed by 富士通株式会社 filed Critical 富士通株式会社
Priority to JP2021569633A priority Critical patent/JP7295469B2/ja
Priority to PCT/JP2020/000184 priority patent/WO2021140568A1/ja
Publication of WO2021140568A1 publication Critical patent/WO2021140568A1/ja
Priority to US17/736,156 priority patent/US11886839B2/en

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/30Creation or generation of source code
    • G06F8/31Programming languages or programming paradigms
    • G06F8/315Object-oriented languages
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/51Source to source
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation

Definitions

  • the present invention relates to a function generation program, a function generation method, and an information processing device.
  • JIT Just In Time
  • the JIT compiler technology refers to a technology for generating a suitable machine language instruction sequence according to the parameters determined at the time of execution, the processing content, and the status of the processor.
  • the machine language instruction sequence generated by using the JIT compiler technology is faster than the executable file consisting of the machine language instruction sequence generated by the AOT (Ahead Of Time) type compiler and which can be processed in general.
  • the purpose is to provide a function generation program, a function generation method, and an information processing device that can reduce the man-hours involved in creating a function.
  • a process of generating a first function which is a function corresponding to the instruction and receives an argument representing an operand of the instruction by referring to a storage unit which stores instruction information related to the instruction, and the above-mentioned.
  • the process of generating a code for calling a second function that returns a machine language representing the process performed by the instruction with respect to the operand represented by the argument inside the first function, and the code for writing the machine language to the memory are described above.
  • a function generation program for causing a computer to execute a process generated inside the first function is provided.
  • FIG. 1 is a hardware configuration diagram of a target machine that executes an executable program.
  • FIG. 2 (a) is a diagram showing an example of C ++ pseudo source code assuming compilation by AOT (Ahead Of Time) compiler technology
  • FIG. 2 (b) is a diagram showing parameters q and arrays in and out. It is a figure which shows an example of the C ++ source code which declared
  • FIG. 2C is a figure which shows an example of the C ++ pseudo source code which declared the initial value of the array Tbl.
  • FIG. 3 is a schematic diagram of an assembly pseudo code obtained by AOT compiler technology.
  • FIG. 4 is a diagram schematically showing the operation of an executable program obtained by AOT compiler technology.
  • FIG. 5 is a diagram showing an example of C ++ pseudo source code of an executable program using JIT compiler technology.
  • FIG. 6 is a schematic diagram of a machine language instruction sequence generated by the JIT compiler technique and a pseudo code obtained by disassembling the instruction sequence when the input parameter q is “8”.
  • FIG. 7 is a schematic diagram showing the operation of an executable program in which a function to be called at the time of execution is generated at the time of execution by the JIT compiler technology.
  • FIG. 8 is a diagram showing an example of pseudo source code of the mnemonic function corresponding to the mov instruction.
  • FIG. 9 is a schematic view showing the operation of the information processing apparatus according to the first embodiment.
  • FIG. 10 is a diagram showing an example of a source file in which the C ++ pseudo source code of the MachineCodeEmitter function is described.
  • FIG. 11 is a functional configuration diagram of the information processing device according to the first embodiment.
  • FIG. 12 is a flowchart showing a function generation method according to the first embodiment.
  • FIG. 13 is a schematic diagram showing a development environment using a source file in which a mnemonic function is described in the first embodiment.
  • FIG. 14 is a schematic diagram showing the contents of the memory when the executable program generated without using the C ++ macro is executed.
  • FIG. 15A is a diagram showing an example of source code in which the first generation unit according to the first embodiment describes the mnemonic function mov as a C ++ macro, and FIG.
  • FIG. 15B is a diagram showing an example of the source code using the macro. In this case, it is a schematic diagram which shows the contents of the memory at the time of executing an executable program.
  • FIG. 16 is a diagram showing commands having the same mnemonics but different machine languages.
  • FIG. 17A is a diagram schematically showing instruction information of the first embodiment when the mnemonics “STRpost” and “STRpre” are adopted, and
  • FIG. 17B is a diagram based on the instruction information. It is a figure which shows the mnemonic function generated according to 1 Embodiment.
  • FIG. 18 is a diagram schematically showing command information used in the second embodiment.
  • FIG. 20A is a schematic diagram of a source file in which a C ++ pseudo source code of the mnemonic function STR according to the second embodiment corresponding to the mnemonic “STRpost” is described
  • FIG. 20B is a schematic diagram of the mnemonic “STRpost”. It is a schematic diagram of the source file in which the C ++ pseudo source code of the mnemonic function STR which concerns on the 2nd Embodiment corresponding to "STRpre" is described.
  • FIG. 20A is a schematic diagram of a source file in which a C ++ pseudo source code of the mnemonic function STR according to the second embodiment corresponding to the mnemonic “STRpost” is described
  • FIG. 20B is a schematic diagram of the mnemonic “STRpost”. It is a schematic diagram of the source file in which the C ++ pseudo source code of the mnemonic function STR which concerns on the 2nd Embodiment corresponding to "STRpre” is described.
  • FIG. 20A is a schematic
  • FIG. 21 (a) is a diagram showing a C ++ pseudo source code of the mnemonic function mov when the argument of the mnemonic function is Operand type
  • FIG. 21 (b) is a diagram showing a developer using this mnemonic function mov. It is a figure which shows the pseudo source code of C ++ of the source file 41 for the application program described by.
  • FIG. 22 (a) is a schematic diagram of a source file in which the C ++ pseudo source code of the mnemonic function mov generated in the second embodiment is described, and FIG. 22 (b) uses this mnemonic function mov. It is a figure which shows the example of the C ++ pseudo source code of the source file for an application program written by a developer.
  • FIG. 23 is a flowchart showing a function generation method according to the second embodiment.
  • FIG. 24A is a diagram showing an example of a source file in which the C ++ source code of the mnemonic function mov generated according to the second embodiment is described, and FIG. 24B is a diagram using this mnemonic function mov. It is a figure which shows the example of the C ++ pseudo source code of the source file for the application program written by the developer.
  • FIG. 25 is a diagram schematically showing command information used in the third embodiment.
  • FIG. 26 is a schematic diagram showing an example of a C ++ pseudo source code of the source file 34 in which the mnemonic function mov according to the third embodiment corresponding to the mov instruction is described.
  • FIG. 24A is a diagram showing an example of a source file in which the C ++ source code of the mnemonic function mov generated according to the second embodiment is described
  • FIG. 24B is a diagram using this mnemonic function mov. It is a figure
  • FIG. 27 is a diagram showing an example of C ++ pseudo source code of a source file for an application program described by a developer using the mnemonic function mov according to the third embodiment.
  • FIG. 28 is a flowchart showing a function generation method according to the third embodiment.
  • 29 (a) and 29 (b) are diagrams showing the grammar of the add instruction in the fourth embodiment.
  • FIG. 30 is a diagram schematically showing command information according to the fourth embodiment.
  • FIG. 31 is a diagram showing an example of the source code of the mnemonic function ADD generated by the control unit according to the fourth embodiment.
  • FIG. 32 is a diagram schematically showing a C ++ pseudo-source code that defines the function “SET ()”.
  • FIG. 33 is a diagram schematically showing a pseudo source code of a source file for an application program written by a developer in C ++ in the fourth embodiment.
  • FIG. 34 is a diagram showing an output example.
  • FIG. 35 is a functional configuration diagram of the information processing apparatus according to the fourth embodiment.
  • FIG. 36 is a schematic diagram showing a C ++ pseudo source code of the mnemonic function ADD generated by the control unit in the fourth embodiment.
  • FIG. 37 is a diagram showing an example of C ++ pseudo source code of the function “SET ()” generated by the fourth generation unit in the fourth embodiment.
  • FIG. 38 is a schematic diagram showing a pseudo source code of the definition file generated by the definition file generation unit in the fourth embodiment.
  • FIG. 39 is a diagram showing C ++ pseudo code of the source file for the application program described by the developer in the fourth embodiment.
  • FIG. 40 is a schematic view showing the development environment according to the fourth embodiment.
  • FIG. 41 is a diagram showing an output example in the fourth embodiment.
  • FIG. 42 is a schematic diagram showing an example of C ++ pseudo source code of the source file according to another example of the fourth embodiment.
  • FIGS. 43 (a) and 43 (b) are diagrams schematically showing inconveniences that occur when a variable argument macro is described at the end of a function that is replaced by a macro.
  • FIG. 44 is a flowchart showing a method of generating a definition file according to the fourth embodiment.
  • FIG. 45 is a hardware configuration diagram of the information processing apparatus according to the first to fourth embodiments.
  • JIT compiler technology is useful for increasing the execution speed of programs.
  • the advantages of such JIT compiler technology will be explained in comparison with AOT (Ahead Of Time) compiler technology.
  • AOT Ahead Of Time
  • this JIT compiler technology is not a technology that converts processor-independent intermediate language code into a machine language instruction sequence that can be directly handled by the processor, but a machine language instruction sequence suitable for parameters determined at execution time. Is a compiler technology that generates.
  • FIG. 1 is a hardware configuration diagram of a target machine that executes an executable program generated by AOT compiler technology or JIT compiler technology.
  • This target machine 1 is a computer such as a server or a PC (Personal Computer), and has a processor 2 and a memory 3.
  • the processor 2 includes a calculation core 4 such as an ALU (Arithmetic and Logic Unit) that performs arithmetic operations and logical operations, and a register file 5.
  • the memory 3 is a volatile memory such as DRAM (Dynamic Random Access Memory) in which an executable program is deployed.
  • the executable program can be generated by compiling the source code using AOT compiler technology as follows.
  • a machine language instruction sequence called by an executable program using JIT compiler technology may be dynamically generated during execution.
  • FIG. 2A is a diagram showing an example of C ++ pseudo-source code 10 on the premise of compiling with AOT compiler technology.
  • GCC GPU Compiler Collection
  • each element of the array "Tbl” is divided by the parameter "q" in the process 10a.
  • the element of the array "in” is divided by the element of the array "Tbl", and it is stored in the array "out".
  • FIG. 2B is a diagram showing an example of C ++ pseudo source code 11 in which the parameter “q” and the arrays “in” and “out” are declared.
  • the parameter "q” is a divisor in the above-mentioned process 10a, and is also referred to as an input parameter below.
  • the array “in” and the array “out” are input data and output data in the process 10b, respectively.
  • the data stored in these arrays “in” and “out” is not particularly limited.
  • the array “in” and the array “out” are declared as a two-dimensional array that stores 1,000,000 images composed of 16 pixel data.
  • FIG. 2C is a diagram showing an example of C ++ pseudo source code 12 in which the initial value of the array Tbl is declared.
  • the array “Tbl” is an array that stores the values of the quantization table that quantizes the pixel data.
  • the array “Tbl” is declared as an array having 16 elements corresponding to each of the arrays "in” and "out”. Then, it is assumed that the initial value of each element of the array “Tbl” is a power of 2.
  • the source codes 10 to 12 in FIGS. 2 (a) to 2 (c) are all described by the developer according to the grammar of C language or C ++, and converted into an assembly by the compiler.
  • FIG. 3 is a schematic diagram of the pseudo code of the assembly 14 obtained by compiling the above-mentioned source code 10 with the AOT compiler technology.
  • a plurality of instructions included in the instruction set of the processor 2 are generated corresponding to the respective processes 10a and 10b.
  • the process 10a is realized by 6 instructions from the mov instruction to the jmplt instruction
  • the process 10b is realized by 10 instructions from the mov instruction to the jmplt instruction.
  • These instructions are instructions included in the instruction set of the processor 2, and perform various operations on the registers and memory described as operands.
  • mnemonic for the mov instruction is "mov" and the mnemonic for the store instruction is "store”.
  • an instruction that performs division such as a div instruction
  • a div instruction is an instruction that has a large number of execution cycles compared to other instructions, regardless of the type of processor. Therefore, the throughput from the start of execution until the result is obtained is large, and this is an instruction that causes a decrease in processing performance.
  • the number of execution cycles of the numerical operation instruction other than the div instruction is 1 to 5, whereas the number of execution cycles of the div instruction may be about 80.
  • the number of loops of the for loop becomes enormous, so that the throughput is further reduced by the div instruction inside the for loop.
  • an executable program composed of the machine language is generated.
  • an assembly for a processor with a virtual instruction set may be generated regardless of the type of processor 2.
  • this assembly may be converted into a machine language instruction sequence for individual processors, but the same point is that the throughput decreases when there is a division instruction such as a div instruction.
  • FIG. 4 is a diagram schematically showing the operation of the executable program obtained by the AOT compiler technology.
  • the executable program 15 accepts the input of each element of the array "in” which is the input data and the input parameter "q". Then, as described above, regardless of the value of the input parameter "q" or the array "in", the executable program performs processing by the machine language instruction sequence obtained from the same assembly 14, and the processing is performed. Store the result in each element of the array "out”.
  • FIG. 5 is a diagram showing an example of C ++ pseudo source code 16 of an executable program using JIT compiler technology.
  • This source code 16 is a code described by the developer so that the execution result thereof is the same as the execution result of the source code 10 of FIG. 2A, and has a process 16a and a process 16b.
  • the process 16a is a process of dividing each element of the array “Tbl” by the parameter “q”, similarly to the process 10a of the source code 10.
  • the process 16b is a process of dividing the element of the array "in” by the element of the array "Tbl” and storing it in the array "out”, similarly to the process 10b of the source code 10.
  • a function such as "mov (R0, i)" whose function name is the same as the mnemonic is described by the developer.
  • the function "mov (R0, i)” is, so to speak, a function corresponding to the assembly "mov R0, #i", and is a function that writes the machine language representing the processing performed by "mov R0, #i” to the memory 3. ..
  • Variables cannot be described in the assembly, and only fixed values such as “mov R0, # 5" and “mov R0, # -128" can be specified at the time of assembly.
  • the variable i can be used as an immediate value. This is one of the advantages of JIT compiler technology.
  • a function whose function name is the same as the mnemonic of the instruction and which writes the machine language indicating the processing performed by the instruction to the memory 3 is hereinafter referred to as a mnemonic function.
  • a machine language instruction sequence is generated using different mnemonic functions depending on the value of the array element "Tbl [i]" which is a divisor.
  • This mnemonic function is a function corresponding to the div instruction, and is a function that writes the machine language that writes the value obtained by dividing the contents of the register R1 by the contents of the register R2 to the register R1 to the memory 3.
  • the execution speed of the program is compared with AOT compiler technology by writing the optimum machine language to reduce the number of execution cycles according to the value of the parameter such as "Tbl [i]". Can be speeded up.
  • FIG. 6 is a schematic diagram showing what kind of machine language instruction sequence the process 16b wrote in the memory during the execution of the executable file obtained by compiling the source code 16.
  • "8" is given to the input parameter q.
  • the pseudo code of the assembly 17 in which the instruction sequence of the machine language is disassembled is also shown.
  • FIG. 7 is a schematic diagram showing the operation of an executable program that generates a function to be called at run time by JIT compiler technology at run time.
  • the operation of the executable program 20 obtained by compiling the source code 16 using the JIT compiler technology will be described.
  • the executable program 20 first accepts the input of the input parameter “q” (step P10). Next, the executable program 20 generates the machine language 18 whose processing speed is increased according to the value of the input parameter “q” (step P11). In the example of FIG. 6 described above, the machine language 18 suitable for the value of "Tbl [i]" is generated.
  • the executable program 20 accepts the input of each element of the array "in” which is the input data (step P12), and stores the processing result in each element of the array "out” (step P13).
  • the machine language 18 does not include the div instruction having a slow throughput, it is possible to perform processing faster than the executable program corresponding to the assembly 14. Moreover, by generating an appropriate machine language 18 according to the value of the input parameter "p" in this way, the JIT compiler technology can make the program execution speed faster than the AOT compiler technology.
  • FIG. 8 is a diagram showing an example of C ++ pseudo source code of the mnemonic function corresponding to the mov instruction.
  • This source code 21 is the source code for defining the mnemonic function mov.
  • the function name of the mnemonic function mov is the same as the mnemonic "mov" of the mov instruction, and there are two arguments, "operand 0" and "operand 1" taken by the mov instruction.
  • the function write is a function that writes the bit string of the argument to the memory 3.
  • the value of "mnemonic” is shifted to the left by 24 bits
  • the value of the variable "op0” is shifted to the left by 16 bits
  • the value of the variable "op1” is shifted to the left by 8 bits.
  • the bit sum with the value is the argument of the function write.
  • the first 8 bits are the opcode of the mov instruction.
  • the next 8 bits of the opcode are the bit strings of the variable "op0", and the next 8 bits are the bit strings of the variable "op1".
  • the last 8 bits are the bit string of the third variable "op2".
  • the developer specifies the format of each instruction by referring to the instruction set specifications, and describes the opcode and each bit string of the operand in the argument of the function write according to the format. There is a need.
  • processors 2 include hundreds to thousands of instructions in an instruction set. For example, in a processor that complies with the ARMv8-A architecture profile for which ARM has established specifications, if instructions with the same name with different operand variations are treated as different instructions, there are about 1000 types of instructions. In this case, the developer has to describe about 1000 kinds of mnemonic functions by himself, and a huge amount of man-hours are required to manually describe and verify the mnemonic functions corresponding to all the instructions.
  • the instruction set may be expanded in the future, and it is not bothersome to describe and verify the mnemonic function each time.
  • the information processing device automatically generates a mnemonic function as follows.
  • FIG. 9 is a schematic diagram showing the operation of the information processing apparatus according to the present embodiment.
  • the information processing device 30 is a computer such as a PC or a server provided with a control unit 31 which is a tool for automatically generating a mnemonic function.
  • the control unit 31 refers to the instruction information 33 for generating the function.
  • the instruction information 33 is information in which the mnemonics of each instruction and the number of operands are associated with each other, and is created in advance by the developer.
  • Each line of the instruction information 33 corresponds to a different instruction, for example, the first line corresponds to the mov instruction and the second line corresponds to the load instruction.
  • the developer stores the mnemonic "mov" of the mov instruction on the first line in the instruction information 33 in association with the number of operands "2" of the mov instruction.
  • the number of operands differs depending on the instruction. For example, in the shiftR instruction, the number of operands is "3".
  • the instruction information 33 is stored as a file in the storage unit in the information processing device 30.
  • the developer may store the instruction information 33 in an external storage unit connected to the information processing device 30 via the network, and the control unit 31 may refer to the storage unit.
  • the control unit 31 reads the instruction information 33 line by line and generates a mnemonic function having a function name corresponding to the mnemonic in that line.
  • the generation method will be described by taking the mnemonic "mov" in the first line as an example.
  • control unit 31 acquires the mnemonic "mov" and the number of operands "2" corresponding to the mnemonic "mov” by reading the first line of the instruction information 33.
  • control unit 31 describes the mnemonic function of the function name corresponding to the mnemonic "mov" in the C ++ source file 34.
  • the mnemonic and the function name have the same name. Therefore, the control unit 31 describes the mnemonic function whose function name 34a is "mov" in the source file 34.
  • the programming language described in the source file 34 is not limited to C ++, and the control unit 31 may describe the C language or C # source code in the source file 34.
  • the mnemonic function mov takes the same number of arguments as the number "2" in the instruction information 33.
  • an empty function "void mov (Operand OP0, Operand OP1) ⁇ " which is a template of the mnemonic function mov, is described.
  • the mnemonic function mov is an example of the first function.
  • each of "OP0" and “OP1" is an argument representing the operand of the mov instruction.
  • the control unit 31 defines the Operand type as the type of the variable representing the operand by describing the source code 34b in the source file 34. Then, the control unit 31 declares each of "OP0" and "OP1" as an Operand type in the code T1.
  • Operand type is a class that has "type” and "value” as members. Of these, “type” stores the types of operands such as registers and immediate values. Then, in “value”, a numerical value such as an immediate value or a register index is stored.
  • the Operand type may be defined in a source file different from the source file 34.
  • control unit 31 generates codes T2 to T4 inside the mnemonic function mov.
  • Code T2 is a statement that assigns the previously acquired function name "mov" to the variable "nm".
  • the character string "mov” is assigned to the variable "nm”, but the function name "mov” and the integer value are made to have a one-to-one correspondence in advance, and the integer value is used as the variable "nm”. May be substituted for.
  • code T3 is a statement that assigns the Operand type "OP0" and "OP1" received as arguments by the mnemonic function mov to the array "oplist”.
  • the code T4 is a code that calls the MachineCodeEmitter function and writes the return value of the MachineCodeEmitter function to the memory 3 by the function write.
  • the MachineCodeEmitter function takes the variable "nm” and the variable “oplist” as arguments, and generates a machine language that represents the processing performed by the instruction represented by the variable "nm” for the operand represented by the variable "oplist”. It is a function.
  • the MachineCodeEmitter function is an example of the second function, and the operation created together with the assembler of the processor 2 has been verified.
  • control unit 31 automatically generated the mnemonic function mov.
  • control unit 31 performs the same processing as above for the second and subsequent lines of the instruction information 33, so that the mnemonic functions whose function names are "load”, “shiftR”, “add”, etc. are automatically executed. Generate with. Then, the control unit 31 outputs the source file 34 in which the mnemonic functions corresponding to all the instructions included in the instruction set of the processor 2 are described to a storage unit such as a memory.
  • the function name of the mnemonic function is the same as the mnemonic of the instruction that the developer is familiar with, it is possible to provide a mnemonic function that is easy for the developer to handle without the trouble of the developer remembering the function name.
  • the number of arguments of the mnemonic function is equal to the number of operands of the instruction.
  • the mnemonic function can be called with the code “mov (OP0, OP1)” which is similar to the grammar of the assembly "mov OP0 OP1" which the developer is familiar with, which improves the convenience of the developer.
  • FIG. 10 is a diagram showing an example of a source file 43 in which the C ++ pseudo source code of the above MachineCodeEmitter function is described.
  • the source file 43 may be a part of the source file of the assembler itself.
  • the functions of the MachineCodeEmitter function are realized by the codes T5 to T8.
  • the code T5 is a statement that declares the variable "mnemonic" and the variables "op0", “op1", “op2”, and "op3" as 32-bit unsigned integers.
  • the code T6 is a code that assigns the opcode corresponding to the content of the variable nm received as an argument by the MachineCodeEmitter function to the variable "mnemonic". For example, when the mnemonic specified by the variable "nm" is "mov", the opcode "0x01000000" of the mov instruction is assigned to the variable "mnemonic".
  • the code T7 positions these variables at the bit positions specified in the instruction specifications by performing bit operations on each of the variables "OP0" and "OP1" according to the contents of the variable "nm". It is a code to make.
  • the code T8 is a statement that generates a bit string in which each of the variables "mnemonic", “op0”, “op1”, and “op2" is concatenated in order from the most significant bit, and returns it as a return value.
  • the bit string is a machine language that expresses the processing performed by the instruction specified by the variable "nm” for the operand specified by the variable "oplist”.
  • the control unit 31 generates a code that calls the MachineCodeEmitter function inside the mnemonic function based on the instruction information 33.
  • the MachineCodeEmitter function is a function that generates a machine language that represents the processing performed by the instruction represented by the argument "nm" on the operand represented by the argument "oplist". Therefore, when creating the mnemonic function, it is not necessary for the developer to manually write the code to generate the machine language based on the instruction specification, and the man-hours required to create the mnemonic function can be reduced.
  • a group of tools for generating a machine language executable file that operates on the processor 2 is also developed.
  • Its tools include a compiler for converting source files written in C or C ++ to assembly language, and an assembler for converting assembly language to machine language.
  • Such tools include, for example, LLVM.
  • the MachineCodeEmitter function is a function built into the LLVM assembler, and its operation has been verified and provided when the assembler was developed. Therefore, in the present embodiment, it is not necessary to verify the operation of whether the mnemonic function generated by the control unit 31 generates the correct machine language. As a result, in addition to the man-hours for creating the mnemonic function, the man-hours required for verifying the operation of the mnemonic function can be reduced, and the man-hours for creating the mnemonic function can be reduced.
  • the MachineCodeEmitter function included in LLVM has been described as an example, but this embodiment is not limited to this.
  • a mnemonic function may be generated to call a machine language generation function in a tool group (for example, GCC) different from LLVM.
  • the machine language generation function is a function having the same function as the MachineCodeEmitter function.
  • the control unit 31 converts the variables "mov", "OP0", and "OP1" in FIG. 9 into the number and types of arguments of the machine language generation function in the codes T2 and T3. Instead, it may be described in the source file 34.
  • FIG. 11 is a functional configuration diagram of the information processing device 30 according to the present embodiment. As shown in FIG. 11, the information processing device 30 includes a control unit 31 and a storage unit 32.
  • the storage unit 32 can be realized by a storage device such as an HDD (Hard Disk Drive) or a memory such as DRAM, and stores the above-mentioned instruction information 33 and the source file 34 of the mnemonic function.
  • a storage device such as an HDD (Hard Disk Drive) or a memory such as DRAM, and stores the above-mentioned instruction information 33 and the source file 34 of the mnemonic function.
  • control unit 31 is a processing unit that controls the entire information processing device 30, and includes a first generation unit 36, a second generation unit 37, a third generation unit 38, and an output unit 39.
  • the first generation unit 36 is a processing unit that generates a mnemonic function corresponding to each instruction with reference to the instruction information 33 and describes the mnemonic function in the source file 34. As an example, the first generation unit 36 acquires a mnemonic from the instruction information 33 and assigns the same function name 34a (see FIG. 9) to the mnemonic function as the mnemonic. Further, the first generation unit 36 declares as the arguments of the mnemonic function the number of arguments equal to the number of operands in the instruction information 33.
  • the first generation unit 36 when the mnemonic in the instruction information 33 is "mov", the first generation unit 36 generates a function "void mov (Operand OP0, Operand OP1) ⁇ " as the mnemonic function mov, and the first generation unit 36 generates the function "void mov (Operand OP0, Operand OP1) ⁇ ".
  • the source code is described in the source file 34.
  • the content of the mnemonic function described by the first generation unit 36 is empty.
  • the first generation unit 36 may describe all the mnemonic functions included in the instruction set in one source file 34, or each of the mnemonic functions may be described in different source files.
  • the second generation unit 37 is a processing unit that generates a code that calls the above-mentioned MachineCodeEmitter function and describes the code in the source file 34.
  • the arguments of the MachineCodeEmitter function are "oplist", which is a variable corresponding to each operand, and "mov”, which is a variable corresponding to the instruction.
  • the MachineCodeEmitter function Upon receiving these arguments, the MachineCodeEmitter function generates a machine language that describes what the instruction does with the operands.
  • the third generation unit 38 is a processing unit that generates a code for writing the machine language generated by the MachineCodeEmitter function to the memory 3 and describes the code in the source file 34.
  • the code is in the format, for example, "write (MachineCodeEmitter (nm, oplist);”.
  • the output unit 39 writes out the source file 34 described by the first to third generation units 36 to 38 to the storage unit 32.
  • FIG. 12 is a flowchart showing a function generation method according to the present embodiment.
  • the first generation unit 36 refers to the instruction information 33 and acquires the mnemonic and the number of operands corresponding to the mnemonic (step S10).
  • the first generation unit 36 generates an empty mnemonic function and describes it in the source file 34 (step S11). For example, when the mnemonic is "mov", the first generation unit 36 describes an empty mnemonic function "void mov (Operand OP0, Operand OP1) ⁇ " in the source file 34. The number of arguments of this mnemonic function is the number of operands acquired in step S10.
  • the second generation unit 37 generates a code that calls the MachineCodeEmitter function (step S12).
  • the second generation unit 37 describes the code “graCodeEmitter (nm, oplist);” that calls the MachineCodeEmitter function inside the mnemonic function described by the first generation unit 36.
  • the second generation unit 37 also describes in the source file 34 a statement for passing the argument value of the mnemonic function to the MachineCodeEmitter function, as in the codes T2, T3, etc. in FIG.
  • the third generation unit 38 generates a code for writing the machine language generated by the MachineCodeEmitter function to the memory 3 (step S13).
  • the third generator 38 generates a code T4 (see FIG. 9) of "write (MachineCodeEmitter (nm, operand list));" in which the MachineCodeEmitter function is described in the argument of the function write, and generates a source file of the code T4 (see FIG. 9). Described in 34.
  • step S14 the processes of steps S10 to S13 are performed for all the lines included in the instruction information 33.
  • the output unit 39 writes the source file 34 including all the mnemonic functions to the storage unit 32 (step S14).
  • each of the first to third generation units 36 to 38 automatically generates a mnemonic function based on the instruction information 33. Therefore, the man-hours required to generate the mnemonic function can be reduced as compared with the case where the developer manually writes the mnemonic function.
  • each generation unit 36 to 38 since each generation unit 36 to 38 generates the mnemonic function in this way, the occurrence of bugs can be suppressed as compared with the case where the developer manually describes the mnemonic function. As a result, the time to wastefully execute the buggy program on the target machine 1 can be reduced, and the wasteful consumption of the hardware resources of the target machine 1 can be improved.
  • FIG. 13 is a schematic diagram showing a development environment using the source file 34 in which the mnemonic function is described.
  • control unit 31 which is a tool for generating the mnemonic function, refers to the instruction information 33 and generates a source file 34 including all the mnemonic functions according to the flowchart of FIG.
  • the developer creates a source file 41 for an application program using, for example, C ++.
  • the source file 41 is a file premised on using the functions of the JIT compiler technology, and includes a description for calling the mnemonic function in the source file 34 in addition to the C ++ library function.
  • the compiler includes a preprocessor for processing directives that start with, for example, #define. Then, in the build, the compiler included in the program group 42 compiles the source file 41.
  • the compiler reads each source file 34, 41, 43 and outputs the intermediate language file of the assembly.
  • the source file 43 is a source file in which the above-mentioned MachineCodeEmitter function is described. Then, the assembler converts the intermediate language file into a machine language instruction sequence to generate an object file.
  • the linker After that, the linker generates a binary executable program 44 that can be executed by the processor 2 by linking the object file with various libraries.
  • the above-mentioned source file 43 has been described as an example of being a part of the source file of the assembler itself. Through the operation verification when developing the assembler, it has been verified that the operation of the MachineCodeEmitter function described in the source file 43 is correct.
  • the execution library file may be available even though the assembler source file is not open to the public. In that case, instead of the source file 43, the execution library file 43a whose function of the machine language generation function has been converted into the instruction sequence of the machine language in advance is used as an input, and the executable program 44 is generated by linking this. Just do it.
  • the executable program 44 can be generated from the source file 41 for the application program.
  • the executable program 44 uses JIT compiler technology to generate an optimal machine language instruction sequence at runtime according to the parameters and environment at runtime. Therefore, the executable program 44 is particularly effective for speeding up an application program that requires a large number of loops and a large-scale operation such as deep learning and image processing. Similarly, application programs used in image processing such as video compression, encryption processing, decryption processing, blockchain technology, and the like can also be speeded up.
  • the mnemonic function may be described as a C ++ macro as follows.
  • FIG. 14 is a schematic diagram showing the contents of the memory 3 when the executable program 44 generated without using the C ++ macro is executed.
  • the mnemonic function mov (OP0, OP1) is described in the source file 41 by the developer.
  • the address to execute the instruction reaches the memory address in which the machine language corresponding to the call processing of the mnemonic function mov (OP0, OP1) is stored, the mnemonic function mov in the source file 34 is called by the function call.
  • the processing of the function call has a large overhead and slows down the program execution because the data of the registers R0, R1, ... Is saved in the memory 3 before the processing and the data is returned to the registers R0, R1, ... After the processing. Resulting in.
  • FIG. 15A is a diagram showing an example of the source code 45 in which the first generation unit 36 generated the mnemonic function mov as a C ++ macro.
  • the first generation unit 36 describes the macro of the mnemonic function mov in the source file 34 using the macro “#define” in step S11 (see FIG. 12).
  • FIG. 15B is a schematic diagram showing the contents of the memory 3 when the executable program 44 is executed when the macro is used in this way.
  • the preprocessor expands the source code 45 to the part where the mnemonic function mov (OP0, OP1) is described in the source file 41 at compile time. Therefore, the machine language that executes "mov OP0, OP1" can be written to the memory 3 without calling the function, and the executable program 44 speeds up the execution speed of the process of generating the machine language by the JIT compilation technology. Is possible.
  • an instruction set there may be a plurality of instructions having the same mnemonics but different machine languages. If the function name of the mnemonic function is changed for each of these instructions in order to reflect such a difference, the number of function names that the developer should remember increases, and the burden on the developer increases. Therefore, in the present embodiment, an example in which an increase in the burden on the developer can be suppressed even when there are a plurality of instructions having the same mnemonics but different machine languages will be described.
  • FIG. 16 is a diagram showing an example in which such an instruction is described in an assembly. These instructions 51 and 52 are both store instructions, and their mnemonics are all "STR" and are the same.
  • the instruction 51 writes the value of the "SRC register” to the memory 3 (see FIG. 1) of the address stored in the "address register", and then sets the value stored in the "address register” to the "immediate value". It is an instruction that increments by the amount.
  • the instruction 52 is an instruction that first increments the value stored in the "address register” by the “immediate value” and writes the value of the "SRC register” to the memory 3 of the address of the incremented value.
  • the instructions 51 and 52 are instructions that perform different processing because the timing of incrementing the value stored in the "address register" by the "immediate value" is different.
  • the character string following the mnemonic is "SRC register, [address register], immediate value”
  • the character string is "SRC register, [address register, immediate value]!. It has become.
  • the assembler distinguishes between the two based on such a difference in character strings, and inside the assembler, the mnemonic of the instruction 51 is read as "STRpost", and the mnemonic of the instruction 52 is read as "STRpre".
  • FIG. 17A is a diagram schematically showing the command information 33 of the first embodiment when these mnemonics “STRpost” and “STRpre” are adopted.
  • FIG. 17B is a diagram showing the mnemonic function generated according to the first embodiment based on the instruction information 33.
  • the mnemonic function STRpost corresponding to the instruction 51 and the mnemonic function STRpre corresponding to the instruction 52 are generated.
  • the developer remembers the function names "STRpost” and "STRpre” and describes them in the source file for the application program.
  • the function name of the mnemonic function is suppressed from increasing as follows.
  • FIG. 18 is a diagram schematically showing the instruction information 33 used in the present embodiment.
  • the function name, the mnemonic, the number of operands, and the type of the operand are stored in association with each other.
  • Each line of the instruction information 33 corresponds to a different instruction, for example, the first line corresponds to the mov instruction and the second line corresponds to the load instruction.
  • the instruction information 33 is created in advance by the developer.
  • the function name is the name of the mnemonic function, and the name corresponding to each mnemonic is stored.
  • the function name corresponding to these instructions is "STR".
  • the number of operands is the number of operands taken by each instruction, as in the first embodiment.
  • the operand type is a list of types indicating the type of instruction operand.
  • the first operand is a register and the second operand is an immediate value.
  • a Register type indicating a register and an Immediate type indicating an immediate value are defined in advance, and a list of these types is stored in the instruction information 33 in advance in association with the mnemonic “mov”.
  • the first component of the list indicates the type of the first operand, and the second component indicates the type of the second operand.
  • the third component of the list indicates the type of the third operand.
  • the argument types of the mnemonic function STR corresponding to the mnemonic "STRpost" are Register type and PostIncAddrReg type.
  • the argument types of the mnemonic function STR corresponding to the mnemonic "STRpre” are the Register type and the PreIncAddrReg type.
  • the number of operands of the mnemonic "STRpost" is "3" as shown in FIG. 17 (a), whereas in the present embodiment, the number is as shown in FIG. It becomes “2".
  • the PostIncAddrReg type has two members as described later, and the second and third operands of the STRpost instruction can be stored in these members.
  • the PreIncAddrReg type also has two members, and since the second and third operands of the STRpre instruction can be stored in these members, the number of operands corresponding to "STRpre" is also "2".
  • 19 (a) to 19 (e) are diagrams showing an example of C ++ pseudo source code that defines the type of the operand.
  • Figure 19 (a) is an example of the source code that defines the Register type.
  • the Register type is a type indicating a register as described above.
  • the class name of the class that defines the Register type is "Reg”
  • the members of that class are "regIndex”.
  • “RegIndex” is a variable that stores the index of the register, and is declared as, for example, an unsigned integer type.
  • Figure 19 (b) is an example of the source code that defines the AddrReg type.
  • the AddrReg type is a type indicating an address register.
  • the members of the class "AddrReg” representing the AddrReg type are "regIndex" that stores the index of the register that holds the base value of the address and "imm_value” that stores the immediate value that is the address offset value.
  • the initial value of "imm_value” is 0.
  • Figure 19 (c) is an example of the source code that defines the PostIncAddrReg type.
  • the members of the PostIncAddrReg type class are "regIndex”, which stores the index of the register that holds the base value of the address, and "imm_value”, which stores the immediate value that indicates how much the base value of the address is incremented after the instruction is executed. ..
  • FIG. 19 (d) is an example of the source code that defines the PreIncAddrReg type.
  • the members of the PreIncAddrReg type class are "regIndex” that stores the index of the register that holds the base value of the address and "imm_value” that stores the immediate value that indicates how much the base value of the address is incremented before executing the instruction. is there.
  • Figure 19 (e) is an example of the source code that defines the Immediate type.
  • the Immediate type is a type that shows an immediate value as described above.
  • the class name of the class that defines the Immediate type is "Imm”, and the members of that class are "imm_value”.
  • Imm_value is an integer type variable that stores an immediate value.
  • FIG. 20A is a schematic diagram of the source file 34 in which the C ++ pseudo source code of the mnemonic function STR corresponding to the mnemonic "STRpost" is described.
  • the source code of this mnemonic function STR is generated by the control unit 31 based on the instruction information 33 as follows.
  • the function name corresponding to the mnemonic "STRpost" is "STR"
  • the control unit 31 sets the function name 53a of this mnemonic function to "STR”.
  • control unit 31 identifies that the number of operands of the mnemonic "STRpost" is "2" by referring to the instruction information 33, and sets two variables "OP0" and "OP1_2" in the code T11. Declare as an argument.
  • control unit 31 specifies that the operand types of the mnemonic "STRpost" are the Register type and the PostIncAddrReg type by referring to the instruction information 33. Based on this, the control unit 31 declares each type of each variable "OP0" and "OP1_2" as a Register type and a PostIncAddrReg type in the code T11.
  • control unit 31 generates codes T12 to T15 inside this mnemonic function STR.
  • the code T12 is a statement that assigns the mnemonic "STRpost" of the instruction information 33 to the variable "nm". Further, the control unit 31 specifies the number of variables to be included in the argument "oplist" of the MachineCodeEmitter function based on the Register type and the PostIncAddrReg type specified from the instruction information 33. For example, the Register type has one member variable, and the PostIncAddrReg type has two member variables, so the total number of member variables of these types is three. Therefore, the control unit 31 generates code T13 that declares three Operand type variables "op0", "op1", and "op2" corresponding to the three members. Of these, the variable "op0" corresponds to the Register type variable "OP0".
  • the variables "op1" and "op2" are two variables corresponding to the PostIncAddrReg type variable "OP1_2".
  • the number of member variables of each of the Register type, AddrReg type, PostIncAddrReg type, PostIncAddrReg type, and Immediate type may be defined in advance in the source file that defines each class in FIG.
  • the code T14 is a code that converts each of the variables "OP0" and "OP1_2" received as arguments by the mnemonic function STR into the type of the argument "oplist" of the MachineCodeEmitter function.
  • Code T15 is a code that calls the MachineCodeEmitter function and writes the machine language generated by the MachineCodeEmitter function to the memory 3 by the function write.
  • each of the variables "OP0" and “OP1_2” received as arguments by the mnemonic function STR is converted into an Operand type array "oplist" in code T14. Therefore, the types of the variables "OP0" and “OP1_2” can be matched with the type of the second argument "oplist" of the MachineCodeEmitter function, and the MachineCodeEmitter function can generate the machine language intended by the developer.
  • FIG. 20B is a schematic diagram of the source file 34 in which the C ++ pseudo source code of the mnemonic function STR according to the present embodiment corresponding to the mnemonic "STRpre" is described.
  • control unit 31 Similar to the example of FIG. 20A, the control unit 31 also generates the source code of this mnemonic function STR based on the instruction information 33.
  • the function names in FIGS. 20 (a) and 20 (b) are the same in "STR", these functions are C ++ because the types of the second arguments of these functions are different. It does not matter because it is grammatically distinguished as separate functions.
  • a mnemonic function having the same function name can be generated from these mnemonics. .. Therefore, it is possible to prevent the function name of the mnemonic function from increasing, and it is possible to suppress the increase in the function name that the developer should remember.
  • this embodiment also has the advantage of facilitating debugging as follows.
  • FIG. 21A is a diagram showing a C ++ pseudo source code 55 of the mnemonic function mov when the argument of the mnemonic function is represented by a common type called Operand type, unlike the present embodiment.
  • the type conversion code as in this embodiment is not described inside the mnemonic function mov.
  • FIG. 21B is a diagram showing a C ++ pseudo source code of the source file 41 for the application program written by the developer using this mnemonic function mov.
  • the developer notices the error in the source code of the source file 41 only after recognizing that the result obtained by the output is different from the original result. become. Also, if the developer does not notice that the result is strange, the developer will overlook the error as if the correct output is obtained as it is. Furthermore, even if the developer notices that the output is strange, if the number of lines described in the source file 41 is large, it takes time for the developer to identify the part where the description is incorrect, and it takes a long time to debug. It takes time.
  • FIG. 22A is a schematic diagram of the source file 34 in which the C ++ pseudo source code of the mnemonic function mov generated in the present embodiment is described.
  • the argument type of the mnemonic function mov is ⁇ Register type, Immediate type ⁇ .
  • FIG. 22B is a diagram showing an example of C ++ pseudo source code of the source file 41 for the application program written by the developer using this mnemonic function mov.
  • FIG. 23 is a flowchart showing a function generation method according to the present embodiment.
  • the first generation unit 36 refers to the instruction information 33 and acquires the corresponding function names, mnemonics, the number of operands, and the types of the operands (step S20).
  • the first generation unit 36 generates an empty mnemonic function and describes it in the source file 34 (step S21).
  • the number of arguments of the mnemonic function is the number of operands acquired in step S20.
  • the first generation unit 36 generates code T11 (see FIG. 20A) that declares the argument type of the mnemonic function in the operand type acquired in step S20.
  • the second generation unit 37 generates a code that converts the variable type received as an argument by the mnemonic function into the Operand type of the array "oplist" which is the second argument of the MachineCodeEmitter function (step S22). For example, the second generation unit 37 generates the code T14 described in FIG. 20 and describes it inside the mnemonic function.
  • the second generation unit 37 generates a code that calls the MachineCodeEmitter function (step S23). For example, the second generation unit 37 generates the code "graCodeEmitter (nm, oplist);" that calls the MachineCodeEmitter function, and describes it inside the mnemonic function. At this time, the second generation unit 37 passes the array "oplist" after the type conversion in step S22 to the second argument of the chelCodeEmitter. At the same time, the second generation unit 37 also describes in the source file 34 a statement for declaring and substituting variables such as the codes T11 and T12 in FIG.
  • the third generation unit 38 generates a code for writing the machine language generated by the MachineCodeEmitter function to the memory 3, and describes it in the source file 34 (step S24).
  • the third generation unit 38 describes the code "write (MachineCodeEmitter (nm, oplist));" in which the MachineCodeEmitter function is described in the argument of the function write in the source file 34.
  • step S25 the processes of steps S20 to S24 are performed for all the lines included in the instruction information 33.
  • the output unit 39 writes the source file 34 including all the mnemonic functions to the storage unit 32 (step S25).
  • step S21 the first generation unit 36 generates code T11 (see FIG. 20A) that declares the argument type of the mnemonic function as the operand type.
  • code T11 see FIG. 20A
  • the function names of a plurality of mnemonic functions can be made the same, so that it is possible to prevent the number of function names that the developer should remember from increasing.
  • FIG. 24A is a diagram showing an example of a source file 34 in which the C ++ source code of the mnemonic function mov generated according to the second embodiment is described.
  • this source code there are restrictions on the types such as Register type and Immediate type for the arguments OP0 and OP1, but there are no restrictions on the argument values themselves.
  • FIG. 24B is a diagram showing an example of C ++ pseudo source code of the source file 41 for the application program written by the developer using this mnemonic function mov.
  • the value of the second operand of the mov instruction is limited to the range of -256 to +255, so the value "-1000000” is an inappropriate value as the second argument.
  • the developer is made to notice the error of the source code in the source file 41 as follows.
  • FIG. 25 is a diagram schematically showing the instruction information 33 used in the present embodiment.
  • the function name, the mnemonic, the number of operands, the type of the operand, and the restrictions imposed on the operands are stored in association with each other. Similar to the first and second embodiments, the instruction information 33 is created in advance by the developer.
  • each line of the instruction information 33 corresponds to a different instruction.
  • the first line corresponds to the mov instruction, and the restrictions imposed on the operands are expressed in the list format ⁇ register index range is 0 to 31, and immediate value range is -256 to +255 ⁇ .
  • the first component of the list represents a restriction on the first operand, and the second component represents a restriction on the second operand. If the instruction takes a third operand, the restrictions on that third operand are stored in the third component of the list.
  • the second line of the instruction information 33 corresponds to the shiftR instruction, and the restrictions imposed on the operands are ⁇ register index range 0 to 31, register index range 0 to 31, and immediate value range. It becomes -63 to +63 ⁇ .
  • FIG. 26 is a schematic diagram showing an example of C ++ pseudo source code of the source file 34 in which the mnemonic function mov according to the present embodiment corresponding to the mov instruction is described.
  • the source code of this mnemonic function mov is generated by the control unit 31 based on the instruction information 33 as follows.
  • control unit 31 describes the codes T11 to T15 in the mnemonic function mov in the same manner as in the second embodiment. Further, the control unit 31 acquires the limit imposed on the operand for each instruction by referring to the instruction information 33. For example, in the case of the mov instruction, the control unit 31 acquires a limit of ⁇ the register index range is 0 to 31, and the immediate value range is -256 to +255 ⁇ .
  • control unit 31 generates a code T16 that raises an exception when the operand represented by the argument of the mnemonic function mov violates the above restriction, and describes it in the source file 34.
  • the if statement determines whether the operand violates the restriction, and if so, the throw statement generates an exception. For example, if the value of regIndex of "OP0" is not in the range of 0 to 31, the error message "" Invalid register index is passed to mov mnemonic function. "" Is output to the standard output when the program is executed. .. If the value of "OP1" is not in the range of -256 to +255, the error message "" Invalid immediate value is passed to mov mnemonic function. "” Is output to the standard output when the program is executed. Will be done.
  • FIG. 27 is a diagram showing an example of C ++ pseudo source code of the source file 41 for the application program written by the developer using this mnemonic function mov.
  • the value of the second operand of the mov instruction is limited to the range of -256 to +255. Therefore, when the statement "mov (reg0, imm0);” is executed, an exception occurs and the character string "" Invalid immediate value is passed to mov mnemonic function. "" Is output to the standard output.
  • the developer can notice that the argument of the mnemonic function mov violates the limitation of the mov instruction, and can easily debug the source code 66.
  • FIG. 28 is a flowchart showing a function generation method according to the present embodiment.
  • the first generation unit 36 refers to the instruction information 33 and acquires the corresponding function name, mnemonic, number of operands, operand type, and restrictions imposed on the operands (step S30).
  • the first generation unit 36 generates an empty mnemonic function and describes it in the source file 34 (step S31).
  • the number of arguments of the mnemonic function is the number of operands acquired by the acquisition unit 35 in step S30.
  • the type of the argument is the type of the operand acquired by the acquisition unit 35 in step S30.
  • the second generation unit 37 generates a code that raises an exception when the operand corresponding to the variable received by the mnemonic function as an argument violates the restriction (step S32). For example, the second generation unit 37 generates the code T16 described in FIG. 26 and describes it inside the mnemonic function.
  • the second generation unit 37 generates a code for converting the variable type received as an argument by the mnemonic function into an operand type array which is the second argument of the MachineCodeEmitter function (step S33).
  • the second generation unit 37 describes the code T14 described in FIG. 26 inside the mnemonic function.
  • the second generation unit 37 generates a code that calls the MachineCodeEmitter function (step S34). For example, the second generation unit 37 describes the code "MICodeEmitter (nm, oplist)" inside the mnemonic function. At the same time, the second generation unit 37 also describes in the source file 34 a statement for declaring and substituting variables such as the codes T12 and T13 in FIG.
  • the third generation unit 38 generates a code for writing the machine language generated by the MachineCodeEmitter function to the memory 3 (step S35).
  • the third generation unit 38 describes in the source file 34 the code “write (MachineCodeEmitter (nm, oplist));” in which the MachineCodeEmitter function is described in the argument of the function write.
  • step S36 the processes of steps S30 to S35 are performed for all the lines included in the instruction information 33.
  • the output unit 39 writes the source file 34 including all the mnemonic functions to the storage unit 32 (step S36).
  • step S32 the second generation unit 37 generates code T16 (see FIG. 26) that raises an exception when the operand violates the restriction. Therefore, the developer can notice the error in the source code 66 (see FIG. 27) at an early stage, and the man-hours required for the developer to debug can be reduced. Moreover, the time to wastefully execute the buggy program on the target machine 1 can be reduced, and the wasteful consumption of the hardware resources of the target machine 1 can be improved.
  • the types of "limitation imposed on the operand" of the instruction information 33 are (1) “the register index is within a specific range", (2) “the immediate value is within a specific range”, and (3). ) "Immediate value is an integer”, (4) "Immediate value is a decimal” and so on.
  • the data format of the instruction information 33 acquired by the control unit 31 is a number (1) to (4) of the type of "limit imposed on the operand", an upper limit value of the limit, and a lower limit value of the limit. It becomes a form to have.
  • a template of the code for checking the violation of the operand corresponding to (1) to (4) may be prepared in advance, and in step S32, the control unit 31 may refer to the required template. Further, in the case where it is necessary to check the upper limit value and the lower limit value of the limit, the control unit 31 may generate a code that generates an exception by embedding these values in the template.
  • FIG. 29 (a) and 29 (b) are diagrams showing the syntax of the assembly of the add instruction. There are various types of add instructions that take various operands, but FIG. 29 (a) illustrates an add instruction that uses a "DST register” and two "SRC registers" as operands. This add instruction is an instruction to store the value obtained by adding the contents of the two "SRC registers" in the "DST register".
  • FIG. 29 (b) is a diagram illustrating an add instruction that takes three operands of "DST register", "SRC register", and "immediate value".
  • This add instruction is an instruction to store the value obtained by adding the "immediate value” to the contents of the "SRC register” in the "DST register".
  • FIG. 30 is a diagram schematically showing command information 33 according to the present embodiment.
  • the instruction information 33 stores the function name, the mnemonic, the number of operands, the type of the operand, and the restrictions imposed on the operands in association with each other according to the third embodiment.
  • the function name is represented by uppercase letters.
  • the instruction information 33 is created in advance by the developer.
  • the control unit 31 Since the two function names "ADD" are stored in the instruction information 33 corresponding to the two add instructions in FIGS. 29 (a) and 29 (b), the control unit 31 has two mnemonics according to the third embodiment.
  • the function ADD will be generated.
  • the mnemonic function ADD corresponding to the second line of the instruction information 33 will be described as an example.
  • the operand type of this mnemonic function ADD is ⁇ Register type, Register type, Immediate type ⁇ .
  • the restrictions imposed on the first operand and the second operand are both "the index range of the register is 0 to 31".
  • the restriction imposed on the third operand is "the range of immediate values is -1024 to +1023".
  • FIG. 31 is a diagram showing an example of the source code of the mnemonic function ADD generated by the control unit 31 according to the third embodiment based on the instruction information 33.
  • control unit 31 generates the source file 34 whose file name is "mnemonic.h", and the description of the mnemonic function ADD starts from the 20th line of the source file 34.
  • this source file 34 the same type of code as described in the third embodiment is designated by the same reference numerals as those in the third embodiment, and the description thereof will be omitted.
  • code T11 to T16 described in the third embodiment are generated by the control unit 31.
  • code T16 is a code that raises an exception when the operand represented by the argument of the mnemonic function ADD violates the restriction in the instruction information 33.
  • control unit 31 generates the code T17 that calls the function "SET ()" on the 21st line of the source file 34.
  • FIG. 32 is a diagram schematically showing a C ++ pseudo source code that defines the function "SET ()".
  • control unit 31 The definition of the function "SET ()" is described by the control unit 31 in a part of the source file 34, mnemonic.h.
  • control unit 31 generates the codes T20 to T22 for defining the function "SET ()" in the source file 34.
  • code T20 is the code that declares the macro of the function "SET ()".
  • the function "SET ()” is defined as being replaced by the function "setCodeInfo (__FILE__, __LINE___, __func__)" by the preprocessor.
  • variables "__FILE__” and “__LINE___” that appear in the arguments of the function "setCodeInfo” are predefined macros in C ++, and the variables “__func__” are predefined identifiers in C ++. These variables are converted to their desired contents by the preprocessor at compile time. For example, “__FILE__” is converted to the file name of the file in which the "__FILE__” is described. Also, “__LINE__” is converted to the line number in which the "__LINE__” is described. Then, “__func__” is converted into the function name of the function in which the "__func__” is described.
  • the code T21 is a code that defines the char type global variables "g_filename” and "g_funcname” and the int type global variable "g_line”.
  • code T22 is the code that defines the contents of the function "setCodeInfo".
  • the function "setCodeInfo” is defined as a function that takes three arguments “filename”, “line”, and “funcname” and assigns each to the global variables "g_filename”, "g_line”, and "g_funcname”.
  • the preprocessor replaces "SET ()" with "setCodeInfo (__FILE__, __LINE___, __func__)” at the position of code T17 in the source file 34 (see FIG. 31). Further, the preprocessor replaces "__FILE__” with the character string "mnemonic.h” which is the file name of the calling source file 34, and “__LINE__” is the line number of the function "SET ()" in the source file 34. Replace with "21”. The preprocessor also replaces "__func__” with the function name "ADD" of the mnemonic function ADD, which is the function that called the function "SET ()”.
  • FIG. 33 is a diagram schematically showing a pseudo source code of a source file 41 for an application program written by a developer in C ++.
  • the file name of the source file 41 is "sample.cpp" and the developer describes the codes T25 to T28 in the source file 41.
  • code T25 is a statement that defines each variable of "reg0", “reg1", and "imm0". Of these, the variables "reg0" and “reg1” are defined as Reg type. The variable “imm0” is defined as Imm type.
  • the code T26 is a statement that assigns a value to each variable member of "reg0", “reg1", and "imm0".
  • "0" is assigned to the member “regIndex” of the variable "reg0”
  • "1” is assigned to the member “regIndex” of the variable "reg1”.
  • "100000” is assigned to the member "value" of the variable "imm0”.
  • the code T27 is a code that calls the mnemonic function ADD and passes the contents of the above variables "reg0", “reg1", and "imm0” to its arguments.
  • the developer writes the code T27 inside the try statement to handle the exception.
  • the value "100000” is assigned to the variable "imm0”, but according to the instruction information 33 (see FIG. 30), the possible values of the third argument of the mnemonic function add are -1024 to +1023. Limited to range. Therefore, executing this mnemonic function ADD throws an exception in code T16 (see FIG. 31).
  • code T28 is a code to output the contents of each global variable "g_filename", "g_line”, and "g_filename” to the standard output when an exception is thrown in this way.
  • "mnemonic.h”, “22”, and “ADD” are stored in each of "g_filename”, “g_line”, and “g_filename”, so these are output to the standard output. Will be.
  • the program group 42 may build according to the process of FIG. 13 described in the first embodiment.
  • FIG. 34 is a diagram showing an output example to the standard output when the executable program 44 generated in this way is executed on the target machine 1 (see FIG. 1).
  • the third argument of the mnemonic function ADD in the source file 41 does not satisfy the limitation specified in the instruction information 33. Therefore, the error message 74 "Invalid immediate value of OP2 is passed to add mnemonic function." In the code T16 (see FIG. 31) is output to the standard output. Further, a message 75 indicating the contents of each global variable "g_filename", "g_line”, and "g_funcname" in the code T28 (see FIG. 33) is also output to the standard output.
  • the developer can notice that the argument of the mnemonic function ADD is erroneously specified somewhere in the program written by himself / herself based on the error message 74 and the message 75.
  • the file name "mnemonic.h” of the source file 34 that defines the mnemonic function ADD is output instead of the file name "sample.cpp" of the erroneous source file 41. ..
  • the number of lines and the function name in the message 75 are not the number of lines and the function name in the source file 41 (sample.cpp) but the number of lines and the function name in the source file 34 (mnemonic.h). It is output.
  • the present embodiment facilitates debugging by the developer as follows.
  • FIG. 35 is a functional configuration diagram of the information processing device 30 according to the present embodiment.
  • the same elements as described in the first to third embodiments are designated by the same reference numerals as those in these embodiments, and the description thereof will be omitted below.
  • control unit 31 of the information processing apparatus 30 has a fourth generation unit 80 and a definition file generation unit in addition to the first to third generation units 36 to 38 and the output unit 39 described above. Has 81 and.
  • FIG. 36 is a schematic diagram showing a C ++ pseudo source code of the mnemonic function ADD generated by the control unit 31 in this embodiment.
  • the control unit 31 generates a source file 34 whose file name is "mnemonic.h", and the control unit 31 generates a mnemonic function ADD in the source file 34.
  • the first generation unit 36 generates the code T11 as an argument of the mnemonic function ADD in the same manner as in the first embodiment.
  • the code T11 is a code that declares the types of the arguments "OP0", "OP1", and "OP2" corresponding to the three operands of the instruction add.
  • the first generation unit 36 describes the code T18 at the first position among the plurality of arguments of the mnemonic function ADD.
  • Code T18 is the code that defines the types of the "strFile", “line”, and “strFunc” variables.
  • “strFile” is a character string type variable for storing the file name.
  • “line” is an integer type variable for storing the number of lines in a file.
  • “strFunc” is a character string type variable for storing the function name.
  • the order in which the variables "strFile", “line”, and “strFunc” in the code T18 are described is not particularly limited. The first generator 36 may describe these variables in code T18 in any order.
  • control unit 31 generates other codes T12 to T16 in the source file 34 in the same manner as in the third embodiment.
  • the fourth generation unit 80 generates the code T17 in the source file 34. Similar to the example of FIG. 31, code T17 is a code that calls the function "SET ()". Further, the fourth generation unit 80 generates a code that defines the processing of the function "SET ()" in a part of the source file 34.
  • FIG. 37 is a diagram showing an example of C ++ pseudo source code of the function “SET ()” generated by the fourth generation unit 80 in the present embodiment.
  • each of the codes T21 and T22 is a code that assigns each argument of the function "setCodeIndo" to each of the global variables "g_filename”, “g_funcname”, and "g_line” as in the example of FIG.
  • the definition file generation unit 81 (FIG. 35) is a processing unit that generates the definition file 82 illustrated in FIG. 38.
  • FIG. 38 is a schematic diagram showing a pseudo source code of the definition file 82 generated by the definition file generation unit 81.
  • the definition file 82 has a plurality of macros starting with "#define". These macros are generated by the definition file generation unit 81 so as to correspond to each of the mnemonic functions.
  • Each macro is a macro that gives an instruction to the preprocessor to add a new variable to the argument of each mnemonic function in the source file for the application program described by the developer. This will be described by taking the source file of FIG. 39 as an example.
  • FIG. 39 is a diagram showing C ++ pseudo code of the source file 41 for the application program described by the developer in this embodiment.
  • the same code as described in FIG. 33 is designated by the same reference numeral as in FIG. 33, and the description thereof will be omitted below.
  • the developer describes the function name of the mnemonic function in lowercase letters of the alphabet.
  • the developer describes the code T27 that calls the mnemonic function on the 101st line as "add (reg0, reg1, imm0)".
  • the value "100000” is assigned by the code T26 to the member "value” of the third argument "imm0" of the mnemonic function add in the code T27.
  • This value is an inappropriate value that does not satisfy the limitation of "-1024 to 1023" in the instruction information 33 (see FIG. 30).
  • this macro instructs the preprocessor to replace the function name "add” of the mnemonic function add in the source file 41 with "ADD".
  • this macro tells the preprocessor to add each of the new arguments "__FILE__”, “__LINE__”, and “__func__” before the argument of the mnemonic function add.
  • “__VA_ARGS__” is a predefined identifier indicating a variable length argument in which the argument of the mnemonic function add is stored.
  • each of "__FILE__”, “__LINE___”, and “__func__” is a C ++ predefined macro or identifier that is replaced with a file name, line number, and function name.
  • the preprocessor replaces each of these predefined macros and predefined identifiers with filenames, line numbers, and function names.
  • the file name and line number are examples of function information related to the mnemonic function add. Therefore, the file name, line number, and function name in which the mnemonic function "add" is described are passed as arguments of the mnemonic function "ADD".
  • the definition file generation unit 81 generates such a definition file 82 by referring to the instruction information 33 (see FIG. 30), and stores it in the storage unit 32.
  • the definition file generation unit 81 reads the instruction information 33 line by line, acquires the function name, and generates a directive for each function name. If the acquired function name is SUB, the definition file generation unit 81 will generate the directive "#define subcutaneous SUB (__FILE__, __LINE__, __func__, __VA_ARGS__)" in the definition file 82.
  • FIG. 40 is a schematic diagram showing a development environment according to the present embodiment.
  • FIG. 40 the same elements as described in FIG. 13 of the first embodiment are designated by the same reference numerals as those in the first embodiment, and the description thereof will be omitted below.
  • control unit 31 generates the mnemonic function source file 34 and the definition file 82.
  • the developer creates the source file 41 for the application program using C ++.
  • a case where the developer creates a source file 41 whose file name is "sample.cpp" as shown in FIG. 39 and describes the code T27 that calls the mnemonic function and on the 101st line of the source file 41 will be described. ..
  • the compiler, assembler, and linker program group 42 builds.
  • the preprocessor included in the compiler first reads the source files 34, 41, 43 and the definition file 82.
  • the binary format execution library file 43a in which the machine language generation function is described may be used instead of the source file 43 in which the MachineCodeEmitter function is described.
  • the preprocessor replaces "add (reg0, reg1, imm0);” on the 101st line of the source file 41 with "ADD (__FILE__, __LINE__, __func__, reg0, reg1, imm0);” according to the definition file 82. ..
  • the preprocessor further stores the contents at the time when the 101st line of the source file 41 is executed in each of "__FILE__”, “__LINE__”, and "__func__”. Therefore, "sample.cpp" which is the file name of the source file 41 is stored in "__FILE__”. Further, in “__LINE__”, the line number "101" in which the mnemonic function add is described in the source file 41 is stored. Further, "__func__” stores the function name "func0" after being replaced by the preprocessor.
  • the compiler generates an assembly file
  • the assembler converts the assembly file into a machine language instruction sequence to generate an object file.
  • the linker After that, the linker generates a binary-format executable program 44 that can be executed by the processor 2 (see FIG. 1) by linking the object file with various libraries.
  • FIG. 41 is a diagram showing an output example to the standard output when the executable program 44 generated in this way is executed on the target machine 1 (see FIG. 1).
  • the third argument of the mnemonic function ADD in the source file 41 does not satisfy the limitation specified in the instruction information 33. Therefore, the error message 84 "Invalid immediate value of OP2 is passed to add mnemonic function.” In the code T16 (see FIG. 36) is output to the standard output.
  • the message 85 "file name: sample.cpp, line: 101, function name: func0" including these contents is output to the standard output.
  • the message 85 includes the file name "sample.cpp" of the source file 41 for the application program written by the developer, the number of lines "101" in which the error occurred in the source file 41, and the function in which the error occurred. Contains the name "func0".
  • the developer can specify the file name of the source file 41 in which the error has occurred and the position where the error has occurred in the source file 41, which makes it easy for the developer. Can be debugged. As a result, the time required for debugging can be shortened, and program development can be made more efficient.
  • FIG. 42 is a schematic diagram showing an example of C ++ pseudo source code of the source file 41 according to another example of the present embodiment.
  • the developer describes the mnemonic function ADD in the source file 41, and describes the predefined macros and the predefined identifiers of "__FILE__”, “__LINE__”, and "__func__” in the arguments. ..
  • the file name of the source file 41 in which the mnemonic function ADD is described is stored in "__FILE__”.
  • the line number in which the mnemonic function ADD is described in the source file 41 and the function name of the function func0 including the description are stored in "__LINE__” and "__func__”, respectively.
  • the definition file generation unit 81 automatically generates the definition file 82, so that such complexity can be avoided and the burden on the developer can be reduced.
  • the code T18 indicating the argument of the mnemonic function ADD is described in the position before the code T11 in the source file 34, but the code T18 is changed to the code T11 in the reverse order. It is also conceivable to describe it in the position behind. In this case, the macro corresponding to the mnemonic function ADD also reverses the order of the arguments and becomes "#define add strings ADD (__VA_ARGS__, __FILE__, __LINE___, __func__)". However, such a description causes the following inconveniences.
  • 43 (a) and 43 (b) are diagrams schematically showing such inconveniences.
  • the instructions included in the instruction set include instructions with the same mnemonic but different numbers of operands.
  • the add instruction is one such instruction, and the add instruction which takes three register type operands and the add instruction which takes a total of four operands of three register type and one immediate value type are The case where it exists will be described.
  • the add instruction that takes three register-type operands is an instruction that adds the values of the registers specified by the second and third operands and stores the result in the register specified by the first operand.
  • the add instruction that takes a total of four operands, three register types and one immediate value type is an instruction that adds the values of the registers specified by the second and third operands.
  • the result of the addition is added to the immediate value specified in the third operand, and the result is stored in the first operand.
  • the former add instruction can be considered as a case where the immediate value of the latter add instruction is "0".
  • FIG. 43A in which the compilation is successful, will be described first.
  • the developer describes the code “add (x1, x2, x3, imm)" in the source file 41 for the application program.
  • the code “add (x1, x2, x3, imm)” corresponds to the add instruction that takes four operands.
  • this code after replacement calls the definition of the function ADD in the source file 34.
  • the types of each of the seven arguments of the function ADD in the source file 34 match "ADD (x1, x2, x3, imm, __FILE__, __LINE__, __func__)". Therefore, the compilation will be successful.
  • FIG. 43B is a schematic diagram illustrating a case where compilation fails.
  • the developer describes the code "add (x1, x2, x3)" including three arguments corresponding to the add instruction having three operands in the source file 41.
  • the macro "#define add
  • ADD (__VA_ARGS___, __FILE__, __LINE__, __func__)" in the definition file 82 causes the preprocessor to add the above code to "ADD (x1, x2, x3, __FILE__, __LINE__, __LINE__,)". Replace with "_func__)". Then, this code after the replacement calls the definition of the function ADD in the source file 34.
  • the first generation unit 36 describes the function information such as the file name at the first position among the plurality of arguments of the mnemonic function ADD. It is preferable to write the code T18.
  • the preprocessor uses the macro "#define add (..) ADD (__ FILE__, __LINE__, __func__, __VA_ARGS__)" in the definition file 82 to "ADD (__FILE__, __LINE__, __func__, x3, x2). ) ”.
  • the compiler makes it a C ++ grammar that the call to the ADD function with 6 arguments is a call that omits the 7th argument in the definition of the function ADD with 7 arguments in the source file 34. It can be recognized immediately.
  • the six arguments that are not omitted are string type, integer type, string type, register type, register type, and register type, respectively, which is the first of the ADD functions defined in the source file 34. Matches the types of 6 arguments. Therefore, the above description "add (x1, x2, x3)" can be compiled without error.
  • FIG. 44 is a flowchart showing a method of generating a definition file according to the present embodiment.
  • the definition file generation unit 81 acquires the function name from the instruction information 33 (see FIG. 30) (step S40), and generates the macro #define corresponding to the function name (step S41). For example, consider the case where the definition file generation unit 81 acquires the function name "ADD" on the first line of the instruction information 33. In this case, the definition file generation unit 81 generates a macro "#define add defined ADD (__FILE__, __LINE___, __func__, __VA_ARGS__)".
  • the definition file generation unit 81 repeats steps S40 and S41 for each line of the instruction information 33 (see FIG. 30).
  • the above macro "#define add defined ADD (__FILE__, __LINE__, __func__, __VA_ARGS__)" is all functions except the function name "add” before replacement and the function name "ADD" after replacement. Same format for names. Therefore, when the function names are the same, the macros are also the same. Therefore, when the function names are duplicated, the definition file generation unit 81 performs steps S40 and S41 from the next function name of the instruction information 33. repeat.
  • the definition file generation unit 81 writes the definition file 82 in which the macros corresponding to all the function names in the instruction information 33 are described to the storage unit 32 (step S42).
  • FIG. 45 is a hardware configuration diagram of the information processing device 30 according to the first to fourth embodiments.
  • the information processing device 30 includes a storage device 30a, a memory 30b, a processor 30c, a communication interface 30d, a display device 30e, and an input device 30f. Each of these parts is connected to each other by a bus 30 g.
  • the storage device 30a is a non-volatile storage device such as an HDD or SSD (Solid State Drive), and stores the function generation program 90 according to the present embodiment.
  • the function generation program 90 may be recorded on a computer-readable recording medium 30h, and the processor 30c may be made to read the function generation program 90 on the recording medium 30h.
  • Examples of such a recording medium 30h include a physically portable recording medium such as a CD-ROM (Compact Disc-Read Only Memory), a DVD (Digital Versatile Disc), and a USB (Universal Serial Bus) memory. Further, a semiconductor memory such as a flash memory or a hard disk drive may be used as the recording medium 30h. These recording media 30h are not temporary media such as a carrier wave having no physical form.
  • a physically portable recording medium such as a CD-ROM (Compact Disc-Read Only Memory), a DVD (Digital Versatile Disc), and a USB (Universal Serial Bus) memory.
  • a semiconductor memory such as a flash memory or a hard disk drive may be used as the recording medium 30h.
  • These recording media 30h are not temporary media such as a carrier wave having no physical form.
  • the function generation program 90 may be stored in a device connected to a public line, the Internet, a LAN (Local Area Network), or the like, and the processor 30c may read and execute the function generation program 90.
  • the memory 30b is hardware that temporarily stores data such as DRAM, on which the above-mentioned function generation program 90 is deployed.
  • the processor 30c is hardware such as a CPU (Central Processing Unit) and a GPU (Graphical Processing Unit) that controls each part of the information processing device 30 and executes a function generation program 90 in cooperation with the memory 30b. ..
  • the function generation program 90 By executing the function generation program 90 in cooperation with the memory 30b and the processor 30c in this way, the first generation unit 36, the second generation unit 37, the third generation unit 38, and the output of FIG. 11 A control unit 31 including the unit 39 is realized. Further, the fourth generation unit 80 and the definition file generation unit 81 in FIG. 35 are also realized by executing the function generation program 90 in cooperation with the memory 30b and the processor 30c. Further, each of the storage units 32 of FIGS. 11 and 35 is realized by the storage device 30a and the memory 30b.
  • the communication interface 30d is an interface for connecting the information processing device 30 to a network such as a LAN.
  • the display device 30e is hardware such as a liquid crystal display device, and displays a prompt prompting the developer to input various information, an error message at compile time, and the like.
  • the input device 30f is hardware such as a keyboard and a mouse. For example, the developer operates the input device 30f to instruct the information processing device 30 to execute compilation.

Landscapes

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

Abstract

命令に関する命令情報を記憶した記憶部32を参照して、命令に対応した関数であって、命令のオペランドを表す引数OP0、OP1を受け取る第1の関数を生成する処理S11と、引数が表すオペランドに対して命令が行う処理を表す機械語を返す第2の関数を呼び出すコードを第1の関数の内部に生成する処理S12と、機械語をメモリ3に書き込むコードを第1の関数の内部に生成する処理S13とをコンピュータに実行させるための関数生成プログラム。

Description

関数生成プログラム、関数生成方法、及び情報処理装置
 本発明は、関数生成プログラム、関数生成方法、及び情報処理装置に関する。
 プログラムの実行速度を高速化する技術の一つとしてJIT(Just In Time)コンパイラ技術がある。JITコンパイラ技術とは、実行時に決定されるパラメータ、処理内容、及びプロセッサの状況に応じて、好適な機械語の命令列を生成する技術を言う。JITコンパイラ技術を用いて生成した機械語の命令列は、AOT(Ahead Of Time)型のコンパイラが生成する汎用的に処理可能な機械語の命令列からなる実行ファイルよりも処理が高速である。
 但し、JITコンパイラ技術を使うためには、命令セットに含まれる命令ごとに、その命令を実行する機械語を生成する関数を開発者が自ら手作業でソースコードに記述する必要がある。よって、これらの関数を生成し、かつ各関数が正しい機械語を生成するかをテストする工数が膨大となる。
特開2000-56981号公報
 一側面によれば、関数の作成に伴う工数を減らすことが可能な関数生成プログラム、関数生成方法、及び情報処理装置を提供することを目的とする。
 一側面によれば、命令に関する命令情報を記憶した記憶部を参照して、前記命令に対応した関数であって、前記命令のオペランドを表す引数を受け取る第1の関数を生成する処理と、前記引数が表す前記オペランドに対して前記命令が行う処理を表す機械語を返す第2の関数を呼び出すコードを前記第1の関数の内部に生成する処理と、前記機械語をメモリに書き込むコードを前記第1の関数の内部に生成する処理と、をコンピュータに実行させるための関数生成プログラムが提供される。
 一側面によれば、関数の作成に伴う工数を減らすことが可能となる。
図1は、実行可能プログラムを実行するターゲットマシンのハードウェア構成図である。 図2(a)は、AOT(Ahead Of Time)コンパイラ技術でコンパイルすることを前提としたC++の疑似ソースコードの一例を示す図であり、図2(b)は、パラメータqと配列in、outを宣言したC++のソースコードの一例を示す図であり、図2(c)は、配列Tblの初期値を宣言したC++の疑似ソースコードの一例を示す図である。 図3は、AOTコンパイラ技術で得られたアセンブリの疑似コードの模式図である。 図4は、AOTコンパイラ技術で得られた実行可能プログラムの動作について模式的に示す図である。 図5は、JITコンパイラ技術を使用する実行可能プログラムのC++の疑似ソースコードの一例を示す図である。 図6は、入力パラメータqが「8」の場合の、JITコンパイラ技術で生成した機械語の命令列と、それを逆アセンブルした疑似コードの模式図である。 図7は、実行時に呼び出す関数を、JITコンパイラ技術で実行時に生成する実行可能プログラムの動作について示す模式図である。 図8は、mov命令に対応したニーモニック関数の疑似ソースコードの例を示す図である。 図9は、第1実施形態に係る情報処理装置の動作を示す模式図である。 図10は、MachineCodeEmitter関数のC++の疑似ソースコードが記述されたソースファイルの一例を示す図である。 図11は、第1実施形態に係る情報処理装置の機能構成図である。 図12は、第1実施形態に係る関数生成方法について示すフローチャートである。 図13は、第1実施形態において、ニーモニック関数が記述されたソースファイルを利用した開発環境について示す模式図である。 図14は、C++のマクロを使用しないで生成した実行可能プログラムを実行するときのメモリの内容を示す模式図である。 図15(a)は、第1実施形態に係る第1の生成部がC++のマクロとしてニーモニック関数movを記述したソースコードの一例を示す図であり、図15(b)は、マクロを使用した場合において、実行可能プログラムを実行するときのメモリの内容を示す模式図である。 図16は、ニーモニックが同一で機械語が相違する命令について示す図である。 図17(a)は、ニーモニック「STRpost」、「STRpre」を採用した場合の第1実施形態の命令情報を模式的に示す図であり、図17(b)は、この命令情報に基づいて第1実施形態に従って生成したニーモニック関数について示す図である。 図18は、第2実施形態で使用する命令情報について模式的に示す図である。 図19(a)~(e)は、第2実施形態においてオペランドの型を定義するC++の疑似ソースコードの例について示す図である。 図20(a)は、ニーモニック「STRpost」に対応した第2実施形態に係るニーモニック関数STRのC++の疑似ソースコードが記述されたソースファイルの模式図であり、図20(b)は、ニーモニック「STRpre」に対応した第2実施形態に係るニーモニック関数STRのC++の疑似ソースコードが記述されたソースファイルの模式図である。 図21(a)は、ニーモニック関数の引数をOperand型とした場合のニーモニック関数movのC++の疑似ソースコードを示す図であり、図21(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似ソースコードを示す図である。 図22(a)は、第2実施形態で生成したニーモニック関数movのC++の疑似ソースコードが記述されたソースファイルの模式図であり、図22(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイルのC++の疑似ソースコードの例を示す図である。 図23は、第2実施形態に係る関数生成方法について示すフローチャートである。 図24(a)は、第2実施形態に従って生成したニーモニック関数movのC++のソースコードが記述されたソースファイルの例を示す図であり、図24(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイルのC++の疑似ソースコードの例を示す図である。 図25は、第3実施形態で使用する命令情報について模式的に示す図である。 図26は、mov命令に対応した第3実施形態に係るニーモニック関数movが記述されたソースファイル34のC++の疑似ソースコードの例について示す模式図である。 図27は、第3実施形態に係るニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイルのC++の疑似ソースコードの例を示す図である。 図28は、第3実施形態に係る関数生成方法について示すフローチャートである。 図29(a)、(b)は、第4実施形態において、add命令の文法について示す図である。 図30は、第4実施形態に係る命令情報を模式的に示す図である。 図31は、第4実施形態に従って制御部が生成したニーモニック関数ADDのソースコードの一例を示す図である。 図32は、関数「SET()」を定義するC++の疑似ソースコードを模式的に示す図である。 図33は、第4実施形態において開発者がC++で記述したアプリケーションプログラム用のソースファイルの疑似ソースコードを模式的に示す図である。 図34は、出力例を示す図である。 図35は、第4実施形態に係る情報処理装置の機能構成図である。 図36は、第4実施形態において制御部が生成したニーモニック関数ADDのC++の疑似ソースコードを示す模式図である。 図37は、第4実施形態において第4の生成部が生成する関数「SET()」のC++の疑似ソースコードの一例を示す図である。 図38は、第4実施形態において定義ファイル生成部が生成した定義ファイルの疑似ソースコードを示す模式図である。 図39は、第4実施形態において開発者が記述したアプリケーションプログラム用のソースファイルのC++の疑似コードを示す図である。 図40は、第4実施形態に係る開発環境について示す模式図である。 図41は、第4実施形態における出力例を示す図である。 図42は、第4実施形態の別の例に係るソースファイルのC++の疑似ソースコードの例を示す模式図である。 図43(a)、(b)は、マクロで置換される関数の最後に可変引数マクロを記述したときに生じる不都合について模式的に示す図である。 図44は、第4実施形態に係る定義ファイルの生成方法について示すフローチャートである。 図45は、第1~第4実施形態に係る情報処理装置のハードウェア構成図である。
 本実施形態の説明に先立ち、本願発明者が検討した事項について説明する。
 前述のようにJITコンパイラ技術はプログラムの実行速度の高速化に有用である。このようなJITコンパイラ技術の利点について、AOT(Ahead Of Time)コンパイラ技術と比較しながら説明する。なお、このJITコンパイラ技術は、プロセッサに依存しない中間言語のコードをプロセッサが直接扱える機械語の命令列に実行時に変換する技術ではなく、実行時に決定されるパラメータ等に適した機械語の命令列を生成するコンパイラ技術である。
 図1は、AOTコンパイラ技術やJITコンパイラ技術により生成された実行可能プログラムを実行するターゲットマシンのハードウェア構成図である。
 このターゲットマシン1は、サーバやPC(Personal Computer)等の計算機であって、プロセッサ2とメモリ3とを有する。
 このうち、プロセッサ2は、算術演算や論理演算を行うALU(Arithmetic and Logic Unit)等の計算コア4とレジスタファイル5とを備える。レジスタファイル5は、インデックスn(=0,1,2,…)で識別される複数の汎用のレジスタRnを備えたハードウェアである。
 一方、メモリ3は、実行可能プログラムが展開されるDRAM(Dynamic Random Access Memory)等の揮発性メモリである。その実行可能プログラムは、以下のようにAOTコンパイラ技術を用いてソースコードをコンパイルすることにより生成することができる。また、JITコンパイラ技術で実行可能プログラムが呼び出す機械語の命令列を実行中に動的に生成してもよい。
 図2(a)は、AOTコンパイラ技術でコンパイルすることを前提としたC++の疑似ソースコード10の一例を示す図である。
 AOTコンパイラ技術では、開発者はC言語やC++の文法に即してソースコードを記述し、そのソースコードをGCC(GNU Compiler Collection)等のコンパイラが機械語の命令列にコンパイルする。
 図2(a)の例では、処理10aにおいて配列「Tbl」の各要素をパラメータ「q」で除する。そして、処理10bにおいて、配列「in」の要素を配列「Tbl」の要素で除し、それを配列「out」に格納する。
 図2(b)は、パラメータ「q」と配列「in」、「out」を宣言したC++の疑似ソースコード11の一例を示す図である。
 パラメータ「q」は、前述の処理10aにおける除数であり、以下では入力パラメータとも呼ぶ。また、配列「in」と配列「out」は、それぞれ処理10bにおける入力データと出力データである。これらの配列「in」、「out」に格納するデータは特に限定されない。ここでは16個の画素データからなる画像を1000000枚格納する二次元配列として配列「in」と配列「out」を宣言する。
 図2(c)は、配列Tblの初期値を宣言したC++の疑似ソースコード12の一例を示す図である。
 配列「Tbl」は、画素データを量子化する量子化テーブルの値を格納する配列である。ここでは、各配列「in」、「out」に対応した16個の要素を持つ配列として配列「Tbl」を宣言する。そして、配列「Tbl」の各要素の初期値は2のべき乗であると仮定する。
 図2(a)~図2(c)のソースコード10~12は全てC言語やC++の文法に即して開発者が記述し、コンパイラによってアセンブリに変換される。
 図3は、AOTコンパイラ技術で前述のソースコード10をコンパイルして得られたアセンブリ14の疑似コードの模式図である。
 そのアセンブリ14には、プロセッサ2の命令セットに含まれる複数の命令が、各処理10a、10bに対応して生成されている。
 例えば、処理10aはmov命令からjmplt命令に至る6個の命令で実現され、処理10bはmov命令からjmplt命令に至る10個の命令で実現される。これらの命令は、プロセッサ2の命令セットに含まれる命令であって、オペランドとして記述されたレジスタやメモリに対して種々の操作を行う。なお、ここでは図1と同様にレジスタをRn(n=0,1,2,…)で表し、命令の位置を表すラベルをLm(m=0,1,2,…)で表す。そして、最初にレジスタR2に入力パラメータ「q」が保存されているものとする。
 また、命令セットに含まれる全ての命令は、ニーモニックと呼ばれる名前で一意に識別される。例えば、mov命令のニーモニックは「mov」であり、store命令のニーモニックは「store」である。
 アセンブリ14においては、命令のニーモニックの後ろにオペランドを記述するという文法が採用される。例えば、「mov R0, #0」は、即値である「0」をレジスタR0に格納する命令である。また、「load R1, [Tbl[R0]]」は、メモリ3上に値が保持されている配列「Tbl」のa番目の要素(aはレジスタR0の内容)の値をレジスタR1にロードする命令である。
 一方、「store [Tbl[R0]], R1」は、レジスタR1の内容を、メモリ3上に値が保持されている配列「Tbl」のb番目の要素(bはレジスタR0の内容)に格納する命令である。また、「div R1, R1, R2」は、レジスタR1の内容をレジスタR2の内容で除し、その値をレジスタR1に格納する命令である。そして、「jmplt R0, #16, L0」は、レジスタR0の内容が即値の「16」未満の場合にラベルL0にジャンプする命令である。
 ここで、処理10bにおける命令「div R2, R2, R1」について考える。この命令は、ソースコード10の処理10bにおける「in[i]/Tbl[i]」に相当する命令である。除数の「Tbl[i]」は、ソースコード10の処理10aにおいて入力パラメータ「q」で除されている。上記の命令「div R2, R2, R1」は入力パラメータ「q」の値の如何を問わずに正しい除算の結果を与える命令である。したがって、アセンブリ14は、どのような入力パラメータ「q」に対しても正しい結果を与える汎用的なコードとなっている。
 しかしながら、div命令のような除算を行う命令は、どのような種類のプロセッサであっても、他の命令と比較して実行サイクル数が多い命令である。したがって、実行開始してからその結果が得られるまでのスループットが大きく、処理性能の低下を招いてしまう命令である。プロセッサ2の種類にもよるが、div命令以外の数値演算命令の実行サイクル数は1~5であるのに対し、div命令の実行サイクル数は80程度もあることがある。更に、深層学習や画像処理等ではforループのループの回数が膨大となるため、そのforループの内側にあるdiv命令によってスループットの低下が更に顕著となる。
 このようなアセンブリ14をアセンブラが機械語の命令列に翻訳することにより機械語からなる実行可能プログラムが生成されることになる。LLVMのようにコンパイラの種類によっては、プロセッサ2の種類によらず、仮想的な命令セットを持つプロセッサ向けのアセンブリを生成することがある。この場合、このアセンブリを個別のプロセッサ向けの機械語の命令列に変換することもあるが、div命令のような除算命令があるとスループットが低下する点は同じである。
 図4は、AOTコンパイラ技術で得られた実行可能プログラムの動作について模式的に示す図である。
 図4に示すように、実行可能プログラム15は、入力データである配列「in」の各要素と入力パラメータ「q」の入力を受け付ける。そして、前述のように入力パラメータ「q」や配列「in」の値の如何を問わずに、実行可能プログラムは同一のアセンブリ14から得られた機械語の命令列により処理を行い、その処理の結果を配列「out」の各要素に格納する。
 次に、スループットの低下を抑制し得るJITコンパイラ技術を前提としたプログラムについて説明する。
 図5は、JITコンパイラ技術を使用する実行可能プログラムのC++の疑似ソースコード16の一例を示す図である。
 このソースコード16は、その実行結果が図2(a)のソースコード10の実行結果と同一になるように開発者によって記述されたコードであって、処理16aと処理16bとを有する。このうち、処理16aは、ソースコード10の処理10aと同様に、配列「Tbl」の各要素をパラメータ「q」で除する処理である。また、処理16bは、ソースコード10の処理10bと同様に、配列「in」の要素を配列「Tbl」の要素で除してそれを配列「out」に格納する処理である。
 その処理16bには、関数名がニーモニックと同一の「mov(R0, i)」等の関数が開発者によって記述される。関数「mov(R0, i)」は、言わばアセンブリ「mov R0, #i」に対応した関数であって、「mov R0, #i」が行う処理を表す機械語をメモリ3に書き込む関数である。なお、アセンブリ中では変数は記述することができず、「mov R0, #5」や「mov R0, #-128」など、アセンブリの時点では固定の値しか指定することができない。JITコンパイラ技術を用いた場合、即値に変数iが使用できる。このことはJITコンパイラ技術の利点の1つである。このように関数名が命令のニーモニックと同一であり、かつその命令が行う処理を表す機械語をメモリ3に書き込む関数のことを以下ではニーモニック関数と呼ぶ。
 処理16bは、i=0~15に対してin[i]/Tbl[i]を実行する機械語の命令列をメモリ3に書き込む処理を実行する記述である。この例では開発者がswitch文を記述したことにより、除数である配列要素「Tbl[i]」の値に応じて異なるニーモニック関数を使って機械語の命令列が生成される。
 例えば、「Tbl[i]」の値が「1」の場合には、「in[i]」に対する除数が「1」となるため、「in[i]」に対して何も行う必要がない。よって、この場合は、「case 1」において「in[i]」の値が格納されているレジスタR1の値に対して演算する機械語の生成は行わず、そのままout[i]へ値を格納する機械語をメモリ3に書き込むのみである。
 一方、「Tbl[i]」の値が「2」の場合には、「case 2」においてshiftR命令の機械語の生成に対応した「shiftR(R1, R1, #1)」を実行する。このニーモニック関数は、レジスタR1の内容を1ビットだけ右にシフトし、その結果をレジスタR1に書き込む処理を表す機械語をメモリ3に書き込む関数である。よって、「shiftR(R1, R1, #1)」を実行することにより、レジスタR1に格納されている「in[i]」を2で除したのと等価な処理を行う機械語をメモリ3に書き込むことができる。
 また、「Tbl[i]」の値が「4」の場合には、「case 4」において「shiftR(R1, R1, #2)」を実行する。これにより、レジスタR1の内容が右に2ビットだけシフトし、レジスタR1に格納されている「in[i]」を4で除したのと等価な処理を行う機械語をメモリ3に書き込むことができる。このように、除数が2のべき乗の値の場合には、shiftR命令に対応するニーモニック関数が実行される。
 そして、「Tbl[i]」の値が「1」、「2」、「4」のような2のべき乗ではない場合には、「default」において「div(R1, R1, R2)」を実行する。このニーモニック関数は、div命令に対応した関数であって、レジスタR1の内容をレジスタR2の内容で除した値をレジスタR1に書き込む機械語をメモリ3に書き込む関数である。
 このようなソースコード16によれば、「Tbl[i]」の値が「1」、「2」、「4」のような2のべき乗である場合には、div命令よりも実行サイクル数が少ないshiftR命令に等価な機械語や何もしない機械語がメモリ3に書き込まれる。そして、「Tbl[i]」の値が「1」、「2」、「4」のような2のべき乗でない場合にのみdiv命令に等価な機械語がメモリ3に書き込まれる。
 JITコンパイラ技術では、このように「Tbl[i]」等のパラメータの値に応じて実行サイクル数を低減するのに最適な機械語を書き込むことにより、AOTコンパイラ技術と比較してプログラムの実行速度を高速化することができる。
 図6は、ソースコード16をコンパイルして得られた実行ファイルの実行中に、処理16bがメモリにどのような機械語の命令列を書き込んだかを示す模式図である。なお、その実行ファイルを実行する際、入力パラメータqに「8」を与えている。また、図6では、この機械語の命令列を逆アセンブルしたアセンブリ17の疑似コードも併記している。
 図6に示すように、q=8の場合には、配列「Tbl」の各要素が先頭から順に「1」、「2」、「4」となる。よって、処理16bのforループ実行に際して、i=0(case 1)、i=1(case 2)、i=2(case 4)の各場合に対応したshiftR関数とstore関数の各々が生成する機械語18がメモリ3内に配置されることになる。そして、その機械語18を逆アセンブルしたコードは、アセンブリ17におけるコード17a、17b、17cとなる。
 図7は、実行時に呼び出す関数を、JITコンパイラ技術で実行時に生成する実行可能プログラムの動作について示す模式図である。ここでは、JITコンパイラ技術を用いたソースコード16をコンパイルして得られた実行可能プログラム20の動作について説明する。
 図7に示すように、実行可能プログラム20は、まず入力パラメータ「q」の入力を受け付ける(ステップP10)。次いで、実行可能プログラム20は、その入力パラメータ「q」の値に応じて、処理が高速になる機械語18を生成する(ステップP11)。前述の図6の例では、「Tbl[i]」の値に適した機械語18が生成される。
 続いて、実行可能プログラム20は、入力データである配列「in」の各要素の入力を受け付けて(ステップP12)、処理の結果を配列「out」の各要素に格納する(ステップP13)。
 このとき、機械語18の中にはスループットの遅いdiv命令が含まれていないため、アセンブリ14に対応する実行可能プログラムよりも高速な処理を行うことができる。しかも、このように入力パラメータ「p」の値に応じて適切な機械語18を生成することにより、JITコンパイラ技術ではAOTコンパイラ技術よりもプログラムの実行速度を高速化できる。
 ところで、このようなJITコンパイラ技術で使用するニーモニック関数はC++やC言語等のライブラリには存在しない関数であるため、開発者が予め手作業でニーモニック関数を記述しておく必要がある。
 図8は、mov命令に対応したニーモニック関数のC++の疑似ソースコードの一例を示す図である。
 このソースコード21は、ニーモニック関数movを定義するためのソースコードである。そのニーモニック関数movの関数名は、mov命令のニーモニック「mov」と同じであり、かつ引数はmov命令がとる「オペランド0」と「オペランド1」の二個である。
 ニーモニック関数movの内部には、mov命令の処理を表す機械語をメモリ3に書き込むコードが記述される。ここでは、命令長は32ビットであり、mov命令のオペコードは8ビットで「0x01」であるとする。この場合、開発者は、変数「mnemonic」にオペコードの「0x01」を代入する文「unsigned mnemonic = 0x01;」をニーモニック関数movの本体に記述する。同様に、開発者は、変数「op0」、「op1」の各々に「オペランド0」、「オペランド1」を代入する文「unsigned op0 = オペランド0;」、「unsigned op1 = オペランド1;」をニーモニック関数movの本体に記述する。
 そして、これらの文の後に、開発者は、「write((mnemonic<<24)+(op0<<16)+(op1<<8));」という文を記述する。関数writeは、引数のビット列をメモリ3に書き込む関数である。この例では、「mnemonic」の値を左に24ビットだけシフトしたビット列と、変数「op0」の値を左に16ビットだけシフトした値と、変数「op1」の値を左に8ビットだけシフトした値とのビット和が関数writeの引数となる。このビット列においては、先頭の8ビットがmov命令のオペコードとなる。そして、そのオペコードの次の8ビットが変数「op0」のビット列であり、その次の8ビットが変数「op1」のビット列である。なお、アセンブリ17のshiftR R1, R1, #1等のようにオペランドを3つとる命令に対応するニーモニック関数では、最後の8ビットが3番目の変数「op2」のビット列である。
 このようなニーモニック関数を記述するには、開発者は、命令セットの仕様書を参照して各命令のフォーマットを特定し、そのフォーマットに従って関数writeの引数にオペコードとオペランドの各々のビット列を記述する必要がある。
 しかしながら、このように手作業でニーモニック関数を記述するのは極めて煩雑な作業であり、開発者の負担増を招いてしまう。また、ニーモニック関数が所望の機械語を正しくメモリ3に書き込む動作するかの検証作業も手作業で行う必要があるため開発者の負担が更に増してしまう。特に、命令セットに含まれる命令の個数が数百個から千個を超えるプロセッサ2もある。例えば、ARM社が仕様を策定しているARMv8-A architecture profileに従うプロセッサでは、オペランドのバリエーションが異なる同一名称の命令を異なる命令として扱うと、約1000種類もの命令がある。この場合には約1000種類ものニーモニック関数を開発者が自ら記述しなければならず、全ての命令に対応したニーモニック関数の記述と検証とを手作業で行うために膨大な工数が必要となる。
 更に、命令セットは将来的に拡張されることがあり、その度にニーモニック関数の記述と検証をするのは煩わしさに耐えない。
 以下に、ニーモニック関数を作成するための工数を減らすことが可能な各実施形態について説明する。
 (第1実施形態)
 本実施形態では、以下のようにして情報処理装置がニーモニック関数を自動的に生成する。
[全体構成]
 図9は、本実施形態に係る情報処理装置の動作を示す模式図である。
 この情報処理装置30は、ニーモニック関数を自動的に生成するツールである制御部31を備えたPCやサーバ等の計算機である。ニーモニック関数を生成するに際し、制御部31は、関数を生成するための命令情報33を参照する。
 命令情報33は、各命令のニーモニックとオペランドの個数とを対応付けた情報であって、開発者によって予め作成される。命令情報33の各々の行はそれぞれ異なる命令に対応しており、例えば1行目はmov命令に対応し、2行目はload命令に対応する。
 この例では、開発者が、一行目のmov命令のニーモニック「mov」を、mov命令のオペランドの個数「2」と対応付けて命令情報33に格納する。なお、オペランドの個数は命令によって異なり、例えばshiftR命令ではオペランドの個数は「3」となる。
 その命令情報33は、情報処理装置30内の記憶部にファイルとして格納される。なお、ネットワークを介して情報処理装置30と接続された外部の記憶部に開発者が命令情報33を格納し、その記憶部を制御部31が参照してもよい。
 制御部31は、命令情報33を一行ずつ読み込んで、その行にあるニーモニックに対応した関数名を有するニーモニック関数を生成する。その生成方法について一行目のニーモニック「mov」を例にして説明する。
 まず、制御部31は、命令情報33の一行目を読み込むことにより、ニーモニック「mov」とこれに対応したオペランドの個数「2」とを取得する。
 次いで、制御部31は、ニーモニック「mov」に対応した関数名のニーモニック関数をC++のソースファイル34に記述する。本実施形態ではニーモニックと関数名とを同名にする。そのため、制御部31は、関数名34aが「mov」のニーモニック関数をソースファイル34に記述することになる。なお、ソースファイル34に記述するプログラミング言語はC++に限定されず、制御部31がC言語やC#のソースコードをソースファイル34に記述してもよい。
 また、そのニーモニック関数movは、命令情報33における個数「2」と同数の引数をとる。これにより、ニーモニック関数movのひな形である「void mov(Operand OP0,Operand OP1){}」という中身が空の関数が記述されることになる。なお、ニーモニック関数movは第1の関数の一例である。
 また、「OP0」と「OP1」の各々は、mov命令のオペランドを表す引数である。ここでは、制御部31がソースファイル34にソースコード34bを記述することにより、オペランドを表す変数の型としてOperand型を定義する。そして、制御部31は、コードT1において「OP0」と「OP1」の各々をOperand型として宣言する。
 Operand型は、メンバとして「type」と「value」とを有するクラスである。このうち、「type」には、レジスタや即値等のオペランドの種類が格納される。そして、「value」には、即値やレジスタのインデックス等の数値が格納される。なお、ソースファイル34とは別のソースファイルにおいてOperand型を定義してもよい。
 続いて、制御部31は、ニーモニック関数movの内部にコードT2~T4を生成する。
 コードT2は、先に取得した関数名「mov」を変数「nm」に代入する文である。なお、この例では変数「nm」に文字列である「mov」を代入しているが、関数名「mov」と整数値とを予め一対一に対応させておき、その整数値を変数「nm」に代入してもよい。
 また、コードT3は、ニーモニック関数movが引数として受け取ったOperand型の「OP0」と「OP1」とを配列「oplist」に代入する文である。
 そして、コードT4は、MachineCodeEmitter関数を呼び出し、そのMachineCodeEmitter関数の返り値を関数writeでメモリ3に書き込むコードである。MachineCodeEmitter関数は、変数「nm」と変数「oplist」とを引数として受け取り、変数「oplist」で表されるオペランドに対して変数「nm」で表される命令が行う処理を表す機械語を生成する関数である。なお、MachineCodeEmitter関数は、第2の関数の一例であって、プロセッサ2のアセンブラと共に作成された動作が検証済の関数である。
 以上により、制御部31が、ニーモニック関数movを自動的に生成したことになる。
 この後は、命令情報33の二行目以降に対しても制御部31が上記と同様の処理を行うことにより、関数名が「load」、「shiftR」、「add」等のニーモニック関数を自動で生成する。そして、制御部31が、プロセッサ2の命令セットに含まれる全ての命令に対応したニーモニック関数が記述されたソースファイル34をメモリ等の記憶部に出力する。
 これにより、開発者が手作業でニーモニック関数を記述する手間がなくなり、ニーモニック関数を生成するための工数を低減できる。
 更に、そのニーモニック関数の関数名は、開発者が慣れ親しんだ命令のニーモニックと同一となるため、開発者が関数名を覚える手間がなく、開発者にとって扱いやすいニーモニック関数を提供できる。
 しかも、そのニーモニック関数の引数の個数は、命令のオペランドの個数に等しい。これにより、開発者が慣れ親しんだ「mov OP0 OP1」というアセンブリの文法に類似したコード「mov(OP0,OP1)」でニーモニック関数を呼び出すことができるため、開発者の利便性が向上する。
 図10は、上記のMachineCodeEmitter関数のC++の疑似ソースコードが記述されたソースファイル43の一例を示す図である。そのソースファイル43は、アセンブラ自身のソースファイルの一部でもよい。
 この例では、コードT5~T8によりMachineCodeEmitter関数の機能が実現される。このうち、コードT5は、変数「mnemonic」と変数「op0」、「op1」、「op2」、「op3」の各々を32ビットの符号無し整数として宣言する文である。
 また、コードT6は、MachineCodeEmitter関数が引数として受け取った変数nmの内容に対応したオペコードを変数「mnemonic」に代入するコードである。例えば、変数「nm」で特定されるニーモニックが「mov」の場合には、mov命令のオペコード「0x01000000」が変数「mnemonic」に代入される。
 そして、コードT7は、変数「nm」の内容に応じて変数「OP0」、「OP1」の各々に対してビット操作を行うことにより、命令の仕様で定められたビット位置にこれらの変数を位置させるコードである。例えば、mov命令の場合には、32ビットの内の17~24ビットに第1オペランドが位置し、8~16ビットに第2オペランドが位置する。そこで、mov命令の場合には、文「op0=OP0<<16」を実行することにより、32ビットの内の17~24ビットに変数「OP0」のビット列を位置させる。一方、変数「OP1」については、文「op1=OP1<<8」を実行することにより、32ビットの8~16ビット目に「OP1」のビット列を位置させる。なお、mov命令は第3オペランドをとらないため、文「op2=0」により変数「op2」を「0」にする。
 更に、コードT8は、各変数「mnemonic」、「op0」、「op1」、「op2」の各々を上位ビットから順に連結したビット列を生成し、それを返り値として返す文である。そのビット列は、変数「oplist」で特定されるオペランドに対して変数「nm」で特定される命令が行う処理を表す機械語である。
 以上説明した関数生成方法によれば、制御部31が、命令情報33に基づいてニーモニック関数の内部にMachineCodeEmitter関数を呼び出すコードを生成する。MachineCodeEmitter関数は、引数「nm」で表される命令が、引数「oplist」で表されるオペランドに対して行う処理を表す機械語を生成する関数である。そのため、ニーモニック関数の作成に際し、命令の仕様書を基にして開発者が手作業で機械語を生成するコードを記述する必要がなくなり、ニーモニック関数を作成するのに要する工数を減らすことができる。
 プロセッサ2(図1参照)を開発する際には、そのプロセッサ2で動作する機械語の実行ファイルを生成するためのツール群も開発される。そのツール群には、C言語やC++言語で記述されたソースファイルをアセンブリ言語に変換するためのコンパイラや、アセンブリ言語を機械語に変換するためのアセンブラが含まれる。そのようなツール群としては、例えばLLVMがある。MachineCodeEmitter関数は、LLVMのアセンブラに内蔵されている関数であり、アセンブラを開発した際にその動作が検証されて提供されている。そのため、本実施形態では、制御部31が生成したニーモニック関数が正しい機械語を生成しているかという動作検証を行う必要がない。これにより、ニーモニック関数を作成する工数に加え、ニーモニック関数の動作検証に要する工数も低減でき、ニーモニック関数の作成に伴う工数を低減することができる。
 なお、本実施形態ではLLVMの中に含まれるMachineCodeEmitter関数を例に説明したが、本実施形態はこれに限定されない。例えば、MachineCodeEmitter関数に代えて、LLVMとは別のツール群(例えばGCC)の中の機械語生成関数を呼び出すようにニーモニック関数を生成してもよい。機械語生成関数は、MachineCodeEmitter関数と同等の機能を有する関数である。この場合は、制御部31は、図9の各変数「mov」、「OP0」、「OP1」をその機械語生成関数の引数の個数や型に変換するようなコードを各コードT2、T3に代えてソースファイル34に記述すればよい。
 また、図9の例では、最大で三つの変数「OP0」、「OP1」、「OP2」を配列「oplist」にまとめてMachineCodeEmitter関数に渡すことができるが、各変数「OP0」、「OP1」、「OP2」を別々の引数として受け取る機械語生成関数もある。その場合には、制御部31は、コードT3を生成せずに、各変数「OP0」、「OP1」、「OP2」のそれぞれを別々の引数として機械語生成関数に渡すようなコードを生成すればよい。
[機能構成]
 次に、本実施形態に係る情報処理装置30の機能構成について説明する。
 図11は、本実施形態に係る情報処理装置30の機能構成図である。
 図11に示すように、情報処理装置30は、制御部31と記憶部32とを有する。
 このうち、記憶部32は、HDD(Hard Disk Drive)等の記憶装置やDRAM等のメモリによって実現することができ、前述の命令情報33とニーモニック関数のソースファイル34とを記憶する。
 また、制御部31は、情報処理装置30の全体を制御する処理部であり、第1の生成部36、第2の生成部37、第3の生成部38、及び出力部39を備える。
 第1の生成部36は、命令情報33を参照して、各命令に対応したニーモニック関数を生成し、そのニーモニック関数をソースファイル34に記述する処理部である。一例として、第1の生成部36は、命令情報33からニーモニックを取得し、そのニーモニックと同じ関数名34a(図9参照)をニーモニック関数に付与する。また、第1の生成部36は、ニーモニック関数の引数として、命令情報33におけるオペランドの個数に等しい個数の引数を宣言する。
 例えば、命令情報33におけるニーモニックが「mov」の場合には、第1の生成部36は、ニーモニック関数movとして「void mov(Operand OP0,Operand OP1){}」という関数を生成し、その関数のソースコードをソースファイル34に記述する。なお、第1の生成部36が記述したニーモニック関数の中身は空である。
 また、第1の生成部36は、命令セットに含まれる全てのニーモニック関数を一つのソースファイル34に記述してもよいし、ニーモニック関数の各々を異なるソースファイルに記述してもよい。
 一方、第2の生成部37は、前述のMachineCodeEmitter関数を呼び出すコードを生成し、そのコードをソースファイル34に記述する処理部である。MachineCodeEmitter関数の引数は、各オペランドに対応した変数である「oplist」と、命令に対応した変数である「mov」である。これらの引数を受け取ると、MachineCodeEmitter関数は、命令がオペランドに対して行う処理を表す機械語を生成する。
 そして、第3の生成部38は、MachineCodeEmitter関数が生成した機械語をメモリ3に書き込むコードを生成し、そのコードをソースファイル34に記述する処理部である。そのコードは、例えば「write(MachineCodeEmitter(nm, oplist);」という書式になる。
 出力部39は、第1~第3の生成部36~38が記述したソースファイル34を記憶部32に書き出す。
[処理の流れ]
 図12は、本実施形態に係る関数生成方法について示すフローチャートである。
 まず、第1の生成部36が、命令情報33を参照して、ニーモニックとこれに対応するオペランドの個数とを取得する(ステップS10)。
 次いで、第1の生成部36が、中身が空のニーモニック関数を生成し、それをソースファイル34に記述する(ステップS11)。例えば、ニーモニックが「mov」の場合は、第1の生成部36は、「void mov(Operand OP0,Operand OP1){}」という中身が空のニーモニック関数をソースファイル34に記述する。なお、このニーモニック関数の引数の個数は、ステップS10で取得したオペランドの個数となる。
 次に、第2の生成部37がMachineCodeEmitter関数を呼び出すコードを生成する(ステップS12)。例えば、第2の生成部37は、第1の生成部36が記述したニーモニック関数の内部に、MachineCodeEmitter関数を呼び出すコード「MaschineCodeEmitter(nm,oplist);」を記述する。
 これと共に、第2の生成部37は、図9のコードT2、T3等のように、ニーモニック関数の引数の値をMachineCodeEmitter関数に渡すための文もソースファイル34に記述する。
 続いて、第3の生成部38が、MachineCodeEmitter関数が生成した機械語をメモリ3に書き込むコードを生成する(ステップS13)。一例として、第3の生成部38は、関数writeの引数にMachineCodeEmitter関数を記述した「write(MachineCodeEmitter(nm, オペランドリスト));」というコードT4(図9参照)を生成し、それをソースファイル34に記述する。
 そして、命令情報33に含まれる全ての行に対してステップS10~S13の処理を行う。その後、出力部39が、全てのニーモニック関数を含むソースファイル34を記憶部32に書き出す(ステップS14)。
 以上説明した本実施形態によれば、第1~第3の生成部36~38の各々が命令情報33に基づいてニーモニック関数を自動的に生成する。そのため、開発者が手作業でニーモニック関数を記述する場合と比較して、ニーモニック関数を生成する際の工数を減らすことができる。
 しかも、このように各生成部36~38がニーモニック関数を生成することで、開発者が手作業でニーモニック関数を記述する場合よりもバグの発生を抑制できる。その結果、バグのあるプログラムをターゲットマシン1で無駄に実行する時間が減り、ターゲットマシン1のハードウェア資源の無駄な消費を改善できる。
[開発環境]
 開発者は、上記のようにニーモニック関数が記述されたソースファイル34を利用することにより、ターゲットマシン1のプロセッサ2で実行する様々なアプリケーションプログラムを開発することができる。そこで、そのアプリケーションプログラムの開発環境について以下に説明する。
 図13は、ニーモニック関数が記述されたソースファイル34を利用した開発環境について示す模式図である。
 この例では、情報処理装置30の内部に開発環境を構築する場合を想定する。その場合、ニーモニック関数を生成するツールである制御部31が命令情報33を参照し、図12のフローチャートに従って全てのニーモニック関数を含むソースファイル34を生成する。
 一方、開発者は、例えばC++を用いてアプリケーションプログラム用のソースファイル41を作成する。そのソースファイル41は、JITコンパイラ技術の機能を使用することを前提としたファイルであって、C++のライブラリ関数に加えて、ソースファイル34にあるニーモニック関数を呼び出す記述を含む。
 そして、開発者の指示の下で、コンパイラ、アセンブラ、及びリンカのプログラム群42がビルドを行う。このうち、コンパイラには、例えば#defineで始まるディレクティブの処理を行うためのプリプロセッサが含まれる。そして、ビルドにおいては、プログラム群42に含まれるコンパイラがソースファイル41をコンパイルする。
 このとき、コンパイラは、各ソースファイル34、41、43を読み込んでアセンブリの中間言語ファイルを出力する。これらのソースファイルのうち、ソースファイル43は、前述のMachineCodeEmitter関数が記述されたソースファイルである。そして、アセンブラがその中間言語ファイルを機械語の命令列に変換してオブジェクトファイルを生成する。
 その後、リンカは、オブジェクトファイルと種々のライブラリとをリンクすることにより、プロセッサ2で実行可能なバイナリ形式の実行可能プログラム44を生成する。
 なお、ここでは、前述のソースファイル43が、アセンブラ自身のソースファイルの一部であることを例にして説明した。アセンブラを開発するときの動作検証を通じて、ソースファイル43に記述されたMachineCodeEmitter関数の動作が正しいことは検証されている。
 なお、機械語の生成ルールが秘匿されているようなCPUでは、アセンブラのソースファイルが公開されていないものの、実行ライブラリファイルが入手可能なこともある。その場合には、ソースファイル43に代えて機械語生成関数の機能を予め機械語の命令列に変換済みの実行ライブラリファイル43aを入力として用い、これをリンクすることにより実行可能プログラム44を生成すればよい。
 以上により、アプリケーションプログラム用のソースファイル41から実行可能プログラム44を生成することができる。
 その実行可能プログラム44は、JITコンパイラ技術によって、実行時のパラメータや環境に応じて最適な機械語の命令列を実行時に生成する。そのため、この実行可能プログラム44は、深層学習や画像処理等のようにループの回数が膨大で大規模な演算が必要なアプリケーションプログラムの高速化に特に有効である。同様に、動画圧縮等の画像処理、暗号化処理、復号処理、及びブロックチェーン技術等で使用するアプリケーションプログラムも高速化することができる。
 なお、実行可能プログラム44の実行速度を更に速めるために、以下のようにC++のマクロとしてニーモニック関数を記述してもよい。
 図14は、C++のマクロを使用しないで生成した実行可能プログラム44を実行するときのメモリ3の内容を示す模式図である。
 この例では、開発者によってソースファイル41にニーモニック関数mov(OP0,OP1)が記述されている場合を想定している。この場合、命令を実行すべきアドレスがニーモニック関数mov(OP0,OP1)の呼び出し処理に対応する機械語が格納されたメモリアドレスに到達すると、関数呼び出しによってソースファイル34におけるニーモニック関数movが呼び出される。
 関数呼び出しの処理は、処理前にレジスタR0、R1、…のデータをメモリ3に退避させたり、処理後にそのデータをレジスタR0、R1、…に復帰させたりするためオーバーヘッドが大きく、プログラム実行を遅くしてしまう。
 一方、図15(a)は、第1の生成部36がC++のマクロとしてニーモニック関数movを生成したしたソースコード45の一例を示す図である。
 図15(a)に示されるように、第1の生成部36は、ステップS11(図12参照)において、マクロ「#define」を用いてニーモニック関数movのマクロをソースファイル34に記述する。
 また、図15(b)は、このようにマクロを使用した場合において、実行可能プログラム44を実行するときのメモリ3の内容を示す模式図である。
 マクロを利用すると、コンパイル時にプリプロセッサがソースファイル41においてニーモニック関数mov(OP0,OP1)が記述された部分にソースコード45を展開する。そのため、関数呼び出しを行わなくても「mov OP0, OP1」を実行する機械語をメモリ3に書き込むことができ、実行可能プログラム44がJITコンパイル技術で機械語を生成する処理の実行速度を速めることが可能となる。
 (第2実施形態)
 命令セットの中には、ニーモニックが同一であるにも関わらず、機械語が相違する複数の命令が存在する場合がある。そのような相違を反映させるために、これらの命令ごとにニーモニック関数の関数名も変えてしまうと、開発者が覚えるべき関数名が増えてしまい、開発者の負担が増えてしまう。そこで、本実施形態では、ニーモニックが同一で機械語が相違する複数の命令が存在する場合でも開発者の負担増を抑制できる例について説明する。
 まず、ニーモニックが同一で機械語が相違する命令について説明する。
 図16は、そのような命令をアセンブリで記述した例について示す図である。
 これらの命令51、52は、いずれもストア命令であって、そのニーモニックはいずれも「STR」で同一である。
 このうち、命令51は、「アドレスレジスタ」に格納されているアドレスのメモリ3(図1参照)に「SRCレジスタ」の値を書き込み、その後、「アドレスレジスタ」に格納されている値を「即値」分だけインクリメントする命令である。
 一方、命令52は、「アドレスレジスタ」に格納されている値を最初に「即値」分だけインクリメントし、インクリメントされた値のアドレスのメモリ3に「SRCレジスタ」の値を書き込む命令である。
 このように、命令51、52は、「アドレスレジスタ」に格納されている値を「即値」分だけインクリメントするタイミングが相違しており、異なる処理を行う命令である。
 例えば、命令51ではニーモニックに続く文字列が「SRCレジスタ、[アドレスレジスタ]、即値」となっているのに対し、命令52ではその文字列が「SRCレジスタ、[アドレスレジスタ、即値]!」となっている。アセンブラは、このような文字列の相違に基づいて両者を区別し、アセンブラ内部で命令51のニーモニックを「STRpost」と読み替え、かつ命令52のニーモニックを「STRpre」と読み替えている。
 図17(a)は、これらのニーモニック「STRpost」、「STRpre」を採用した場合の第1実施形態の命令情報33を模式的に示す図である。
 そして、図17(b)は、この命令情報33に基づいて、第1実施形態に従って生成したニーモニック関数について示す図である。
 図17(b)に示すように、この場合は、命令51に対応するニーモニック関数STRpostと、命令52に対応するニーモニック関数STRpreが生成される。開発者は、関数名「STRpost」、「STRpre」を覚えておき、これらをアプリケーションプログラム用のソースファイルに記述することになる。
 しかしながら、これらのニーモニック関数の元となる二つの命令はいずれもストア命令であるにも関わらず、このように関数名が異なると開発者が覚えるべき関数名が増えてしまい、開発者の負担が増加することになる。
 そこで、本実施形態では、以下のようにしてニーモニック関数の関数名が増加するのを抑制する。
 図18は、本実施形態で使用する命令情報33について模式的に示す図である。
 図18に示すように、本実施形態に係る命令情報33においては、関数名、ニーモニック、オペランドの個数、及びオペランドの型が対応付けられて格納される。命令情報33の各々の行はそれぞれ異なる命令に対応しており、例えば1行目はmov命令に対応し、2行目はload命令に対応する。なお、第1実施形態と同様に、命令情報33は開発者によって予め作成される。
 この命令情報33において、関数名は、ニーモニック関数の名前であって、各ニーモニックに対応した名前が格納される。なお、本実施形態では関数名とニーモニックとを一対一に対応させる必要はなく、ニーモニックにこだわらずに開発者が覚えやすい同一の関数名を複数のニーモニックに対応させてもよい。例えば、STRpost命令とSTRpre命令はいずれもストア命令であるため、これらの命令に対応した関数名はいずれも「STR」とする。
 また、オペランドの個数は、第1実施形態と同様に、各命令がとるオペランドの個数である。
 そして、オペランドの型は、命令のオペランドの種類を示す型のリストである。例えば、mov命令においては、第1オペランドはレジスタであり、第2オペランドは即値となる。本実施形態では、レジスタを示すRegister型と即値を示すImmediate型とを予め定義しておき、これらの型のリストをニーモニック「mov」に対応付けて命令情報33に予め格納する。なお、そのリストの第1成分は第1オペランドの型を示し、第2成分は第2オペランドの型を示す。また、三つのオペランドをとる命令においては、リストの第3成分は第3オペランドの型を示す。
 ここで、C++の文法においては、二つの関数の関数名と引数の個数とが同一であっても、それらの引数の型が異なれば各関数を異なる関数として扱うことができる。
 そこで、本実施形態では、二つのニーモニック関数STRの各々で引数の型を変えることにより、関数名と引数の個数とが同一であっても異なる処理を実現できるようにする。この例では、ニーモニック「STRpost」に対応したニーモニック関数STRの引数の型をRegister型とPostIncAddrReg型とする。そして、ニーモニック「STRpre」に対応したニーモニック関数STRの引数の型をRegister型とPreIncAddrReg型とする。
 これにより、本実施形態に係る命令情報33においては、関数名が「STR」で同一であり、かつ、オペランドの型が異なる複数の相異なるニーモニック「STRpre」、「STRpost」が存在することになる。
 なお、第1実施形態における命令情報33では、図17(a)のようにニーモニック「STRpost」のオペランドの個数が「3」であるのに対し、本実施形態では図18のようにその個数は「2」となる。これは、後述のようにPostIncAddrReg型には二つのメンバがあり、これらのメンバにSTRpost命令の第2オペランドと第3オペランドを格納することができるためである。同様に、PreIncAddrReg型も二つのメンバがあり、これらのメンバにSTRpre命令の第2オペランドと第3オペランドを格納できるため、「STRpre」に対応したオペランドの個数も「2」となる。
 図19(a)~(e)は、オペランドの型を定義するC++の疑似ソースコードの例について示す図である。
 図19(a)は、Register型を定義するソースコードの例である。Register型は、前述のようにレジスタを示す型である。ここでは、Register型を定義するクラスのクラス名を「Reg」とし、そのクラスのメンバを「regIndex」とする。「regIndex」は、レジスタのインデックスを格納する変数であり、例えば符号無し整数型として宣言される。
 図19(b)は、AddrReg型を定義するソースコードの例である。AddrReg型は、アドレスレジスタを示す型である。AddrReg型を表すクラス「AddrReg」のメンバは、アドレスのベース値を保持するレジスタのインデックスを格納する「regIndex」と、アドレスオフセット値である即値を格納する「imm_value」である。なお、「imm_value」の初期値は0とする。
 図19(c)は、PostIncAddrReg型を定義するソースコードの例である。
 PostIncAddrReg型のクラスのメンバは、アドレスのベース値を保持するレジスタのインデックスを格納する「regIndex」と、命令実行後にアドレスのベース値をどれだけインクリメントするかを示す即値を格納する「imm_value」である。
 図19(d)は、PreIncAddrReg型を定義するソースコードの例である。
 PreIncAddrReg型のクラスのメンバは、アドレスのベース値を保持するレジスタのインデックスを格納する「regIndex」と、命令実行前にアドレスのベース値をどれだけインクリメントするかを示す即値を格納する「imm_value」である。
 図19(e)は、Immediate型を定義するソースコードの例である。Immediate型は、前述のように即値を示す型である。この例では、Immediate型を定義するクラスのクラス名を「Imm」とし、そのクラスのメンバを「imm_value」とする。「imm_value」は、即値を格納する整数型の変数である。
 図20(a)は、ニーモニック「STRpost」に対応したニーモニック関数STRのC++の疑似ソースコードが記述されたソースファイル34の模式図である。
 このニーモニック関数STRのソースコードは、命令情報33に基づいて制御部31が次のように生成する。
 例えば、命令情報33(図18参照)においてニーモニック「STRpost」に対応する関数名は「STR」であるから、制御部31はこのニーモニック関数の関数名53aを「STR」とする。
 また、制御部31は、命令情報33を参照することによりニーモニック「STRpost」のオペランドの個数が「2」であることを特定し、コードT11において「OP0」と「OP1_2」の2個の変数を引数として宣言する。
 更に、制御部31は、命令情報33を参照することによりニーモニック「STRpost」のオペランドの型がRegister型とPostIncAddrReg型であることを特定する。これに基づいて、制御部31は、コードT11において各変数「OP0」と「OP1_2」の各々の型をRegister型とPostIncAddrReg型として宣言する。
 また、制御部31は、このニーモニック関数STRの内部においてコードT12~T15を生成する。
 このうち、コードT12は、命令情報33のニーモニック「STRpost」を変数「nm」に代入する文である。また、制御部31は、命令情報33から特定したRegister型とPostIncAddrReg型に基づいて、MachineCodeEmitter関数の引数「oplist」に含める変数の個数を特定する。例えば、Register型はメンバ変数が一つであり、PostIncAddrReg型はメンバ変数が二つであるため、これらの型のメンバ変数の総数は三つとなる。そこで、制御部31は、三つのメンバに対応する三つのOperand型の変数「op0」、「op1」、「op2」を宣言するコードT13を生成する。このうち、変数「op0」は、Register型の変数「OP0」に対応する。また、変数「op1」、「op2」は、PostIncAddrReg型の変数「OP1_2」に対応した二つの変数である。なお、Register型、AddrReg型、PostIncAddrReg型、PostIncAddrReg型、及びImmediateの各々の型がそれぞれいくつのメンバ変数を有するかは、図19の各クラスを定義するソースファイルにおいて予め定義しておけばよい。
 一方、コードT14は、ニーモニック関数STRが引数として受け取った変数「OP0」、「OP1_2」の各々を、MachineCodeEmitter関数の引数「oplist」の型に変換するコードである。
 例えば、文「op0.type = REGISTER」により、変数OP0の型「Register」に対応した文字列「REGISTER」が変数op0のメンバ「type」に代入される。また、文「op0.value = OP0.regIndex;」により、変数OP0のメンバ「regIndex」が、変数op0のメンバ「value」に代入される。
 同様に、文「op1.type = REGISTER;」と文「op1.value = OP1_2.regIndex;」は、PostIncAddrReg型の変数OP1_2をOperand型の変数op1に型変換をするための文である。そして、文「op2.type = IMMEDIATE_VALUE;」と文「op2.value = OP1_2.imm_value;」は、PostIncAddrReg型の変数「OP1_2」をOperand型の変数「op2」に型変換をするための文である。
 更に、文「oplist={op0,op1,op2}」は、Operand型の配列「oplist」の各要素に上記の各変数「op0」、「op1」、「op2」を代入するコードである。その配列「oplist」は、コードT15においてMachineCodeEmitter関数に渡される。
 コードT15は、MachineCodeEmitter関数を呼び出して、そのMachineCodeEmitter関数が生成した機械語を関数writeでメモリ3に書き込むコードである。
 このようなソースコードによれば、ニーモニック関数STRが引数として受け取った変数「OP0」、「OP1_2」の各々がコードT14においてOperand型の配列「oplist」に変換される。そのため、MachineCodeEmitter関数の第2引数「oplist」の型に各変数「OP0」、「OP1_2」の型を合わせることができ、開発者が意図した機械語をMachineCodeEmitter関数が生成することができる。
 図20(b)は、ニーモニック「STRpre」に対応した本実施形態に係るニーモニック関数STRのC++の疑似ソースコードが記述されたソースファイル34の模式図である。
 図20(a)の例と同様に、このニーモニック関数STRのソースコードについても制御部31が命令情報33に基づいて生成する。なお、図20(a)と図20(b)では関数名がいずれも「STR」で同一となっているが、これらの関数の第2引数の型が相違するため、これらの関数はC++の文法上は別々の関数として区別されるため問題にはならない。
 このように、本実施形態においては、関数名と引数の個数が同一でオペランドの型が異なる複数のニーモニックを命令情報33に格納することにより、これらのニーモニックから同じ関数名のニーモニック関数を生成できる。そのため、ニーモニック関数の関数名が増大するのを防止でき、開発者が覚えるべき関数名が増えるのを抑制することができる。
 また、本実施形態では以下のようにデバッグが容易になるという利点も得られる。
 図21(a)は、本実施形態とは異なり、ニーモニック関数の引数をOperand型という共通の型で表した場合のニーモニック関数movのC++の疑似ソースコード55を示す図である。この場合は、ニーモニック関数movの引数とMachineCodeEmitter関数の第2引数の型がいずれもOperand型であるため、本実施形態のような型変換のコードはニーモニック関数movの内部に記述されていない。
 そして、図21(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似ソースコードを示す図である。
 開発者は、ソースファイル41における文「op0.type=REGISTER;」によって第1引数「OP0」がレジスタであることを意図しており、かつ文「op1.type=IMMEDIATE_VALUE」によって第2引数「OP1」が即値であることを意図している。また、ソースファイル41における文「mov(OP1,OP0);」は、図21(a)においてニーモニック関数movが引数として2つのOperand型の変数を受け付けるよう記述されているため、C++の文法上は問題がない。
 しかし、ニーモニック関数movとMachineCodeEmitter関数は、mov命令の第1オペランドがレジスタであり、かつ第2オペランドが即値であることを前提として作成されている。これに対し、文「mov(OP1, OP0);」においては第1引数に即値を表す変数「OP1」が記述され、第2引数にレジスタを表す変数「OP0」が記述されている。文「mov(OP1,OP0);」は、C++の文法上は問題がないため、このような誤りがあってもコンパイル時にエラーが出ない。
 よって、この場合には、コンパイル済みのプログラムを実行した後に、開発者がその出力で得られる結果が本来の結果と異なっていることを認識して初めてソースファイル41のソースコードの誤りに気付くことになる。また、結果がおかしいことに開発者が気付かなければ、そのまま正しい出力が得られているものとして開発者が誤りを見過ごしてしまうことになる。更に、仮に出力がおかしいことに開発者が気付いたとしても、ソースファイル41の記述行数が多い場合には、記述が誤っている箇所を開発者が特定するのに時間がかかり、デバックに長時間を要してしまう。
 一方、図22(a)は、本実施形態で生成したニーモニック関数movのC++の疑似ソースコードが記述されたソースファイル34の模式図である。本実施形態では、ニーモニック関数movの引数の型は{Register型、Immediate型}となる。
 そして、図22(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似ソースコードの例を示す図である。
 ここで、開発者が誤ってニーモニック関数movの第1引数と第2引数の各々の型を逆にしてしまい、「mov(imm,reg);」と記述したとする。この場合は、ソースファイル41におけるニーモニック関数movの呼び出し時の引数の型の順番が相違しているため、コンパイル時にコンパイラがエラーを出す。よって、図22(a)の例よりも早く開発者が間違いに気づくことができ、かつコンパイル時のエラーメッセージに基づいて間違いの箇所を特定するのが容易となる。
[処理の流れ]
 次に、本実施形態に係る関数生成方法について説明する。
 図23は、本実施形態に係る関数生成方法について示すフローチャートである。
 まず、第1の生成部36が、命令情報33を参照して、相互に対応する関数名、ニーモニック、オペランドの個数、及びオペランドの型を取得する(ステップS20)。
 次いで、第1の生成部36が、中身が空のニーモニック関数を生成し、それをソースファイル34に記述する(ステップS21)。そのニーモニック関数の引数の個数は、ステップS20で取得したオペランドの個数である。また、第1の生成部36は、ニーモニック関数の引数の型を、ステップS20で取得したオペランドの型に宣言するコードT11(図20(a)参照)を生成する。
 次に、第2の生成部37が、ニーモニック関数が引数として受け取った変数の型を、MachineCodeEmitter関数の第2引数である配列「oplist」のOperand型に変換するコードを生成する(ステップS22)。例えば、第2の生成部37は、図20で説明したコードT14を生成し、それをニーモニック関数の内部に記述する。
 次いで、第2の生成部37がMachineCodeEmitter関数を呼び出すコードを生成する(ステップS23)。例えば、第2の生成部37は、MachineCodeEmitter関数を呼び出すコード「MaschineCodeEmitter(nm,oplist);」を生成し、それをニーモニック関数の内部に記述する。このとき、第2の生成部37は、MaschineCodeEmitterの第2引数に、ステップS22の型変換後の配列「oplist」を渡す。これと共に、第2の生成部37は、図20のコードT11、T12等のような変数の宣言と代入を行う文もソースファイル34に記述する。
 続いて、第3の生成部38が、MachineCodeEmitter関数が生成した機械語をメモリ3に書き込むコードを生成し、それをソースファイル34に記述する(ステップS24)。一例として、第3の生成部38は、関数writeの引数にMachineCodeEmitter関数を記述した「write(MachineCodeEmitter(nm, oplist));」というコードをソースファイル34に記述する。
 そして、命令情報33に含まれる全ての行に対してステップS20~S24の処理を行う。その後、出力部39が、全てのニーモニック関数を含むソースファイル34を記憶部32に書き出す(ステップS25)。
 以上説明した本実施形態によれば、ステップS21において、第1の生成部36が、ニーモニック関数の引数の型をオペランドの型に宣言するコードT11(図20(a)参照)を生成する。これにより、複数のニーモニック関数の関数名を同一にすることができるため、開発者が覚えるべき関数名が増加するのを防止できる。
 しかも、図22(a)、(b)を参照して説明したように、ニーモニック関数の引数の型が間違っているとコンパイル時にエラーが出るため、ソースファイル41のバグを低減できる。そのため、バグのあるプログラムをターゲットマシン1で無駄に実行する時間が減り、ターゲットマシン1のハードウェア資源の無駄な消費を改善でき、かつ開発者がデバックをするのに要する工数を改善できる。
 (第3実施形態)
 命令セットに含まれる命令には、オペランドの値に制限が課せられている命令がある。例えば、「mov オペランド0、オペランド1」というフォーマットで記述されるmov命令においては、「オペランド1」の即値の範囲は、符号付9ビットの整数で表現できる-256~+255に制限される。開発者がこのような制限を忘れてニーモニック関数movをソースファイル34に記述しても、そのソースファイル34はコンパイル時にエラーとはならず、プログラム実行時にエラーとなる。これについて図24(a)、(b)を参照しながら説明する。
 図24(a)は、第2実施形態に従って生成したニーモニック関数movのC++のソースコードが記述されたソースファイル34の例を示す図である。このソースコードにおいては、引数のOP0、OP1に対してはRegister型やImmediate型等の型の制限はあるものの、引数の値自体には制限がない。
 図24(b)は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似ソースコードの例を示す図である。
 この例では、文「imm.value=-1000000;」により、変数immのメンバ「value」に値「-1000000」を代入している。前述のように、mov命令の第2オペランドの値は-256~+255の範囲内に制限されているため、値「-1000000」は第2引数として不適切な値である。
 しかし、ソースファイル41はC++の文法上は正しく記述されているためコンパイル時にエラーは発生しない。また、コンパイルで得られた実行可能プログラムを実行すると、その実行可能プログラムは、MachineCodeEmitter関数を呼び出すことにより、即値-1000000をレジスタに格納するmov命令に対応する機械語を生成しようとする。但し、そのような動作に対応する機械語は存在しないので、実行可能プログラムはその機械語を生成することができずエラーを出力する。このとき、ソースファイル41の記述行数が多い場合には、そのソースファイル41におけるどのニーモニック関数の呼び出しがこのエラーの原因となっているかを開発者が特定するのは難しい。
 そこで、本実施形態では、以下のようにしてソースファイル41におけるソースコードの誤りを開発者が気付けるようにする。
 図25は、本実施形態で使用する命令情報33について模式的に示す図である。
 図25に示すように、本実施形態に係る命令情報33においては、関数名、ニーモニック、オペランドの個数、オペランドの型、及びオペランドに課された制限の各々が対応付けられて格納される。第1、第2実施形態と同様に、この命令情報33は、開発者によって予め作成される。
 また、第1、第2実施形態と同様に、命令情報33の各々の行はそれぞれ異なる命令に対応する。例えば、1行目はmov命令に対応しており、オペランドに課された制限は{レジスタのインデックスの範囲が0~31、即値の範囲が-256~+255}というリスト形式で表現される。なお、そのリストの第1成分は第1オペランドに対する制限を表し、第2成分は第2オペランドに対する制限を表す。命令が第3オペランドをとる場合には、その第3オペランドに対する制限がリストの第3成分に格納される。
 また、命令情報33の2行目はshiftR命令に対応しており、オペランドに課された制限は{レジスタのインデックスの範囲が0~31、レジスタのインデックスの範囲が0~31、即値の範囲が-63~+63}となる。
 図26は、mov命令に対応した本実施形態に係るニーモニック関数movが記述されたソースファイル34のC++の疑似ソースコードの例について示す模式図である。
 このニーモニック関数movのソースコードは、命令情報33に基づいて制御部31が次のように生成する。
 まず、制御部31は、第2実施形態と同様にしてニーモニック関数movにコードT11~T15を記述する。更に、制御部31は、命令情報33を参照することにより、オペランドに課せられた制限を命令ごとに取得する。例えば、mov命令の場合は、{レジスタのインデックスの範囲が0~31、即値の範囲が-256~+255}という制限を制御部31が取得する。
 そして、制御部31は、ニーモニック関数movの引数が表すオペランドが上記の制限を違反している場合に例外を発生させるコードT16を生成し、それをソースファイル34に記述する。
 ここでは、if文によりオペランドが制限を違反しているかどうかを判断し、違反している場合にthrow文で例外を生成する。例えば、「OP0」のregIndexの値が0~31の範囲にない場合には、プログラム実行の際に「”Invalid register index is passed to mov mnemonic function.”」というエラーメッセージが標準出力に出力される。また、「OP1」のvalueの値が-256~+255の範囲にない場合には、プログラム実行の際に「”Invalid immediate value is passed to mov mnemonic function.”」というエラーメッセージが標準出力に出力される。
 そして、図27は、このニーモニック関数movを利用して開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似ソースコードの例を示す図である。
 この例では、文「imm0.value = 1000000;」により、ニーモニック関数movの第2引数「imm0」のメンバ「value」に1000000を代入している。前述のように、mov命令の第2オペランドの値は-256~+255の範囲に制限されている。よって、文「mov(reg0, imm0);」を実行すると例外が発生し、「”Invalid immediate value is passed to mov mnemonic function.”」という文字列が標準出力に出力されることになる。
 これにより、開発者は、ニーモニック関数movの引数がmov命令の制限を違反していることに気づくことができ、ソースコード66を簡単にデバッグすることができる。
[処理の流れ]
 次に、本実施形態に係る関数生成方法について説明する。
 図28は、本実施形態に係る関数生成方法について示すフローチャートである。
 まず、第1の生成部36が、命令情報33を参照して、相互に対応する関数名、ニーモニック、オペランドの個数、オペランドの型、及びオペランドに課された制限を取得する(ステップS30)。
 次いで、第1の生成部36が、中身が空のニーモニック関数を生成し、それをソースファイル34に記述する(ステップS31)。そのニーモニック関数の引数の個数は、ステップS30で取得部35が取得したオペランドの個数である。また、その引数の型は、ステップS30で取得部35が取得したオペランドの型である。
 次に、第2の生成部37が、ニーモニック関数が引数として受け取った変数に対応するオペランドが制限を違反している場合に例外を発生させるコードを生成する(ステップS32)。例えば、第2の生成部37は、図26で説明したコードT16を生成し、それをニーモニック関数の内部に記述する。
 次に、第2の生成部37が、ニーモニック関数が引数として受け取った変数の型を、MachineCodeEmitter関数の第2引数であるoperand型の配列に変換するコードを生成する(ステップS33)。例えば、第2の生成部37は、図26で説明したコードT14をニーモニック関数の内部に記述する。
 次いで、第2の生成部37がMachineCodeEmitter関数を呼び出すコードを生成する(ステップS34)。例えば、第2の生成部37は、ニーモニック関数の内部に「MaschineCodeEmitter(nm,oplist)」というコードを記述する。これと共に、第2の生成部37は、図26のコードT12、T13等のような変数の宣言と代入を行う文もソースファイル34に記述する。
 続いて、第3の生成部38が、MachineCodeEmitter関数が生成した機械語をメモリ3に書き込むコードを生成する(ステップS35)。例えば、第3の生成部38は、関数writeの引数にMachineCodeEmitter関数を記述した「write(MachineCodeEmitter(nm, oplist));」というコードをソースファイル34に記述する。
 そして、命令情報33に含まれる全ての行に対してステップS30~S35の処理を行う。その後、出力部39が、全てのニーモニック関数を含むソースファイル34を記憶部32に書き出す(ステップS36)。
 以上説明した本実施形態によれば、ステップS32において、第2の生成部37が、オペランドが制限を違反している場合に例外を発生させるコードT16(図26参照)を生成する。そのため、開発者が早期にソースコード66(図27参照)の誤りに気付くことができ、開発者がデバッグするのに要する工数を減らすことができる。しかも、バグのあるプログラムをターゲットマシン1で無駄に実行する時間が減り、ターゲットマシン1のハードウェア資源の無駄な消費を改善できる。
 なお、命令情報33の「オペランドに課された制限」の種類としては、(1)「レジスタインデックスが特定の範囲内である」、(2)「即値が特定の範囲内である」、(3)「即値は整数である」、(4)「即値は小数である」等がある。この場合、制御部31が取得する命令情報33のデータ形式は、「オペランドに課された制限」の種類の番号(1)~(4)と、制限の上限値と、制限の下限値とを有する形式となる。
 そして、(1)~(4)に対応するオペランドの違反をチェックするコードのテンプレートをあらかじめ用意しておき、ステップS32では制御部31が必要なテンプレートを参照すればよい。更に、制限の上限値と下限値とをチェックする必要があるケースでは、制御部31がこれらの値をテンプレートに埋め込むことで例外を発生するコードを生成すればよい。
 (第4実施形態)
 本実施形態では、開発者がソースコードの誤りに気付くのを第3実施形態よりも容易にする。なお、本実施形態で使用するニーモニック関数は特に限定されないが、以下ではadd命令に対応したニーモニック関数を例にして説明をする。そこで、まずadd命令について説明する。
 図29(a)、(b)は、add命令のアセンブリの文法について示す図である。
 add命令には様々なオペランドをとる種類があるが、図29(a)では「DSTレジスタ」と二つの「SRCレジスタ」とをオペランドとするadd命令について例示している。このadd命令は、二つの「SRCレジスタ」の内容同士を加算した値を「DSTレジスタ」に格納する命令である。
 一方、図29(b)は、「DSTレジスタ」、「SRCレジスタ」、及び「即値」の三つのオペランドをとるadd命令を例示する図である。このadd命令は、「SRCレジスタ」の内容に「即値」を加算した値を「DSTレジスタ」に格納する命令である。
 図30は、本実施形態に係る命令情報33を模式的に示す図である。
 図30に示すように、この命令情報33には、第3実施形態に従って関数名、ニーモニック、オペランドの個数、オペランドの型、及びオペランドに課された制限の各々が対応付けられて格納される。なお、本実施形態では関数名をアルファベットの大文字で表すことにする。また、第1~第3実施形態と同様に、命令情報33は開発者によって予め作成される。
 図29(a)、(b)の二つのadd命令に対応して命令情報33には二つの関数名「ADD」が格納されているため、制御部31は、第3実施形態に従って二つのニーモニック関数ADDを生成することになる。第3実施形態で説明したように、引数の個数と関数名とが同一の複数のニーモニック関数が存在しても、それらの引数の型が異なればC++の文法上は両者を区別することができる。
 以下では、命令情報33の二行目に対応したニーモニック関数ADDを例にして説明する。命令情報33によれば、このニーモニック関数ADDのオペランドの型は{Register型,Register型,Immediate型}である。また、第1オペランドと第2オペランドに課された制限は、いずれも「レジスタのインデックスの範囲が0~31」である。そして、第3オペランドに課された制限は、「即値の範囲が-1024~+1023」である。
 図31は、この命令情報33に基づいて、第3実施形態に従って制御部31が生成したニーモニック関数ADDのソースコードの一例を示す図である。
 ここでは、ファイル名が「mnemonic.h」のソースファイル34を制御部31が生成し、そのソースファイル34の20行目からニーモニック関数ADDの記述が始まるものとする。なお、このソースファイル34において第3実施形態で説明したのと同種のコードには第3実施形態と同じ符号を付し、その説明は省略する。
 図31に示すように、このソースファイル34には、第3実施形態で説明したコードT11~T16が制御部31によって生成される。このうち、コードT16は、ニーモニック関数ADDの引数が表すオペランドが命令情報33における制限を違反している場合に例外を発生させるコードである。
 更に、この例では、ソースファイル34の21行目に、制御部31が関数「SET()」を呼び出すコードT17を生成する。
 図32は、関数「SET()」を定義するC++の疑似ソースコードを模式的に示す図である。
 関数「SET()」の定義は、制御部31によってソースファイル34であるmnemonic.hの一部に記述される。この例では、制御部31が、関数「SET()」を定義するためのコードT20~T22をソースファイル34に生成する。
 このうち、コードT20は、関数「SET()」のマクロを宣言するコードである。ここでは、関数「SET()」は、プリプロセッサによって関数「setCodeInfo(__FILE__, __LINE__, __func__)」に置換されるものとして定義される。
 その関数「setCodeInfo」の引数に現れる変数「__FILE__」と「__LINE__」はC++における事前定義マクロであり、変数「__func__」はC++における事前定義識別子である。これらの変数は、コンパイル時にプリプロセッサによって所定の内容に変換される。例えば、「__FILE__」は、当該「__FILE__」が記述されたファイルのファイル名に変換される。また、「__LINE__」は、当該「__LINE__」が記述された行番号に変換される。そして、「__func__」は、当該「__func__」が記述された関数の関数名に変換される。
 一方、コードT21は、char型のグローバル変数「g_filename」、「g_funcname」とint型のグローバル変数「g_line」とを定義するコードである。
 そして、コードT22は、関数「setCodeInfo」の中身を定義するコードである。関数「setCodeInfo」は、三つの引数「filename」、「line」、及び「funcname」を受け取り、その各々をグローバル変数「g_filename」、「g_line」、及び「g_funcname」に代入する関数として定義される。
 この例では、ソースファイル34(図31参照)のコードT17の位置においてプリプロセッサが「SET()」を「setCodeInfo(__FILE__, __LINE__, __func__)」に置換する。更に、プリプロセッサは、「__FILE__」を呼び出し元のソースファイル34のファイル名である文字列「mnemonic.h」に置換し、「__LINE__」をソースファイル34における関数「SET()」の行番号である「21」に置換する。また、プリプロセッサは、「__func__」を関数「SET()」の呼び出し元の関数であるニーモニック関数ADDの関数名「ADD」に置換する。
 よって、ソースファイル34をコンパイルして生成した実行可能プログラムを実行すると、コードT17に対応する部分の実行時に、変数「g_filename」に「mnemonic.h」が格納され、変数「g_funcname」に「ADD」が格納される。そして、変数「g_line」に「21」が格納される。
 図33は、開発者がC++で記述したアプリケーションプログラム用のソースファイル41の疑似ソースコードを模式的に示す図である。ここではソースファイル41のファイル名を「sample.cpp」とし、開発者がそのソースファイル41にコードT25~T28を記述したものとする。
 このうち、コードT25は、「reg0」、「reg1」、及び「imm0」の各変数を定義する文である。このうち、変数「reg0」及び「reg1」はReg型として定義される。また、変数「imm0」はImm型として定義される。
 また、コードT26は、「reg0」、「reg1」、及び「imm0」の各変数のメンバに値を代入する文である。この例では、変数「reg0」のメンバ「regIndex」に「0」が代入され、変数「reg1」のメンバ「regIndex」に「1」が代入される。そして、変数「imm0」のメンバ「value」には「100000」が代入される。
 一方、コードT27は、ニーモニック関数ADDを呼び出すと共に、その引数に上記の各変数「reg0」、「reg1」、「imm0」の内容を渡すコードである。ここでは、例外処理を行うために開発者がtry文の内部にコードT27を記述する。前述のように変数「imm0」には値「100000」が代入されているが、命令情報33(図30参照)によればニーモニック関数addの第3引数がとり得る値は-1024~+1023の範囲に制限されている。よって、このニーモニック関数ADDを実行するとコードT16(図31参照)において例外が投げられることになる。
 そして、コードT28は、このように例外が投げられたときに、各グローバル変数「g_filename」、「g_line」、及び「g_filename」の内容を標準出力に出力するためのコードである。この例では前述のように「g_filename」、「g_line」、及び「g_filename」の各々に「mnemonic.h」、「22」、及び「ADD」が格納されているため、これらが標準出力に出力されることになる。
 このソースファイル41から実行可能プログラム44(図13参照)を生成するには、第1実施形態で説明した図13の処理に従ってプログラム群42がビルドを行えばよい。
 図34は、このようにして生成した実行可能プログラム44をターゲットマシン1(図1参照)で実行したときの標準出力への出力例を示す図である。
 この例では、前述のようにソースファイル41(図33参照)におけるニーモニック関数ADDの第3引数が命令情報33で規定される制限を満たしていない。よって、標準出力には、コードT16(図31参照)における「Invalid immediate value of OP2 is passed to add mnemonic function.」というエラーメッセージ74が出力される。更に、コードT28(図33参照)における各グローバル変数「g_filename」、「g_line」、及び「g_funcname」の内容を示すメッセージ75も標準出力に出力される。
 開発者は、エラーメッセージ74とメッセージ75とに基づいて、自らが記述したプログラムのどこかでニーモニック関数ADDの引数を誤って指定していることに気づくことができる。
 しかし、メッセージ75には、誤りのあるソースファイル41のファイル名である「sample.cpp」ではなく、ニーモニック関数ADDを定義しているソースファイル34のファイル名「mnemonic.h」が出力されている。更に、メッセージ75における行数や関数名にも、記述に誤りがあるソースファイル41(sample.cpp)における行数や関数名ではなく、ソースファイル34(mnemonic.h)の行数や関数名が出力される。
 これではアプリケーションプログラム用のソースファイル41(sample.cpp)のどこに間違いがあるのか開発者が分らず、アプリケーションプログラムのデバッグに長時間を要し、プログラム開発が非効率となってしまう。更に、コンパイラに対し複数のソースファイル41を与えている場合、どのソースファイル41の中のADD関数の使用で誤っているのかの判別も困難である。
 この点に鑑み、本実施形態では以下のようにして開発者がデバッグするのを容易にする。
[機能構成]
 図35は、本実施形態に係る情報処理装置30の機能構成図である。
 なお、図35において、第1~第3実施形態で説明したのと同じ要素にはこれらの実施形態におけるのと同じ符号を付し、以下ではその説明を省略する。
 図35に示すように、情報処理装置30の制御部31は、既述の第1~第3の生成部36~38と出力部39の他に、第4の生成部80と定義ファイル生成部81とを有する。
 図36は、本実施形態において制御部31が生成したニーモニック関数ADDのC++の疑似ソースコードを示す模式図である。ここでは、ファイル名が「mnemonic.h」というソースファイル34を制御部31が生成し、そのソースファイル34に制御部31がニーモニック関数ADDを生成するものとする。
 なお、図36において、第1~第3実施形態で説明したのと同種のコードには同じ符号を付し、以下ではその説明を省略する。
 図36に示すように、本実施形態では、第1実施形態と同様にして第1の生成部36がニーモニック関数ADDの引数にコードT11を生成する。そのコードT11は、命令addの三つのオペランドに対応した各引数「OP0」、「OP1」、及び「OP2」の型を宣言するコードである。
 また、第1の生成部36は、ニーモニック関数ADDの複数の引数のうちの最初の位置にコードT18を記述する。コードT18は、「strFile」、「line」、及び「strFunc」の各変数の型を定義するコードである。これらの変数のうち、「strFile」は、ファイル名を格納するための文字列型の変数である。また、「line」は、ファイルにおける行数を格納するための整数型の変数である。そして、「strFunc」は、関数名を格納するための文字列型の変数である。なお、コードT18における「strFile」、「line」、及び「strFunc」の各変数を記述する順序は特に限定されない。第1の生成部36は、これらの変数を任意の順序でコードT18に記述し得る。
 そして、制御部31は、第3実施形態と同様にしてその他のコードT12~T16をソースファイル34に生成する。
 更に、これらのコードT12~T16の他に、第4の生成部80がソースファイル34にコードT17を生成する。図31の例と同様に、コードT17は、関数「SET()」を呼び出すコードである。また、第4の生成部80は、ソースファイル34の一部に関数「SET()」の処理を定義するコードを生成する。
 図37は、本実施形態において第4の生成部80が生成する関数「SET()」のC++の疑似ソースコードの一例を示す図である。
 図32の例と異なり、本実施形態では、コードT20において関数「setCodeInfo」の引数に、ニーモニック関数ADDの引数である「strFile」、「line」、及び「strFunc」の各変数が渡される。
 また、コードT21とT22の各々は、図32の例と同様に関数「setCodeIndo」の各引数をグローバル変数「g_filename」、「g_funcname」、及び「g_line」の各々に代入するコードである。
 一方、定義ファイル生成部81(図35)は、図38に例示する定義ファイル82を生成する処理部である。
 図38は、定義ファイル生成部81が生成した定義ファイル82の疑似ソースコードを示す模式図である。
 図38に示すように、定義ファイル82は、「#define」で始まる複数のマクロを有する。これらのマクロは、ニーモニック関数の各々に対応するように定義ファイル生成部81により生成される。そして、各マクロは、開発者が記述したアプリケーションプログラム用のソースファイルにおける各ニーモニック関数の引数に新たな変数を追加する指示をプリプロセッサに与えるマクロとなっている。これについて図39のソースファイルを例にして説明する。
 図39は、本実施形態において開発者が記述したアプリケーションプログラム用のソースファイル41のC++の疑似コードを示す図である。なお、図39において、図33で説明したのと同じコードには図33におけるのと同じ符号を付し、以下ではその説明を省略する。
 なお、このソースファイル41においては、図33の例とは異なり、開発者がニーモニック関数の関数名をアルファベットの小文字で記述するものとする。例えば、開発者は、101行目においてニーモニック関数を呼び出すコードT27を「add(reg0, reg1, imm0)」と記述する。そのコードT27におけるニーモニック関数addの第3引数「imm0」のメンバ「value」には、コードT26によって「100000」という値が代入されている。この値は、命令情報33(図30参照)における「-1024~1023」との制限を満たさない不適切な値である。
 この場合の定義ファイル82(図38参照)の一行目のマクロ「#define add(...) ADD(__FILE__, __LINE__, __func__, __VA_ARGS__)」の動作について説明する。
 まず、このマクロは、ソースファイル41におけるニーモニック関数addの関数名「add」を「ADD」に置換するようにプリプロセッサに指示を出す。更に、このマクロは、ニーモニック関数addの引数の前に、新たな引数として「__FILE__」、「__LINE__」、及び「__func__」の各々を追加するようにプリプロセッサに指示を出す。なお、「__VA_ARGS__」は、ニーモニック関数addの引数が格納される可変長引数を示す事前定義識別子である。これにより、ソースファイル41の101行目の記述「add(reg0, reg1, imm0);」は、プリプロセッサによって「ADD(__FILE__, __LINE__, __func__, reg0, reg1, imm0);」と置換されることになる。
 前述のように、「__FILE__」、「__LINE__」、及び「__func__」の各々は、ファイル名、行番号、及び関数名に置換されるC++の事前定義マクロや事前定義識別子である。プリプロセッサは、これらの事前定義マクロや事前定義識別子の各々を、ファイル名、行番号、及び関数名に置換する。なお、ファイル名、及び行番号の各々は、ニーモニック関数addに関する関数情報の一例である。したがって、ニーモニック関数「ADD」の引数として、ニーモニック関数「add」が記述されたファイル名、行番号、関数名が渡されることになる。
 定義ファイル生成部81は、命令情報33(図30参照)を参照することによりこのような定義ファイル82を生成し、それを記憶部32に格納する。
 例えば、定義ファイル生成部81は、命令情報33を一行ずつ読み込んで関数名を取得し、その関数名ごとにディレクティブを生成する。取得した関数名がSUBの場合には、定義ファイル生成部81は、定義ファイル82にディレクティブ「#define sub(...) SUB(__FILE__, __LINE__, __func__, __VA_ARGS__)」を生成することになる。
[開発環境]
 図40は、本実施形態に係る開発環境について示す模式図である。
 なお、図40において、第1実施形態の図13で説明したのと同じ要素には第1実施形態におけるのと同じ符号を付し、以下ではその説明を省略する。
 ここでは、情報処理装置30の内部に開発環境を構築する場合を想定する。その場合、制御部31がニーモニック関数のソースファイル34と定義ファイル82とを生成する。
 一方、開発者は、C++を用いてアプリケーションプログラム用のソースファイル41を作成する。以下では、開発者が図39のようにファイル名が「sample.cpp」のソースファイル41を作成し、そのソースファイル41の101行目にニーモニック関数andを呼び出すコードT27を記述した場合について説明する。
 そして、開発者の指示の下で、コンパイラ、アセンブラ、及びリンカのプログラム群42がビルドを行う。ビルドに際しては、まずコンパイラに含まれるプリプロセッサがソースファイル34、41、43と定義ファイル82とを読み込む。なお、第1実施形態で説明したように、MachineCodeEmitter関数が記述されたソースファイル43に代えて、機械語生成関数が記述されたバイナリ形式の実行ライブラリファイル43aを使用してもよい。
 次いで、プリプロセッサが、定義ファイル82に従って、ソースファイル41の101行目の「add(reg0, reg1, imm0);」を「ADD(__FILE__, __LINE__, __func__, reg0, reg1, imm0);」に置換する。
 このとき、プリプロセッサは、更に「__FILE__」、「__LINE__」、及び「__func__」の各々に、ソースファイル41の101行目を実行した時点での内容を格納する。よって、「__FILE__」にはソースファイル41のファイル名である「sample.cpp」が格納される。また、「__LINE__」には、ソースファイル41においてニーモニック関数addが記述されている行番号の「101」が格納される。更に、「__func__」には、プリプロセッサによって置換された後の関数名である「func0」が格納される。
 そして、「sample.cpp」、「101」、及び「func0」の各々の内容は、ソースファイル34におけるニーモニック関数ADD(図36参照)に、引数「strFile」、「line」、及び「strFunc」として渡される。この状態で当該ソースファイル34のコードT17における関数「SET()」が実行されることにより、グローバル変数「g_filename」、「g_funcname」、及び「g_line」の各々への代入が実行される。これにより、本実施形態では、グローバル変数「g_filename」、「g_funcname」、及び「g_line」の各々に「sample.cpp」、「func0」、及び「101」が代入されることになる。
 続いて、コンパイラがアセンブリファイルを生成し、更にアセンブラがそのアセンブリファイルを機械語の命令列に変換してオブジェクトファイルを生成する。
 その後、リンカは、オブジェクトファイルと種々のライブラリとをリンクすることにより、プロセッサ2(図1参照)で実行可能なバイナリ形式の実行可能プログラム44を生成する。
 図41は、このようにして生成した実行可能プログラム44をターゲットマシン1(図1参照)で実行したときの標準出力への出力例を示す図である。
 前述のように、この例ではソースファイル41におけるニーモニック関数ADDの第3引数が命令情報33で規定される制限を満たしていない。よって、標準出力には、コードT16(図36参照)における「Invalid immediate value of OP2 is passed to add mnemonic function.」というエラーメッセージ84が出力される。
 更に、図39のコードT28における各グローバル変数「g_filename」、「g_line」、及び「g_funcname」の内容を示すメッセージ85も標準出力に出力される。
 このとき、本実施形態では、定義ファイル82(図38参照)を使用したことで、前述のようにグローバル変数「g_filename」、「g_funcname」、及び「g_line」の各々内容は「sample.cpp」、「func0」、及び「101」となっている。
 よって、ソースファイル41(図39参照)のコードT28を実行することにより、これらの内容を含む「file name:sample.cpp, line:101, function name: func0」というメッセージ85が標準出力に出力される。そのメッセージ85には、開発者が自ら記述したアプリケーションプログラム用のソースファイル41のファイル名「sample.cpp」と、そのソースファイル41でエラーが発生した行数「101」と、エラーが発生した関数名「func0」が含まれる。
 よって、図34の例と異なり、本実施形態では、エラーが発生したソースファイル41のファイル名や、そのソースファイル41でエラーが発生した位置を開発者が特定することができ、開発者が容易にデバッグをすることができる。その結果、デバッグに要する時間を短縮でき、プログラム開発を効率化することが可能となる。
 なお、図41におけるのと同様の実行結果を得るために、定義ファイル82を使用せずに、例えば開発者が図42に示すアプリケーション用のソースファイル41を記述することも考えられる。
 図42は、本実施形態の別の例に係るソースファイル41のC++の疑似ソースコードの例を示す模式図である。
 図42の例では、開発者が、ソースファイル41にニーモニック関数ADDを記述すると共に、その引数に「__FILE__」、「__LINE__」、及び「__func__」の各事前定義マクロや事前定義識別子を自ら記述する。この場合は、ニーモニック関数ADDが記述されたソースファイル41のファイル名が「__FILE__」に格納される。また、ソースファイル41においてニーモニック関数ADDが記述されている行番号と、その記述を含む関数func0の関数名がそれぞれ「__LINE__」と「__func__」に格納される。
 このような記述を行うことによっても図41におけるのと同様の実行結果を得ることができる。しかし、関数の引数に「__FILE__」、「__LINE__」、及び「__func__」の各事前定義マクロと事前定義識別子を開発者が自ら記述するのは極めて煩わしく、更にタイプミスも発生する恐れもある。
 これに対し、本実施形態では定義ファイル生成部81が自動的に定義ファイル82を生成するため、このような煩雑さを回避することができ、開発者の負担減を図ることができる。
 なお、本実施形態では、図36に示したように、ソースファイル34においてニーモニック関数ADDの引数を示すコードT18をコードT11の前の位置に記述したが、順番を逆にしてコードT18をコードT11の後ろの位置に記述することも考えられる。この場合は、ニーモニック関数ADDに対応したマクロも、引数の順番を逆にして「#define add(...) ADD(__VA_ARGS__, __FILE__, __LINE__, __func__)」となる。しかし、このような記述では以下のような不都合が生じる。
 図43(a)、(b)は、そのような不都合について模式的に示す図である。
 命令セットに含まれる命令には、同一のニーモニックでオペランドの個数が異なる命令が存在する。ここで、add命令がそのような命令の一つであり、レジスタ型のオペランドを3個とるadd命令と、3個のレジスタ型と1個の即値型の合計4個のオペランドをとるadd命令が存在する場合を説明する。
 レジスタ型のオペランドを3個とるadd命令は、第2、第3オペランドで指定されるレジスタの値を加算し、その結果を第1オペランドで指定されるレジスタに格納する命令とする。
 一方、3個のレジスタ型と1個の即値型の合計4個のオペランドをとるadd命令は、第2、第3オペランドで指定されるレジスタの値を加算する命令とする。その加算の結果は、第3オペランドで指定される即値と加算され、その結果は第1オペランドに格納される。
 この場合、前者のadd命令は、後者のadd命令の即値を「0」としたケースとして考えることができる。
 一方、C++では、関数の定義において複数の引数を記述した場合であっても、省略時の値が明記された最後の引数を省略してその関数を呼び出すことができる。この特徴を利用して、本実施形態においては、オペランドの個数が異なる2種類のadd命令に対応した一つのニーモニック関数addの定義のみをソースファイル34に記述する。
 図43(a)、(b)における「void ADD(Reg x1, Reg x2, Reg x3, Imm imm=imm(0), string &strFile, size_t line, string &strFunc」が、このように2種類のadd命令の各々の引数を考慮したニーモニック関数ADDであったとする。
 このニーモニック関数ADDにおいては、最初の四個の引数「x1」、「x2」、「x3」、「imm」がadd命令のオペランドに対応する。なお、前述のように、この例ではコードT11、T18の順序が図36の例と逆になっている。
 この場合に、コンパイルが成功する図43(a)についてまず説明する。
 図43(a)の例では、アプリケーションプログラム用のソースファイル41に開発者がコード「add(x1, x2, x3, imm)」を記述した場合を想定している。そのコード「add(x1, x2, x3, imm)」は、4個のオペランドをとるadd命令に対応したコードである。
 この場合、定義ファイル82におけるマクロ「#define add(...) ADD(__VA_ARGS__, __FILE__, __LINE__, __func__)」によって、プリプロセッサは上記のコードを「ADD(x1, x2, x3, imm, __FILE__, __LINE__, __func__)」に置換する。
 そして、置換後のこのコードが、ソースファイル34における関数ADDの定義を呼び出す。この場合、「ADD(x1, x2, x3, imm, __FILE__, __LINE__, __func__)」とソースファイル34における関数ADDの7個の引数の各々の型は一致する。よって、コンパイルは成功することになる。
 一方、図43(b)はコンパイルが失敗する場合を例示する模式図である。
 ここでは、開発者が、3個のオペランドをとるadd命令に対応した3個の引数を含むコード「add(x1, x2, x3)」をソースファイル41に記述した場合を想定している。この場合は、定義ファイル82におけるマクロ「#define add(...) ADD(__VA_ARGS__, __FILE__, __LINE__, __func__)」によって、プリプロセッサは上記のコードを「ADD(x1, x2, x3, __FILE__, __LINE__, __func__)」に置換する。そして、置換後のこのコードが、ソースファイル34における関数ADDの定義を呼び出す。
 しかし、「ADD(x1, x2, x3, __FILE__, __LINE__, __func__)」の第6引数「__func__」は文字列型であるのに対し、ソースファイル34における関数ADDの第6引数「line」は整数型である。よって、呼び出し側と呼び出される側の各々の引数の型が一致せず、コンパイルは成功しない。
 このような不都合を回避するために、図36に示したように、第1の生成部36が、ニーモニック関数ADDの複数の引数のうちの最初の位置に、ファイル名等の関数情報を記述したコードT18を記述するのが好ましい。
 例えば、図43(a)のソースファイル34においてコードT11、T18の順番を入れ替え、本実施形態のようにコードT11よりも前の位置にコードT18を記述し、かつソースファイル41に「add(x1, x2, x3)」と記述した場合を考える。この場合は、定義ファイル82のマクロ「#define add(..) ADD(__FILE__, __LINE__, __func__, __VA_ARGS__)」により、プリプロセッサが上記のコードを「ADD(__FILE__, __LINE__, __func__, x1, x2, x3)」に置換する。コンパイラは、このように6個の引数を持つADD関数の呼び出しを、ソースファイル34における7個の引数を持つ関数ADDの定義において7個目の引数を省略した呼び出しであることをC++の文法に即して認識できる。
 また、省略されていない6個の引数はそれぞれ、文字列型、整数型、文字列型、レジスタ型、レジスタ型、レジスタ型であり、これはソースファイル34で定義されているADD関数の最初の6個の引数の型に一致している。よって、上記の記述「add(x1, x2, x3)」は、エラーなくコンパイルすることができる。
[処理の流れ]
 次に、本実施形態に係る定義ファイルの生成方法について説明する。
 図44は、本実施形態に係る定義ファイルの生成方法について示すフローチャートである。
 まず、定義ファイル生成部81が、命令情報33(図30参照)から関数名を取得し(ステップS40)、その関数名に対応したマクロ#defineを生成する(ステップS41)。例えば、定義ファイル生成部81が命令情報33の1行目の関数名「ADD」を取得した場合を考える。この場合は、定義ファイル生成部81は、「#define add(...) ADD(__FILE__, __LINE__, __func__, __VA_ARGS__)」というマクロを生成する。
 そして、定義ファイル生成部81は、命令情報33(図30参照)の各行に対してステップS40とステップS41とを繰り返す。なお、上記のマクロ「#define add(...) ADD(__FILE__, __LINE__, __func__, __VA_ARGS__)」は、置換前の関数名「add」と置換後の関数名「ADD」を除き、全ての関数名について同じ書式である。よって、関数名が同一の場合にはマクロも同一となるため、関数名が重複している場合には、定義ファイル生成部81は、命令情報33の次の関数名からステップS40とステップS41とを繰り返す。
 その後、定義ファイル生成部81が、命令情報33における全ての関数名に対応したマクロが記述された定義ファイル82を記憶部32に書き出す(ステップS42)。
 以上により、本実施形態に係る定義ファイルの生成方法の基本ステップを終了する。
 (ハードウェア構成)
 次に、第1~第4実施形態に係る情報処理装置30のハードウェア構成について説明する。
 図45は、第1~第4実施形態に係る情報処理装置30のハードウェア構成図である。
 図45に示すように、情報処理装置30は、記憶装置30a、メモリ30b、プロセッサ30c、通信インターフェース30d、表示装置30e、及び入力装置30fを有する。これらの各部は、バス30gにより相互に接続される。
 このうち、記憶装置30aは、HDDやSSD(Solid State Drive)等の不揮発性のストレージデバイスであり、本実施形態に係る関数生成プログラム90を記憶する。
 なお、関数生成プログラム90をコンピュータが読み取り可能な記録媒体30hに記録させておき、プロセッサ30cに記録媒体30hの関数生成プログラム90を読み取らせるようにしてもよい。
 そのような記録媒体30hとしては、例えばCD-ROM(Compact Disc - Read Only Memory)、DVD(Digital Versatile Disc)、及びUSB(Universal Serial Bus)メモリ等の物理的な可搬型記録媒体がある。また、フラッシュメモリ等の半導体メモリやハードディスクドライブを記録媒体30hとして使用してもよい。これらの記録媒体30hは、物理的な形態を持たない搬送波のような一時的な媒体ではない。
 更に、公衆回線、インターネット、及びLAN(Local Area Network)等に接続された装置に関数生成プログラム90を記憶させておき、プロセッサ30cがその関数生成プログラム90を読み出して実行するようにしてもよい。
 一方、メモリ30bは、DRAM等のようにデータを一時的に記憶するハードウェアであって、その上に前述の関数生成プログラム90が展開される。
 プロセッサ30cは、情報処理装置30の各部を制御したり、メモリ30bと協働して関数生成プログラム90を実行したりするCPU(Central Processing Unit)やGPU(Graphical Processing Unit)等のハードウェアである。
 このようにメモリ30bとプロセッサ30cとが協働して関数生成プログラム90を実行することにより、図11の第1の生成部36、第2の生成部37、第3の生成部38、及び出力部39を備えた制御部31が実現される。また、図35の第4の生成部80と定義ファイル生成部81も、メモリ30bとプロセッサ30cとが協働して関数生成プログラム90を実行することにより実現される。また、図11と図35の各々の記憶部32は、記憶装置30aとメモリ30bによって実現される。
 更に、通信インターフェース30dは、情報処理装置30をLAN等のネットワークに接続するためのインターフェースである。
 そして、表示装置30eは、液晶表示装置等のハードウェアであって、開発者に種々の情報の入力を促すプロンプトや、コンパイル時のエラーメッセージ等を表示する。また、入力装置30fは、キーボードやマウス等のハードウェアである。例えば、開発者は、入力装置30fを操作することにより、情報処理装置30に対してコンパイルの実行の指示を出すことになる。
1…ターゲットマシン、2…プロセッサ、3…メモリ、4…計算コア、5…レジスタファイル、30…情報処理装置、30a…記憶装置、30b…メモリ、30c…プロセッサ、30d…通信インターフェース、30e…表示装置、30f…入力装置、30g…バス、30h…記録媒体、31…制御部、32…記憶部、33…命令情報、34…ニーモニック関数のソースファイル、36…第1の生成部、37…第2の生成部、38…第3の生成部、39…出力部、80…第4の生成部、81…定義ファイル生成部。

Claims (12)

  1.  命令に関する命令情報を記憶した記憶部を参照して、前記命令に対応した関数であって、前記命令のオペランドを表す引数を受け取る第1の関数を生成する処理と、
     前記引数が表す前記オペランドに対して前記命令が行う処理を表す機械語を返す第2の関数を呼び出すコードを前記第1の関数の内部に生成する処理と、
     前記機械語をメモリに書き込むコードを前記第1の関数の内部に生成する処理と、
     をコンピュータに実行させるための関数生成プログラム。
  2.  前記命令情報は、前記オペランドの個数と前記命令の名前とを対応付けた情報であり、
     前記記憶部を参照して、前記命令の名前と同じ関数名を前記第1の関数に付ける処理と、
     前記記憶部を参照して、前記個数に等しい個数の前記引数を宣言するコードを生成する処理とを更に有することを特徴とする請求項1に記載の関数生成プログラム。
  3.  前記命令情報は、前記オペランドの種類を表す型と前記命令とを対応付けた情報であり、
     前記記憶部を参照して、前記引数の型を前記オペランドの前記型に宣言するコードを生成する処理と、
     前記第1の関数が前記引数として受け取った変数を、前記第2の関数の引数の型に変換して該第2の関数に渡すコードを生成する処理とを更に有することを特徴とする請求項1に記載の関数生成プログラム。
  4.  前記命令情報は、前記オペランドの種類を表す型、前記命令、及び前記第1の関数の関数名を対応付けた情報であり、
     前記命令情報に、前記関数名が同一であり、かつ、前記オペランドの型が異なる複数の相異なる前記命令が存在することを特徴とする請求項3に記載の関数生成プログラム。
  5.  前記命令情報は、前記オペランドに課された制限を前記命令に対応付けた情報であり、
     前記記憶部を参照して、前記引数に対応する前記オペランドが前記制限を違反している場合に例外を発生させるコードを生成する処理を更に有することを特徴とする請求項1に記載の関数生成プログラム。
  6.  前記第1の関数を呼び出すようにソースファイルに記述されたコードに引数を追加して、追加した前記引数に、前記ソースファイルにおける前記第1の関数に関する関数情報を格納する指示をプリプロセッサに与える定義ファイルを生成する処理を更に有することを特徴とする請求項5に記載の関数生成プログラム。
  7.  前記命令情報は、前記命令、前記制限、及び前記第1の関数の関数名の各々を対応付けた情報であり、
     前記定義ファイルを生成する処理は、前記命令情報を記憶した前記記憶部を参照して、前記指示を行うマクロを前記関数名ごとに生成することにより行われることを特徴とする請求項6に記載の関数生成プログラム。
  8.  前記関数情報が格納される前記引数を、前記第1の関数の複数の引数のうちの最初の位置に生成する処理を更に有することを特徴とする請求項7に記載の関数生成プログラム。
  9.  前記関数情報は、前記ソースファイルのファイル名、前記ソースファイルにおいて前記第1の関数を呼び出す前記コードが記述された行番号、及び前記第1の関数の関数名のいずれかであることを特徴とする請求項6に記載の関数生成プログラム。
  10.  前記第1の関数を生成する処理において、マクロとして前記第1の関数を生成することを特徴とする請求項1に記載の関数生成プログラム。
  11.  命令に関する命令情報を記憶した記憶部を参照して、前記命令に対応した関数であって、前記命令のオペランドを表す引数を受け取る第1の関数を生成する処理と、
     前記引数が表す前記オペランドに対して前記命令が行う処理を表す機械語を返す第2の関数を呼び出すコードを前記第1の関数の内部に生成する処理と、
     前記機械語をメモリに書き込むコードを前記第1の関数の内部に生成する処理と、
     をコンピュータが実行することを特徴とする関数生成方法。
  12.  命令に関する命令情報を記憶した記憶部を参照して、前記命令に対応した関数であって、前記命令のオペランドを表す引数を受け取る第1の関数を生成する第1の生成部と、
     前記引数が表す前記オペランドに対して前記命令が行う処理を表す機械語を返す第2の関数を呼び出すコードを前記第1の関数の内部に生成する第2の生成部と、
     前記機械語をメモリに書き込むコードを前記第1の関数の内部に生成する第3の生成部と、
     を有することを特徴とする情報処理装置。
     
PCT/JP2020/000184 2020-01-07 2020-01-07 関数生成プログラム、関数生成方法、及び情報処理装置 WO2021140568A1 (ja)

Priority Applications (3)

Application Number Priority Date Filing Date Title
JP2021569633A JP7295469B2 (ja) 2020-01-07 2020-01-07 関数生成プログラム、関数生成方法、及び情報処理装置
PCT/JP2020/000184 WO2021140568A1 (ja) 2020-01-07 2020-01-07 関数生成プログラム、関数生成方法、及び情報処理装置
US17/736,156 US11886839B2 (en) 2020-01-07 2022-05-04 Non-transitory computer-readable recording medium, function generation method, and information processing device

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
PCT/JP2020/000184 WO2021140568A1 (ja) 2020-01-07 2020-01-07 関数生成プログラム、関数生成方法、及び情報処理装置

Related Child Applications (1)

Application Number Title Priority Date Filing Date
US17/736,156 Continuation US11886839B2 (en) 2020-01-07 2022-05-04 Non-transitory computer-readable recording medium, function generation method, and information processing device

Publications (1)

Publication Number Publication Date
WO2021140568A1 true WO2021140568A1 (ja) 2021-07-15

Family

ID=76788762

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/JP2020/000184 WO2021140568A1 (ja) 2020-01-07 2020-01-07 関数生成プログラム、関数生成方法、及び情報処理装置

Country Status (3)

Country Link
US (1) US11886839B2 (ja)
JP (1) JP7295469B2 (ja)
WO (1) WO2021140568A1 (ja)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN116302218B (zh) * 2023-03-15 2024-05-10 北京百度网讯科技有限公司 函数信息的添加方法、装置、设备以及存储介质

Family Cites Families (12)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6247174B1 (en) * 1998-01-02 2001-06-12 Hewlett-Packard Company Optimization of source code with embedded machine instructions
JPH11224199A (ja) 1998-02-06 1999-08-17 Matsushita Electric Ind Co Ltd 翻訳装置と情報処理装置および記録媒体
JP2000056981A (ja) 1998-08-06 2000-02-25 Matsushita Electric Ind Co Ltd プログラム変換装置
JP2001344113A (ja) 2000-05-31 2001-12-14 Nec Corp 実行時コンパイラシステム及び実行時コンパイル方法
US6993754B2 (en) * 2001-11-13 2006-01-31 Hewlett-Packard Development Company, L.P. Annotations to executable images for improved dynamic optimization functions
JP4443100B2 (ja) 2002-07-31 2010-03-31 インターナショナル・ビジネス・マシーンズ・コーポレーション プログラム変換方法、これを用いたデータ処理装置及びプログラム
US7380242B2 (en) * 2003-05-14 2008-05-27 Mainsoft Israel Ltd. Compiler and software product for compiling intermediate language bytecodes into Java bytecodes
US7673293B2 (en) * 2004-04-20 2010-03-02 Hewlett-Packard Development Company, L.P. Method and apparatus for generating code for scheduling the execution of binary code
US7318143B2 (en) * 2004-10-20 2008-01-08 Arm Limited Reuseable configuration data
US8458684B2 (en) 2009-08-19 2013-06-04 International Business Machines Corporation Insertion of operation-and-indicate instructions for optimized SIMD code
KR20120031756A (ko) 2010-09-27 2012-04-04 삼성전자주식회사 Cpu와 gpu를 사용하는 이종 시스템에서 가상화를 이용한 어플리케이션 컴파일 및 실행 방법 및 장치
US8819649B2 (en) * 2011-09-09 2014-08-26 Microsoft Corporation Profile guided just-in-time (JIT) compiler and byte code generation

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
1 August 2016 (2016-08-01), pages 1 - 6, ISSN: 2188-8574, Retrieved from the Internet <URL:https://ipsj.ixsq.nii.ac.jp/ej/?action=repository_uri&itemid=172900&fiie_id=1&file_no=1> [retrieved on 20200203] *

Also Published As

Publication number Publication date
JPWO2021140568A1 (ja) 2021-07-15
US11886839B2 (en) 2024-01-30
US20220261224A1 (en) 2022-08-18
JP7295469B2 (ja) 2023-06-21

Similar Documents

Publication Publication Date Title
JP4057938B2 (ja) コンパイラ、コンパイル方法、及びプログラム開発ツール
US20050223363A1 (en) Evaluation of a code segment
US7917899B2 (en) Program development apparatus, method for developing a program, and a computer program product for executing an application for a program development apparatus
US8448151B2 (en) Method for binarizing initial script on operating system and operating method of binary script
Blum Professional assembly language
Hyde The art of assembly language
KR20200021517A (ko) 벡터 요소들 내부의 비트 값들의 시험
WO2021140568A1 (ja) 関数生成プログラム、関数生成方法、及び情報処理装置
KR0125605B1 (ko) 프로그램의 아키덱쳐 변환방법 및 장치와 그 방법 및 장치를 사용하여 프로그램의 동작을 검증하는 방법 및 장치
Bezzubikov et al. Automatic dynamic binary translator generation from instruction set description
Korenkov et al. Declarative target architecture definition for data-driven development toolchain
Markstedter Blue Fox: Arm Assembly Internals and Reverse Engineering
JP7295466B2 (ja) クラス生成プログラム及びクラス生成方法
JP7315872B2 (ja) プロセッサ、シミュレータプログラム、アセンブラプログラム、及び情報処理プログラム
Wang et al. Synthesizing Device Drivers with Ghost Writer
JP3915208B2 (ja) コンパイル装置
CN118069142A (zh) 编译优化方法、装置、电子设备及存储介质
Himmelbauer et al. The Vienna Architecture Description Language
Fokina et al. Automated Generation of Machine Instruction Decoders
CN116775127A (zh) 一种基于RetroWrite框架的静态符号执行插桩方法
Mráček A decompiler for Objective-C
Pokale et al. A Petite Guide to Programming in 64bit X86 Assembly Language for Linux
CN118069143A (zh) 访存处理方法、装置、电子设备及存储介质
Antelius Retargeting a C Compiler for a DSP Processor
JP2009252170A (ja) コンバータ及びプログラム変換方法

Legal Events

Date Code Title Description
121 Ep: the epo has been informed by wipo that ep was designated in this application

Ref document number: 20911823

Country of ref document: EP

Kind code of ref document: A1

ENP Entry into the national phase

Ref document number: 2021569633

Country of ref document: JP

Kind code of ref document: A

NENP Non-entry into the national phase

Ref country code: DE

122 Ep: pct application non-entry in european phase

Ref document number: 20911823

Country of ref document: EP

Kind code of ref document: A1