develooper Front page | perl.perl5.porters | Postings from August 2009

[patch] implement OP_IS_NUMCOMPARE like other OP_IS_*

From:
Jim Cromie
Date:
August 9, 2009 11:26
Subject:
[patch] implement OP_IS_NUMCOMPARE like other OP_IS_*
Message ID:
cfe85dfa0908091126r1bac7bfdlaa9fe851192435d0@mail.gmail.com
From 1f42d35acf0e0fc6fc330d0e7de0e2b5fbce4c79 Mon Sep 17 00:00:00 2001
From: Jim Cromie <jim.cromie@gmail.com>
Date: Wed, 5 Aug 2009 14:48:41 -0600
Subject: [PATCH] implement OP_IS_NUMCOMPARE like others

move macro-def (hardcoded in op.c) to generated file, just like
OP_IS_SOCKET, OP_IS_FILETEST, OP_IS_FT_ACCESS.  This results in a
small optimization, as generating code detects a contiguous range,
and replaces 14 booleans with 2.

The effect is nearly unmeasurable; iirc, gcc on linux gave the old
code a bitmapped comparator, which is fast by default.
---
 op.c      |    8 --------
 opcode.pl |   52 +++++++++++++++++++++++++++++-----------------------
 opnames.h |    3 +++
 3 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/op.c b/op.c
index a28e477..303833a 100644
--- a/op.c
+++ b/op.c
@@ -6366,14 +6366,6 @@ Perl_ck_bitop(pTHX_ OP *o)
 
     PERL_ARGS_ASSERT_CK_BITOP;
 
