]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix VEX register allocator (v3) to work with HInstrSB, HInstrVec. jit-hacks
authorIvo Raisr <ivosh@ivosh.net>
Sun, 13 Aug 2017 17:18:11 +0000 (19:18 +0200)
committerIvo Raisr <ivosh@ivosh.net>
Tue, 15 Aug 2017 09:50:50 +0000 (11:50 +0200)
It does not support If-Then-Else, though.

VEX/priv/host_generic_reg_alloc3.c
VEX/priv/host_generic_regs.h

index a1c64ee9a3cdbbd26c9d0f351a1b967873f17858..88644ec0e9b3e677c093ececaadc91efd5e248cf 100644 (file)
@@ -217,7 +217,7 @@ static inline void print_state(
    }
 }
 
-static inline void emit_instr(HInstr* instr, HInstrArray* instrs_out,
+static inline void emit_instr(HInstr* instr, HInstrVec* instrs_out,
                               const RegAllocControl* con, const HChar* why)
 {
    if (DEBUG_REGALLOC) {
@@ -237,7 +237,7 @@ static inline void emit_instr(HInstr* instr, HInstrArray* instrs_out,
    Returns rreg's index. */
 static inline UInt spill_vreg(
    HReg vreg, UInt v_idx, UInt current_ii, VRegState* vreg_state, UInt n_vregs,
-   RRegState* rreg_state, UInt n_rregs, HInstrArray* instrs_out,
+   RRegState* rreg_state, UInt n_rregs, HInstrVec* instrs_out,
    const RegAllocControl* con)
 {
    /* Check some invariants first. */
@@ -320,10 +320,10 @@ static inline HReg find_vreg_to_spill(
    }
 
    if (hregIsInvalid(vreg_found)) {
-      vex_printf("doRegisterAllocation_v3: cannot find a register in class: ");
+      vex_printf("doRegisterAllocation: cannot find a register in class: ");
       ppHRegClass(target_hregclass);
       vex_printf("\n");
-      vpanic("doRegisterAllocation_v3: cannot find a register.");
+      vpanic("doRegisterAllocation: cannot find a register.");
    }
 
    return vreg_found;
@@ -391,9 +391,9 @@ static Bool find_free_rreg(
 
    Takes unallocated instructions and returns allocated instructions.
 */
-HInstrArray* doRegisterAllocation(
+HInstrSB* doRegisterAllocation(
    /* Incoming virtual-registerised code. */ 
-   HInstrArray* instrs_in,
+   HInstrSB* sb_in,
 
    /* Register allocator controls to use. */
    const RegAllocControl* con
@@ -401,8 +401,11 @@ HInstrArray* doRegisterAllocation(
 {
    vassert((con->guest_sizeB % LibVEX_GUEST_STATE_ALIGN) == 0);
 
+   /* TODO-JIT: for now, work only with the first HInstrVec. */
+   HInstrVec* instrs_in = sb_in->insns;
+
    /* The main register allocator state. */
-   UInt       n_vregs = instrs_in->n_vregs;
+   UInt       n_vregs = sb_in->n_vregs;
    VRegState* vreg_state = NULL;
    if (n_vregs > 0) {
       vreg_state = LibVEX_Alloc_inline(n_vregs * sizeof(VRegState));
@@ -416,40 +419,42 @@ HInstrArray* doRegisterAllocation(
    vassert(n_rregs > 0);
    STATIC_ASSERT(N_RREGUNIVERSE_REGS == 64);
 
-   /* Info on register usage in the incoming instruction array. Computed once
+   /* Info on register usage in the incoming instructions. Computed once
       and remains unchanged, more or less; updated sometimes by the
       direct-reload optimisation. */
    HRegUsage* reg_usage
-      = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->arr_used);
+      = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->insns_used);
 
    /* The live range numbers are signed shorts, and so limiting the
       number of instructions to 15000 comfortably guards against them
       overflowing 32k. */
-   vassert(instrs_in->arr_used <= 15000);
-
-   /* The output array of instructions. */
-   HInstrArray* instrs_out = newHInstrArray();
-
-
-#  define OFFENDING_VREG(_v_idx, _instr, _mode)                        \
-   do {                                                                \
-      vex_printf("\n\nOffending vreg = %u\n", (_v_idx));               \
-      vex_printf("\nOffending instruction = ");                        \
-      con->ppInstr((_instr), con->mode64);                             \
-      vex_printf("\n");                                                \
-      vpanic("doRegisterAllocation_v3: first event for vreg is #_mode# \
-             (should be Write)");                                      \
+   vassert(instrs_in->insns_used <= 15000);
+
+   /* The output SB of instructions. */
+   HInstrSB* sb_out = newHInstrSB();
+   sb_out->n_vregs = n_vregs;
+   HInstrVec* instrs_out = sb_out->insns;
+
+
+#  define OFFENDING_VREG(_v_idx, _instr, _mode)                     \
+   do {                                                             \
+      vex_printf("\n\nOffending vreg = %u\n", (_v_idx));            \
+      vex_printf("\nOffending instruction = ");                     \
+      con->ppInstr((_instr), con->mode64);                          \
+      vex_printf("\n");                                             \
+      vpanic("doRegisterAllocation: first event for vreg is #_mode# \
+             (should be Write)");                                   \
    } while (0)
 
-#  define OFFENDING_RREG(_r_idx, _instr, _mode)                        \
-   do {                                                                \
-      vex_printf("\n\nOffending rreg = ");                             \
-      con->ppReg(con->univ->regs[(_r_idx)]);                           \
-      vex_printf("\nOffending instruction = ");                        \
-      con->ppInstr((_instr), con->mode64);                             \
-      vex_printf("\n");                                                \
-      vpanic("doRegisterAllocation_v3: first event for rreg is #_mode# \
-             (should be Write)");                                      \
+#  define OFFENDING_RREG(_r_idx, _instr, _mode)                     \
+   do {                                                             \
+      vex_printf("\n\nOffending rreg = ");                          \
+      con->ppReg(con->univ->regs[(_r_idx)]);                        \
+      vex_printf("\nOffending instruction = ");                     \
+      con->ppInstr((_instr), con->mode64);                          \
+      vex_printf("\n");                                             \
+      vpanic("doRegisterAllocation: first event for rreg is #_mode# \
+             (should be Write)");                                   \
    } while (0)
 
 
@@ -468,7 +473,7 @@ HInstrArray* doRegisterAllocation(
                                      vreg_state, n_vregs, rreg_state, n_rregs, \
                                      &reg_usage[(_ii)], (_reg_class),          \
                                      reg_usage, (_ii) + 1,                     \
-                                     instrs_in->arr_used - 1, con);            \
+                                     instrs_in->insns_used - 1, con);          \
          _r_free_idx = spill_vreg(vreg_to_spill, hregIndex(vreg_to_spill),     \
                                   (_ii), vreg_state, n_vregs,                  \
                                   rreg_state, n_rregs,                         \
@@ -503,8 +508,13 @@ HInstrArray* doRegisterAllocation(
 
 
    /* --- Stage 1. Scan the incoming instructions. --- */
-   for (UShort ii = 0; ii < instrs_in->arr_used; ii++) {
-      const HInstr* instr = instrs_in->arr[ii];
+   for (UShort ii = 0; ii < instrs_in->insns_used; ii++) {
+      const HInstr* instr = instrs_in->insns[ii];
+
+      HInstrIfThenElse* hite = con->isIfThenElse(instr);
+      if (UNLIKELY(hite != NULL)) {
+         vpanic("doRegisterAllocation: If-Then-Else unsupported");
+      }
 
       con->getRegUsage(&reg_usage[ii], instr, con->mode64);
 
@@ -526,7 +536,7 @@ HInstrArray* doRegisterAllocation(
             con->ppInstr(instr, con->mode64);
             vex_printf("\n");
             vex_printf("vreg %u (n_vregs %u)\n", v_idx, n_vregs);
-            vpanic("doRegisterAllocation_v3: out-of-range vreg");
+            vpanic("doRegisterAllocation: out-of-range vreg");
          }
 
          /* Note the register class. */
@@ -747,13 +757,13 @@ HInstrArray* doRegisterAllocation(
 
 
    /* --- State 3. Process instructions. --- */
-   for (UShort ii = 0; ii < instrs_in->arr_used; ii++) {
-      HInstr* instr = instrs_in->arr[ii];
+   for (UShort ii = 0; ii < instrs_in->insns_used; ii++) {
+      HInstr* instr = instrs_in->insns[ii];
 
       if (DEBUG_REGALLOC) {
          vex_printf("\n====----====---- Instr %d ----====----====\n", ii);
          vex_printf("---- ");
-         con->ppInstr(instrs_in->arr[ii], con->mode64);
+         con->ppInstr(instrs_in->insns[ii], con->mode64);
          vex_printf("\n\nInitial state:\n");
          print_state(con, vreg_state, n_vregs, rreg_state, n_rregs, ii);
          vex_printf("\n");
@@ -766,7 +776,7 @@ HInstrArray* doRegisterAllocation(
       Bool do_sanity_check
          = toBool(
               SANITY_CHECKS_EVERY_INSTR
-              || ii == instrs_in->arr_used - 1
+              || ii == instrs_in->insns_used - 1
               || (ii > 0 && (ii % 17) == 0)
            );
 
@@ -964,7 +974,7 @@ HInstrArray* doRegisterAllocation(
          the instruction into one that reads directly from the spill slot.
          This is clearly only possible for x86 and amd64 targets, since ppc and
          arm are load-store architectures. If successful, replace
-         instrs_in->arr[ii] with this new instruction, and recompute
+         instrs_in->insns[ii] with this new instruction, and recompute
          its reg_usage, so that the change is invisible to the standard-case
          handling that follows. */
       if ((con->directReload != NULL) && (reg_usage[ii].n_vRegs <= 2)) {
@@ -999,7 +1009,7 @@ HInstrArray* doRegisterAllocation(
                                   reg_usage[ii].vRegs[1]));
             }
 
-            HInstr* reloaded = con->directReload(instrs_in->arr[ii],
+            HInstr* reloaded = con->directReload(instrs_in->insns[ii],
                                                  vreg_found, spill_offset);
             if (debug_direct_reload && (reloaded != NULL)) {
                vex_printf("[%3d] ", spill_offset);
@@ -1011,7 +1021,7 @@ HInstrArray* doRegisterAllocation(
                /* Update info about the instruction, so it looks as if it had
                   been in this form all along. */
                instr = reloaded;
-               instrs_in->arr[ii] = reloaded;
+               instrs_in->insns[ii] = reloaded;
                con->getRegUsage(&reg_usage[ii], instr, con->mode64);
                if (debug_direct_reload) {
                   vex_printf("  -->  ");
@@ -1135,7 +1145,7 @@ HInstrArray* doRegisterAllocation(
       }
    }
 
-   return instrs_out;
+   return sb_out;
 }
 
 /*----------------------------------------------------------------------------*/
index 8694922b1f83a528c55dd96a3014346e47082c76..978e4b68a47caaefd17e9b3e2bdb00209c98638d 100644 (file)
@@ -527,7 +527,7 @@ typedef
 
       /* Is this instruction actually HInstrIfThenElse? Returns pointer to
          HInstrIfThenElse if yes, NULL otherwise. */
-      HInstrIfThenElse* (*isIfThenElse) (const HInstr*);
+      HInstrIfThenElse* (*isIfThenElse)(const HInstr*);
 
       /* Return insn(s) to spill/restore a real register to a spill slot offset.
          Also a function to move between registers.
@@ -548,7 +548,7 @@ typedef
    RegAllocControl;
 
 extern HInstrSB* doRegisterAllocation(
-   HInstrSB* instrs_in,
+   HInstrSB* sb_in,
    const RegAllocControl* con
 );