From: Julian Seward Date: Sun, 22 Aug 2010 12:38:53 +0000 (+0000) Subject: Merge from branches/THUMB: A spechelper interface change that allows X-Git-Tag: svn/VALGRIND_3_6_1^2~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1e4df0402949342dd3ddc6653b2f5ec5065cfc91;p=thirdparty%2Fvalgrind.git Merge from branches/THUMB: A spechelper interface change that allows the helper to look back at the previous IR statements. May be backed out if it turns out no longer to be needed for optimising Thumb translations. git-svn-id: svn://svn.valgrind.org/vex/trunk@2012 --- diff --git a/VEX/priv/guest_amd64_defs.h b/VEX/priv/guest_amd64_defs.h index 3d6e128bd0..6525076f1e 100644 --- a/VEX/priv/guest_amd64_defs.h +++ b/VEX/priv/guest_amd64_defs.h @@ -61,8 +61,10 @@ DisResult disInstr_AMD64 ( IRSB* irbb, /* Used by the optimiser to specialise calls to helpers. */ extern -IRExpr* guest_amd64_spechelper ( HChar* function_name, - IRExpr** args ); +IRExpr* guest_amd64_spechelper ( HChar* function_name, + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ); /* Describes to the optimiser which part of the guest state require precise memory exceptions. This is logically part of the guest diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c index e3f9d510f7..c24cba37b9 100644 --- a/VEX/priv/guest_amd64_helpers.c +++ b/VEX/priv/guest_amd64_helpers.c @@ -867,7 +867,9 @@ static Bool isU64 ( IRExpr* e, ULong n ) } IRExpr* guest_amd64_spechelper ( HChar* function_name, - IRExpr** args ) + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ) { # define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) # define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) diff --git a/VEX/priv/guest_ppc_defs.h b/VEX/priv/guest_ppc_defs.h index 36dbbc6974..dd3c62e7c8 100644 --- a/VEX/priv/guest_ppc_defs.h +++ b/VEX/priv/guest_ppc_defs.h @@ -62,12 +62,16 @@ DisResult disInstr_PPC ( IRSB* irbb, /* Used by the optimiser to specialise calls to helpers. */ extern -IRExpr* guest_ppc32_spechelper ( HChar* function_name, - IRExpr** args ); +IRExpr* guest_ppc32_spechelper ( HChar* function_name, + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ); extern -IRExpr* guest_ppc64_spechelper ( HChar* function_name, - IRExpr** args ); +IRExpr* guest_ppc64_spechelper ( HChar* function_name, + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ); /* Describes to the optimser which part of the guest state require precise memory exceptions. This is logically part of the guest diff --git a/VEX/priv/guest_ppc_helpers.c b/VEX/priv/guest_ppc_helpers.c index d3b046dfc9..e056a65328 100644 --- a/VEX/priv/guest_ppc_helpers.c +++ b/VEX/priv/guest_ppc_helpers.c @@ -182,13 +182,17 @@ void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst, /* Helper-function specialiser. */ IRExpr* guest_ppc32_spechelper ( HChar* function_name, - IRExpr** args ) + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ) { return NULL; } IRExpr* guest_ppc64_spechelper ( HChar* function_name, - IRExpr** args ) + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ) { return NULL; } diff --git a/VEX/priv/guest_x86_defs.h b/VEX/priv/guest_x86_defs.h index 4a5bf3731a..09d647a9d9 100644 --- a/VEX/priv/guest_x86_defs.h +++ b/VEX/priv/guest_x86_defs.h @@ -61,8 +61,10 @@ DisResult disInstr_X86 ( IRSB* irbb, /* Used by the optimiser to specialise calls to helpers. */ extern -IRExpr* guest_x86_spechelper ( HChar* function_name, - IRExpr** args ); +IRExpr* guest_x86_spechelper ( HChar* function_name, + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ); /* Describes to the optimiser which part of the guest state require precise memory exceptions. This is logically part of the guest diff --git a/VEX/priv/guest_x86_helpers.c b/VEX/priv/guest_x86_helpers.c index 95bae8a19e..7aa7a3392a 100644 --- a/VEX/priv/guest_x86_helpers.c +++ b/VEX/priv/guest_x86_helpers.c @@ -772,8 +772,10 @@ static inline Bool isU32 ( IRExpr* e, UInt n ) && e->Iex.Const.con->Ico.U32 == n ); } -IRExpr* guest_x86_spechelper ( HChar* function_name, - IRExpr** args ) +IRExpr* guest_x86_spechelper ( HChar* function_name, + IRExpr** args, + IRStmt** precedingStmts, + Int n_precedingStmts ) { # define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) # define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 018cb51de2..5696e22d57 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -931,6 +931,7 @@ static IRExpr* mkZeroForXor ( IROp op ) switch (op) { case Iop_Xor8: return IRExpr_Const(IRConst_U8(0)); case Iop_Xor16: return IRExpr_Const(IRConst_U16(0)); + case Iop_Sub32: case Iop_Xor32: return IRExpr_Const(IRConst_U32(0)); case Iop_Xor64: return IRExpr_Const(IRConst_U64(0)); case Iop_XorV128: return IRExpr_Const(IRConst_V128(0)); @@ -1584,11 +1585,13 @@ static IRExpr* fold_Expr ( IRExpr* e ) } /* Xor8/16/32/64/V128(t,t) ==> 0, for some IRTemp t */ + /* Sub32(t,t) ==> 0, for some IRTemp t */ if ( (e->Iex.Binop.op == Iop_Xor64 || e->Iex.Binop.op == Iop_Xor32 || e->Iex.Binop.op == Iop_Xor16 || e->Iex.Binop.op == Iop_Xor8 - || e->Iex.Binop.op == Iop_XorV128) + || e->Iex.Binop.op == Iop_XorV128 + || e->Iex.Binop.op == Iop_Sub32) && sameIRTemps(e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { e2 = mkZeroForXor(e->Iex.Binop.op); } @@ -2199,8 +2202,10 @@ static Bool isOneU1 ( IRExpr* e ) /*---------------------------------------------------------------*/ static -IRSB* spec_helpers_BB ( IRSB* bb, - IRExpr* (*specHelper) ( HChar*, IRExpr**) ) +IRSB* spec_helpers_BB( + IRSB* bb, + IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int) + ) { Int i; IRStmt* st; @@ -2215,7 +2220,8 @@ IRSB* spec_helpers_BB ( IRSB* bb, continue; ex = (*specHelper)( st->Ist.WrTmp.data->Iex.CCall.cee->name, - st->Ist.WrTmp.data->Iex.CCall.args ); + st->Ist.WrTmp.data->Iex.CCall.args, + &bb->stmts[0], i ); if (!ex) /* the front end can't think of a suitable replacement */ continue; @@ -4361,7 +4367,7 @@ static Bool iropt_verbose = False; /* True; */ static IRSB* cheap_transformations ( IRSB* bb, - IRExpr* (*specHelper) (HChar*, IRExpr**), + IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int), Bool (*preciseMemExnsFn)(Int,Int) ) { @@ -4512,10 +4518,13 @@ static void considerExpensives ( /*OUT*/Bool* hasGetIorPutI, */ -IRSB* do_iropt_BB ( IRSB* bb0, - IRExpr* (*specHelper) (HChar*, IRExpr**), - Bool (*preciseMemExnsFn)(Int,Int), - Addr64 guest_addr ) +IRSB* do_iropt_BB( + IRSB* bb0, + IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int), + Bool (*preciseMemExnsFn)(Int,Int), + Addr64 guest_addr, + VexArch guest_arch + ) { static Int n_total = 0; static Int n_expensive = 0; @@ -4546,6 +4555,15 @@ IRSB* do_iropt_BB ( IRSB* bb0, bb = cheap_transformations( bb, specHelper, preciseMemExnsFn ); + if (guest_arch == VexArchARM) { + /* Translating Thumb2 code produces a lot of chaff. We have to + work extra hard to get rid of it. */ + bb = cprop_BB(bb); + bb = spec_helpers_BB ( bb, specHelper ); + redundant_put_removal_BB ( bb, preciseMemExnsFn ); + do_deadcode_BB( bb ); + } + if (vex_control.iropt_level > 1) { /* Peer at what we have, to decide how much more effort to throw diff --git a/VEX/priv/ir_opt.h b/VEX/priv/ir_opt.h index c92b9532e1..ecdb146b77 100644 --- a/VEX/priv/ir_opt.h +++ b/VEX/priv/ir_opt.h @@ -43,10 +43,13 @@ /* Top level optimiser entry point. Returns a new BB. Operates under the control of the global "vex_control" struct. */ extern -IRSB* do_iropt_BB ( IRSB* bb, - IRExpr* (*specHelper) (HChar*, IRExpr**), - Bool (*preciseMemExnsFn)(Int,Int), - Addr64 guest_addr ); +IRSB* do_iropt_BB( + IRSB* bb, + IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int), + Bool (*preciseMemExnsFn)(Int,Int), + Addr64 guest_addr, + VexArch guest_arch + ); /* Do a constant folding/propagation pass. */ extern