From: Julian Seward Date: Mon, 20 Dec 2004 04:12:14 +0000 (+0000) Subject: Move the IR tree matcher into its own module to get rid of X-Git-Tag: svn/VALGRIND_3_0_1^2~661 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9a7b8a138d9084372a749c135ccb67bcb7c70c9;p=thirdparty%2Fvalgrind.git Move the IR tree matcher into its own module to get rid of duplication. git-svn-id: svn://svn.valgrind.org/vex/trunk@673 --- diff --git a/VEX/Makefile b/VEX/Makefile index 3d0aa7c039..7ad1f565e5 100644 --- a/VEX/Makefile +++ b/VEX/Makefile @@ -15,9 +15,11 @@ PRIV_HEADERS = priv/host-x86/hdefs.h \ priv/main/vex_util.h \ priv/guest-x86/gdefs.h \ priv/guest-arm/gdefs.h \ + priv/ir/irmatch.h \ priv/ir/iropt.h LIB_OBJS = priv/ir/irdefs.o \ + priv/ir/irmatch.o \ priv/ir/iropt.o \ priv/main/vex_main.o \ priv/main/vex_globals.o \ @@ -89,6 +91,10 @@ priv/ir/irdefs.o: $(ALL_HEADERS) priv/ir/irdefs.c $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/irdefs.o \ -c priv/ir/irdefs.c +priv/ir/irmatch.o: $(ALL_HEADERS) priv/ir/irmatch.c + $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/irmatch.o \ + -c priv/ir/irmatch.c + priv/ir/iropt.o: $(ALL_HEADERS) priv/ir/iropt.c $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/iropt.o \ -c priv/ir/iropt.c diff --git a/VEX/priv/host-arm/isel.c b/VEX/priv/host-arm/isel.c index 3329f965be..092d3f5e62 100644 --- a/VEX/priv/host-arm/isel.c +++ b/VEX/priv/host-arm/isel.c @@ -43,130 +43,6 @@ #include "host-arm/hdefs.h" - -/*---------------------------------------------------------*/ -/*--- Stuff for pattern matching on IR. This isn't ---*/ -/*--- arm specific, and should be moved elsewhere. ---*/ -/*---------------------------------------------------------*/ - -#define DECLARE_PATTERN(_patt) \ - static IRExpr* _patt = NULL - -#define DEFINE_PATTERN(_patt,_expr) \ - do { \ - if (!(_patt)) { \ - vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ - LibVEX_SetAllocMode(AllocModePERMANENT); \ - _patt = (_expr); \ - LibVEX_SetAllocMode(AllocModeTEMPORARY); \ - vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ - } \ - } while (0) - - -#define N_MATCH_BINDERS 4 -typedef - struct { - IRExpr* bindee[N_MATCH_BINDERS]; - } - MatchInfo; - - - -static void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee ) -{ - if (n < 0 || n >= N_MATCH_BINDERS) - vpanic("setBindee: out of range index"); - if (mi->bindee[n] != NULL) - vpanic("setBindee: bindee already set"); - mi->bindee[n] = bindee; -} - -static Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) -{ - switch (p->tag) { - case Iex_Binder: /* aha, what we were looking for. */ - setBindee(mi, p->Iex.Binder.binder, e); - return True; -#if 0 - case Iex_GetI: - if (e->tag != Iex_GetI) return False; - if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False; - /* we ignore the offset limit hints .. */ - if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset)) - return False; - return True; -#endif - case Iex_Unop: - if (e->tag != Iex_Unop) return False; - if (p->Iex.Unop.op != e->Iex.Unop.op) return False; - if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg)) - return False; - return True; - case Iex_Binop: - if (e->tag != Iex_Binop) return False; - if (p->Iex.Binop.op != e->Iex.Binop.op) return False; - if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1)) - return False; - if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2)) - return False; - return True; - case Iex_LDle: - if (e->tag != Iex_LDle) return False; - if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False; - if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr)) - return False; - return True; - case Iex_Const: - if (e->tag != Iex_Const) return False; - return eqIRConst(p->Iex.Const.con, e->Iex.Const.con); - default: - ppIRExpr(p); - vpanic("match"); - } -} - -#if 0 -static Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) -{ - Int i; - for (i = 0; i < N_MATCH_BINDERS; i++) - mi->bindee[i] = NULL; - return matchWrk(mi, p, e); -} -#endif - -#if 0 -/*-----*/ -/* These are duplicated in guest-arm/toIR.c */ -static IRExpr* unop ( IROp op, IRExpr* a ) -{ - return IRExpr_Unop(op, a); -} - -static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ) -{ - return IRExpr_Binop(op, a1, a2); -} - -static IRExpr* mkU64 ( ULong i ) -{ - return IRExpr_Const(IRConst_U64(i)); -} - -static IRExpr* mkU32 ( UInt i ) -{ - return IRExpr_Const(IRConst_U32(i)); -} - -static IRExpr* bind ( Int binder ) -{ - return IRExpr_Binder(binder); -} -#endif - - - /*---------------------------------------------------------*/ /*--- ISelEnv ---*/ /*---------------------------------------------------------*/ diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 65495d2b85..f0f9cd7b1d 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -37,6 +37,7 @@ #include "libvex_ir.h" #include "libvex.h" +#include "ir/irmatch.h" #include "main/vex_util.h" #include "main/vex_globals.h" #include "host-generic/h_generic_regs.h" @@ -44,96 +45,10 @@ /*---------------------------------------------------------*/ -/*--- Stuff for pattern matching on IR. This isn't ---*/ -/*--- x86 specific, and should be moved elsewhere. ---*/ +/*--- misc helpers ---*/ /*---------------------------------------------------------*/ -#define DECLARE_PATTERN(_patt) \ - static IRExpr* _patt = NULL - -#define DEFINE_PATTERN(_patt,_expr) \ - do { \ - if (!(_patt)) { \ - vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ - LibVEX_SetAllocMode(AllocModePERMANENT); \ - _patt = (_expr); \ - LibVEX_SetAllocMode(AllocModeTEMPORARY); \ - vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ - } \ - } while (0) - - -#define N_MATCH_BINDERS 4 -typedef - struct { - IRExpr* bindee[N_MATCH_BINDERS]; - } - MatchInfo; - - -static void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee ) -{ - if (n < 0 || n >= N_MATCH_BINDERS) - vpanic("setBindee: out of range index"); - if (mi->bindee[n] != NULL) - vpanic("setBindee: bindee already set"); - mi->bindee[n] = bindee; -} - -static Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) -{ - switch (p->tag) { - case Iex_Binder: /* aha, what we were looking for. */ - setBindee(mi, p->Iex.Binder.binder, e); - return True; -#if 0 - case Iex_GetI: - if (e->tag != Iex_GetI) return False; - if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False; - /* we ignore the offset limit hints .. */ - if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset)) - return False; - return True; -#endif - case Iex_Unop: - if (e->tag != Iex_Unop) return False; - if (p->Iex.Unop.op != e->Iex.Unop.op) return False; - if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg)) - return False; - return True; - case Iex_Binop: - if (e->tag != Iex_Binop) return False; - if (p->Iex.Binop.op != e->Iex.Binop.op) return False; - if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1)) - return False; - if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2)) - return False; - return True; - case Iex_LDle: - if (e->tag != Iex_LDle) return False; - if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False; - if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr)) - return False; - return True; - case Iex_Const: - if (e->tag != Iex_Const) return False; - return eqIRConst(p->Iex.Const.con, e->Iex.Const.con); - default: - ppIRExpr(p); - vpanic("match"); - } -} - -static Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) -{ - Int i; - for (i = 0; i < N_MATCH_BINDERS; i++) - mi->bindee[i] = NULL; - return matchWrk(mi, p, e); -} - -/*-----*/ -/* These are duplicated in x86toIR.c */ +/* These are duplicated in guest-x86/toIR.c */ static IRExpr* unop ( IROp op, IRExpr* a ) { return IRExpr_Unop(op, a); @@ -161,7 +76,6 @@ static IRExpr* bind ( Int binder ) - /*---------------------------------------------------------*/ /*--- ISelEnv ---*/ /*---------------------------------------------------------*/ diff --git a/VEX/priv/ir/irmatch.c b/VEX/priv/ir/irmatch.c new file mode 100644 index 0000000000..21ee601b36 --- /dev/null +++ b/VEX/priv/ir/irmatch.c @@ -0,0 +1,119 @@ + +/*---------------------------------------------------------------*/ +/*--- ---*/ +/*--- This file (ir/irmatch.c) is ---*/ +/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of LibVEX, a library for dynamic binary + instrumentation and translation. + + Copyright (C) 2004 OpenWorks, LLP. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; Version 2 dated June 1991 of the + license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability + for damages. See the GNU General Public License for more details. + + Neither the names of the U.S. Department of Energy nor the + University of California nor the names of its contributors may be + used to endorse or promote products derived from this software + without prior written permission. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +*/ + +/* Provides a facility for doing IR tree matching. */ + +#include "main/vex_util.h" +#include "ir/irmatch.h" + + +/* Assign a value to a binder. Checks for obvious stupidities. */ + +static +void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee ) +{ + if (n < 0 || n >= N_IRMATCH_BINDERS) + vpanic("setBindee: out of range index"); + if (mi->bindee[n] != NULL) + vpanic("setBindee: bindee already set"); + mi->bindee[n] = bindee; +} + + +/* This is the actual matching function, recursing over the pattern + and expression trees in the obvious way, and dumping any matches + found into 'mi'. */ + +static +Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) +{ + switch (p->tag) { + case Iex_Binder: /* aha, what we were looking for. */ + setBindee(mi, p->Iex.Binder.binder, e); + return True; +#if 0 + case Iex_GetI: + if (e->tag != Iex_GetI) return False; + if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False; + /* we ignore the offset limit hints .. */ + if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset)) + return False; + return True; +#endif + case Iex_Unop: + if (e->tag != Iex_Unop) return False; + if (p->Iex.Unop.op != e->Iex.Unop.op) return False; + if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg)) + return False; + return True; + case Iex_Binop: + if (e->tag != Iex_Binop) return False; + if (p->Iex.Binop.op != e->Iex.Binop.op) return False; + if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1)) + return False; + if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2)) + return False; + return True; + case Iex_LDle: + if (e->tag != Iex_LDle) return False; + if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False; + if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr)) + return False; + return True; + case Iex_Const: + if (e->tag != Iex_Const) return False; + return eqIRConst(p->Iex.Const.con, e->Iex.Const.con); + default: + ppIRExpr(p); + vpanic("match"); + } +} + + +/* Top level entry point to the matcher. */ + +Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) +{ + Int i; + for (i = 0; i < N_IRMATCH_BINDERS; i++) + mi->bindee[i] = NULL; + return matchWrk(mi, p, e); +} + + + +/*---------------------------------------------------------------*/ +/*--- end ir/irmatch.c ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/ir/irmatch.h b/VEX/priv/ir/irmatch.h new file mode 100644 index 0000000000..2bf124dd34 --- /dev/null +++ b/VEX/priv/ir/irmatch.h @@ -0,0 +1,90 @@ + +/*---------------------------------------------------------------*/ +/*--- ---*/ +/*--- This file (ir/irmatch.h) is ---*/ +/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of LibVEX, a library for dynamic binary + instrumentation and translation. + + Copyright (C) 2004 OpenWorks, LLP. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; Version 2 dated June 1991 of the + license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability + for damages. See the GNU General Public License for more details. + + Neither the names of the U.S. Department of Energy nor the + University of California nor the names of its contributors may be + used to endorse or promote products derived from this software + without prior written permission. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +*/ + +/* Provides a facility for doing IR tree matching. */ + +#ifndef __LIBVEX_IRMATCH_H +#define __LIBVEX_IRMATCH_H + +#include "libvex_basictypes.h" +#include "libvex_ir.h" + + +/* Patterns are simply IRExpr* trees, with IRExpr_Binder nodes at the + leaves, indicating binding points. Use these magic macros to + declare and define patterns. */ + +#define DECLARE_PATTERN(_patt) \ + static IRExpr* _patt = NULL + +#define DEFINE_PATTERN(_patt,_expr) \ + do { \ + if (!(_patt)) { \ + vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ + LibVEX_SetAllocMode(AllocModePERMANENT); \ + _patt = (_expr); \ + LibVEX_SetAllocMode(AllocModeTEMPORARY); \ + vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \ + } \ + } while (0) + + +/* This type returns the result of a match -- it records what + the binders got instantiated to. */ + +#define N_IRMATCH_BINDERS 4 + +typedef + struct { + IRExpr* bindee[N_IRMATCH_BINDERS]; + } + MatchInfo; + + +/* The matching function. p is expected to have zero or more + IRExpr_Binds in it, numbered 0, 1, 2 ... Returns True if a match + succeeded. */ + +extern +Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ); + + +#endif /* ndef __LIBVEX_IRMATCH_H */ + + + +/*---------------------------------------------------------------*/ +/*--- end ir/irmatch.h ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/ir/iropt.h b/VEX/priv/ir/iropt.h index 5b7bfbfef0..a2b7dd1173 100644 --- a/VEX/priv/ir/iropt.h +++ b/VEX/priv/ir/iropt.h @@ -33,6 +33,9 @@ USA. */ +#ifndef __LIBVEX_IROPT_H +#define __LIBVEX_IROPT_H + #include "libvex_basictypes.h" #include "libvex_ir.h" #include "libvex.h" @@ -63,6 +66,8 @@ void do_cse_BB ( IRBB* bb ); extern void do_treebuild_BB ( IRBB* bb ); +#endif /* ndef __LIBVEX_IROPT_H */ + /*---------------------------------------------------------------*/ /*--- end ir/iropt.h ---*/ /*---------------------------------------------------------------*/