Teach instCombine to remove malloc+free if malloc's only uses are comparisons
[oota-llvm.git] / utils / userloc.pl
index ab636e8a69770d8bb8a01f121808e1970018a2de..4da2f4029250163d1cf06d25e17592e7f6e28823 100755 (executable)
 #           then the cwd is used. The directory must be an LLVM tree checked out
 #           from cvs. 
 #
-# Syntax:   userloc.pl [-recurse|-tag=tag|-html... <directory>...
+# Syntax:   userloc.pl [-tag=tag|-html... <directory>...
 #
 # Options:
-#           -recurse
-#               Recurse through sub directories. Without this, only the
-#               specified directory is examined
 #           -tag=tag
 #               Use "tag" to select the revision (as per cvs -r option)
+#           -filedetails
+#               Report details about lines of code in each file for each user
 #           -html
 #               Generate HTML output instead of text output
-
-die "Usage userloc.pl [-recurse|-tag=tag|-html] <directories>..." 
+#           -topdir
+#               Specify where the top llvm source directory is. Otherwise the
+#               llvm-config tool is used to find it.
+# Directories:
+#   The directories passed after the options should be relative paths to
+#   directories of interest from the top of the llvm source tree, e.g. "lib"
+#   or "include", etc.
+
+die "Usage userloc.pl [-tag=tag|-html] <directories>..." 
   if ($#ARGV < 0);
 
 my $tag = "";
-my $recurse = 0;
 my $html = 0;
 my $debug = 0;
-while ( substr($ARGV[0],0,1) eq '-' )
+my $filedetails = "";
+my $srcroot = "";
+while ( defined($ARGV[0]) && substr($ARGV[0],0,1) eq '-' )
 {
-  if ($ARGV[0] eq "-recurse") {
-    $recurse = 1;
-  } elsif ($ARGV[0] =~ /-tag=.*/) {
+  if ($ARGV[0] =~ /-tag=.*/) {
     $tag = $ARGV[0];
     $tag =~ s#-tag=(.*)#$1#;
+  } elsif ($ARGV[0] =~ /-filedetails/) {
+    $filedetails = 1;
   } elsif ($ARGV[0] eq "-html") {
     $html = 1;
   } elsif ($ARGV[0] eq "-debug") {
     $debug = 1;
+  } elsif ($ARGV[0] eq "-topdir") {
+    shift; $srcroot = $ARGV[0]; shift;
   } else {
     die "Invalid option: $ARGV[0]";
   }
   shift;
 }
 
-die "Usage userloc.pl [-recurse|-tag=tag|-html] <directories>..." 
-  if ($#ARGV < 0);
-
+if (length($srcroot) == 0) {
+  chomp($srcroot = `llvm-config --src-root`);
+}
+if (! -d "$srcroot") {
+  die "Invalid source root: $srcroot\n";
+}
+chdir($srcroot);
+my $llvmdo = "$srcroot/utils/llvmdo -topdir '$srcroot'";
 my %Stats;
-my %StatsDetails;
+my %FileStats;
 
-sub ValidateFile
+my $annotate = "cvs -z6 annotate -lf ";
+if (length($tag) > 0)
 {
-  my $f = $_[0];
-  my $d = $_[1];
-
-  if ( $d =~ ".*autoconf.*")
-  {
-    return 1 if ($f eq "configure.ac");
-    return 1 if ($f eq "AutoRegen.sh");
-    return 0;
-  }
-  return 0 if ( "$f" eq "configure");
-  return 0 if ( "$f" eq 'PPCPerfectShuffle.h' );
-  return 0 if ( $f =~ /.*\.cvs/);
-  return 1;
+  $annotate = $annotate . " -r" . $tag;
 }
 
 sub GetCVSFiles
 {
   my $d = $_[0];
   my $files ="";
-  open STATUS, "cvs -nfz6 status $d -l 2>/dev/null |" 
-    || die "Can't 'cvs status'";
-  while ( defined($line = <STATUS>) )
-  {
-    if ( $line =~ /^File:.*/ )
-    {
-      chomp($line);
-      $line =~ s#^File: ([A-Za-z0-9._-]*)[ \t]*Status:.*#$1#;
-      $files = "$files $d/$line" if (ValidateFile($line,$d));
-    }
-
+  open FILELIST, 
+    "$llvmdo -dirs \"$d\" -code-only echo |" || die "Can't get list of files with llvmdo";
+  while ( defined($line = <FILELIST>) ) {
+    chomp($file = $line);
+    print "File: $file\n" if ($debug);
+    $files = "$files $file";
   }
   return $files;
 }
 
-my $annotate = "cvs -z6 annotate -lf ";
-if (length($tag) > 0)
-{
-  $annotate = $annotate . " -r" . $tag;
-}
-
 sub ScanDir
 {
   my $Dir = $_[0];
   my $files = GetCVSFiles($Dir);
 
-  open (DATA,"$annotate $files 2>/dev/null |")
+  open (DATA,"$annotate $files 2>&1 |")
     || die "Can't read cvs annotation data";
 
+  my $curfile = "";
   while ( defined($line = <DATA>) )
   {
-    if ($line =~ /^[0-9.]*[ \t]*\([^)]*\):/)
-    {
-      chomp($line);
-      $line =~ s#^[0-9.]*[ \t]*\(([a-zA-Z0-9_.-]*) [^)]*\):.*#$1#;
-      $Stats{$line}++;
+    chomp($line);
+    if ($line =~ '^Annotations for.*') {
+      $curfile = $line;
+      $curfile =~ s#^Annotations for ([[:print:]]*)#$1#;
+      print "Scanning: $curfile\n" if ($debug);
+    } elsif ($line =~ /^[0-9.]*[ \t]*\([^)]*\):/) {
+      $uname = $line;
+      $uname =~ s#^[0-9.]*[ \t]*\(([a-zA-Z0-9_.-]*) [^)]*\):.*#$1#;
+      $Stats{$uname}++;
+      if ($filedetails) {
+        $FileStats{$uname} = {} unless exists $FileStats{$uname};
+        ${$FileStats{$uname}}{$curfile}++;
+      }
     }
   }
-
   close DATA;
 }
 
-sub ValidateDirectory
-{
-  my $d = $_[0];
-  return 0 if (! -d "$d" || ! -d "$d/CVS");
-  return 0 if ($d =~ /.*CVS.*/);
-  return 0 if ($d =~ /.*Debug.*/);
-  return 0 if ($d =~ /.*Release.*/);
-  return 0 if ($d =~ /.*Profile.*/);
-  return 0 if ($d =~ /.*docs\/CommandGuide\/html.*/);
-  return 0 if ($d =~ /.*docs\/CommandGuide\/man.*/);
-  return 0 if ($d =~ /.*docs\/CommandGuide\/ps.*/);
-  return 0 if ($d =~ /.*docs\/CommandGuide\/man.*/);
-  return 0 if ($d =~ /.*docs\/HistoricalNotes.*/);
-  return 0 if ($d =~ /.*docs\/img.*/);
-  return 0 if ($d =~ /.*bzip2.*/);
-  return 1 if ($d =~ /.*projects\/Stacker.*/);
-  return 1 if ($d =~ /.*projects\/sample.*/);
-  return 0 if ($d =~ /.*projects\/llvm-.*/);
-  return 0 if ($d =~ /.*win32.*/);
-  return 0 if ($d =~ /.*\/.libs\/.*/);
-  return 1;
-}
-
-my $RowCount = 0;
 sub printStats
 {
   my $dir = $_[0];
@@ -143,58 +119,62 @@ sub printStats
   my $user;
   my $total = 0;
 
-  if ($RowCount % 10 == 0)
-  {
-    if ($html) {
-      print " <tr><th style=\"text-align:left\">Directory</th>\n";
-      foreach $user (sort keys %Stats)
-      {
-        print "<th style=\"text-align:right\">",$user,"</th>\n";
-      }
-      print "</tr>\n";
-    }
-  }
-
-  $RowCount++;
+  foreach $user (keys %Stats) { $total += $Stats{$user}; }
 
-  if ($html)
-    { print "<tr><td style=\"text-align:left\">",$dir,"</td>"; }
-  else
-    { print $dir,"\n"; }
-
-  foreach $user (keys %{$hash}) { $total += $hash->{$user}; }
+  if ($html) { 
+    print "<p>Total Source Lines: $total<br/></p>\n";
+    print "<table>";
+    print " <tr><th style=\"text-align:right\">LOC</th>\n";
+    print " <th style=\"text-align:right\">\%LOC</th>\n";
+    print " <th style=\"text-align:left\">User</th>\n";
+    print "</tr>\n";
+  }
 
   foreach $user ( sort keys %Stats )
   {
-    my $v = $hash->{$user};
+    my $v = $Stats{$user};
     if (defined($v))
     {
-      if ($html)
-      {
-        printf "<td style=\"text-align:right\">%d<br/>(%2.1f%%)</td>", $v,
-          (100.0/$total)*$v;
-      }
-      else
-      {
-        printf "%8d (%4.1f%%): %s\n", $v, (100.0/$total)*$v, $user;
+      if ($html) {
+        printf "<tr><td style=\"text-align:right\">%d</td><td style=\"text-align:right\">(%4.1f%%)</td><td style=\"text-align:left\">", $v, (100.0/$total)*$v;
+        if ($filedetails) {
+          print "<a href=\"#$user\">$user</a></td></tr>";
+        } else {
+          print $user,"</td></tr>";
+        }
+      } else {
+        printf "%8d  (%4.1f%%)  %s\n", $v, (100.0/$total)*$v, $user;
       }
     }
-    elsif ($html)
-    {
-      print "<td style=\"text-align:right\">-&nbsp;</td>";
+  }
+  print "</table>\n" if ($html);
+
+  if ($filedetails) {
+    foreach $user (sort keys %FileStats) {
+      my $total = 0;
+      foreach $file (sort keys %{$FileStats{$user}}) { 
+        $total += ${$FileStats{$user}}{$file}
+      }
+      if ($html) {
+        print "<table><tr><th style=\"text-align:left\" colspan=\"3\"><a name=\"$user\">$user</a></th></tr>\n";
+      } else {
+        print $user,":\n";
+      }
+      foreach $file (sort keys %{$FileStats{$user}}) {
+        my $v = ${$FileStats{$user}}{$file};
+        if ($html) { 
+          printf "<tr><td style=\"text-align:right\">&nbsp;&nbsp;%d</td><td
+          style=\"text-align:right\">&nbsp;%4.1f%%</td><td
+          style=\"text-align:left\">%s</td></tr>",$v, (100.0/$total)*$v,$file;
+        } else {
+          printf "%8d  (%4.1f%%)  %s\n", $v, (100.0/$total)*$v, $file;
+        }
+      }
+      if ($html) { print "</table>\n"; }
     }
   }
-  print "</tr>\n" if ($html);
 }
 
-my @ALLDIRS = @ARGV;
-
-if ($recurse)
-{
-  $Dirs = join(" ", @ARGV);
-  $Dirs = `find $Dirs -type d \! -name CVS -print`;
-  @ALLDIRS = split(' ',$Dirs);
-}
 
 if ($html)
 {
@@ -209,37 +189,28 @@ print "LLVM directory. Lines of code are attributed by the user that last\n";
 print "committed the line. This does not necessarily reflect authorship.</p>\n";
 }
 
-my @ignored_dirs;
-
-for $Dir (@ALLDIRS) 
-{ 
-  if ( ValidateDirectory($Dir) )
-  {
-    ScanDir($Dir); 
-  }
-  elsif ($html)
-  {
-    push @ignored_dirs, $Dir;
-  }
+my @DIRS;
+if ($#ARGV > 0) {
+  @DIRS = @ARGV;
+} else {
+  push @DIRS, 'include';
+  push @DIRS, 'lib';
+  push @DIRS, 'tools';
+  push @DIRS, 'runtime';
+  push @DIRS, 'docs';
+  push @DIRS, 'test';
+  push @DIRS, 'utils';
+  push @DIRS, 'examples';
+  push @DIRS, 'projects/Stacker';
+  push @DIRS, 'projects/sample';
+  push @DIRS, 'autoconf';
 }
-
-if ($html)
-{
-  print "<table>\n";
+  
+for $Index ( 0 .. $#DIRS) { 
+  print "Scanning Dir: $DIRS[$Index]\n" if ($debug);
+  ScanDir($DIRS[$Index]); 
 }
 
-printStats("Total",\%Stats);
+printStats;
 
-if ($html) 
-{
-  print "</table>";
-  if (scalar @ignored_dirs > 0) {
-    print "<p>The following directories were skipped:</p>\n";
-    print "<ol>\n";
-    foreach $index (0 .. $#ignored_dirs) {
-      print " <li>", $ignored_dirs[$index], "</li>\n";
-    }
-    print "</ol>\n";
-  }
-  print "</body></html>\n";
-}
+print "</body></html>\n" if ($html) ;