Discussion:
vex: r3345 - in /branches/VEX_JIT_HACKS: priv/ir_defs.c priv/ir_opt.c pub/libvex_ir.h
(too old to reply)
s***@valgrind.org
2017-04-04 21:26:45 UTC
Permalink
Raw Message
Author: iraisr
Date: Tue Apr 4 22:26:45 2017
New Revision: 3345

Log:
Add a 'hint' to If-Then-Else control flow diamon.

Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h

Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Tue Apr 4 22:26:45 2017
@@ -1601,6 +1601,31 @@
ppIRTypeEnvDefd(NULL, defset, depth);
}

+void ppIRIfThenElse_Hint(IRIfThenElse_Hint hint)
+{
+ switch (hint) {
+ case IfThenElse_ThenLikely: vex_printf("IfThenElse_ThenLikely"); break;
+ case IfThenElse_ElseLikely: vex_printf("IfThenElse_ElseLikely"); break;
+ default: vpanic("ppIRIfThenElse_Hint");
+ }
+}
+
+void ppIRIfThenElse(const IRIfThenElse* ite, const IRTypeEnv* tyenv, UInt depth)
+{
+ vex_printf("if (");
+ ppIRExpr(ite->cond);
+ vex_printf(") [");
+ ppIRIfThenElse_Hint(ite->hint);
+ vex_printf("] then {\n");
+ ppIRStmtVec(ite->then_leg, tyenv, depth + 1);
+ print_depth(depth);
+ vex_printf("} else {\n");
+ ppIRStmtVec(ite->else_leg, tyenv, depth + 1);
+ print_depth(depth);
+ vex_printf("}\n");
+ ppIRPhiVec(ite->phi_nodes, depth);
+}
+
void ppIRStmt(const IRStmt* s, const IRTypeEnv* tyenv, UInt depth)
{
print_depth(depth);
@@ -1686,16 +1711,7 @@
vex_printf(" } ");
break;
case Ist_IfThenElse:
- vex_printf("if (");
- ppIRExpr(s->Ist.IfThenElse.cond);
- vex_printf(") then {\n");
- ppIRStmtVec(s->Ist.IfThenElse.then_leg, tyenv, depth + 1);
- print_depth(depth);
- vex_printf("} else {\n");
- ppIRStmtVec(s->Ist.IfThenElse.else_leg, tyenv, depth + 1);
- print_depth(depth);
- vex_printf("}\n");
- ppIRPhiVec(s->Ist.IfThenElse.phi_nodes, depth);
+ ppIRIfThenElse(s->Ist.IfThenElse.details, tyenv, depth);
break;
default:
vpanic("ppIRStmt");
@@ -2214,8 +2230,7 @@
return lg;
}

-
-/* Constructors -- IRStmt */
+/* Constructors -- IRIfThenElse */

IRPhi* mkIRPhi(IRTemp dst, IRTemp srcThen, IRTemp srcElse)
{
@@ -2245,6 +2260,22 @@
return defset;
}

+IRIfThenElse* mkIRIfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes)
+{
+ IRIfThenElse* ite = LibVEX_Alloc_inline(sizeof(IRIfThenElse));
+ ite->cond = cond;
+ ite->hint = hint;
+ ite->then_leg = then_leg;
+ ite->else_leg = else_leg;
+ ite->phi_nodes = phi_nodes;
+ return ite;
+}
+
+
+/* Constructors -- IRStmt */
+
IRStmt* IRStmt_NoOp ( void )
{
/* Just use a single static closure. */
@@ -2353,15 +2384,14 @@
return s;
}

-IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRStmtVec* then_leg,
- IRStmtVec* else_leg, IRPhiVec* phi_nodes)
-{
- IRStmt* s = LibVEX_Alloc_inline(sizeof(IRStmt));
- s->tag = Ist_IfThenElse;
- s->Ist.IfThenElse.cond = cond;
- s->Ist.IfThenElse.then_leg = then_leg;
- s->Ist.IfThenElse.else_leg = else_leg;
- s->Ist.IfThenElse.phi_nodes = phi_nodes;
+IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes)
+{
+ IRStmt* s = LibVEX_Alloc_inline(sizeof(IRStmt));
+ s->tag = Ist_IfThenElse;
+ s->Ist.IfThenElse.details = mkIRIfThenElse(cond, hint, then_leg, else_leg,
+ phi_nodes);
return s;
}

@@ -2673,11 +2703,13 @@
s->Ist.Exit.jk,
deepCopyIRConst(s->Ist.Exit.dst),
s->Ist.Exit.offsIP);
- case Ist_IfThenElse:
- return IRStmt_IfThenElse(deepCopyIRExpr(s->Ist.IfThenElse.cond),
- deepCopyIRStmtVec(s->Ist.IfThenElse.then_leg, parent),
- deepCopyIRStmtVec(s->Ist.IfThenElse.else_leg, parent),
- deepCopyIRPhiVec(s->Ist.IfThenElse.phi_nodes));
+ case Ist_IfThenElse: {
+ const IRIfThenElse* ite = s->Ist.IfThenElse.details;
+ return IRStmt_IfThenElse(deepCopyIRExpr(ite->cond), ite->hint,
+ deepCopyIRStmtVec(ite->then_leg, parent),
+ deepCopyIRStmtVec(ite->else_leg, parent),
+ deepCopyIRPhiVec(ite->phi_nodes));
+ }
default:
vpanic("deepCopyIRStmt");
}
@@ -3822,7 +3854,8 @@
addStmtToIRStmtVec(bb->stmts, st);
}

-IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond)
+IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond,
+ IRIfThenElse_Hint hint)
{
IRStmtVec* then_leg = emptyIRStmtVec();
then_leg->id = nextIRStmtVecID(bb);
@@ -3832,7 +3865,8 @@
else_leg->id = nextIRStmtVecID(bb);
else_leg->parent = parent;

- IRStmt* st = IRStmt_IfThenElse(cond, then_leg, else_leg, emptyIRPhiVec());
+ IRStmt* st = IRStmt_IfThenElse(cond, hint, then_leg, else_leg,
+ emptyIRPhiVec());
addStmtToIRStmtVec(parent, st);
return st;
}
@@ -4120,9 +4154,9 @@
case Ist_Exit:
return isIRAtom(st->Ist.Exit.guard);
case Ist_IfThenElse:
- return isIRAtom(st->Ist.IfThenElse.cond)
- && isFlatIRStmtVec(st->Ist.IfThenElse.then_leg)
- && isFlatIRStmtVec(st->Ist.IfThenElse.else_leg);
+ return isIRAtom(st->Ist.IfThenElse.details->cond)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.details->then_leg)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.details->else_leg);
default:
vpanic("isFlatIRStmt(st)");
}
@@ -4352,8 +4386,8 @@
{
vassert(stmt->tag == Ist_IfThenElse);

- IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
- IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+ IRStmtVec* then_leg = stmt->Ist.IfThenElse.details->then_leg;
+ IRStmtVec* else_leg = stmt->Ist.IfThenElse.details->else_leg;

useBeforeDef_Temp(bb, then_leg, stmt, phi->srcThen, def_counts);
useBeforeDef_Temp(bb, else_leg, stmt, phi->srcElse, def_counts);
@@ -4456,7 +4490,7 @@
useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Exit.guard, def_counts);
break;
case Ist_IfThenElse:
- useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond,
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.details->cond,
def_counts);
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -5047,8 +5081,8 @@
sanityCheckFail(bb,stmt,"IRStmt.Exit.offsIP: too low");
break;
case Ist_IfThenElse:
- tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
- if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
+ tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.details->cond, gWordTy);
+ if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.details->cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -5116,8 +5150,9 @@
tcStmt(bb, stmts, stmt, require_flat, gWordTy);

