]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Allow constant folding to apply to IRStmt_Exit.
authorJulian Seward <jseward@acm.org>
Thu, 19 Aug 2004 17:58:45 +0000 (17:58 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 19 Aug 2004 17:58:45 +0000 (17:58 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@183

VEX/priv/ir/irdefs.c
VEX/priv/ir/iropt.c

index abe97eeaef2ad418d1793606531571ef07420c32..7ff7bcfd27d9b9d091d7da5a2946f10c08ecdcee 100644 (file)
@@ -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;
index dacd123279aad231ab9c153cbb8ac15147b2f9b2..4e888c10f7c736322948dade52ff3265013c8436 100644 (file)
@@ -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