From 805078a1bf7c7194da47d5f5e7f9fed5bf734ca3 Mon Sep 17 00:00:00 2001 From: James Zern Date: Sun, 23 Feb 2014 16:33:14 -0800 Subject: [PATCH] build: convert rtcd.sh to perl significantly speeds up file generation. the goal of this change is to convert rtcd.sh to perl as directly as possible to allow for simple comparison. future changes can make it more perl-like. --- Linux [CREATE] vpx_scale_rtcd.h real 0m0.485s -> 0m0.022s [CREATE] vp8_rtcd.h real 0m4.619s -> 0m0.060s [CREATE] vp9_rtcd.h real 0m10.102s -> 0m0.087s Windows [CREATE] vpx_scale_rtcd.h real 0m8.360s -> 0m0.080s [CREATE] vp8_rtcd.h real 1m8.083s -> 0m0.160s [CREATE] vp9_rtcd.h real 2m6.489s -> 0m0.233s Change-Id: Idfb71188206c91237d6a3c3a81dfe00d103f11ee --- build/make/rtcd.pl | 414 +++++++++++++++++++ build/make/rtcd.sh | 373 ----------------- libs.mk | 4 +- vp8/common/rtcd_defs.pl | 541 +++++++++++++++++++++++++ vp8/common/rtcd_defs.sh | 542 ------------------------- vp8/vp8_common.mk | 4 +- vp9/common/vp9_rtcd_defs.pl | 778 ++++++++++++++++++++++++++++++++++++ vp9/common/vp9_rtcd_defs.sh | 760 ----------------------------------- vp9/vp9_common.mk | 4 +- vpx_scale/vpx_scale.mk | 4 +- vpx_scale/vpx_scale_rtcd.pl | 35 ++ vpx_scale/vpx_scale_rtcd.sh | 34 -- 12 files changed, 1776 insertions(+), 1717 deletions(-) create mode 100755 build/make/rtcd.pl delete mode 100755 build/make/rtcd.sh create mode 100644 vp8/common/rtcd_defs.pl delete mode 100644 vp8/common/rtcd_defs.sh create mode 100644 vp9/common/vp9_rtcd_defs.pl delete mode 100644 vp9/common/vp9_rtcd_defs.sh create mode 100644 vpx_scale/vpx_scale_rtcd.pl delete mode 100644 vpx_scale/vpx_scale_rtcd.sh diff --git a/build/make/rtcd.pl b/build/make/rtcd.pl new file mode 100755 index 000000000..18ee80d36 --- /dev/null +++ b/build/make/rtcd.pl @@ -0,0 +1,414 @@ +#!/usr/bin/env perl + +no strict 'refs'; +use warnings; +use Getopt::Long; +Getopt::Long::Configure("auto_help"); + +my %ALL_FUNCS = (); +my @ALL_ARCHS; +my @ALL_FORWARD_DECLS; +my @REQUIRES; + +my %opts = (); +my %disabled = (); +my %required = (); + +my @argv; +foreach (@ARGV) { + $disabled{$1} = 1, next if /--disable-(.*)/; + $required{$1} = 1, next if /--require-(.*)/; + push @argv, $_; +} + +# NB: use GetOptions() instead of GetOptionsFromArray() for compatibility. +@ARGV = @argv; +GetOptions( + \%opts, + 'arch=s', + 'sym=s', + 'config=s', +); + +foreach my $opt (qw/arch config/) { + if (!defined($opts{$opt})) { + warn "--$opt is required!\n"; + Getopt::Long::HelpMessage('-exit' => 1); + } +} + +foreach my $defs_file (@ARGV) { + if (!-f $defs_file) { + warn "$defs_file: $!\n"; + Getopt::Long::HelpMessage('-exit' => 1); + } +} + +open CONFIG_FILE, $opts{config} or + die "Error opening config file '$opts{config}': $!\n"; + +my %config = (); +while () { + next if !/^CONFIG_/; + chomp; + my @pair = split /=/; + $config{$pair[0]} = $pair[1]; +} +close CONFIG_FILE; + +# +# Routines for the RTCD DSL to call +# +sub vpx_config($) { + return (defined $config{$_[0]}) ? $config{$_[0]} : ""; +} + +sub specialize { + my $fn=$_[0]; + shift; + foreach my $opt (@_) { + eval "\$${fn}_${opt}=${fn}_${opt}"; + } +} + +sub add_proto { + my $fn = splice(@_, -2, 1); + $ALL_FUNCS{$fn} = \@_; + specialize $fn, "c"; +} + +sub require { + foreach my $fn (keys %ALL_FUNCS) { + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + + # if we already have a default, then we can disable it, as we know + # we can do better. + my $best = eval "\$${fn}_default"; + if ($best) { + my $best_ofn = eval "\$${best}"; + if ($best_ofn && "$best_ofn" ne "$ofn") { + eval "\$${best}_link = 'false'"; + } + } + eval "\$${fn}_default=${fn}_${opt}"; + eval "\$${fn}_${opt}_link='true'"; + } + } +} + +sub forward_decls { + push @ALL_FORWARD_DECLS, @_; +} + +# +# Include the user's directives +# +foreach my $f (@ARGV) { + open FILE, "<", $f or die "cannot open $f: $!\n"; + my $contents = join('', ); + close FILE; + eval $contents or warn "eval failed: $@\n"; +} + +# +# Process the directives according to the command line +# +sub process_forward_decls() { + foreach (@ALL_FORWARD_DECLS) { + $_->(); + } +} + +sub determine_indirection { + vpx_config("CONFIG_RUNTIME_CPU_DETECT") eq "yes" or &require(@ALL_ARCHS); + foreach my $fn (keys %ALL_FUNCS) { + my $n = ""; + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + my $link = eval "\$${fn}_${opt}_link"; + next if $link && $link eq "false"; + $n .= "x"; + } + if ($n eq "x") { + eval "\$${fn}_indirect = 'false'"; + } else { + eval "\$${fn}_indirect = 'true'"; + } + } +} + +sub declare_function_pointers { + foreach my $fn (sort keys %ALL_FUNCS) { + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + print "$rtyp ${ofn}($args);\n"; + } + if (eval "\$${fn}_indirect" eq "false") { + print "#define ${fn} ${dfn}\n"; + } else { + print "RTCD_EXTERN $rtyp (*${fn})($args);\n"; + } + print "\n"; + } +} + +sub set_function_pointers { + foreach my $fn (sort keys %ALL_FUNCS) { + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + if (eval "\$${fn}_indirect" eq "true") { + print " $fn = $dfn;\n"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + next if "$ofn" eq "$dfn"; + my $link = eval "\$${fn}_${opt}_link"; + next if $link && $link eq "false"; + my $cond = eval "\$have_${opt}"; + print " if (${cond}) $fn = $ofn;\n" + } + } + } +} + +sub filter { + my @filtered; + foreach (@_) { push @filtered, $_ unless $disabled{$_}; } + return @filtered; +} + +# +# Helper functions for generating the arch specific RTCD files +# +sub common_top() { + my $include_guard = uc($opts{sym})."_H_"; + print <) { + if (/HAVE_DSPR2=yes/) { + @ALL_ARCHS = filter(qw/mips32 dspr2/); + last; + } + } + close CONFIG_FILE; + mips; +} elsif ($opts{arch} eq 'armv5te') { + @ALL_ARCHS = filter(qw/edsp/); + arm; +} elsif ($opts{arch} eq 'armv6') { + @ALL_ARCHS = filter(qw/edsp media/); + arm; +} elsif ($opts{arch} eq 'armv7') { + @ALL_ARCHS = filter(qw/edsp media neon/); + arm; +} else { + unoptimized; +} + +__END__ + +=head1 NAME + +rtcd - + +=head1 SYNOPSIS + +Usage: rtcd.pl [options] FILE + +See 'perldoc rtcd.pl' for more details. + +=head1 DESCRIPTION + +Reads the Run Time CPU Detections definitions from FILE and generates a +C header file on stdout. + +=head1 OPTIONS + +Options: + --arch=ARCH Architecture to generate defs for (required) + --disable-EXT Disable support for EXT extensions + --require-EXT Require support for EXT extensions + --sym=SYMBOL Unique symbol to use for RTCD initialization function + --config=FILE File with CONFIG_FOO=yes lines to parse diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh deleted file mode 100755 index 93c9adcac..000000000 --- a/build/make/rtcd.sh +++ /dev/null @@ -1,373 +0,0 @@ -#!/bin/sh -self=$0 - -usage() { - cat <&2 -Usage: $self [options] FILE - -Reads the Run Time CPU Detections definitions from FILE and generates a -C header file on stdout. - -Options: - --arch=ARCH Architecture to generate defs for (required) - --disable-EXT Disable support for EXT extensions - --require-EXT Require support for EXT extensions - --sym=SYMBOL Unique symbol to use for RTCD initialization function - --config=FILE File with CONFIG_FOO=yes lines to parse -EOF - exit 1 -} - -die() { - echo "$@" >&2 - exit 1 -} - -die_argument_required() { - die "Option $opt requires argument" -} - -for opt; do - optval="${opt#*=}" - case "$opt" in - --arch) die_argument_required;; - --arch=*) arch=${optval};; - --disable-*) eval "disable_${opt#--disable-}=true";; - --require-*) REQUIRES="${REQUIRES}${opt#--require-} ";; - --sym) die_argument_required;; - --sym=*) symbol=${optval};; - --config=*) config_file=${optval};; - -h|--help) - usage - ;; - -*) - die "Unrecognized option: ${opt%%=*}" - ;; - *) - defs_file="$defs_file $opt" - ;; - esac - shift -done -for f in $defs_file; do [ -f "$f" ] || usage; done -[ -n "$arch" ] || usage - -# Import the configuration -[ -f "$config_file" ] && eval $(grep CONFIG_ "$config_file") - -# -# Routines for the RTCD DSL to call -# -prototype() { - rtyp="" - case "$1" in - unsigned) rtyp="$1 "; shift;; - esac - rtyp="${rtyp}$1" - fn="$2" - args="$3" - - eval "${2}_rtyp='$rtyp'" - eval "${2}_args='$3'" - ALL_FUNCS="$ALL_FUNCS $fn" - specialize $fn c -} - -specialize() { - fn="$1" - shift - for opt in "$@"; do - eval "${fn}_${opt}=${fn}_${opt}" - done -} - -require() { - for fn in $ALL_FUNCS; do - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - - # if we already have a default, then we can disable it, as we know - # we can do better. - best=$(eval "echo \$${fn}_default") - best_ofn=$(eval "echo \$${best}") - [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false" - eval "${fn}_default=${fn}_${opt}" - eval "${fn}_${opt}_link=true" - done - done -} - -forward_decls() { - ALL_FORWARD_DECLS="$ALL_FORWARD_DECLS $1" -} - -# -# Include the user's directives -# -for f in $defs_file; do - . $f -done - -# -# Process the directives according to the command line -# -process_forward_decls() { - for fn in $ALL_FORWARD_DECLS; do - eval $fn - done -} - -determine_indirection() { - [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS - for fn in $ALL_FUNCS; do - n="" - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - link=$(eval "echo \$${fn}_${opt}_link") - [ "$link" = "false" ] && continue - n="${n}x" - done - if [ "$n" = "x" ]; then - eval "${fn}_indirect=false" - else - eval "${fn}_indirect=true" - fi - done -} - -declare_function_pointers() { - for fn in $ALL_FUNCS; do - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - echo "$rtyp ${ofn}($args);" - done - if [ "$(eval "echo \$${fn}_indirect")" = "false" ]; then - echo "#define ${fn} ${dfn}" - else - echo "RTCD_EXTERN $rtyp (*${fn})($args);" - fi - echo - done -} - -set_function_pointers() { - for fn in $ALL_FUNCS; do - n="" - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - if $(eval "echo \$${fn}_indirect"); then - echo " $fn = $dfn;" - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - [ "$ofn" = "$dfn" ] && continue; - link=$(eval "echo \$${fn}_${opt}_link") - [ "$link" = "false" ] && continue - cond="$(eval "echo \$have_${opt}")" - echo " if (${cond}) $fn = $ofn;" - done - fi - echo - done -} - -filter() { - filtered="" - for opt in "$@"; do - [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt" - done - echo $filtered -} - -# -# Helper functions for generating the arch specific RTCD files -# -common_top() { - outfile_basename=$(basename ${symbol:-rtcd}) - include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | \ - tr -c '[A-Z0-9]' _)H_ - cat < $$@ @@ -162,7 +162,7 @@ INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%) endif CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh -CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.sh +CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.pl CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emmintrin_compat.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops_aligned.h diff --git a/vp8/common/rtcd_defs.pl b/vp8/common/rtcd_defs.pl new file mode 100644 index 000000000..130d96535 --- /dev/null +++ b/vp8/common/rtcd_defs.pl @@ -0,0 +1,541 @@ +sub vp8_common_forward_decls() { +print <