if (stmt->tag == Ist_IfThenElse) {
- const IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
- const IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+ const IRIfThenElse* ite = stmt->Ist.IfThenElse.details;
+ const IRStmtVec* then_leg = ite->then_leg;
+ const IRStmtVec* else_leg = ite->else_leg;

if (then_leg->parent == NULL) {
sanityCheckFail(bb, stmt, "IfThenElse.then.parent is NULL");
@@ -5138,8 +5173,7 @@
id_counts, n_ids, gWordTy);
sanityCheckIRStmtVec(bb, else_leg, require_flat, def_counts,
id_counts, n_ids, gWordTy);
- sanityCheckIRPhiNodes(bb, stmts, stmt,
- stmt->Ist.IfThenElse.phi_nodes, def_counts);
+ sanityCheckIRPhiNodes(bb, stmts, stmt, ite->phi_nodes, def_counts);
}
}
}

Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Tue Apr 4 22:26:45 2017
@@ -510,14 +510,16 @@
st->Ist.Exit.dst,
st->Ist.Exit.offsIP));
break;
- case Ist_IfThenElse:
- e1 = flatten_Expr(tyenv, stmts, st->Ist.IfThenElse.cond);
- addStmtToIRStmtVec(
- stmts, IRStmt_IfThenElse(e1,
- flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, parent),
- flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, parent),
- st->Ist.IfThenElse.phi_nodes));
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ e1 = flatten_Expr(tyenv, stmts, ite->cond);
+ addStmtToIRStmtVec(stmts,
+ IRStmt_IfThenElse(e1, ite->hint,
+ flatten_IRStmtVec(tyenv, ite->then_leg, parent),
+ flatten_IRStmtVec(tyenv, ite->else_leg, parent),
+ ite->phi_nodes));
break;
+ }
default:
vex_printf("\n");
ppIRStmt(st, tyenv, 0);
@@ -720,8 +722,9 @@

if (st->tag == Ist_IfThenElse) {
/* Consider "then" and "else" legs in isolation. */
- redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg);
- redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ redundant_get_removal_IRStmtVec(tyenv, ite->then_leg);
+ redundant_get_removal_IRStmtVec(tyenv, ite->else_leg);
}

} /* for (UInt i = 0; i < stmts->stmts_used; i++) */
@@ -1009,10 +1012,11 @@

/* Consider "then" and "else" legs in isolation. They get a new env. */
if (st->tag == Ist_IfThenElse) {
- redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
- preciseMemExnsFn, pxControl, newHHW());
- redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
- preciseMemExnsFn, pxControl, newHHW());
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ redundant_put_removal_IRStmtVec(tyenv, ite->then_leg, preciseMemExnsFn,
+ pxControl, newHHW());
+ redundant_put_removal_IRStmtVec(tyenv, ite->else_leg, preciseMemExnsFn,
+ pxControl, newHHW());
}
}
}
@@ -2862,9 +2866,9 @@
}

case Ist_IfThenElse: {
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
- IRExpr *fcond = fold_Expr(env,
- subst_Expr(env, st->Ist.IfThenElse.cond));
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
+ IRExpr *fcond = fold_Expr(env, subst_Expr(env, ite->cond));
if (fcond->tag == Iex_Const) {
/* Interesting. The condition on this "if-then-else" has folded down
to a constant. */
@@ -2890,22 +2894,18 @@
vpanic("IfThenElse leg lifting unimplemented");
}

- SubstEnv* then_env
- = newSubstEnv(env->tyenv, st->Ist.IfThenElse.then_leg, env);
- IRStmtVec* then_stmts
- = subst_and_fold_Stmts(then_env, st->Ist.IfThenElse.then_leg);
+ SubstEnv* then_env = newSubstEnv(env->tyenv, ite->then_leg, env);
+ IRStmtVec* then_stmts = subst_and_fold_Stmts(then_env, ite->then_leg);
subst_and_fold_PhiNodes(then_env, then_stmts, True /* srcThen */,
- st->Ist.IfThenElse.phi_nodes);
+ ite->phi_nodes);