-#define OP_IS_NUMCOMPARE(op) \
-	((op) == OP_LT   || (op) == OP_I_LT || \
-	 (op) == OP_GT   || (op) == OP_I_GT || \
-	 (op) == OP_LE   || (op) == OP_I_LE || \
-	 (op) == OP_GE   || (op) == OP_I_GE || \
-	 (op) == OP_EQ   || (op) == OP_I_EQ || \
-	 (op) == OP_NE   || (op) == OP_I_NE || \
-	 (op) == OP_NCMP || (op) == OP_I_NCMP)
     o->op_private = (U8)(PL_hints & HINT_INTEGER);
     if (!(o->op_flags & OPf_STACKED) /* Not an assignment */
 	    && (o->op_type == OP_BIT_OR
diff --git a/opcode.pl b/opcode.pl
index 2cc242f..21b66eb 100755
--- a/opcode.pl
+++ b/opcode.pl
@@ -355,9 +355,11 @@ my %opflags = (
     'u' => 128,		# defaults to $_
 );
 
-my %OP_IS_SOCKET;
-my %OP_IS_FILETEST;
-my %OP_IS_FT_ACCESS;
+# opnames => opnums if an arg has respective property
+my %OP_IS_SOCKET;	# /Fs/
+my %OP_IS_FILETEST;	# /F-/
+my %OP_IS_FT_ACCESS;	# /F-+/
+my %OP_IS_NUMCOMP;	# /S</
 my $OCSHIFT = 9;
 my $OASHIFT = 13;
 
@@ -382,6 +384,9 @@ for my $op (@ops) {
 	    $OP_IS_FILETEST{$op} = $opnum{$op} if $arg =~ s/-//;
 	    $OP_IS_FT_ACCESS{$op} = $opnum{$op} if $arg =~ s/\+//;
         }
+	elsif ($arg =~ /^S</) {
+	    $OP_IS_NUMCOMP{$op} = $opnum{$op} if $arg =~ s/<//;
+	}
 	my $argnum = ($arg =~ s/\?//) ? 8 : 0;
         die "op = $op, arg = $arg\n"
 	    unless exists $argnum{$arg};
@@ -419,6 +424,7 @@ EO_OP_IS_COMMENT
 gen_op_is_macro( \%OP_IS_SOCKET, 'OP_IS_SOCKET');
 gen_op_is_macro( \%OP_IS_FILETEST, 'OP_IS_FILETEST');
 gen_op_is_macro( \%OP_IS_FT_ACCESS, 'OP_IS_FILETEST_ACCESS');
+gen_op_is_macro( \%OP_IS_NUMCOMP,   'OP_IS_NUMCOMPARE');
 
 sub gen_op_is_macro {
     my ($op_is, $macname) = @_;
@@ -439,14 +445,14 @@ sub gen_op_is_macro {
 	if ( $op_is->{$last} - $op_is->{$first} == scalar @rest + 1) {
 	    
 	    # contiguous ops -> optimized version
-	    print $on "(op) >= OP_" . uc($first) . " && (op) <= OP_" . uc($last);
-	    print $on ")\n\n";
+	    print $on "(op) >= OP_" . uc($first) .
+		  " && (op) <= OP_" . uc($last);
 	}
 	else {
 	    print $on join(" || \\\n\t ",
-			  map { "(op) == OP_" . uc() } sort keys %$op_is);
-	    print $on ")\n\n";
+			   map { "(op) == OP_" . uc() } sort keys %$op_is);
 	}
+	print $on ")\n\n";
     }
 }
 
@@ -612,8 +618,7 @@ __END__
 # scalar      - S            list     - L            array     - A
 # hash        - H            sub (CV) - C            file      - F
 # socket      - Fs           filetest - F-           filetest_access - F-+
-
-# reference - R
+# reference   - R            number-compare - S<
 # "?" denotes an optional operand.
 
 # Nothing.
@@ -717,20 +722,21 @@ stringify	string			ck_fun		fsT@	S
 left_shift	left bitshift (<<)	ck_bitop	fsT2	S S
 right_shift	right bitshift (>>)	ck_bitop	fsT2	S S
 
-lt		numeric lt (<)		ck_null		Iifs2	S S
-i_lt		integer lt (<)		ck_null		ifs2	S S
-gt		numeric gt (>)		ck_null		Iifs2	S S
-i_gt		integer gt (>)		ck_null		ifs2	S S
-le		numeric le (<=)		ck_null		Iifs2	S S
-i_le		integer le (<=)		ck_null		ifs2	S S
-ge		numeric ge (>=)		ck_null		Iifs2	S S
-i_ge		integer ge (>=)		ck_null		ifs2	S S
-eq		numeric eq (==)		ck_null		Iifs2	S S
-i_eq		integer eq (==)		ck_null		ifs2	S S
-ne		numeric ne (!=)		ck_null		Iifs2	S S
-i_ne		integer ne (!=)		ck_null		ifs2	S S
-ncmp		numeric comparison (<=>)	ck_null		Iifst2	S S
-i_ncmp		integer comparison (<=>)	ck_null		ifst2	S S
+# keep contiguous for OP_IS_NUMCOMPARE
+lt		numeric lt (<)		ck_null		Iifs2	S S<
+i_lt		integer lt (<)		ck_null		ifs2	S S<
+gt		numeric gt (>)		ck_null		Iifs2	S S<
+i_gt		integer gt (>)		ck_null		ifs2	S S<
+le		numeric le (<=)		ck_null		Iifs2	S S<
+i_le		integer le (<=)		ck_null		ifs2	S S<
+ge		numeric ge (>=)		ck_null		Iifs2	S S<
+i_ge		integer ge (>=)		ck_null		ifs2	S S<
+eq		numeric eq (==)		ck_null		Iifs2	S S<
+i_eq		integer eq (==)		ck_null		ifs2	S S<
+ne		numeric ne (!=)		ck_null		Iifs2	S S<
+i_ne		integer ne (!=)		ck_null		ifs2	S S<
+ncmp		numeric comparison (<=>)	ck_null		Iifst2	S S<
+i_ncmp		integer comparison (<=>)	ck_null		ifst2	S S<
 
 slt		string lt		ck_null		ifs2	S S
 sgt		string gt		ck_null		ifs2	S S
diff --git a/opnames.h b/opnames.h
index 3914ea8..cd8090b 100644
--- a/opnames.h
+++ b/opnames.h
@@ -401,4 +401,7 @@ typedef enum opcode {
 #define OP_IS_FILETEST_ACCESS(op)	\
 	((op) >= OP_FTRREAD && (op) <= OP_FTEEXEC)
 
+#define OP_IS_NUMCOMPARE(op)	\
+	((op) >= OP_LT && (op) <= OP_I_NCMP)
+
 /* ex: set ro: */
-- 
1.6.2.5




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About