summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2015-10-21 17:31:46 +0200
committerWim Taymans <wtaymans@redhat.com>2016-03-07 10:33:30 +0100
commit933c023b4f347290720d760178ee9c5e6752017e (patch)
tree165ab0bbbe3f32b004a1e1d62782cf9174c4cbe2
parenta949162bc35aade5507a0118490d36c52d70ea3f (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.am3
-rw-r--r--orc/c/orc-c.c3
-rw-r--r--orc/orc.h1
-rw-r--r--orc/orcinstruction.c242
-rw-r--r--orc/orcinstruction.h6
-rw-r--r--orc/orcprogram.c138
-rw-r--r--orc/orcprogram.h14
-rw-r--r--orc/orcserialize.c496
-rw-r--r--orc/orcserialize.h37
-rw-r--r--orc/x86/orc-x86-compiler.c3
-rw-r--r--tools/orcc.c26
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];
diff --git a/orc/orc.h b/orc/orc.h
index 575a087..d8263a8 100644
--- a/orc/orc.h
+++ b/orc/orc.h
@@ -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); */
{