|
From: <sv...@va...> - 2017-06-08 12:15:59
|
Author: iraisr
Date: Thu Jun 8 13:15:50 2017
New Revision: 3388
Log:
Introduce RegAllocSettings
Modified:
branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c
branches/VEX_JIT_HACKS/priv/host_generic_regs.h
branches/VEX_JIT_HACKS/priv/main_main.c
Modified: branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c Thu Jun 8 13:15:50 2017
@@ -157,7 +157,7 @@
considered.
To do this we don't actually need to see the incoming instruction
- stream. Rather, what we need us the HRegUsage records for the
+ stream. Rather, what we need is the HRegUsage records for the
incoming instruction stream. Hence that is passed in.
Returns an index into the state array indicating the (v,r) pair to
@@ -354,44 +354,12 @@
Takes an expandable array of pointers to unallocated insns.
Returns an expandable array of pointers to allocated insns.
*/
-HInstrArray* doRegisterAllocation (
-
+HInstrSB* doRegisterAllocation (
/* Incoming virtual-registerised code. */
- HInstrArray* instrs_in,
-
- /* The real-register universe to use. This contains facts about
- real registers, one of which is the set of registers available
- for allocation. */
- const RRegUniverse* univ,
-
- /* Return True iff the given insn is a reg-reg move, in which
- case also return the src and dst regs. */
- Bool (*isMove) ( const HInstr*, HReg*, HReg* ),
-
- /* Get info about register usage in this insn. */
- void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool ),
-
- /* Apply a reg-reg mapping to an insn. */
- void (*mapRegs) ( HRegRemap*, HInstr*, Bool ),
-
- /* Return one, or, if we're unlucky, two insn(s) to spill/restore a
- real reg to a spill slot byte offset. The two leading HInstr**
- args are out parameters, through which the generated insns are
- returned. Also (optionally) a 'directReload' function, which
- attempts to replace a given instruction by one which reads
- directly from a specified spill slot. May be NULL, in which
- case the optimisation is not attempted. */
- void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ),
- void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool ),
- HInstr* (*directReload) ( HInstr*, HReg, Short ),
- Int guest_sizeB,
-
- /* For debug printing only. */
- void (*ppInstr) ( const HInstr*, Bool ),
- void (*ppReg) ( HReg ),
+ HInstrSB* sb_in,
- /* 32/64bit mode */
- Bool mode64
+ /* Register allocator settings. */
+ const RegAllocSettings* settings
)
{
# define N_SPILL64S (LibVEX_N_SPILL_BYTES / 8)
@@ -419,7 +387,7 @@
/* Info on register usage in the incoming instruction array.
Computed once and remains unchanged, more or less; updated
sometimes by the direct-reload optimisation. */
- HRegUsage* reg_usage_arr; /* [0 .. instrs_in->arr_used-1] */
+ HRegUsage* reg_usage_arr; /* [0 .. instrs_in->insns_used-1] */
/* Used when constructing vreg_lrs (for allocating stack
slots). */
@@ -443,32 +411,33 @@
HRegRemap remap;
/* The output array of instructions. */
- HInstrArray* instrs_out;
+ HInstrSB* instrs_out;
+ HInstrVec *instrs_in = sb_in->insns;
/* Sanity checks are expensive. They are only done periodically,
not at each insn processed. */
Bool do_sanity_check;
- vassert(0 == (guest_sizeB % LibVEX_GUEST_STATE_ALIGN));
+ vassert(0 == (settings->guest_sizeB % LibVEX_GUEST_STATE_ALIGN));
vassert(0 == (LibVEX_N_SPILL_BYTES % LibVEX_GUEST_STATE_ALIGN));
vassert(0 == (N_SPILL64S % 2));
/* The live range numbers are signed shorts, and so limiting the
number of insns to 15000 comfortably guards against them
overflowing 32k. */
- vassert(instrs_in->arr_used <= 15000);
+ vassert(instrs_in->insns_used <= 15000);
# define INVALID_INSTRNO (-2)
-# define EMIT_INSTR(_instr) \
- do { \
- HInstr* _tmp = (_instr); \
- if (DEBUG_REGALLOC) { \
- vex_printf("** "); \
- (*ppInstr)(_tmp, mode64); \
- vex_printf("\n\n"); \
- } \
- addHInstr ( instrs_out, _tmp ); \
+# define EMIT_INSTR(_instr) \
+ do { \
+ HInstr* _tmp = (_instr); \
+ if (DEBUG_REGALLOC) { \
+ vex_printf("** "); \
+ settings->ppInstr(_tmp, settings->mode64); \
+ vex_printf("\n\n"); \
+ } \
+ addHInstr(instrs_out->insns, _tmp); \
} while (0)
# define PRINT_STATE \
@@ -476,13 +445,13 @@
Int z, q; \
for (z = 0; z < n_rregs; z++) { \
vex_printf(" rreg_state[%2d] = ", z); \
- (*ppReg)(univ->regs[z]); \
+ settings->ppReg(settings->univ->regs[z]); \
vex_printf(" \t"); \
switch (rreg_state[z].disp) { \
case Free: vex_printf("Free\n"); break; \
case Unavail: vex_printf("Unavail\n"); break; \
case Bound: vex_printf("BoundTo "); \
- (*ppReg)(rreg_state[z].vreg); \
+ settings->ppReg(rreg_state[z].vreg); \
vex_printf("\n"); break; \
} \
} \
@@ -503,12 +472,12 @@
/* --------- Stage 0: set up output array --------- */
/* --------- and allocate/initialise running state. --------- */
- instrs_out = newHInstrArray();
+ instrs_out = newHInstrSB();
/* ... and initialise running state. */
/* n_rregs is no more than a short name for n_available_real_regs. */
- n_rregs = univ->allocable;
- n_vregs = instrs_in->n_vregs;
+ n_rregs = settings->univ->allocable;
+ n_vregs = sb_in->n_vregs;
/* If this is not so, vreg_state entries will overflow. */
vassert(n_vregs < 32767);
@@ -557,7 +526,7 @@
/* An array to hold the reg-usage info for the incoming
instructions. */
reg_usage_arr
- = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->arr_used-1);
+ = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->insns_used-1);
/* ------ end of SET UP TO COMPUTE VREG LIVE RANGES ------ */
@@ -587,15 +556,16 @@
/* ------ start of ITERATE OVER INSNS ------ */
- for (Int ii = 0; ii < instrs_in->arr_used; ii++) {
+ for (Int ii = 0; ii < instrs_in->insns_used; ii++) {
- (*getRegUsage)( ®_usage_arr[ii], instrs_in->arr[ii], mode64 );
+ settings->getRegUsage(®_usage_arr[ii], instrs_in->insns[ii],
+ settings->mode64);
if (0) {
vex_printf("\n%d stage1: ", ii);
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
vex_printf("\n");
- ppHRegUsage(univ, ®_usage_arr[ii]);
+ ppHRegUsage(settings->univ, ®_usage_arr[ii]);
}
/* ------ start of DEAL WITH VREG LIVE RANGES ------ */
@@ -609,7 +579,7 @@
Int k = hregIndex(vreg);
if (k < 0 || k >= n_vregs) {
vex_printf("\n");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
vex_printf("\n");
vex_printf("vreg %d, n_vregs %d\n", k, n_vregs);
vpanic("doRegisterAllocation: out-of-range vreg");
@@ -714,10 +684,10 @@
} else if (!isW && isR) {
if (rreg_live_after[j] == INVALID_INSTRNO) {
vex_printf("\nOFFENDING RREG = ");
- (*ppReg)(univ->regs[j]);
+ settings->ppReg(settings->univ->regs[j]);
vex_printf("\n");
vex_printf("\nOFFENDING instr = ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
vex_printf("\n");
vpanic("doRegisterAllocation: "
"first event for rreg is Read");
@@ -727,10 +697,10 @@
vassert(isR && isW);
if (rreg_live_after[j] == INVALID_INSTRNO) {
vex_printf("\nOFFENDING RREG = ");
- (*ppReg)(univ->regs[j]);
+ settings->ppReg(settings->univ->regs[j]);
vex_printf("\n");
vex_printf("\nOFFENDING instr = ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
vex_printf("\n");
vpanic("doRegisterAllocation: "
"first event for rreg is Modify");
@@ -744,7 +714,7 @@
ensureRRLRspace(&rreg_lrs_la, &rreg_lrs_size, rreg_lrs_used);
if (0)
vex_printf("FLUSH 1 (%d,%d)\n", flush_la, flush_db);
- rreg_lrs_la[rreg_lrs_used].rreg = univ->regs[j];
+ rreg_lrs_la[rreg_lrs_used].rreg = settings->univ->regs[j];
rreg_lrs_la[rreg_lrs_used].live_after = toShort(flush_la);
rreg_lrs_la[rreg_lrs_used].dead_before = toShort(flush_db);
rreg_lrs_used++;
@@ -781,7 +751,7 @@
if (0)
vex_printf("FLUSH 2 (%d,%d)\n",
rreg_live_after[j], rreg_dead_before[j]);
- rreg_lrs_la[rreg_lrs_used].rreg = univ->regs[j];
+ rreg_lrs_la[rreg_lrs_used].rreg = settings->univ->regs[j];
rreg_lrs_la[rreg_lrs_used].live_after = toShort(rreg_live_after[j]);
rreg_lrs_la[rreg_lrs_used].dead_before = toShort(rreg_dead_before[j]);
rreg_lrs_used++;
@@ -808,7 +778,7 @@
for (Int j = 0; j < n_rregs; j++) {
if (!rreg_state[j].has_hlrs)
continue;
- ppReg(univ->regs[j]);
+ settings->ppReg(settings->univ->regs[j]);
vex_printf(" hinted\n");
}
}
@@ -844,14 +814,14 @@
vex_printf("RRegLRs by LA:\n");
for (Int j = 0; j < rreg_lrs_used; j++) {
vex_printf(" ");
- (*ppReg)(rreg_lrs_la[j].rreg);
+ settings->ppReg(rreg_lrs_la[j].rreg);
vex_printf(" la = %d, db = %d\n",
rreg_lrs_la[j].live_after, rreg_lrs_la[j].dead_before );
}
vex_printf("RRegLRs by DB:\n");
for (Int j = 0; j < rreg_lrs_used; j++) {
vex_printf(" ");
- (*ppReg)(rreg_lrs_db[j].rreg);
+ settings->ppReg(rreg_lrs_db[j].rreg);
vex_printf(" la = %d, db = %d\n",
rreg_lrs_db[j].live_after, rreg_lrs_db[j].dead_before );
}
@@ -943,7 +913,7 @@
/* This reflects LibVEX's hard-wired knowledge of the baseBlock
layout: the guest state, then two equal sized areas following
it for two sets of shadow state, and then the spill area. */
- vreg_lrs[j].spill_offset = toShort(guest_sizeB * 3 + ss_no * 8);
+ vreg_lrs[j].spill_offset = toShort(settings->guest_sizeB * 3 + ss_no * 8);
/* Independent check that we've made a sane choice of slot */
sanity_check_spill_offset( &vreg_lrs[j] );
@@ -979,16 +949,14 @@
correctly set up our running state, which tracks the status of
each real register. */
- insn_count = original_insn_count;
-
/* ------ BEGIN: Process each insn in turn. ------ */
- for (Int ii = 0; ii < instrs_in->arr_used; ii++) {
+ for (Int ii = 0; ii < instrs_in->insns_used; ii++) {
if (DEBUG_REGALLOC) {
vex_printf("\n====----====---- Insn %d ----====----====\n", ii);
vex_printf("---- ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
vex_printf("\n\nInitial state:\n");
PRINT_STATE;
vex_printf("\n");
@@ -1002,7 +970,7 @@
do_sanity_check
= toBool(
False /* Set to True for sanity checking of all insns. */
- || ii == instrs_in->arr_used-1
+ || ii == instrs_in->insns_used-1
|| (ii > 0 && (ii % 17) == 0)
);
@@ -1022,7 +990,7 @@
vex_printf("considering la %d .. db %d reg = ",
rreg_lrs_la[j].live_after,
rreg_lrs_la[j].dead_before);
- (*ppReg)(reg);
+ settings->ppReg(reg);
vex_printf("\n");
}
@@ -1063,7 +1031,7 @@
vassert(rreg_state[j].eq_spill_slot == False);
continue;
}
- vassert(hregClass(univ->regs[j])
+ vassert(hregClass(settings->univ->regs[j])
== hregClass(rreg_state[j].vreg));
vassert( hregIsVirtual(rreg_state[j].vreg));
}
@@ -1103,7 +1071,7 @@
the dst to the src's rreg, and that's all. */
HReg vregS = INVALID_HREG;
HReg vregD = INVALID_HREG;
- if ( (*isMove)( instrs_in->arr[ii], &vregS, &vregD ) ) {
+ if (settings->isMove(instrs_in->insns[ii], &vregS, &vregD)) {
if (!hregIsVirtual(vregS)) goto cannot_coalesce;
if (!hregIsVirtual(vregD)) goto cannot_coalesce;
/* Check that *isMove is not telling us a bunch of lies ... */
@@ -1116,9 +1084,9 @@
if (vreg_lrs[m].live_after != ii) goto cannot_coalesce;
if (DEBUG_REGALLOC) {
vex_printf("COALESCE ");
- (*ppReg)(vregS);
+ settings->ppReg(vregS);
vex_printf(" -> ");
- (*ppReg)(vregD);
+ settings->ppReg(vregD);
vex_printf("\n\n");
}
/* Find the state entry for vregS. */
@@ -1167,7 +1135,7 @@
vreg_state[m] = INVALID_RREG_NO;
if (DEBUG_REGALLOC) {
vex_printf("free up ");
- (*ppReg)(univ->regs[j]);
+ settings->ppReg(settings->univ->regs[j]);
vex_printf("\n");
}
}
@@ -1208,7 +1176,7 @@
than before it. */
if (DEBUG_REGALLOC) {
vex_printf("need to free up rreg: ");
- (*ppReg)(rreg_lrs_la[rreg_lrs_la_next].rreg);
+ settings->ppReg(rreg_lrs_la[rreg_lrs_la_next].rreg);
vex_printf("\n\n");
}
Int k = hregIndex(rreg_lrs_la[rreg_lrs_la_next].rreg);
@@ -1227,8 +1195,8 @@
if ((!eq_spill_opt) || !rreg_state[k].eq_spill_slot) {
HInstr* spill1 = NULL;
HInstr* spill2 = NULL;
- (*genSpill)( &spill1, &spill2, univ->regs[k],
- vreg_lrs[m].spill_offset, mode64 );
+ settings->genSpill(&spill1, &spill2, settings->univ->regs[k],
+ vreg_lrs[m].spill_offset, settings->mode64);
vassert(spill1 || spill2); /* can't both be NULL */
if (spill1)
EMIT_INSTR(spill1);
@@ -1275,7 +1243,7 @@
that the change is invisible to the standard-case handling
that follows. */
- if (directReload && reg_usage_arr[ii].n_vRegs <= 2) {
+ if (settings->directReload != NULL && reg_usage_arr[ii].n_vRegs <= 2) {
Bool debug_direct_reload = False;
HReg cand = INVALID_HREG;
Bool nreads = 0;
@@ -1309,19 +1277,21 @@
vassert(! sameHReg(reg_usage_arr[ii].vRegs[0],
reg_usage_arr[ii].vRegs[1]));
- reloaded = directReload ( instrs_in->arr[ii], cand, spilloff );
+ reloaded = settings->directReload(instrs_in->insns[ii], cand,
+ spilloff);
if (debug_direct_reload && !reloaded) {
vex_printf("[%3d] ", spilloff); ppHReg(cand); vex_printf(" ");
- ppInstr(instrs_in->arr[ii], mode64);
+ settings->ppInstr(instrs_in->insns[ii], settings->mode64);
}
if (reloaded) {
/* Update info about the insn, so it looks as if it had
been in this form all along. */
- instrs_in->arr[ii] = reloaded;
- (*getRegUsage)( ®_usage_arr[ii], instrs_in->arr[ii], mode64 );
+ instrs_in->insns[ii] = reloaded;
+ settings->getRegUsage(®_usage_arr[ii], instrs_in->insns[ii],
+ settings->mode64);
if (debug_direct_reload && !reloaded) {
vex_printf(" --> ");
- ppInstr(reloaded, mode64);
+ settings->ppInstr(reloaded, settings->mode64);
}
}
@@ -1340,7 +1310,7 @@
vassert(hregIsVirtual(vreg));
if (0) {
- vex_printf("considering "); (*ppReg)(vreg); vex_printf("\n");
+ vex_printf("considering "); settings->ppReg(vreg); vex_printf("\n");
}
/* Now we're trying to find a rreg for "vreg". First of all,
@@ -1351,7 +1321,7 @@
Int n = vreg_state[m];
if (IS_VALID_RREGNO(n)) {
vassert(rreg_state[n].disp == Bound);
- addToHRegRemap(&remap, vreg, univ->regs[n]);
+ addToHRegRemap(&remap, vreg, settings->univ->regs[n]);
/* If this rreg is written or modified, mark it as different
from any spill slot value. */
if (reg_usage_arr[ii].vMode[j] != HRmRead)
@@ -1370,7 +1340,7 @@
Int k;
for (k = 0; k < n_rregs; k++) {
if (rreg_state[k].disp != Free
- || hregClass(univ->regs[k]) != hregClass(vreg))
+ || hregClass(settings->univ->regs[k]) != hregClass(vreg))
continue;
if (rreg_state[k].has_hlrs) {
/* Well, at least we can use k_suboptimal if we really
@@ -1391,7 +1361,7 @@
Int p = hregIndex(vreg);
vassert(IS_VALID_VREGNO(p));
vreg_state[p] = toShort(k);
- addToHRegRemap(&remap, vreg, univ->regs[k]);
+ addToHRegRemap(&remap, vreg, settings->univ->regs[k]);
/* Generate a reload if needed. This only creates needed
reloads because the live range builder for vregs will
guarantee that the first event for a vreg is a write.
@@ -1402,8 +1372,8 @@
vassert(vreg_lrs[p].reg_class != HRcINVALID);
HInstr* reload1 = NULL;
HInstr* reload2 = NULL;
- (*genReload)( &reload1, &reload2, univ->regs[k],
- vreg_lrs[p].spill_offset, mode64 );
+ settings->genReload(&reload1, &reload2, settings->univ->regs[k],
+ vreg_lrs[p].spill_offset, settings->mode64);
vassert(reload1 || reload2); /* can't both be NULL */
if (reload1)
EMIT_INSTR(reload1);
@@ -1437,7 +1407,7 @@
rreg_state[k].is_spill_cand = False;
if (rreg_state[k].disp != Bound)
continue;
- if (hregClass(univ->regs[k]) != hregClass(vreg))
+ if (hregClass(settings->univ->regs[k]) != hregClass(vreg))
continue;
rreg_state[k].is_spill_cand = True;
/* Note, the following loop visits only the virtual regs
@@ -1457,7 +1427,7 @@
of consequent reloads required. */
Int spillee
= findMostDistantlyMentionedVReg (
- reg_usage_arr, ii+1, instrs_in->arr_used, rreg_state, n_rregs );
+ reg_usage_arr, ii+1, instrs_in->insns_used, rreg_state, n_rregs );
if (spillee == -1) {
/* Hmmmmm. There don't appear to be any spill candidates.
@@ -1472,7 +1442,7 @@
vassert(IS_VALID_RREGNO(spillee));
vassert(rreg_state[spillee].disp == Bound);
/* check it's the right class */
- vassert(hregClass(univ->regs[spillee]) == hregClass(vreg));
+ vassert(hregClass(settings->univ->regs[spillee]) == hregClass(vreg));
/* check we're not ejecting the vreg for which we are trying
to free up a register. */
vassert(! sameHReg(rreg_state[spillee].vreg, vreg));
@@ -1487,8 +1457,8 @@
if ((!eq_spill_opt) || !rreg_state[spillee].eq_spill_slot) {
HInstr* spill1 = NULL;
HInstr* spill2 = NULL;
- (*genSpill)( &spill1, &spill2, univ->regs[spillee],
- vreg_lrs[m].spill_offset, mode64 );
+ settings->genSpill(&spill1, &spill2, settings->univ->regs[spillee],
+ vreg_lrs[m].spill_offset, settings->mode64);
vassert(spill1 || spill2); /* can't both be NULL */
if (spill1)
EMIT_INSTR(spill1);
@@ -1513,8 +1483,9 @@
vassert(vreg_lrs[m].reg_class != HRcINVALID);
HInstr* reload1 = NULL;
HInstr* reload2 = NULL;
- (*genReload)( &reload1, &reload2, univ->regs[spillee],
- vreg_lrs[m].spill_offset, mode64 );
+ settings->genReload(&reload1, &reload2,
+ settings->univ->regs[spillee],
+ vreg_lrs[m].spill_offset, settings->mode64);
vassert(reload1 || reload2); /* can't both be NULL */
if (reload1)
EMIT_INSTR(reload1);
@@ -1533,7 +1504,7 @@
/* So after much twisting and turning, we have vreg mapped to
rreg_state[spillee].rreg. Note that in the map. */
- addToHRegRemap(&remap, vreg, univ->regs[spillee]);
+ addToHRegRemap(&remap, vreg, settings->univ->regs[spillee]);
} /* iterate over virtual registers in this instruction. */
@@ -1548,9 +1519,9 @@
and emit that.
*/
- /* NOTE, DESTRUCTIVELY MODIFIES instrs_in->arr[ii]. */
- (*mapRegs)( &remap, instrs_in->arr[ii], mode64 );
- EMIT_INSTR( instrs_in->arr[ii] );
+ /* NOTE, DESTRUCTIVELY MODIFIES instrs_in->insns[ii]. */
+ settings->mapRegs(&remap, instrs_in->insns[ii], settings->mode64);
+ EMIT_INSTR(instrs_in->insns[ii]);
if (DEBUG_REGALLOC) {
vex_printf("After dealing with current insn:\n");
@@ -1610,10 +1581,6 @@
# undef PRINT_STATE
}
-static UInt count_longest_insn_seq(HInstrVec* insns,
- HInstrIfThenElse* (*isIfThenElse)(const HInstr*))
-{
- UInt longest_insn_count = 0;
/*---------------------------------------------------------------*/
Modified: branches/VEX_JIT_HACKS/priv/host_generic_regs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_generic_regs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_generic_regs.h Thu Jun 8 13:15:50 2017
@@ -486,45 +486,58 @@
/*--- Reg alloc: TODO: move somewhere else ---*/
/*---------------------------------------------------------*/
+/* Settings for the register allocator. Immutable (do not change at all). */
+typedef
+ struct {
+ /* The real-register universe to use. This contains facts about
+ real registers, one of which is the set of registers available
+ for allocation. */
+ const RRegUniverse* univ;
+
+ /* Return True iff the given insn is a reg-reg move, in which
+ case also return the src and dst regs. */
+ Bool (*isMove)(const HInstr*, HReg*, HReg*);
+
+ /* Get info about register usage in this insn. */
+ void (*getRegUsage)(HRegUsage*, const HInstr*, Bool);
+
+ /* Apply a reg-reg mapping to an insn. */
+ void (*mapRegs)(HRegRemap*, HInstr*, Bool);
+
+ /* Is this instruction actually HInstrIfThenElse? */
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*);
+
+ /* Return one, or, if we're unlucky, two insn(s) to spill/restore a
+ real reg to a spill slot byte offset. The two leading HInstr**
+ args are out parameters, through which the generated insns are
+ returned. Also (optionally) a 'directReload' function, which
+ attempts to replace a given instruction by one which reads
+ directly from a specified spill slot. May be NULL, in which
+ case the optimisation is not attempted. */
+ void (*genSpill)( HInstr**, HInstr**, HReg, Int, Bool);
+ void (*genReload)( HInstr**, HInstr**, HReg, Int, Bool);
+ HInstr* (*directReload)( HInstr*, HReg, Short);
+ UInt guest_sizeB;
+
+ /* For debug printing only. */
+ void (*ppInstr)(const HInstr*, Bool);
+ void (*ppCondCode)(HCondCode);
+ void (*ppReg)(HReg);
+
+ /* 32/64bit mode */
+ Bool mode64;
+ }
+ RegAllocSettings;
+
+
extern
HInstrSB* doRegisterAllocation (
/* Incoming virtual-registerised code. */
HInstrSB* sb_in,
- /* The real-register universe to use. This contains facts about
- real registers, one of which is the set of registers available
- for allocation. */
- const RRegUniverse* univ,
-
- /* Return True iff the given insn is a reg-reg move, in which
- case also return the src and dst regs. */
- Bool (*isMove) (const HInstr*, HReg*, HReg*),
-
- /* Get info about register usage in this insn. */
- void (*getRegUsage) (HRegUsage*, const HInstr*, Bool),
-
- /* Apply a reg-reg mapping to an insn. */
- void (*mapRegs) (HRegRemap*, HInstr*, Bool),
-
- /* Is this instruction actually HInstrIfThenElse? Returns pointer to
- HInstrIfThenElse if yes, NULL otherwise. */
- HInstrIfThenElse* (*isIfThenElse) (const HInstr*),
-
- /* Return insn(s) to spill/restore a real reg to a spill slot
- offset. And optionally a function to do direct reloads. */
- void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ),
- void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool ),
- HInstr* (*directReload) ( HInstr*, HReg, Short ),
- Int guest_sizeB,
-
- /* For debug printing only. */
- void (*ppInstr) ( const HInstr*, Bool ),
- void (*ppCondCode)(HCondCode),
- void (*ppReg) ( HReg ),
-
- /* 32/64bit mode */
- Bool mode64
+ /* Register allocator settings. */
+ const RegAllocSettings* settings
);
Modified: branches/VEX_JIT_HACKS/priv/main_main.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/main_main.c (original)
+++ branches/VEX_JIT_HACKS/priv/main_main.c Thu Jun 8 13:15:50 2017
@@ -1052,11 +1052,13 @@
}
/* Register allocate. */
- rcode = doRegisterAllocation ( vcode, rRegUniv,
- isMove, getRegUsage, mapRegs, isIfThenElse,
- genSpill, genReload, directReload,
- guest_sizeB,
- ppInstr, ppCondCode, ppReg, mode64 );
+ RegAllocSettings settings = {
+ .univ = rRegUniv, .isMove = isMove, .getRegUsage = getRegUsage,
+ .mapRegs = mapRegs, .isIfThenElse = isIfThenElse, .genSpill = genSpill,
+ .genReload = genReload, .directReload = directReload,
+ .guest_sizeB = guest_sizeB, .ppInstr = ppInstr, .ppCondCode = ppCondCode,
+ .ppReg = ppReg, .mode64 = mode64};
+ rcode = doRegisterAllocation(vcode, &settings);
vexAllocSanityCheck();
|