Perl script to rename files in a directory tree
It seems correct to me except these lines:

$s1 =~ s/\.cxx/\.cpp/g;
$s1 =~ s/\.hxx/\.h/g;
$s1 =~ s/\.(cxx|hxx)//g;


There're no needs to do the substitution g lobal and also you need to anchor the regex at the end:

$s1 =~ s/\.cxx$/.cpp/;
$s1 =~ s/\.hxx$/.h/;
$s1 =~ s/\.(cxx|hxx)$//;