From: Julian Seward Date: Thu, 19 Aug 2004 17:58:45 +0000 (+0000) Subject: Allow constant folding to apply to IRStmt_Exit. X-Git-Tag: svn/VALGRIND_3_0_1^2~1151 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cdd932ccb7e2b8dd08f4baef2bfb36e7a4b60be2;p=thirdparty%2Fvalgrind.git Allow constant folding to apply to IRStmt_Exit. git-svn-id: svn://svn.valgrind.org/vex/trunk@183 --- diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index abe97eeaef..7ff7bcfd27 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -36,10 +36,11 @@ void ppIRType ( IRType ty ) void ppIRConst ( IRConst* con ) { switch (con->tag) { - case Ico_U8: vex_printf( "0x%x", (UInt)(con->Ico.U8)); break; - case Ico_U16: vex_printf( "0x%x", (UInt)(con->Ico.U16)); break; - case Ico_U32: vex_printf( "0x%x", (UInt)(con->Ico.U32)); break; - case Ico_U64: vex_printf( "0x%llx", (ULong)(con->Ico.U64)); break; + case Ico_Bit: vex_printf( "%d:Bit", con->Ico.Bit ? 1 : 0); break; + case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break; + case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break; + case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break; + case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break; case Ico_F64: vex_printf("(f64 value)"); break; default: vpanic("ppIRConst"); } @@ -299,6 +300,13 @@ void ppIRBB ( IRBB* bb ) /* Constructors -- IRConst */ +IRConst* IRConst_Bit ( Bool bit ) +{ + IRConst* c = LibVEX_Alloc(sizeof(IRConst)); + c->tag = Ico_Bit; + c->Ico.Bit = bit; + return c; +} IRConst* IRConst_U8 ( UChar u8 ) { IRConst* c = LibVEX_Alloc(sizeof(IRConst)); @@ -665,6 +673,7 @@ IRType lookupIRTypeEnv ( IRTypeEnv* env, IRTemp tmp ) IRType typeOfIRConst ( IRConst* con ) { switch (con->tag) { + case Ico_Bit: return Ity_Bit; case Ico_U8: return Ity_I8; case Ico_U16: return Ity_I16; case Ico_U32: return Ity_I32; diff --git a/VEX/priv/ir/iropt.c b/VEX/priv/ir/iropt.c index dacd123279..4e888c10f7 100644 --- a/VEX/priv/ir/iropt.c +++ b/VEX/priv/ir/iropt.c @@ -350,21 +350,27 @@ static IRExpr* fold_Expr ( IRExpr* e ) (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 & e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); break; + case Iop_Or32: + e2 = IRExpr_Const(IRConst_U32( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 + | e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); + break; case Iop_Shl32: e2 = IRExpr_Const(IRConst_U32( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 << e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); break; + case Iop_CmpEQ32: + e2 = IRExpr_Const(IRConst_Bit( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 + == e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); + break; case Iop_32HLto64: e2 = IRExpr_Const(IRConst_U64( (((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)) << 32) | ((ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) )); break; - -case Iop_CmpEQ32: - vex_printf("FOLD: warning, missed CmpEQ32\n"); -break; default: goto unhandled; } @@ -497,7 +503,8 @@ static IRExpr* subst_Expr ( Hash64* env, IRExpr* ex ) /* Apply the subst to stmt, then fold the result as much as possible. - Much simplified due to stmt being previously flattened. */ + Much simplified due to stmt being previously flattened. Returning + NULL means the statement has been turned into a no-op. */ static IRStmt* subst_and_fold_Stmt ( Hash64* env, IRStmt* st ) { @@ -545,11 +552,26 @@ static IRStmt* subst_and_fold_Stmt ( Hash64* env, IRStmt* st ) } if (st->tag == Ist_Exit) { - vassert(isAtom(st->Ist.Exit.cond)); - return IRStmt_Exit( - fold_Expr(subst_Expr(env, st->Ist.Exit.cond)), - st->Ist.Exit.dst - ); + IRExpr* fcond; + vassert(isAtom(st->Ist.Exit.cond)); + fcond = fold_Expr(subst_Expr(env, st->Ist.Exit.cond)); + if (fcond->tag == Iex_Const) { + /* Interesting. The condition on this exit has folded down to + a constant. */ + vassert(fcond->Iex.Const.con->tag == Ico_Bit); + if (fcond->Iex.Const.con->Ico.Bit == False) { + /* exit is never going to happen, so dump the statement. */ + return NULL; + } else { + vassert(fcond->Iex.Const.con->Ico.Bit == True); + /* Hmmm. The exit has become unconditional. Leave it as + it is for now, since we'd have to truncate the BB at + this point, which is tricky. */ + /* fall out into the reconstruct-the-exit code. */ + vex_printf("subst_and_fold_Stmt: IRStmt_Exit became unconditional\n"); + } + } + return IRStmt_Exit(fcond,st->Ist.Exit.dst); } vex_printf("\n"); @@ -586,6 +608,10 @@ static IRBB* cprop_BB ( IRBB* in ) st2 = subst_and_fold_Stmt( env, in->stmts[i] ); + /* If the statement has been folded into a no-op, forget it. */ + if (!st2) + continue; + /* Now consider what the stmt looks like. If it's of the form 't = const' or 't1 = t2', add it to the running environment and not to the output BB. Otherwise, add it to the output