Friday save.
authortwisti <none@none>
Fri, 4 Mar 2005 17:09:13 +0000 (17:09 +0000)
committertwisti <none@none>
Fri, 4 Mar 2005 17:09:13 +0000 (17:09 +0000)
src/vm/jit/schedule/schedule.c
src/vm/jit/schedule/schedule.h

index 65e43d6cc22054594831af2f0da93248d43bd151..e9a875261b9bcd6d846df0e716c0a79d26b76c96 100644 (file)
@@ -1,4 +1,5 @@
-/* vm/jit/schedule/schedule.c - architecture independent instruction scheduler
+/* src/vm/jit/schedule/schedule.c - architecture independent instruction
+                                    scheduler
 
    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
@@ -28,7 +29,7 @@
 
    Changes:
 
-   $Id: schedule.c 1973 2005-03-02 16:27:05Z twisti $
+   $Id: schedule.c 1985 2005-03-04 17:09:13Z twisti $
 
 */
 
@@ -50,22 +51,12 @@ scheduledata *schedule_init(registerdata *rd)
        /* XXX quick hack: just use a fix number of instructions */
        sd->mi = DMNEW(minstruction, 100);
 
-       sd->micount = 0;
-
        sd->intregs_define_dep = DMNEW(s4, rd->intregsnum);
        sd->fltregs_define_dep = DMNEW(s4, rd->fltregsnum);
 
        sd->intregs_use_dep = DMNEW(nodelink*, rd->intregsnum);
        sd->fltregs_use_dep = DMNEW(nodelink*, rd->fltregsnum);
 
-       /* clear all pointers */
-
-       MSET(sd->intregs_define_dep, 0, s4, rd->intregsnum);
-       MSET(sd->fltregs_define_dep, 0, s4, rd->fltregsnum);
-
-       MSET(sd->intregs_use_dep, 0, nodelink*, rd->intregsnum);
-       MSET(sd->fltregs_use_dep, 0, nodelink*, rd->fltregsnum);
-
        sd->memory_define_dep = NULL;
        sd->memory_use_dep = NULL;
 
@@ -73,35 +64,27 @@ scheduledata *schedule_init(registerdata *rd)
 }
 
 
-/* schedule_calc_priority ******************************************************
-
-   Calculates the current node's priority by getting highest priority
-   of the dependency nodes, adding this nodes latency plus 1 (for the
-   instruction itself).
-
-*******************************************************************************/
-
-void schedule_calc_priority(minstruction *mi)
+void schedule_setup(scheduledata *sd, registerdata *rd)
 {
-       s4 i;
-       s4 pathpriority;
+       sd->micount = 0;
+       sd->leaders = NULL;
 
-       /* check all dependencies for their priority */
+       /* set define array to -1, because 0 is a valid node number */
 
-       pathpriority = 0;
+       MSET(sd->intregs_define_dep, -1, s4, rd->intregsnum);
+       MSET(sd->fltregs_define_dep, -1, s4, rd->fltregsnum);
 
-       for (i = 0; i < 3; i++) {
-/*             if (mi->opdep[i]) { */
-/*                     if (mi->opdep[i]->priority > pathpriority) */
-/*                             pathpriority = mi->opdep[i]->priority; */
-/*             } */
-       }
+       /* clear all use pointers */
 
-       mi->priority = pathpriority + mi->latency + 1;
+       MSET(sd->intregs_use_dep, 0, nodelink*, rd->intregsnum);
+       MSET(sd->fltregs_use_dep, 0, nodelink*, rd->fltregsnum);
+
+       sd->memory_define_dep = NULL;
+       sd->memory_use_dep = NULL;
 }
 
 