- SubstEnv* else_env
- = newSubstEnv(env->tyenv, st->Ist.IfThenElse.else_leg, env);
- IRStmtVec* else_stmts
- = subst_and_fold_Stmts(else_env, st->Ist.IfThenElse.else_leg);
+ SubstEnv* else_env = newSubstEnv(env->tyenv, ite->else_leg, env);
+ IRStmtVec* else_stmts = subst_and_fold_Stmts(else_env, ite->else_leg);
subst_and_fold_PhiNodes(else_env, else_stmts, False /* srcThen */,
- st->Ist.IfThenElse.phi_nodes);
+ ite->phi_nodes);

- return IRStmt_IfThenElse(fcond, then_stmts, else_stmts,
- st->Ist.IfThenElse.phi_nodes);
+ return IRStmt_IfThenElse(fcond, ite->hint, then_stmts, else_stmts,
+ ite->phi_nodes);
}

default:
@@ -3214,11 +3214,11 @@
addUses_Expr(set, st->Ist.Exit.guard);
return;
case Ist_IfThenElse: {
- addUses_Expr(set, st->Ist.IfThenElse.cond);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ addUses_Expr(set, ite->cond);

- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- const IRPhi* phi = phi_nodes->phis[i];
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ const IRPhi* phi = ite->phi_nodes->phis[i];
addUses_Temp(set, phi->srcThen);
addUses_Temp(set, phi->srcElse);
}
@@ -3226,10 +3226,8 @@
Int i_unconditional_exit; // TODO-JIT: unused at the moment
/* Consider both legs simultaneously. If either of them reports an
IRTemp in use, then it won't be eliminated. */
- do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.then_leg,
- &i_unconditional_exit);
- do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.else_leg,
- &i_unconditional_exit);
+ do_deadcode_IRStmtVec(set, ite->then_leg, &i_unconditional_exit);
+ do_deadcode_IRStmtVec(set, ite->else_leg, &i_unconditional_exit);
return;
}
default:
@@ -3357,8 +3355,9 @@
IRStmt* st = stmts->stmts[i];

if (st->tag == Ist_IfThenElse) {
- spec_helpers_IRStmtVec(st->Ist.IfThenElse.then_leg, specHelper, any);
- spec_helpers_IRStmtVec(st->Ist.IfThenElse.else_leg, specHelper, any);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ spec_helpers_IRStmtVec(ite->then_leg, specHelper, any);
+ spec_helpers_IRStmtVec(ite->else_leg, specHelper, any);
continue;
}

@@ -4103,12 +4102,15 @@
case Ist_NoOp: case Ist_IMark: case Ist_AbiHint:
case Ist_WrTmp: case Ist_Exit: case Ist_LoadG:
paranoia = 0; break;
- case Ist_IfThenElse:
- anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ anyDone |= do_cse_IRStmtVec(tyenv, ite->then_leg,
allowLoadsToBeCSEd);
- anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
+ anyDone |= do_cse_IRStmtVec(tyenv, ite->else_leg,
allowLoadsToBeCSEd);
- paranoia = 0; break;
+ paranoia = 0;
+ break;
+ }
default:
vpanic("do_cse_IRStmtVec(1)");
}
@@ -4399,8 +4401,9 @@
}

if (st->tag == Ist_IfThenElse) {
- collapse_AddSub_chains_IRStmtVec(st->Ist.IfThenElse.then_leg);
- collapse_AddSub_chains_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ collapse_AddSub_chains_IRStmtVec(ite->then_leg);
+ collapse_AddSub_chains_IRStmtVec(ite->else_leg);
}
} /* for */
}
@@ -4675,8 +4678,9 @@
}

