From ec325cc785916c6a4991fe2e03747a97b7e1ae75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 29 Sep 2010 12:16:56 +0200
Subject: BEAM loader: Combine is_type/1 and is_eq/1 instructions

In the transformation engine in the loader, an is_eq/1 instruction
is currently always preceded by an is_type/1 instruction. Therefore,
save a word and slight amount of time by combining those
instructions into an is_type_eq/2 instruction.
---
 erts/emulator/beam/beam_load.c   | 12 ++++++++++++
 erts/emulator/utils/beam_makeops |  8 +++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

(limited to 'erts')

diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index feac89784b..73644ecfd6 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -3867,11 +3867,23 @@ transform_engine(LoaderState* st)
 	    if (i == 0)
 		goto restart;
 	    break;
+#if defined(TOP_is_eq)
 	case TOP_is_eq:
 	    ASSERT(ap < instr->arity);
 	    if (*pc++ != instr->a[ap].val)
 		goto restart;
 	    break;
+#endif
+	case TOP_is_type_eq:
+	    mask = *pc++;
+
+	    ASSERT(ap < instr->arity);
+	    ASSERT(instr->a[ap].type < BEAM_NUM_TAGS);
+	    if (((1 << instr->a[ap].type) & mask) == 0)
+		goto restart;
+	    if (*pc++ != instr->a[ap].val)
+		goto restart;
+	    break;
 	case TOP_is_same_var:
 	    ASSERT(ap < instr->arity);
 	    i = *pc++;
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index 8a5b8047eb..cb91517f04 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -1315,7 +1315,13 @@ sub tr_gen_from {
 			$types .= "$_ ";
 			$type_mask |= $type_bit{$_};
 		    }
-		    push(@code, &make_op($types, 'is_type', $type_mask));
+		    if ($cond ne 'is_eq') {
+			push(@code, &make_op($types, 'is_type', $type_mask));
+		    } else {
+			$cond = '';
+			push(@code, &make_op($types, 'is_type_eq',
+					     $type_mask, $val));
+		    }
 		}
 	    }
 
-- 
cgit v1.2.3