-void schedule_add_int_define_dep(scheduledata *sd, s4 reg)
+void schedule_add_define_dep(scheduledata *sd, s4 *define_dep, nodelink **use_dep)
 {
        minstruction *mi;
        minstruction *defmi;
@@ -114,32 +97,32 @@ void schedule_add_int_define_dep(scheduledata *sd, s4 reg)
 
        /* get current machine instruction */
 
-       minode = sd->micount;
-       mi = &sd->mi[minode - 1];
+       minode = sd->micount - 1;
+       mi = &sd->mi[minode];
 
        /* get current use dependency nodes, if non-null use them... */
 
-       if ((usenl = sd->intregs_use_dep[reg])) {
+       if ((usenl = *use_dep)) {
                /* add a dependency link node to all use dependency nodes */
 
                while (usenl) {
+                       /* Save next pointer so we can link the current node to the       */
+                       /* machine instructions' dependency list.                         */
+
                        tmpnl = usenl->next;
 
-                       /* don't add to the current machine instruction */
+                       /* don't add the current machine instruction */
 
                        if (usenl->minode != minode) {
                                /* some edges to current machine instruction -> no leader */
 
-                               mi->leader = false;
+                               mi->flags &= ~SCHEDULE_LEADER;
 
                                /* get use machine instruction */
 
-                               usemi = &sd->mi[usenl->minode - 1];
+                               usemi = &sd->mi[usenl->minode];
 
-/*                             nl = DNEW(nodelink); */
-/*                             nl->minode = sd->micount; */
-/*                             nl->next = usemi->deps; */
-/*                             usemi->deps = nl; */
+                               /* link current use node into dependency list */
 
                                usenl->minode = minode;
                                usenl->next = usemi->deps;
@@ -152,17 +135,17 @@ void schedule_add_int_define_dep(scheduledata *sd, s4 reg)
        } else {
                /* ...otherwise use last define dependency, if non-null */
 
-               if ((defnode = sd->intregs_define_dep[reg]) > 0) {
+               if ((defnode = *define_dep) >= 0) {
                        /* some edges to current machine instruction -> no leader */
 
-                       mi->leader = false;
+                       mi->flags &= ~SCHEDULE_LEADER;
 
                        /* get last define machine instruction */
 
-                       defmi = &sd->mi[defnode - 1];
+                       defmi = &sd->mi[defnode];
 
                        nl = DNEW(nodelink);
-                       nl->minode = sd->micount;
+                       nl->minode = minode;
                        nl->next = defmi->deps;
                        defmi->deps = nl;
                }
@@ -171,35 +154,37 @@ void schedule_add_int_define_dep(scheduledata *sd, s4 reg)
        /* Set current instruction as new define dependency and clear use         */
        /* depedencies.                                                           */
 
-       sd->intregs_define_dep[reg] = sd->micount;
-       sd->intregs_use_dep[reg] = NULL;
+       *define_dep = minode;
+       *use_dep = NULL;
 }
 
 
-void schedule_add_int_use_dep(scheduledata *sd, s4 reg)
+void schedule_add_use_dep(scheduledata *sd, s4 *define_dep, nodelink **use_dep)
 {
        minstruction *mi;
        minstruction *defmi;
        nodelink     *nl;
+       s4            minode;
        s4            defnode;
 
        /* get current machine instruction */
 
-       mi = &sd->mi[sd->micount - 1];
+       minode = sd->micount - 1;
+       mi = &sd->mi[minode];
 
        /* get current define dependency instruction */
 
-       if ((defnode = sd->intregs_define_dep[reg]) > 0) {
+       if ((defnode = *define_dep) >= 0) {
                /* some edges to current machine instruction -> no leader */
 
-               mi->leader = false;
+               mi->flags &= ~SCHEDULE_LEADER;
 
                /* add node to dependency list of current define node */
 
-               defmi = &sd->mi[defnode - 1];
+               defmi = &sd->mi[defnode];
 
                nl = DNEW(nodelink);
-               nl->minode = sd->micount;
+               nl->minode = minode;
                nl->next = defmi->deps;
                defmi->deps = nl;
        }
@@ -207,122 +192,116 @@ void schedule_add_int_use_dep(scheduledata *sd, s4 reg)
        /* add node to list of current use nodes */
 
        nl = DNEW(nodelink);
-       nl->minode = sd->micount;
-       nl->next = sd->intregs_use_dep[reg];
-       sd->intregs_use_dep[reg] = nl;
+       nl->minode = minode;
+       nl->next = *use_dep;
+       *use_dep = nl;
 }
 
 
-void schedule_add_flt_define_dep(scheduledata *sd, s4 reg)
+void schedule_add_memory_define_dep(scheduledata *sd)
 {
-       minstruction *mi;
-       minstruction *defmi;
-       minstruction *usemi;
-       nodelink     *usenl;
-       nodelink     *nl;
-       s4            defnode;
+}
 
-       /* get current machine instruction */
 
-       mi = &sd->mi[sd->micount - 1];
+void schedule_add_memory_use_dep(scheduledata *sd)
+{
+}
 
-       /* get current use dependency nodes, if non-null use them... */
 
-       if ((usenl = sd->fltregs_use_dep[reg])) {
-               /* add a dependency link node to all use dependency nodes */
+/* schedule_calc_priorities ****************************************************
 
-               while (usenl) {
-                       /* don't add to the current machine instruction */
+   Calculates the current node's priority by getting highest priority
+   of the dependency nodes, adding this nodes latency plus 1 (for the
+   instruction itself).
 
-                       if (usenl->minode != sd->micount) {
-                               /* some edges to current machine instruction -> no leader */
+*******************************************************************************/
 
-                               mi->leader = false;
+void schedule_calc_priorities(scheduledata *sd)
+{
+       minstruction *mi;
+       nodelink     *nl;
+       s4            i;
+       u1            startcycle;
+       u1            endcycle;
+       s1            priority;
+       s4            criticalpath;
+       s4            currentpath;
 
-                               /* get use machine instruction */
+       /* walk through all machine instructions backwards */
 
-                               usemi = &sd->mi[usenl->minode - 1];
+       for (i = sd->micount - 1, mi = &sd->mi[sd->micount - 1]; i >= 0; i--, mi--) {
+               nl = mi->deps;
 
-                               nl = DNEW(nodelink);
-                               nl->minode = sd->micount;
-                               nl->next = usemi->deps;
-                               usemi->deps = nl;
-                       }
+               /* do we have some dependencies */
 
-                       usenl = usenl->next;
-               }
+               if (nl) {
+                       endcycle = mi->endcycle;
+                       criticalpath = 0;
 
-       } else {
-               /* ...otherwise use last define dependency, if non-null */
+                       /* walk through depedencies and calculate highest latency */
 
-               if ((defnode = sd->fltregs_define_dep[reg]) > 0) {
-                       /* some edges to current machine instruction -> no leader */
+                       while (nl) {
+                               startcycle = sd->mi[nl->minode].startcycle;
+                               priority = sd->mi[nl->minode].priority;
 
-                       mi->leader = false;
+                               currentpath = (endcycle - startcycle) + priority;
 
-                       /* get last define machine instruction */
+                               if (currentpath > criticalpath)
+                                       criticalpath = currentpath;
 
-                       defmi = &sd->mi[defnode - 1];
+                               nl = nl->next;
+                       }
 
-                       nl = DNEW(nodelink);
-                       nl->minode = sd->micount;
-                       nl->next = defmi->deps;
-                       defmi->deps = nl;
+                       mi->priority = criticalpath;
+
+               } else {
+                       /* no dependencies, use virtual sink node */
+
+                       mi->priority = mi->endcycle - mi->startcycle;
                }
-       }
 
-       /* Set current instruction as new define dependency and clear use         */
-       /* depedencies.                                                           */
+               /* add leader to leader list */
 
-       sd->fltregs_define_dep[reg] = sd->micount;
-       sd->fltregs_use_dep[reg] = NULL;
+               if (mi->flags & SCHEDULE_LEADER) {
+                       nl = DNEW(nodelink);
+                       nl->minode = i;
+                       nl->next = sd->leaders;
+                       sd->leaders = nl;
+               }
+       }
 }
 
 
-void schedule_add_flt_use_dep(scheduledata *sd, s4 reg)
+static void schedule_create_graph(scheduledata *sd)
 {
        minstruction *mi;
-       minstruction *defmi;
        nodelink     *nl;
-       s4            defnode;
-
-       /* get current machine instruction */
+       s4            i;
 
-       mi = &sd->mi[sd->micount - 1];
+       FILE *file;
 
-       /* get current define dependency instruction */
+       file = fopen("cacao.dot", "w+");
 
-       if ((defnode = sd->fltregs_define_dep[reg]) > 0) {
-               /* some edges to current machine instruction -> no leader */
+       fprintf(file, "digraph G {\n");
 
-               mi->leader = false;
+       for (i = 0, mi = sd->mi; i < sd->micount; i++, mi++) {
+               nl = mi->deps;
 
-               /* add node to dependency list of current define node */
+               if (nl) {
+                       while (nl) {
+                               s4 priority = mi->priority - sd->mi[nl->minode].priority;
 
-               defmi = &sd->mi[defnode - 1];
+                               fprintf(file, "%d -> %d [ label = \"%d\" ]\n", i, nl->minode, priority);
+                               nl = nl->next;
+                       }
 
-               nl = DNEW(nodelink);
-               nl->minode = sd->micount;
-               nl->next = defmi->deps;
-               defmi->deps = nl;
+               } else {
+                       fprintf(file, "%d\n", i);
+               }
        }
 
-       /* add node to list of current use nodes */
-
-       nl = DNEW(nodelink);
-       nl->minode = sd->micount;
-       nl->next = sd->fltregs_use_dep[reg];
-       sd->fltregs_use_dep[reg] = nl;
-}
-
-
-void schedule_add_memory_define_dep(scheduledata *sd)
-{
-}
-
-
-void schedule_add_memory_use_dep(scheduledata *sd)
-{
+       fprintf(file, "}\n");
+       fclose(file);
 }
 
 
@@ -337,15 +316,35 @@ void schedule_do_schedule(scheduledata *sd)
        minstruction *mi;
        nodelink     *nl;
        s4            i;
+       s4            criticalpath;
+
+       /* calculate priorities and critical path */
+
+       schedule_calc_priorities(sd);
 
        printf("bb start ---\n");
 
-       for (i = 1, mi = sd->mi; i <= sd->micount; i++, mi++) {
+       printf("nodes: %d\n", sd->micount);
+
+       printf("leaders: ");
+       criticalpath = 0;
+       nl = sd->leaders;
+       while (nl) {
+               printf("%d ", nl->minode);
+               if (sd->mi[nl->minode].priority > criticalpath)
+                       criticalpath = sd->mi[nl->minode].priority;
+               nl = nl->next;
+       }
+       printf("\n");
+
+       printf("critical path: %d\n", criticalpath);
+
+       for (i = 0, mi = sd->mi; i < sd->micount; i++, mi++) {
                disassinstr(&mi->instr);
 
-               printf("\t--> #%d, %d, %d, %d, ", i, mi->latency, mi->priority, mi->leader);
+               printf("\t--> #%d, start=%d, end=%d, prio=%d", i, mi->startcycle, mi->endcycle, mi->priority);
 
-               printf("deps= ");
+               printf("deps= ");
                nl = mi->deps;
                while (nl) {
                        printf("%d ", nl->minode);
@@ -355,6 +354,8 @@ void schedule_do_schedule(scheduledata *sd)
                printf("\n");
        }
        printf("bb end ---\n\n");
+
+/*     schedule_create_graph(sd); */
 }
 
 
index f762c6ee7414ddfa57d088340bbd2c732ad27250..e4129ca741226cd255bd1c9a407c37b16b31425a 100644 (file)
@@ -1,4 +1,5 @@
-/* vm/jit/schedule/schedule.h - architecture independent instruction scheduler
+/* src/vm/jit/schedule/schedule.h - architecture independent instruction
+                                    scheduler
 
    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
@@ -28,7 +29,7 @@
 
    Changes:
 
-   $Id: schedule.h 1973 2005-03-02 16:27:05Z twisti $
+   $Id: schedule.h 1985 2005-03-04 17:09:13Z twisti $
 
 */
 
@@ -46,6 +47,11 @@ typedef struct minstruction minstruction;
 typedef struct nodelink nodelink;
 
 
+/* machine instruction flags **************************************************/
+
+#define SCHEDULE_LEADER    0x01
+
+
 /* scheduledata ****************************************************************
 
    XXX
@@ -76,9 +82,10 @@ struct scheduledata {
 
 struct minstruction {
        u4             instr[2];            /* machine instruction word           */
-       u1             latency;             /* instruction latency                */
+       u1             flags;
+       u1             startcycle;          /* start pipeline cycle               */
+       u1             endcycle;            /* end pipeline cycle                 */
        s4             priority;            /* priority of this instruction node  */
-       bool           leader;
        nodelink      *deps;                /* operand dependencies               */
        minstruction  *next;                /* link to next machine instruction   */
 };
@@ -99,13 +106,12 @@ struct nodelink {
 /* function prototypes ********************************************************/
 
 scheduledata *schedule_init(registerdata *rd);
-void schedule_calc_priority(minstruction *mi);
+void schedule_setup(scheduledata *sd, registerdata *rd);
 
-void schedule_add_int_define_dep(scheduledata *sd, s4 reg);
-void schedule_add_flt_define_dep(scheduledata *sd, s4 reg);
+void schedule_calc_priority(minstruction *mi);
 
-void schedule_add_int_use_dep(scheduledata *sd, s4 reg);
-void schedule_add_flt_use_dep(scheduledata *sd, s4 reg);
+void schedule_add_define_dep(scheduledata *sd, s4 *define_dep, nodelink **use_dep);
+void schedule_add_use_dep(scheduledata *sd, s4 *define_dep, nodelink **use_dep);
 
 void schedule_add_memory_define_dep(scheduledata *sd);
 void schedule_add_memory_use_dep(scheduledata *sd);