|
From: <sv...@va...> - 2015-01-17 11:11:06
|
Author: sewardj
Date: Sat Jan 17 11:10:57 2015
New Revision: 3066
Log:
Get the register allocator to annotate NCode blocks with the set of
real registers live after the block. This is then used to generate
minimal save/restore sets around C helper calls made from NCode
blocks. Greatly reduces the amount of code in NCode code sections.
Modified:
branches/NCODE/priv/host_amd64_defs.c
branches/NCODE/priv/host_amd64_defs.h
branches/NCODE/priv/host_generic_reg_alloc2.c
Modified: branches/NCODE/priv/host_amd64_defs.c
==============================================================================
--- branches/NCODE/priv/host_amd64_defs.c (original)
+++ branches/NCODE/priv/host_amd64_defs.c Sat Jan 17 11:10:57 2015
@@ -981,11 +981,12 @@
AMD64Instr* AMD64Instr_NCode ( NCodeTemplate* tmpl, HReg* regsR,
HReg* regsA, HReg* regsS ) {
AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
- i->tag = Ain_NCode;
- i->Ain.NCode.tmpl = tmpl;
- i->Ain.NCode.regsR = regsR;
- i->Ain.NCode.regsA = regsA;
- i->Ain.NCode.regsS = regsS;
+ i->tag = Ain_NCode;
+ i->Ain.NCode.tmpl = tmpl;
+ i->Ain.NCode.regsR = regsR;
+ i->Ain.NCode.regsA = regsA;
+ i->Ain.NCode.regsS = regsS;
+ i->Ain.NCode.liveAfter = NULL;
return i;
}
AMD64Instr* AMD64Instr_NC_Jmp32 ( AMD64CondCode cc ) {
@@ -3643,6 +3644,7 @@
/*MOD*/RelocationBuffer* rb,
const NInstr* ni,
const NRegMap* nregMap,
+ const HRegSet* hregsLiveAfter,
/* for debug printing only */
Bool verbose, NLabel niLabel );
@@ -3671,6 +3673,7 @@
vassert(endness_host == VexEndnessLE);
vassert(hi->tag == Ain_NCode);
const NCodeTemplate* tmpl = hi->Ain.NCode.tmpl;
+ const HRegSet* hregsLiveAfter = hi->Ain.NCode.liveAfter;
NRegMap nregMap;
nregMap.regsR = hi->Ain.NCode.regsR;
@@ -3718,14 +3721,16 @@
for (i = 0; i < nHot; i++) {
offsetsHot[i] = AssemblyBuffer__getNext(ab_hot);
NLabel lbl = mkNLabel(Nlz_Hot, i);
- emit_AMD64NInstr(ab_hot, rb, tmpl->hot[i], &nregMap, verbose, lbl);
+ emit_AMD64NInstr(ab_hot, rb, tmpl->hot[i], &nregMap,
+ hregsLiveAfter, verbose, lbl);
}
/* And the cold code */
for (i = 0; i < nCold; i++) {
offsetsCold[i] = AssemblyBuffer__getNext(ab_cold);
NLabel lbl = mkNLabel(Nlz_Cold, i);
- emit_AMD64NInstr(ab_cold, rb, tmpl->cold[i], &nregMap, verbose, lbl);
+ emit_AMD64NInstr(ab_cold, rb, tmpl->cold[i], &nregMap,
+ hregsLiveAfter, verbose, lbl);
}
/* Now visit the new relocation entries. */
@@ -3867,7 +3872,9 @@
static
void emit_AMD64NInstr ( /*MOD*/AssemblyBuffer* ab,
/*MOD*/RelocationBuffer* rb,
- const NInstr* ni, const NRegMap* nregMap,
+ const NInstr* ni,
+ const NRegMap* nregMap,
+ const HRegSet* hregsLiveAfter,
/* the next 2 are for debug printing only */
Bool verbose, NLabel niLabel )
{
@@ -3957,8 +3964,9 @@
overestimate of (1) -- for example, all regs available to
reg-alloc -- and refine it later.
*/
- HRegSet* set_1 = HRegSet__new();
- { Int nregs; HReg* arr;
+ const HRegSet* set_1 = hregsLiveAfter; //HRegSet__new();
+ if (0) {
+ Int nregs; HReg* arr;
getAllocableRegs_AMD64(&nregs, &arr);
HRegSet__fromVec(set_1, arr, nregs);
}
@@ -4017,8 +4025,10 @@
stackMove = (stackMove + 31) & ~31;
UInt i;
- HI( AMD64Instr_Alu64R(Aalu_SUB, AMD64RMI_Imm(stackMove),
- hregAMD64_RSP()) );
+ if (stackMove > 0) {
+ HI( AMD64Instr_Alu64R(Aalu_SUB, AMD64RMI_Imm(stackMove),
+ hregAMD64_RSP()) );
+ }
for (i = 0; i < n_to_preserve; i++) {
HReg r = HRegSet__index(to_preserve, i);
AMD64Instr* i1 = NULL;
@@ -4067,9 +4077,10 @@
if (i1) HI(i1);
if (i2) HI(i2);
}
- HI( AMD64Instr_Alu64R(Aalu_ADD, AMD64RMI_Imm(stackMove),
- hregAMD64_RSP()) );
-
+ if (stackMove > 0) {
+ HI( AMD64Instr_Alu64R(Aalu_ADD, AMD64RMI_Imm(stackMove),
+ hregAMD64_RSP()) );
+ }
break;
}
Modified: branches/NCODE/priv/host_amd64_defs.h
==============================================================================
--- branches/NCODE/priv/host_amd64_defs.h (original)
+++ branches/NCODE/priv/host_amd64_defs.h Sat Jan 17 11:10:57 2015
@@ -745,6 +745,7 @@
HReg* regsR; /* Result regs, INVALID_HREG terminated */
HReg* regsA; /* Arg regs, ditto */
HReg* regsS; /* Scratch regs, ditto */
+ HRegSet* liveAfter; /* initially NULL, filled in by RA */
} NCode;
/* --- for NCode only --- */
Modified: branches/NCODE/priv/host_generic_reg_alloc2.c
==============================================================================
--- branches/NCODE/priv/host_generic_reg_alloc2.c (original)
+++ branches/NCODE/priv/host_generic_reg_alloc2.c Sat Jan 17 11:10:57 2015
@@ -39,6 +39,10 @@
#include "main_util.h"
#include "host_generic_regs.h"
+// ******** WARNING KLUDGE DO NOT COMMIT
+#include "host_amd64_defs.h"
+// ******** WARNING KLUDGE DO NOT COMMIT
+
/* Set to 1 for lots of debugging output. */
#define DEBUG_REGALLOC 0
@@ -1533,6 +1537,27 @@
vex_printf("\n");
# endif
+ /* ------ Post-instruction actions for NCode blocks ------ */
+
+ /* If this instruction is an NCode block, annotate it with the
+ set of registers that are live after it. */
+ { AMD64Instr* ai = instrs_in->arr[ii];
+ if (ai->tag == Ain_NCode) {
+ //vex_printf("RA: after NCode: ");
+ vassert(ai->Ain.NCode.liveAfter == NULL);
+ HRegSet* live_after_NCode = HRegSet__new();
+ for (k = 0; k < n_rregs; k++) {
+ if (rreg_state[k].disp == Free)
+ continue;
+ //ppHRegAMD64(rreg_state[k].rreg);
+ HRegSet__add(live_after_NCode, rreg_state[k].rreg);
+ //vex_printf(" ");
+ }
+ //vex_printf("\n");
+ ai->Ain.NCode.liveAfter = live_after_NCode;
+ }
+ }
+
} /* iterate over insns */
/* ------ END: Process each insn in turn. ------ */
|