if (st->tag == Ist_IfThenElse) {
- do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.then_leg);
- do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ do_redundant_GetI_elimination(tyenv, ite->then_leg);
+ do_redundant_GetI_elimination(tyenv, ite->else_leg);
}
}
}
@@ -4695,10 +4699,9 @@
IRStmt* st = stmts->stmts[i];

if (st->tag == Ist_IfThenElse) {
- do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.then_leg,
- pxControl);
- do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.else_leg,
- pxControl);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ do_redundant_PutI_elimination(tyenv, ite->then_leg, pxControl);
+ do_redundant_PutI_elimination(tyenv, ite->else_leg, pxControl);
}

if (st->tag != Ist_PutI)
@@ -4898,19 +4901,18 @@
deltaIRExpr(d->mAddr, delta_tmp);
break;
case Ist_IfThenElse: {
- deltaIRExpr(st->Ist.IfThenElse.cond, delta_tmp);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ deltaIRExpr(ite->cond, delta_tmp);
/* Traverse "then" and "else" legs. Also nested IRStmtVec's need to
be unrolled otherwise the main IRStmtVec will break horribly. */
- deltaIRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, delta_tmp,
- delta_id, stmts);
- deltaIRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, delta_tmp,
- delta_id, stmts);
+ deltaIRStmtVec(tyenv, ite->then_leg, delta_tmp, delta_id, stmts);
+ deltaIRStmtVec(tyenv, ite->else_leg, delta_tmp, delta_id, stmts);

- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- phi_nodes->phis[i]->dst += delta_tmp;
- phi_nodes->phis[i]->srcThen += delta_tmp;
- phi_nodes->phis[i]->srcElse += delta_tmp;
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ IRPhi* phi = ite->phi_nodes->phis[i];
+ phi->dst += delta_tmp;
+ phi->srcThen += delta_tmp;
+ phi->srcElse += delta_tmp;
}
break;
}
@@ -5493,15 +5495,14 @@
aoccCount_Expr(uses, st->Ist.Exit.guard);
return;
case Ist_IfThenElse: {
- aoccCount_Expr(uses, st->Ist.IfThenElse.cond);
- aoccCount_IRStmtVec(uses, st->Ist.IfThenElse.then_leg,
- max_ga_known, max_ga);
- aoccCount_IRStmtVec(uses, st->Ist.IfThenElse.else_leg,
- max_ga_known, max_ga);
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- uses[phi_nodes->phis[i]->srcThen]++;
- uses[phi_nodes->phis[i]->srcElse]++;
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ aoccCount_Expr(uses, ite->cond);
+ aoccCount_IRStmtVec(uses, ite->then_leg, max_ga_known, max_ga);
+ aoccCount_IRStmtVec(uses, ite->else_leg, max_ga_known, max_ga);
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ IRPhi* phi = ite->phi_nodes->phis[i];
+ uses[phi->srcThen]++;
+ uses[phi->srcElse]++;
}
return;
}
@@ -5918,19 +5919,18 @@
}
return IRStmt_Dirty(d2);
case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
ATmpInfo then_env[A_NENV];
initAEnv(then_env, env);
- IRStmtVec* then_leg
- = atbSubst_StmtVec(tyenv, then_env, st->Ist.IfThenElse.then_leg,
- preciseMemExnsFn, pxControl, uses);
+ IRStmtVec* then_leg = atbSubst_StmtVec(tyenv, then_env, ite->then_leg,
+ preciseMemExnsFn, pxControl, uses);

ATmpInfo else_env[A_NENV];
initAEnv(else_env, env);
- IRStmtVec* else_leg
- = atbSubst_StmtVec(tyenv, else_env, st->Ist.IfThenElse.else_leg,
- preciseMemExnsFn, pxControl, uses);
+ IRStmtVec* else_leg = atbSubst_StmtVec(tyenv, else_env, ite->else_leg,
+ preciseMemExnsFn, pxControl, uses);

