From 56e13af11ede1e40b4212bfc79eb822f66167c7b Mon Sep 17 00:00:00 2001 From: Ivo Raisr Date: Mon, 28 Aug 2017 23:31:03 +0200 Subject: [PATCH] Support If-Then-Else and Phi nodes in VEX/priv/main_main.c. --- VEX/priv/ir_opt.c | 46 ------------------------- VEX/priv/ir_opt.h | 3 -- VEX/priv/main_main.c | 81 ++++++++++++++++++++++---------------------- 3 files changed, 41 insertions(+), 89 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index e0c0fcf137..a16bdd9e83 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -6285,52 +6285,6 @@ static IRStmtVec* atbSubst_StmtVec( } -/*---------------------------------------------------------------*/ -/*--- The phi nodes deconstruction ---*/ -/*---------------------------------------------------------------*/ - -/* This isn't part of IR optimisation however this pass is needed before IRSB - is handed to instruction selection phase. Deconstructs all phi nodes. - Consider this example: - t2 = phi(t1,t0) - which gets trivially deconstructed into statements appended to: - - then leg: - t2 = t1 - - else leg: - t2 = t0 - - Such an IRSB no longer holds SSA property after this pass but subsequent - phases do no require it. */ -static void deconstruct_phi_nodes_IRStmtVec(IRStmtVec* stmts) -{ - for (UInt i = 0; i < stmts->stmts_used; i++) { - IRStmt* st = stmts->stmts[i]; - if (st->tag != Ist_IfThenElse) { - continue; - } - - IRIfThenElse* ite = st->Ist.IfThenElse.details; - IRStmtVec* then_leg = ite->then_leg; - IRStmtVec* else_leg = ite->else_leg; - for (UInt j = 0; j < ite->phi_nodes->phis_used; j++) { - const IRPhi* phi = ite->phi_nodes->phis[j]; - addStmtToIRStmtVec(then_leg, IRStmt_WrTmp(phi->dst, - IRExpr_RdTmp(phi->srcThen))); - addStmtToIRStmtVec(else_leg, IRStmt_WrTmp(phi->dst, - IRExpr_RdTmp(phi->srcElse))); - } - - deconstruct_phi_nodes_IRStmtVec(then_leg); - deconstruct_phi_nodes_IRStmtVec(else_leg); - } -} - -void deconstruct_phi_nodes(IRSB *irsb) -{ - deconstruct_phi_nodes_IRStmtVec(irsb->stmts); -} - - /*---------------------------------------------------------------*/ /*--- MSVC specific transformation hacks ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/ir_opt.h b/VEX/priv/ir_opt.h index 7a8d05fefd..f67ed00107 100644 --- a/VEX/priv/ir_opt.h +++ b/VEX/priv/ir_opt.h @@ -72,9 +72,6 @@ Addr ado_treebuild_BB ( VexRegisterUpdates pxControl ); -/* Deconstructs phi nodes. IRSB is modified and no longer holds SSA propery. */ -extern void deconstruct_phi_nodes(IRSB* bb); - #endif /* ndef __VEX_IR_OPT_H */ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index b27d6ca9ea..8a90755089 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -320,7 +320,6 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, VexGuestLayout* guest_layout; IRSB* irsb; - Int i; Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP; IRType guest_word_type; IRType host_word_type; @@ -589,7 +588,7 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3); vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr); - for (i = 0; i < vta->guest_extents->n_used; i++) { + for (UInt i = 0; i < vta->guest_extents->n_used; i++) { vassert(vta->guest_extents->len[i] < 10000); /* sanity */ } @@ -608,7 +607,7 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, UInt guest_bytes_read = (UInt)vta->guest_extents->len[0]; vex_printf("GuestBytes %lx %u ", vta->guest_bytes_addr, guest_bytes_read ); - for (i = 0; i < guest_bytes_read; i++) { + for (UInt i = 0; i < guest_bytes_read; i++) { UInt b = (UInt)p[i]; vex_printf(" %02x", b ); sum = (sum << 1) ^ b; @@ -632,8 +631,9 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, // the output of the front end, and iropt never screws up the IR by // itself, unless it is being hacked on. So remove this post-iropt // check in "production" use. - // sanityCheckIRSB( irsb, "after initial iropt", - // True/*must be flat*/, guest_word_type ); + /* TODO-JIT: remove for "production" use. */ + sanityCheckIRSB(irsb, "after initial iropt", + True/*must be flat*/, guest_word_type); if (vex_traceflags & VEX_TRACE_OPT1) { vex_printf("\n------------------------" @@ -672,9 +672,10 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, // JRS 2016 Aug 03: as above, this never actually fails in practice. // And we'll sanity check anyway after the post-instrumentation // cleanup pass. So skip this check in "production" use. - // if (vta->instrument1 || vta->instrument2) - // sanityCheckIRSB( irsb, "after instrumentation", - // True/*must be flat*/, guest_word_type ); + /* TODO-JIT: remove for "production" use. */ + if (vta->instrument1 || vta->instrument2) + sanityCheckIRSB(irsb, "after instrumentation", + True/*must be flat*/, guest_word_type ); /* Do a post-instrumentation cleanup pass. */ if (vta->instrument1 || vta->instrument2) { @@ -712,13 +713,15 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, Bool (*isMove) ( const HInstr*, HReg*, HReg* ); void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool ); void (*mapRegs) ( HRegRemap*, HInstr*, Bool ); + HInstrIfThenElse* (*isIfThenElse)(const HInstr*); void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ); void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool ); HInstr* (*genMove) ( HReg, HReg, Bool ); HInstr* (*directReload) ( HInstr*, HReg, Short ); void (*ppInstr) ( const HInstr*, Bool ); + void (*ppCondCode) ( HCondCode ); UInt (*ppReg) ( HReg ); - HInstrArray* (*iselSB) ( const IRSB*, VexArch, const VexArchInfo*, + HInstrSB* (*iselSB) ( const IRSB*, VexArch, const VexArchInfo*, const VexAbiInfo*, Int, Int, Bool, Bool, Addr ); Int (*emit) ( /*MB_MOD*/Bool*, @@ -730,23 +733,25 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, const RRegUniverse* rRegUniv = NULL; Bool mode64, chainingAllowed; - Int i, j, k, out_used; + Int out_used; Int guest_sizeB; Int offB_HOST_EvC_COUNTER; Int offB_HOST_EvC_FAILADDR; Addr max_ga; UChar insn_bytes[128]; - HInstrArray* vcode; - HInstrArray* rcode; + HInstrSB* vcode; + HInstrSB* rcode; isMove = NULL; getRegUsage = NULL; mapRegs = NULL; + isIfThenElse = NULL; genSpill = NULL; genReload = NULL; genMove = NULL; directReload = NULL; ppInstr = NULL; + ppCondCode = NULL; ppReg = NULL; iselSB = NULL; emit = NULL; @@ -861,11 +866,13 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, getRegUsage = CAST_TO_TYPEOF(getRegUsage) X86FN(getRegUsage_X86Instr); mapRegs = CAST_TO_TYPEOF(mapRegs) X86FN(mapRegs_X86Instr); + isIfThenElse = CAST_TO_TYPEOF(isIfThenElse) X86FN(isIfThenElse_X86Instr); genSpill = CAST_TO_TYPEOF(genSpill) X86FN(genSpill_X86); genReload = CAST_TO_TYPEOF(genReload) X86FN(genReload_X86); genMove = CAST_TO_TYPEOF(genMove) X86FN(genMove_X86); directReload = CAST_TO_TYPEOF(directReload) X86FN(directReload_X86); ppInstr = CAST_TO_TYPEOF(ppInstr) X86FN(ppX86Instr); + ppCondCode = CAST_TO_TYPEOF(ppCondCode) X86FN(ppX86CondCode); ppReg = CAST_TO_TYPEOF(ppReg) X86FN(ppHRegX86); iselSB = X86FN(iselSB_X86); emit = CAST_TO_TYPEOF(emit) X86FN(emit_X86Instr); @@ -1072,21 +1079,16 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, vex_printf("\n"); if (vex_traceflags & VEX_TRACE_VCODE) { - for (i = 0; i < vcode->arr_used; i++) { - vex_printf("%3d ", i); - ppInstr(vcode->arr[i], mode64); - vex_printf("\n"); - } - vex_printf("\n"); + ppHInstrSB(vcode, isIfThenElse, ppInstr, ppCondCode, mode64); } /* Register allocate. */ RegAllocControl con = { .univ = rRegUniv, .isMove = isMove, .getRegUsage = getRegUsage, - .mapRegs = mapRegs, .genSpill = genSpill, .genReload = genReload, - .genMove = genMove, .directReload = directReload, - .guest_sizeB = guest_sizeB, .ppInstr = ppInstr, .ppReg = ppReg, - .mode64 = mode64}; + .mapRegs = mapRegs, .isIfThenElse = isIfThenElse, .genSpill = genSpill, + .genReload = genReload, .genMove = genMove, .directReload = directReload, + .guest_sizeB = guest_sizeB, .ppInstr = ppInstr, .ppCondCode = ppCondCode, + .ppReg = ppReg, .mode64 = mode64}; switch (vex_control.regalloc_version) { case 2: rcode = doRegisterAllocation_v2(vcode, &con); @@ -1104,11 +1106,7 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, vex_printf("\n------------------------" " Register-allocated code " "------------------------\n\n"); - for (i = 0; i < rcode->arr_used; i++) { - vex_printf("%3d ", i); - ppInstr(rcode->arr[i], mode64); - vex_printf("\n"); - } + ppHInstrSB(rcode, isIfThenElse, ppInstr, ppCondCode, mode64); vex_printf("\n"); } @@ -1127,22 +1125,25 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, } out_used = 0; /* tracks along the host_bytes array */ - for (i = 0; i < rcode->arr_used; i++) { - HInstr* hi = rcode->arr[i]; + /* TODO-JIT: This needs another interface when assembler/flattener + is given whole HInstrSB and also pointer to function + which prints emitted bytes. */ + for (UInt i = 0; i < rcode->insns->insns_used; i++) { + HInstr* hi = rcode->insns->insns[i]; Bool hi_isProfInc = False; if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) { ppInstr(hi, mode64); vex_printf("\n"); } - j = emit( &hi_isProfInc, - insn_bytes, sizeof insn_bytes, hi, - mode64, vta->archinfo_host.endness, - vta->disp_cp_chain_me_to_slowEP, - vta->disp_cp_chain_me_to_fastEP, - vta->disp_cp_xindir, - vta->disp_cp_xassisted ); + Int j = emit(&hi_isProfInc, + insn_bytes, sizeof insn_bytes, hi, + mode64, vta->archinfo_host.endness, + vta->disp_cp_chain_me_to_slowEP, + vta->disp_cp_chain_me_to_fastEP, + vta->disp_cp_xindir, + vta->disp_cp_xassisted); if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) { - for (k = 0; k < j; k++) + for (Int k = 0; k < j; k++) vex_printf("%02x ", (UInt)insn_bytes[k]); vex_printf("\n\n"); } @@ -1159,7 +1160,7 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, res->offs_profInc = out_used; } { UChar* dst = &vta->host_bytes[out_used]; - for (k = 0; k < j; k++) { + for (Int k = 0; k < j; k++) { dst[k] = insn_bytes[k]; } out_used += j; @@ -1173,8 +1174,8 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, if (vex_traceflags) { /* Print the expansion ratio for this SB. */ - j = 0; /* total guest bytes */ - for (i = 0; i < vta->guest_extents->n_used; i++) { + UInt j = 0; /* total guest bytes */ + for (UInt i = 0; i < vta->guest_extents->n_used; i++) { j += vta->guest_extents->len[i]; } if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n", -- 2.47.2