]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Move the IR tree matcher into its own module to get rid of
authorJulian Seward <jseward@acm.org>
Mon, 20 Dec 2004 04:12:14 +0000 (04:12 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 20 Dec 2004 04:12:14 +0000 (04:12 +0000)
duplication.

git-svn-id: svn://svn.valgrind.org/vex/trunk@673

VEX/Makefile
VEX/priv/host-arm/isel.c
VEX/priv/host-x86/isel.c
VEX/priv/ir/irmatch.c [new file with mode: 0644]
VEX/priv/ir/irmatch.h [new file with mode: 0644]
VEX/priv/ir/iropt.h

index 3d0aa7c03955b47dfde824de4a043bddf2643670..7ad1f565e55d04adec831c6b3d6369c571805204 100644 (file)
@@ -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
index 3329f965be9be2a49143397771d00a7399b23543..092d3f5e6207a39310ca96bedc8f91efcb65e83c 100644 (file)
 #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                                           ---*/
 /*---------------------------------------------------------*/
index 65495d2b858a38c6a2086567ed723696d94dde58..f0f9cd7b1d7a6296b396f2c027e0ad6c937a98ca 100644 (file)
@@ -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"
 
 
 /*---------------------------------------------------------*/
-/*--- 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 (file)
index 0000000..21ee601
--- /dev/null
@@ -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 (file)
index 0000000..2bf124d
--- /dev/null
@@ -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 ---*/
+/*---------------------------------------------------------------*/
index 5b7bfbfef084ae7ab4796fa0a25ca6a1b184c7d5..a2b7dd11738d7c289d1208e7890860efca82e804 100644 (file)
@@ -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 ---*/
 /*---------------------------------------------------------------*/