- const IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
+ const IRPhiVec* phi_nodes = ite->phi_nodes;
IRPhiVec* out = emptyIRPhiVec();
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
IRPhi* phi = phi_nodes->phis[i];
@@ -5953,7 +5953,7 @@
}
}

- return IRStmt_IfThenElse(atbSubst_Expr(env, st->Ist.IfThenElse.cond),
+ return IRStmt_IfThenElse(atbSubst_Expr(env, ite->cond), ite->hint,
then_leg, else_leg, out);
}
default:
@@ -6309,11 +6309,11 @@
continue;
}

- IRStmtVec* then_leg = st->Ist.IfThenElse.then_leg;
- IRStmtVec* else_leg = st->Ist.IfThenElse.else_leg;
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt j = 0; j < phi_nodes->phis_used; j++) {
- const IRPhi* phi = phi_nodes->phis[j];
+ 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,
@@ -6719,13 +6719,13 @@
case Ist_Exit:
vassert(isIRAtom(st->Ist.Exit.guard));
break;
- case Ist_IfThenElse:
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
- changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv,
- st->Ist.IfThenElse.then_leg);
- changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv,
- st->Ist.IfThenElse.else_leg);
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
+ changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv, ite->then_leg);
+ changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv, ite->else_leg);
break;
+ }
default:
vex_printf("\n"); ppIRStmt(st, tyenv, 0);
vpanic("do_XOR_TRANSFORMS_IRStmtVec");
@@ -6937,13 +6937,15 @@
case Ist_Exit:
vassert(isIRAtom(st->Ist.Exit.guard));
break;
- case Ist_IfThenElse:
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
considerExpensives_IRStmtVec(hasGetIorPutI, hasVorFtemps,
- tyenv, st->Ist.IfThenElse.then_leg);
+ tyenv, ite->then_leg);
considerExpensives_IRStmtVec(hasGetIorPutI, hasVorFtemps,
- tyenv, st->Ist.IfThenElse.else_leg);
+ tyenv, ite->else_leg);
break;
+ }
default:
bad:
ppIRStmt(st, tyenv, 0);

Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Tue Apr 4 22:26:45 2017
@@ -2777,17 +2777,60 @@
extern IRTempDefSet* emptyIRTempDefSet(void);
extern IRTempDefSet* deepCopyIRTempDefSet(const IRTempDefSet* defset);

-/* ------------------ Statements ------------------ */

-/* IRStmt and IRStmtVec are mutually recursive. */
+/* --------------- If-Then-Else control flow diamond --------------- */
+
+/* If-Then-Else control flow diamond. It contains:
+ - Guard controling whether "then" or "else" leg is taken
+ - A hint which leg is more likely to be taken (hot path vs cold path)
+ - "then" and "else" legs with vectors of statements
+ At the moment, nested "if-then-else" statements are not supported.
+ - Phi nodes, which are used to merge temporaries from "then" and "else" legs
+
+ A leg can either end with an unconditional exit or join the main flow.
+ At the moment, unconditional exits are not supported.
+*/
+
typedef
- struct _IRStmt
- IRStmt;
+ enum {
+ IfThenElse_ThenLikely=0x1E00,
+ IfThenElse_ElseLikely
+ }
+ IRIfThenElse_Hint;
+
+typedef
+ struct _IRStmtVec
+ IRStmtVec;

typedef
struct _IRTypeEnv
IRTypeEnv;

