}
}
-#define WALK_CHUNKS(process_one_chunk, process_fall_through_leg, \
+#define WALK_CHUNKS(process_one_chunk, process_legs_fork, \
+ process_fall_through_leg, \
process_out_of_line_leg, process_phi_nodes) \
do { \
while (chunk != NULL) { \
process_one_chunk; \
if (chunk->isIfThenElse) { \
+ process_legs_fork; \
if (DEBUG_REGALLOC) { \
print_depth(depth); \
vex_printf("if (!"); \
static inline void print_state(const RegAllocChunk* chunk,
const VRegState* vreg_state, UInt n_vregs, const RRegState* rreg_state,
- Short ii_total_current, const RegAllocControl* con)
+ Short ii_total_current, UInt depth, const RegAllocControl* con,
+ const HChar* comment)
{
- vex_printf("Register Allocator state (current instruction total #%d)\n",
- ii_total_current);
+ print_depth(depth);
+ vex_printf("%s (current instruction total #%d):\n",
+ comment, ii_total_current);
for (UInt v_idx = 0; v_idx < n_vregs; v_idx++) {
const VRegState* vreg = &vreg_state[v_idx];
if (vreg->live_after == INVALID_INSTRNO) {
continue; /* This is a dead vreg. Never comes into live. */
}
+ print_depth(depth);
vex_printf("vreg_state[%3u] \t", v_idx);
UInt written;
for (UInt r_idx = 0; r_idx < chunk->n_rregs; r_idx++) {
const RRegState* rreg = &rreg_state[r_idx];
const RRegLR* lr = chunk->rreg_lr_state[r_idx].lr_current;
+ print_depth(depth);
vex_printf("rreg_state[%2u] = ", r_idx);
UInt written = con->ppReg(con->univ->regs[r_idx]);
for (Int w = 10 - written; w > 0; w--) {
}
}
-static inline void emit_instr(RegAllocChunk* chunk, HInstr* instr,
+static inline void emit_instr(RegAllocChunk* chunk, HInstr* instr, UInt depth,
const RegAllocControl* con, const HChar* why)
{
if (DEBUG_REGALLOC) {
+ print_depth(depth);
vex_printf("** ");
con->ppInstr(instr, con->mode64);
if (why != NULL) {
RegAllocChunk* chunk,
VRegState* vreg_state, UInt n_vregs, RRegState* rreg_state,
HReg vreg, UInt v_idx, Short ii_total_current,
- const RegAllocControl* con)
+ UInt depth, const RegAllocControl* con)
{
UInt n_rregs = chunk->n_rregs;
con->mode64);
vassert(spill1 != NULL || spill2 != NULL); /* cannot be both NULL */
if (spill1 != NULL) {
- emit_instr(chunk, spill1, con, "spill1");
+ emit_instr(chunk, spill1, depth, con, "spill1");
}
if (spill2 != NULL) {
- emit_instr(chunk, spill2, con, "spill2");
+ emit_instr(chunk, spill2, depth, con, "spill2");
}
/* Update register allocator state. */
UInt n_rregs, UInt depth, const RegAllocControl* con)
{
WALK_CHUNKS(stage2_chunk(chunk, vreg_state, n_vregs, n_rregs, depth, con),
+ ;,
stage2(chunk->IfThenElse.fallThrough, vreg_state, n_vregs,
n_rregs, depth + 1, con),
stage2(chunk->IfThenElse.outOfLine, vreg_state, n_vregs,
const RegAllocControl* con)
{
WALK_CHUNKS(stage2_debug_rregs_chunk(chunk, depth, con),
+ ;,
stage2_debug_rregs(chunk->IfThenElse.fallThrough, depth + 1, con),
stage2_debug_rregs(chunk->IfThenElse.outOfLine, depth + 1, con),
;);
ii_chunk, con); \
_r_free_idx = spill_vreg(chunk, vreg_state, n_vregs, rreg_state, \
vreg_to_spill, hregIndex(vreg_to_spill), \
- INSTRNO_TOTAL, con); \
+ INSTRNO_TOTAL, depth, con); \
} \
\
vassert(IS_VALID_RREGNO(_r_free_idx)); \
HRegUsage* reg_usage = &chunk->reg_usage[ii_chunk];
if (DEBUG_REGALLOC) {
+ vex_printf("\n");
print_depth(depth);
- vex_printf("\n====---- Instr: chunk %d, vec %d, total %d ----====\n",
+ vex_printf("====---- Instr: chunk %d, vec %d, total %d ----====\n",
ii_chunk, ii_vec, INSTRNO_TOTAL);
print_depth(depth);
vex_printf("---- ");
con->ppInstr(chunk->instrs_in->insns[ii_vec], con->mode64);
- print_depth(depth);
- vex_printf("\n\nInitial state:\n");
- print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL, con);
+ vex_printf("\n\n");
+ print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL,
+ depth, con, "Initial Register Allocator state");
vex_printf("\n");
}
if (! HRegUsage__contains(reg_usage, vreg)) {
/* Spill the vreg. It is not used by this instruction. */
spill_vreg(chunk, vreg_state, n_vregs, rreg_state,
- vreg, v_idx, INSTRNO_TOTAL, con);
+ vreg, v_idx, INSTRNO_TOTAL, depth, con);
} else {
/* Find or make a free rreg where to move this vreg to. */
UInt r_free_idx = FIND_OR_MAKE_FREE_RREG(
HInstr* move = con->genMove(con->univ->regs[r_idx],
con->univ->regs[r_free_idx], con->mode64);
vassert(move != NULL);
- emit_instr(chunk, move, con, "move");
+ emit_instr(chunk, move, depth, con, "move");
/* Update the register allocator state. */
vassert(vreg_state[v_idx].disp == Assigned);
vreg_state[v_idx].spill_offset, con->mode64);
vassert(reload1 != NULL || reload2 != NULL);
if (reload1 != NULL) {
- emit_instr(chunk, reload1, con, "reload1");
+ emit_instr(chunk, reload1, depth, con, "reload1");
}
if (reload2 != NULL) {
- emit_instr(chunk, reload2, con, "reload2");
+ emit_instr(chunk, reload2, depth, con, "reload2");
}
}
}
con->mapRegs(&remap, instr, con->mode64);
- emit_instr(chunk, instr, con, NULL);
+ emit_instr(chunk, instr, depth, con, NULL);
if (DEBUG_REGALLOC) {
print_depth(depth);
- vex_printf("After dealing with current instruction:\n");
- print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL, con);
+ print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL,
+ depth, con, "Register Allocator state after dealing with"
+ " the current instruction");
vex_printf("\n");
}
# undef FIND_OR_MAKE_FREE_RREG
}
+static void stage4_emit_HInstrIfThenElse(RegAllocChunk* chunk, UInt depth,
+ const RegAllocControl* con)
+{
+ vassert(chunk->isIfThenElse);
+
+ HInstrIfThenElse* hite = newHInstrIfThenElse(
+ chunk->IfThenElse.ccOOL,
+ chunk->IfThenElse.phi_nodes,
+ chunk->IfThenElse.n_phis);
+ hite->fallThrough = chunk->IfThenElse.fallThrough->instrs_out;
+ hite->outOfLine = chunk->IfThenElse.outOfLine->instrs_out;
+
+ emit_instr(chunk, con->genHInstrITE(hite), depth, con, "HInstrIfThenElse");
+
+}
+
static void stage4(RegAllocChunk* chunk, VRegState* vreg_state, UInt n_vregs,
RRegState* rreg_state, UInt depth, const RegAllocControl* con)
{
WALK_CHUNKS(stage4_chunk(chunk, vreg_state, n_vregs, rreg_state, depth, con),
+ stage4_emit_HInstrIfThenElse(chunk, depth, con),
stage4(chunk->IfThenElse.fallThrough, vreg_state, n_vregs,
rreg_state, depth + 1, con),
stage4(chunk->IfThenElse.outOfLine, vreg_state, n_vregs,
/* --- Stage 2. Scan the incoming instructions. --- */
stage2(first_chunk, vreg_state, n_vregs, n_rregs, 0, con);
if (DEBUG_REGALLOC) {
- vex_printf("Initial register allocator state:\n");
+ vex_printf("\n\nInitial register allocator state:\n");
stage2_debug_vregs(vreg_state, n_vregs);
stage2_debug_rregs(first_chunk, 0, con);
}
Bool (*isMove) ( const HInstr*, HReg*, HReg* );
void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool );
void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
- HInstrIfThenElse* (*isIfThenElse)(const HInstr*);
+ HInstrIfThenElse* (*isIfThenElse)( const HInstr* );
void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
HInstr* (*genMove) ( HReg, HReg, Bool );
+ HInstr* (*genHInstrITE) ( HInstrIfThenElse* );
HInstr* (*directReload) ( HInstr*, HReg, Short );
void (*ppInstr) ( const HInstr*, Bool );
void (*ppCondCode) ( HCondCode );
genSpill = NULL;
genReload = NULL;
genMove = NULL;
+ genHInstrITE = NULL;
directReload = NULL;
ppInstr = NULL;
ppCondCode = NULL;
genSpill = CAST_TO_TYPEOF(genSpill) X86FN(genSpill_X86);
genReload = CAST_TO_TYPEOF(genReload) X86FN(genReload_X86);
genMove = CAST_TO_TYPEOF(genMove) X86FN(genMove_X86);
+ genHInstrITE = CAST_TO_TYPEOF(genHInstrITE) X86FN(X86Instr_IfThenElse);
directReload = CAST_TO_TYPEOF(directReload) X86FN(directReload_X86);
ppInstr = CAST_TO_TYPEOF(ppInstr) X86FN(ppX86Instr);
ppCondCode = CAST_TO_TYPEOF(ppCondCode) X86FN(ppX86CondCode);
RegAllocControl con = {
.univ = rRegUniv, .isMove = isMove, .getRegUsage = getRegUsage,
.mapRegs = mapRegs, .isIfThenElse = isIfThenElse, .genSpill = genSpill,
- .genReload = genReload, .genMove = genMove, .directReload = directReload,
- .guest_sizeB = guest_sizeB, .ppInstr = ppInstr, .ppCondCode = ppCondCode,
- .ppReg = ppReg, .mode64 = mode64};
+ .genReload = genReload, .genMove = genMove, .genHInstrITE = genHInstrITE,
+ .directReload = directReload, .guest_sizeB = guest_sizeB,
+ .ppInstr = ppInstr, .ppCondCode = ppCondCode, .ppReg = ppReg,
+ .mode64 = mode64};
rcode = doRegisterAllocation(vcode, &con);
vexAllocSanityCheck();