diff options
author | Wim Taymans <wtaymans@redhat.com> | 2015-10-21 17:31:46 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2016-03-07 10:33:30 +0100 |
commit | 933c023b4f347290720d760178ee9c5e6752017e (patch) | |
tree | 165ab0bbbe3f32b004a1e1d62782cf9174c4cbe2 | |
parent | a949162bc35aade5507a0118490d36c52d70ea3f (diff) |
Add serialization to dot file
Move serialization code into separate file
Add serialization of a program to a dot file
-rw-r--r-- | orc/Makefile.am | 3 | ||||
-rw-r--r-- | orc/c/orc-c.c | 3 | ||||
-rw-r--r-- | orc/orc.h | 1 | ||||
-rw-r--r-- | orc/orcinstruction.c | 242 | ||||
-rw-r--r-- | orc/orcinstruction.h | 6 | ||||
-rw-r--r-- | orc/orcprogram.c | 138 | ||||
-rw-r--r-- | orc/orcprogram.h | 14 | ||||
-rw-r--r-- | orc/orcserialize.c | 496 | ||||
-rw-r--r-- | orc/orcserialize.h | 37 | ||||
-rw-r--r-- | orc/x86/orc-x86-compiler.c | 3 | ||||
-rw-r--r-- | tools/orcc.c | 26 |
11 files changed, 561 insertions, 408 deletions
diff --git a/orc/Makefile.am b/orc/Makefile.am index 87e5947..aff8d60 100644 --- a/orc/Makefile.am +++ b/orc/Makefile.am @@ -18,12 +18,12 @@ liborc_@ORC_MAJORMINOR@_la_SOURCES = \ orccompiler.c \ orcdebug.c \ orcexecutor.c \ - orcinstruction.c \ orclabel.c \ orconce.c \ orcoptimize.c \ orcparse.c \ orcprogram.c \ + orcserialize.c \ orctarget.c \ orcutils.c @@ -74,6 +74,7 @@ pkginclude_HEADERS = \ orcparse.h \ orcprogram.h \ orctarget.h \ + orcserialize.h \ orcutils.h \ arm/orcarm.h \ arm/orcneon.h \ diff --git a/orc/c/orc-c.c b/orc/c/orc-c.c index 0609024..3a2b8ae 100644 --- a/orc/c/orc-c.c +++ b/orc/c/orc-c.c @@ -10,6 +10,7 @@ #include "orcexecutor.h" #include "orctarget.h" #include "orcoptimize.h" +#include "orcserialize.h" #define GET_PROGRAM(c) (c->compiler.program) #define GET_FLAGS(c) (c->compiler.flags) @@ -491,7 +492,7 @@ reduce_c (OrcCCompiler *c, OrcInstruction *insn) argres = reduce_c (c, arg); if (argres == NULL || argres->n_lanes == 0) { ORC_ERROR ("failed to reduce arg %d", arg->id); - orc_instruction_serialize (arg, stderr, 0); + orc_instruction_serialize (arg, stderr, ORC_SERIALIZE_TYPE_DEFAULT,0); return NULL; } carg[i] = argres->lane[0]; @@ -9,6 +9,7 @@ #include <orc/orcoptimize.h> #include <orc/orcparse.h> #include <orc/orcprogram.h> +#include <orc/orcserialize.h> #include <orc/orctarget.h> #include <orc/orcutils.h> diff --git a/orc/orcinstruction.c b/orc/orcinstruction.c deleted file mode 100644 index 37be029..0000000 --- a/orc/orcinstruction.c +++ /dev/null @@ -1,242 +0,0 @@ - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> - -#include "orcutils.h" -#include "orcinstruction.h" - -#define INSN_RES(insn) ((insn)->id) -#define INSN_BITS(insn) ((insn)->bits) -#define INSN_ARGBITS(insn) ((insn)->argbits) -#define INSN_ITEMS(insn) ((insn)->items) -#define INSN_ARG_RES(insn,n) ((insn)->arg[n]) - -typedef struct _OrcInsnPrintInfo OrcInsnPrintInfo; - -struct _OrcInsnPrintInfo { - char name[10]; - int (*print_func) (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output); -}; - -static int -orc_instruction_print_load (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_load (p, %d, %d, a[%d]);\n"; - else - format = "t%d = load x%d %d ptr%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), INSN_ITEMS (insn), INSN_BITS (insn), insn->extra); - - return res; -} - -static int -orc_instruction_print_load_const (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_load_c (p, %d, c[%d]);\n"; - else - format = "t%d = load x%d c%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), INSN_ITEMS (insn), insn->extra); - - return res; -} - -static int -orc_instruction_print_store (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " orc_program_add_store (p, %d, t[%d], a[%d]);\t/* x%d */\n"; - else - format = "store %d t%d ptr%d\t# x%d\n"; - - res += fprintf (output, format, - INSN_BITS (insn), INSN_ARG_RES (insn, 0), insn->extra, INSN_ITEMS (insn)); - - return res; -} - -static int -orc_instruction_print_op2 (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_%s (p, %d, t[%d], t[%d]);\t/* x%d */\n"; - else - format = "t%d = %s %d t%d t%d\t# x%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), info->name, INSN_BITS (insn), - INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); - - return res; -} - -static int -orc_instruction_print_op2_ns (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_%s (p, t[%d], t[%d]);\t/* x%d */\n"; - else - format = "t%d = %s t%d t%d\t# x%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), info->name, INSN_ARG_RES (insn, 0), - INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); - - return res; -} - -static int -orc_instruction_print_op1 (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_%s (p, %d, t[%d], %d);\t/* x%d */\n"; - else - format = "t%d = %s %d t%d %d\t# x%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), info->name, INSN_ARGBITS (insn), - INSN_ARG_RES (insn, 0), INSN_BITS (insn), INSN_ITEMS (insn)); - - return res; -} - -static int -orc_instruction_print_cmp (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - const char **cmp_name; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) { - static const char *c[] = { "ORC_CMP_EQ", "ORC_CMP_SGT" }; - cmp_name = c; - format = " t[%d] = orc_program_add_%s (p, %s, %d, t[%d], t[%d]);\t/* x%d */\n"; - } - else { - static const char *c[] = { "eq", "sgt" }; - cmp_name = c; - format = "t%d = %s %s %d t%d t%d\t# x%d\n"; - } - - res += fprintf (output, format, - INSN_RES (insn), info->name, cmp_name [insn->extra & 1], INSN_BITS (insn), - INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); - - return res; -} - -static int -orc_instruction_print_shuff (const OrcInstruction *insn, - const OrcInsnPrintInfo *info, - int flags, FILE *output) -{ - int res = 0; - const char *format; - - if (flags & ORC_INSTRUCTION_SERIALIZE_C) - format = " t[%d] = orc_program_add_%s (p, %d, %d, t[%d], t[%d], c[%d]);\t/* x%d */\n"; - else - format = "t%d = %s %d:%d t%d t%d c%d\t# x%d\n"; - - res += fprintf (output, format, - INSN_RES (insn), info->name, INSN_ARGBITS (insn), INSN_BITS (insn), - INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), insn->extra, INSN_ITEMS (insn)); - - return res; -} - -static const OrcInsnPrintInfo print_info[] = { - { "#invalid#", NULL }, - - { "load", orc_instruction_print_load }, - { "loadc", orc_instruction_print_load_const }, - { "store", orc_instruction_print_store }, - - { "add", orc_instruction_print_op2 }, - { "sub", orc_instruction_print_op2 }, - { "mul", orc_instruction_print_op2 }, - { "divu", orc_instruction_print_op2 }, - { "divs", orc_instruction_print_op2 }, - - { "and", orc_instruction_print_op2_ns }, - { "or", orc_instruction_print_op2_ns }, - { "xor", orc_instruction_print_op2_ns }, - - { "shl", orc_instruction_print_op2 }, - { "shru", orc_instruction_print_op2 }, - { "shrs", orc_instruction_print_op2 }, - - { "trunc", orc_instruction_print_op1 }, - { "clampu", orc_instruction_print_op1 }, - { "clamps", orc_instruction_print_op1 }, - { "extu", orc_instruction_print_op1 }, - { "exts", orc_instruction_print_op1 }, - - { "cmp", orc_instruction_print_cmp }, - - { "shuff", orc_instruction_print_shuff }, - - { "fadd", orc_instruction_print_op2 }, - { "fsub", orc_instruction_print_op2 }, - { "fmul", orc_instruction_print_op2 }, - { "fdiv", orc_instruction_print_op2 }, - { "fsqrt", orc_instruction_print_op2 }, - - { "fcmp", orc_instruction_print_cmp }, - - { "convff", orc_instruction_print_op1 }, - { "convfi", orc_instruction_print_op1 }, - { "convif", orc_instruction_print_op1 }, - - { "", } -}; - -int -orc_instruction_serialize (const OrcInstruction *insn, FILE *output, int flags) -{ - const OrcInsnPrintInfo *info; - - info = &print_info[insn->opcode]; - return info->print_func (insn, info, flags, output); -} diff --git a/orc/orcinstruction.h b/orc/orcinstruction.h index c6bb4d7..b6b762c 100644 --- a/orc/orcinstruction.h +++ b/orc/orcinstruction.h @@ -82,10 +82,4 @@ struct _OrcInstruction { int extra; }; -#define ORC_INSTRUCTION_SERIALIZE_C (1 << 0) - -int orc_instruction_serialize (const OrcInstruction *insn, - FILE *output, - int flags); - #endif /* _ORC_INSTRUCTION_H_ */ diff --git a/orc/orcprogram.c b/orc/orcprogram.c index b3d04ba..bf924ff 100644 --- a/orc/orcprogram.c +++ b/orc/orcprogram.c @@ -291,141 +291,3 @@ orc_program_add_op (OrcProgram *p, OrcOpcode opcode, } return insn->id; } - -int -orc_constant_serialize (OrcConstant *con, FILE *output, int flags) -{ - int res = 0, i; - - if (flags & ORC_CONSTANT_SERIALIZE_C) { - if (flags & ORC_CONSTANT_SERIALIZE_DECL) { - res += fprintf (output, " uint%d_t c%dv[%d]", con->bits, con->id, con->items); - } else if (flags & ORC_CONSTANT_SERIALIZE_ADD) { - res += fprintf (output, - " c[%d] = orc_program_add_const (p, %d, %d, c%dv)", - con->id, con->items, con->bits, con->id); - } - } else { - if (flags & ORC_CONSTANT_SERIALIZE_DECL) - res += fprintf (output, "c%d", con->id); - } - if (flags & ORC_CONSTANT_SERIALIZE_VALUE) { - if (flags & ORC_CONSTANT_SERIALIZE_DECL) - res += fprintf (output, " = "); - - if (flags & ORC_CONSTANT_SERIALIZE_C) { - res += fprintf (output, "{"); - } else { - res += fprintf (output, "i%d <", con->bits); - } - for (i = 0; i < con->items; i++) { - switch (con->bits) { - case 8: - res += fprintf (output, "0x%02x", ORC_U8 (con->value, i)); - break; - case 16: - res += fprintf (output, "0x%04x", ORC_U16 (con->value, i)); - break; - case 32: - res += fprintf (output, "0x%08x", ORC_U32 (con->value, i)); - break; - case 64: - res += fprintf (output, "0x%016llxLL", (long long int) ORC_U64 (con->value, i)); - break; - default: - break; - } - if (i < con->items - 1) { - if (flags & ORC_CONSTANT_SERIALIZE_C) { - res += fprintf (output, ", "); - } else { - res += fprintf (output, " "); - } - } - } - if (flags & ORC_CONSTANT_SERIALIZE_C) { - res += fprintf (output, "}"); - } else { - res += fprintf (output, ">"); - } - } - if (flags & ORC_CONSTANT_SERIALIZE_C) { - res += fprintf (output, ";"); - } - res += fprintf (output, "\n"); - return res; -} - -int -orc_program_serialize (OrcProgram *p, FILE *output, int flags) -{ - int res = 0, i; - - if (flags & ORC_PROGRAM_SERIALIZE_DECL) { - int con_flags; - - con_flags = ORC_CONSTANT_SERIALIZE_DECL | ORC_CONSTANT_SERIALIZE_VALUE; - - if (flags & ORC_PROGRAM_SERIALIZE_C) { - con_flags |= ORC_CONSTANT_SERIALIZE_C; - } - /* serialize constant definitions */ - for (i = 0; i < p->n_constants; i++) { - OrcConstant *con = GET_CONST (p, i); - res += orc_constant_serialize (con, output, con_flags); - } - if (flags & ORC_PROGRAM_SERIALIZE_C) { - /* C needs declarations of constant and variables */ - if (p->n_constants) - res += fprintf (output, " int c[%d];\n", p->n_constants); - if (p->n_arrays > 0 && p->n_instructions) - res += fprintf (output, " int a[%d];\n", p->n_arrays); - if (p->n_instructions) - res += fprintf (output, " int t[%d];\n", p->n_instructions); - } - res += fprintf (output, "\n"); - } - if (flags & ORC_PROGRAM_SERIALIZE_INSN) { - int insn_flags = 0; - - if (flags & ORC_PROGRAM_SERIALIZE_C) { - int con_flags; - - if (flags & ORC_PROGRAM_SERIALIZE_NEW) { - /* make the program */ - res += fprintf (output, " p = orc_program_new (\"%s\", %d);\n", - p->name, p->n_instructions); - } - if (ORC_PROGRAM_IS_2D (p)) - res += fprintf (output, " orc_program_set_2d (p, 1);\n"); - - /* add the constants to the program */ - con_flags = ORC_CONSTANT_SERIALIZE_C | ORC_CONSTANT_SERIALIZE_ADD; - for (i = 0; i < p->n_constants; i++) { - OrcConstant *con = GET_CONST (p, i); - res += orc_constant_serialize (con, output, con_flags); - } - /* add arrays */ - for (i = 0; i < p->n_arrays; i++) { - OrcArray *arr = &p->arrays[i]; - if (p->n_instructions) - res += fprintf (output, - " a[%d] = orc_program_add_array (p, \"%s\", \"%s\", %d, %d, %d, %d);\n", - arr->id, arr->name, arr->type, arr->bits, arr->align, arr->inc, arr->flags); - } - insn_flags |= ORC_INSTRUCTION_SERIALIZE_C; - } - /* now dump all instructions */ - if (p->n_roots) { - for (i = 0; i < p->n_instructions; i++) { - OrcInstruction *insn = &p->instructions[i]; - if (i == p->m_invariant_end) - res += fprintf (output, " /* M-invariant end */;\n"); - if (i == p->n_invariant_end) - res += fprintf (output, " /* N-invariant end */;\n"); - res += orc_instruction_serialize (insn, output, insn_flags); - } - } - } - return res; -} diff --git a/orc/orcprogram.h b/orc/orcprogram.h index f90a36b..737e7cf 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -54,13 +54,6 @@ struct _OrcArray { #define ORC_ARRAY_UNUSED(a) (((a)->flags & ORC_ARRAY_FLAG_READWRITE) == 0) -#define ORC_CONSTANT_SERIALIZE_C (1<<0) -#define ORC_CONSTANT_SERIALIZE_DECL (1<<1) -#define ORC_CONSTANT_SERIALIZE_VALUE (1<<2) -#define ORC_CONSTANT_SERIALIZE_ADD (1<<3) - -int orc_constant_serialize (OrcConstant *con, FILE *output, int flags); - #define ORC_PROGRAM_FLAG_2D (1<<0) #define ORC_PROGRAM_FLAG_VERIFIED (1<<1) #define ORC_PROGRAM_FLAG_OPTIMIZED (1<<2) @@ -108,13 +101,6 @@ void orc_program_set_2d (OrcProgram *p, int is_2d); void orc_program_finish (OrcProgram *p); void orc_program_free (OrcProgram *p); -#define ORC_PROGRAM_SERIALIZE_C (1<<0) -#define ORC_PROGRAM_SERIALIZE_DECL (1<<1) -#define ORC_PROGRAM_SERIALIZE_INSN (1<<3) -#define ORC_PROGRAM_SERIALIZE_NEW (1<<4) - -int orc_program_serialize (OrcProgram *p, FILE *output, int flags); - int orc_program_add_const (OrcProgram *p, int items, int bits, void *value); int orc_program_add_array (OrcProgram *p, const char *name, const char *type, int bits, int align, int inc, int flags); diff --git a/orc/orcserialize.c b/orc/orcserialize.c new file mode 100644 index 0000000..d634c0f --- /dev/null +++ b/orc/orcserialize.c @@ -0,0 +1,496 @@ +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +#include "orc.h" +#include "orcutils.h" +#include "orcprogram.h" +#include "orcinstruction.h" +#include "orcserialize.h" + +#define GET_CONST(p,idx) (p->constants[idx]) + +#define INSN_ID(insn) ((insn)->id) +#define INSN_BITS(insn) ((insn)->bits) +#define INSN_ARGBITS(insn) ((insn)->argbits) +#define INSN_ITEMS(insn) ((insn)->items) +#define INSN_ARG_RES(insn,n) ((insn)->arg[n]) + +int +orc_constant_serialize (OrcConstant *con, FILE *output, + OrcSerializeType type, OrcSerializeFlags flags) +{ + int res = 0, i; + + if (type == ORC_SERIALIZE_TYPE_C) { + if (flags & ORC_SERIALIZE_FLAG_DECL) { + res += fprintf (output, " uint%d_t c%dv[%d]", con->bits, con->id, con->items); + } else if (flags & ORC_SERIALIZE_FLAG_ADD) { + res += fprintf (output, + " c[%d] = orc_program_add_const (p, %d, %d, c%dv)", + con->id, con->items, con->bits, con->id); + } + } else { + if (flags & ORC_SERIALIZE_FLAG_DECL) + res += fprintf (output, "c%d", con->id); + } + if (flags & ORC_SERIALIZE_FLAG_VALUE) { + if (flags & ORC_SERIALIZE_FLAG_DECL) + res += fprintf (output, " = "); + + if (type == ORC_SERIALIZE_TYPE_C) { + res += fprintf (output, "{"); + } else { + res += fprintf (output, "i%d <", con->bits); + } + for (i = 0; i < con->items; i++) { + switch (con->bits) { + case 8: + res += fprintf (output, "0x%02x", ORC_U8 (con->value, i)); + break; + case 16: + res += fprintf (output, "0x%04x", ORC_U16 (con->value, i)); + break; + case 32: + res += fprintf (output, "0x%08x", ORC_U32 (con->value, i)); + break; + case 64: + res += fprintf (output, "0x%016llxLL", (long long int) ORC_U64 (con->value, i)); + break; + default: + break; + } + if (i < con->items - 1) { + if (type == ORC_SERIALIZE_TYPE_C) { + res += fprintf (output, ", "); + } else { + res += fprintf (output, " "); + } + } + } + if (type == ORC_SERIALIZE_TYPE_C) { + res += fprintf (output, "}"); + } else { + res += fprintf (output, ">"); + } + } + if (type == ORC_SERIALIZE_TYPE_C) { + res += fprintf (output, ";"); + } + return res; +} + + +typedef struct _OrcInsnPrintInfo OrcInsnPrintInfo; + +struct _OrcInsnPrintInfo { + char name[10]; + int (*print_func) (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output); +}; + +static int +orc_instruction_print_load (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_load (p, %d, %d, a[%d]);\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"load x%d %d ptr%d\", fillcolor=\"#ffdddd\"];\n"; + else + format = "t%d = load x%d %d ptr%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), INSN_ITEMS (insn), INSN_BITS (insn), insn->extra); + + return res; +} + +static int +orc_instruction_print_load_const (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_load_c (p, %d, c[%d]);\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"load x%d c%d\", fillcolor=\"#ffffdd\"];\n"; + else + format = "t%d = load x%d c%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), INSN_ITEMS (insn), insn->extra); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "c%d -> t%d [label=\"c%d\"];\n", insn->extra, + INSN_ID (insn), insn->extra); + } + + return res; +} + +static int +orc_instruction_print_store (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " orc_program_add_store (p, %d, t[%d], a[%d]);\t/* x%d */\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d ", insn->id); + format = "[label=\"store %d t%d ptr%d\", fillcolor=\"#ddffdd\"];\n"; + } else + format = "store %d t%d ptr%d\t# x%d\n"; + + res += fprintf (output, format, + INSN_BITS (insn), INSN_ARG_RES (insn, 0), insn->extra, INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), insn->id, INSN_ARG_RES (insn, 0)); + } + + return res; +} + +static int +orc_instruction_print_op2 (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_%s (p, %d, t[%d], t[%d]);\t/* x%d */\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"%s %d t%d t%d\"];\n"; + else + format = "t%d = %s %d t%d t%d\t# x%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), info->name, INSN_BITS (insn), + INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), INSN_ID (insn), INSN_ARG_RES (insn, 0)); + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 1), INSN_ID (insn), INSN_ARG_RES (insn, 1)); + } + return res; +} + +static int +orc_instruction_print_op2_ns (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_%s (p, t[%d], t[%d]);\t/* x%d */\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"%s t%d t%d\"];\n"; + else + format = "t%d = %s t%d t%d\t# x%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), info->name, INSN_ARG_RES (insn, 0), + INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), INSN_ID (insn), INSN_ARG_RES (insn, 0)); + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 1), INSN_ID (insn), INSN_ARG_RES (insn, 1)); + } + + return res; +} + +static int +orc_instruction_print_op1 (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_%s (p, %d, t[%d], %d);\t/* x%d */\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"%s %d t%d %d\", fillcolor=\"#ddffff\"];\n"; + else + format = "t%d = %s %d t%d %d\t# x%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), info->name, INSN_ARGBITS (insn), + INSN_ARG_RES (insn, 0), INSN_BITS (insn), INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), INSN_ID (insn), INSN_ARG_RES (insn, 0)); + } + return res; +} + +static int +orc_instruction_print_cmp (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + const char **cmp_name; + + if (type == ORC_SERIALIZE_TYPE_C) { + static const char *c[] = { "ORC_CMP_EQ", "ORC_CMP_SGT" }; + cmp_name = c; + format = " t[%d] = orc_program_add_%s (p, %s, %d, t[%d], t[%d]);\t/* x%d */\n"; + } else if (type == ORC_SERIALIZE_TYPE_DOT) { + static const char *c[] = { "eq", "sgt" }; + cmp_name = c; + format = "t%d [label=\"%s %s %d t%d t%d\"];\n"; + } else { + static const char *c[] = { "eq", "sgt" }; + cmp_name = c; + format = "t%d = %s %s %d t%d t%d\t# x%d\n"; + } + + res += fprintf (output, format, + INSN_ID (insn), info->name, cmp_name [insn->extra & 1], INSN_BITS (insn), + INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), INSN_ID (insn), INSN_ARG_RES (insn, 0)); + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 1), INSN_ID (insn), INSN_ARG_RES (insn, 1)); + } + return res; +} + +static int +orc_instruction_print_shuff (const OrcInstruction *insn, + const OrcInsnPrintInfo *info, + OrcSerializeType type, + OrcSerializeFlags flags, + FILE *output) +{ + int res = 0; + const char *format; + + if (type == ORC_SERIALIZE_TYPE_C) + format = " t[%d] = orc_program_add_%s (p, %d, %d, t[%d], t[%d], c[%d]);\t/* x%d */\n"; + else if (type == ORC_SERIALIZE_TYPE_DOT) + format = "t%d [label=\"%s %d:%d t%d t%d c%d\", fillcolor=\"#ffddff\"];\n"; + else + format = "t%d = %s %d:%d t%d t%d c%d\t# x%d\n"; + + res += fprintf (output, format, + INSN_ID (insn), info->name, INSN_ARGBITS (insn), INSN_BITS (insn), + INSN_ARG_RES (insn, 0), INSN_ARG_RES (insn, 1), insn->extra, INSN_ITEMS (insn)); + + if (type == ORC_SERIALIZE_TYPE_DOT) { + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 0), INSN_ID (insn), INSN_ARG_RES (insn, 0)); + res += fprintf (output, "t%d -> t%d [label=\"t%d\"];\n", + INSN_ARG_RES (insn, 1), INSN_ID (insn), INSN_ARG_RES (insn, 1)); + res += fprintf (output, "c%d -> t%d [label=\"c%d\"];\n", + insn->extra, INSN_ID (insn), insn->extra); + } + + return res; +} + +static const OrcInsnPrintInfo print_info[] = { + { "#invalid#", NULL }, + + { "load", orc_instruction_print_load }, + { "loadc", orc_instruction_print_load_const }, + { "store", orc_instruction_print_store }, + + { "add", orc_instruction_print_op2 }, + { "sub", orc_instruction_print_op2 }, + { "mul", orc_instruction_print_op2 }, + { "divu", orc_instruction_print_op2 }, + { "divs", orc_instruction_print_op2 }, + + { "and", orc_instruction_print_op2_ns }, + { "or", orc_instruction_print_op2_ns }, + { "xor", orc_instruction_print_op2_ns }, + + { "shl", orc_instruction_print_op2 }, + { "shru", orc_instruction_print_op2 }, + { "shrs", orc_instruction_print_op2 }, + + { "trunc", orc_instruction_print_op1 }, + { "clampu", orc_instruction_print_op1 }, + { "clamps", orc_instruction_print_op1 }, + { "extu", orc_instruction_print_op1 }, + { "exts", orc_instruction_print_op1 }, + + { "cmp", orc_instruction_print_cmp }, + + { "shuff", orc_instruction_print_shuff }, + + { "fadd", orc_instruction_print_op2 }, + { "fsub", orc_instruction_print_op2 }, + { "fmul", orc_instruction_print_op2 }, + { "fdiv", orc_instruction_print_op2 }, + { "fsqrt", orc_instruction_print_op2 }, + + { "fcmp", orc_instruction_print_cmp }, + + { "convff", orc_instruction_print_op1 }, + { "convfi", orc_instruction_print_op1 }, + { "convif", orc_instruction_print_op1 }, + + { "", } +}; + +int +orc_instruction_serialize (const OrcInstruction *insn, FILE *output, + OrcSerializeType type, OrcSerializeFlags flags) +{ + const OrcInsnPrintInfo *info; + + info = &print_info[insn->opcode]; + return info->print_func (insn, info, type, flags, output); +} + +static int +orc_program_serialize_dot (OrcProgram *p, FILE *output, + OrcSerializeType type, OrcSerializeFlags flags) +{ + int res, i; + + res = fprintf (output, "digraph program {\n"); + res += fprintf (output, "node [shape=box, style=filled, fontsize=\"7\", " + " fontname=\"Bitstream Vera Sans\", margin=\"0.0,0.0\", fillcolor=\"#eeeeee\"];"); + + if (flags & ORC_SERIALIZE_FLAG_DECL) { + for (i = 0; i < p->n_constants; i++) { + OrcConstant *con = GET_CONST (p, i); + res += fprintf (output, "c%d [label=\"", con->id); + res += orc_constant_serialize (con, output, type, ORC_SERIALIZE_FLAG_VALUE); + res += fprintf (output, "\", shape=ellipse, style=filled, fillcolor=\"#eeeeff\"];\n"); + } + } + if (flags & ORC_SERIALIZE_FLAG_INSN) { + for (i = 0; i < p->n_instructions; i++) { + OrcInstruction *insn = &p->instructions[i]; + res += orc_instruction_serialize (insn, output, type, 0); + } + } + res += fprintf (output, "}\n"); + + return res; +} + +int +orc_program_serialize (OrcProgram *p, FILE *output, + OrcSerializeType type, OrcSerializeFlags flags) +{ + int res = 0, i; + + if (type == ORC_SERIALIZE_TYPE_DOT) + return orc_program_serialize_dot (p, output, type, flags); + + if (flags & ORC_SERIALIZE_FLAG_DECL) { + int con_flags; + + con_flags = ORC_SERIALIZE_FLAG_DECL | ORC_SERIALIZE_FLAG_VALUE; + + /* serialize constant definitions */ + for (i = 0; i < p->n_constants; i++) { + OrcConstant *con = GET_CONST (p, i); + res += orc_constant_serialize (con, output, type, con_flags); + res += fprintf (output, "\n"); + } + if (type == ORC_SERIALIZE_TYPE_C) { + /* C needs declarations of constant and variables */ + if (p->n_constants) + res += fprintf (output, " int c[%d];\n", p->n_constants); + if (p->n_arrays > 0 && p->n_instructions) + res += fprintf (output, " int a[%d];\n", p->n_arrays); + if (p->n_instructions) + res += fprintf (output, " int t[%d];\n", p->n_instructions); + } + res += fprintf (output, "\n"); + } + if (flags & ORC_SERIALIZE_FLAG_INSN) { + int insn_flags = 0; + + if (type == ORC_SERIALIZE_TYPE_C) { + int con_flags; + + if (flags & ORC_SERIALIZE_FLAG_NEW) { + /* make the program */ + res += fprintf (output, " p = orc_program_new (\"%s\", %d);\n", + p->name, p->n_instructions); + } + if (ORC_PROGRAM_IS_2D (p)) + res += fprintf (output, " orc_program_set_2d (p, 1);\n"); + + /* add the constants to the program */ + con_flags = ORC_SERIALIZE_FLAG_ADD; + for (i = 0; i < p->n_constants; i++) { + OrcConstant *con = GET_CONST (p, i); + res += orc_constant_serialize (con, output, type, con_flags); + res += fprintf (output, "\n"); + } + /* add arrays */ + for (i = 0; i < p->n_arrays; i++) { + OrcArray *arr = &p->arrays[i]; + if (p->n_instructions) + res += fprintf (output, + " a[%d] = orc_program_add_array (p, \"%s\", \"%s\", %d, %d, %d, %d);\n", + arr->id, arr->name, arr->type, arr->bits, arr->align, arr->inc, arr->flags); + } + } + /* now dump all instructions */ + if (p->n_roots) { + for (i = 0; i < p->n_instructions; i++) { + OrcInstruction *insn = &p->instructions[i]; + if (i == p->m_invariant_end) + res += fprintf (output, " /* M-invariant end */;\n"); + if (i == p->n_invariant_end) + res += fprintf (output, " /* N-invariant end */;\n"); + res += orc_instruction_serialize (insn, output, type, insn_flags); + } + } + } + return res; +} + diff --git a/orc/orcserialize.h b/orc/orcserialize.h new file mode 100644 index 0000000..7cd7a08 --- /dev/null +++ b/orc/orcserialize.h @@ -0,0 +1,37 @@ + +#ifndef _ORC_SERIALIZE_H_ +#define _ORC_SERIALIZE_H_ + +#include <orc/orcinstruction.h> +#include <orc/orcprogram.h> + +typedef enum +{ + ORC_SERIALIZE_TYPE_DEFAULT = 0, + ORC_SERIALIZE_TYPE_C = 1, + ORC_SERIALIZE_TYPE_DOT = 2, +} OrcSerializeType; + +typedef enum +{ + ORC_SERIALIZE_FLAG_DECL = (1 << 0), + ORC_SERIALIZE_FLAG_INSN = (1 << 1), + ORC_SERIALIZE_FLAG_VALUE = (1 << 2), + ORC_SERIALIZE_FLAG_ADD = (1 << 3), + ORC_SERIALIZE_FLAG_NEW = (1 << 4), +} OrcSerializeFlags; + +int orc_constant_serialize (OrcConstant *con, FILE *output, + OrcSerializeType type, + OrcSerializeFlags flags); + +int orc_program_serialize (OrcProgram *p, FILE *output, + OrcSerializeType type, + OrcSerializeFlags flags); + +int orc_instruction_serialize (const OrcInstruction *insn, + FILE *output, + OrcSerializeType type, + OrcSerializeFlags flags); + +#endif /* _ORC_SERIALIZE_H_ */ diff --git a/orc/x86/orc-x86-compiler.c b/orc/x86/orc-x86-compiler.c index d7522ab..03e8382 100644 --- a/orc/x86/orc-x86-compiler.c +++ b/orc/x86/orc-x86-compiler.c @@ -11,6 +11,7 @@ #include "orclabel.h" #include "orctarget.h" #include "orcoptimize.h" +#include "orcserialize.h" #define GET_PROGRAM(c) (c->compiler.program) #define GET_FLAGS(c) (c->compiler.flags) @@ -1828,7 +1829,7 @@ reduce_x86 (OrcX86Compiler *c, OrcInstruction *insn) if (arg[i] == NULL || arg[i]->n_lanes == 0) { ORC_ERROR ("failed to reduce arg %d", a->id); - orc_instruction_serialize (a, stderr, 0); + orc_instruction_serialize (a, stderr, ORC_SERIALIZE_TYPE_DEFAULT, 0); return NULL; } } else { diff --git a/tools/orcc.c b/tools/orcc.c index 0457934..be7889f 100644 --- a/tools/orcc.c +++ b/tools/orcc.c @@ -39,6 +39,7 @@ int use_code = FALSE; int use_lazy_init = FALSE; int use_backup = TRUE; int use_internal = FALSE; +int dump_dot = FALSE; const char *init_function = NULL; @@ -85,6 +86,7 @@ void help (void) printf(" --init-function FUNCTION Generate initialization function\n"); printf(" --lazy-init Do Orc compile at function execution\n"); printf(" --no-backup Do not generate backup functions\n"); + printf(" --dot Save .dot graph for each function\n"); printf("\n"); exit (0); @@ -183,6 +185,9 @@ main (int argc, char *argv[]) use_lazy_init = TRUE; } else if (strcmp(argv[i], "--no-backup") == 0) { use_backup = FALSE; + } else if (strcmp(argv[i], "--dot") == 0) { + dump_dot = TRUE; + } else if (strncmp(argv[i], "-", 1) == 0) { } else if (strncmp(argv[i], "-", 1) == 0) { printf("Unknown option: %s\n", argv[i]); exit (1); @@ -270,6 +275,16 @@ main (int argc, char *argv[]) for(i=0;i<n;i++){ orc_program_optimize (programs[i]); + if (dump_dot) { + char dot_name[255]; + + snprintf (dot_name, 255, "%s.dot", programs[i]->name); + output = fopen (dot_name, "w"); + orc_program_serialize (programs[i], output, + ORC_SERIALIZE_TYPE_DOT, + ORC_SERIALIZE_FLAG_DECL | ORC_SERIALIZE_FLAG_INSN); + fclose (output); + } } output = fopen (output_file, "w"); @@ -788,10 +803,10 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline) void output_program_generation (OrcProgram *p, FILE *output, int is_inline) { - orc_program_serialize (p, output, ORC_PROGRAM_SERIALIZE_C | - ORC_PROGRAM_SERIALIZE_DECL | - ORC_PROGRAM_SERIALIZE_INSN | - ORC_PROGRAM_SERIALIZE_NEW); + orc_program_serialize (p, output, ORC_SERIALIZE_TYPE_C, + ORC_SERIALIZE_FLAG_DECL | + ORC_SERIALIZE_FLAG_INSN | + ORC_SERIALIZE_FLAG_NEW); if (use_backup) { fprintf (output, " orc_program_set_backup_func (p, _backup_%s);\n\n", p->name); } @@ -891,7 +906,8 @@ output_code_assembly (OrcProgram *p, FILE *output) { fprintf(output, "/* %s */\n", p->name); fprintf(output, "/*\n"); - orc_program_serialize (p, output, ORC_PROGRAM_SERIALIZE_DECL|ORC_PROGRAM_SERIALIZE_INSN); + orc_program_serialize (p, output, ORC_SERIALIZE_TYPE_DEFAULT, + ORC_SERIALIZE_FLAG_DECL|ORC_SERIALIZE_FLAG_INSN); fprintf(output, "*/\n"); /* output_prototype (p, output); */ { |