+typedef
+ struct {
+ IRExpr* cond;
+ IRIfThenElse_Hint hint;
+ IRStmtVec* then_leg;
+ IRStmtVec* else_leg;
+ IRPhiVec* phi_nodes;
+ }
+ IRIfThenElse;
+
+extern void ppIRIfThenElse_Hint(IRIfThenElse_Hint hint);
+extern void ppIRIfThenElse(const IRIfThenElse* ite, const IRTypeEnv* tyenv,
+ UInt depth);
+extern IRIfThenElse* mkIRIfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes);
+
+
+/* ------------------ Statements ------------------ */
+
+/* IRStmt and IRStmtVec are mutually recursive. */
+typedef
+ struct _IRStmt
+ IRStmt;
+
/* Uniquely identifies IRStmtVec in an IRSB, no matter how deeply nested. */
typedef UShort IRStmtVecID;

@@ -2801,16 +2844,14 @@
to IRStmtVec #0.
- A set which keeps track of which IRTemp's are defined in this IRStmtVec.
*/
-typedef
- struct _IRStmtVec {
- IRStmt** stmts;
- UInt stmts_size;
- UInt stmts_used;
- IRStmtVecID id;
- struct _IRStmtVec* parent;
- IRTempDefSet* defset;
- }
- IRStmtVec;
+struct _IRStmtVec {
+ IRStmt** stmts;
+ UInt stmts_size;
+ UInt stmts_used;
+ IRStmtVecID id;
+ IRStmtVec* parent;
+ IRTempDefSet* defset;
+};

/* Pretty-prints a vector of statements. If 'tyenv' is not NULL, pretty-prints
IRStmtVec's defset using nicer ppIRTypeEnvDefd(). */
@@ -2841,7 +2882,7 @@

typedef
enum {
- Ist_NoOp=0x1E00,
+ Ist_NoOp=0x1F00,
Ist_IMark, /* META */
Ist_AbiHint, /* META */
Ist_Put,
@@ -3098,26 +3139,31 @@
Int offsIP; /* Guest state offset for IP */
} Exit;

- /* If-Then-Else control flow diamond. It contains:
- - Guard controling whether "then" or "else" leg is taken
- - "then" and "else" legs with vectors of statements
- At the moment, nested "if-then-else" statements are not supported.
- - Phi nodes, which are used to merge temporaries from "then" and
- "else" legs
- - TODO-JIT: A hint which leg is more likely to be taken (hot path)
-
- A leg can either end with an unconditional exit or join the main
- flow.
+ /* If-Then-Else control flow diamond. See IRIfThenElse for details.

ppIRIfThenElse output:
- if (<cond>) then { <IRStmtVec> } else { <IRStmtVec> }
- eg. if (t3) then { <then-statements> } else { <else-statements> }
- */
+ if (<cond>) [<hint>] then {
+ <IRTempDefSet>
+ <IRStmtVec>
+ } else {
+ <IRTempDefSet>
+ <IRStmtVec>
+ }
+ <phi-nodes>
+
+ eg. if (t3) [IfThenElse_ThenLikely] then {
+ t4:I32 t7:I32
+
+ t4=0x2
+ t7=Add32(t2,t1)
+ } else {
+ t5:I32
+
+ t5=0x3
+ }
+ t6=phi(t4,t5) */
struct {
- IRExpr* cond;
- IRStmtVec* then_leg;
- IRStmtVec* else_leg;
- IRPhiVec* phi_nodes;
+ IRIfThenElse* details;
} IfThenElse;
} Ist;
};
@@ -3141,8 +3187,9 @@
extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
Int offsIP );
-extern IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRStmtVec* then_leg,
- IRStmtVec* else_leg, IRPhiVec* phi_nodes);
+extern IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes);

/* Deep-copy an IRStmt.
Parent is required for "if-then-else" statements. */
@@ -3242,7 +3289,8 @@
/* Allocates an empty IfThenElse, assigns it a valid IRStmtVecID
and sets the parent for both then and else legs.
The returned IRStmt is added to the parent IRStmtVec and ready to be used. */
-extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond);
+extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond,
+ IRIfThenElse_Hint hint);

/*---------------------------------------------------------------*/
/*--- Helper functions for the IR ---*/
Loading...