| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 1 | #!/usr/bin/perl | 
|  | 2 | # Wrapper around LLVM tools to generate a native .o from llvm-gcc using an | 
|  | 3 | # LLVM back-end (CBE by default). | 
|  | 4 |  | 
|  | 5 | # set up defaults. | 
|  | 6 | $Verbose = 0; | 
| John Criswell | 626f47f | 2004-03-02 15:54:25 +0000 | [diff] [blame] | 7 | $SaveTemps = 1; | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 8 | $PreprocessOnly = 0; | 
|  | 9 | $CompileDontLink = 0; | 
|  | 10 | $Backend = 'cbe'; | 
|  | 11 | chomp ($ProgramName = `basename $0`); | 
|  | 12 |  | 
|  | 13 | sub boldprint { | 
|  | 14 | print "[1m", @_, "[0m"; | 
|  | 15 | } | 
|  | 16 |  | 
|  | 17 | # process command-line options. | 
|  | 18 | # most of these are passed on to llvm-gcc. | 
|  | 19 | $GCCOptions = ""; | 
|  | 20 | for ($i = 0; $i <= $#ARGV; ++$i) { | 
|  | 21 | if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) { | 
|  | 22 | $Backend = $1; | 
|  | 23 | if ($ProgramName =~ /llvm-native-gcc/) { | 
|  | 24 | splice (@ARGV, $i, 1); | 
|  | 25 | --$i; | 
|  | 26 | } | 
|  | 27 | } elsif ($ARGV[$i] eq "-E") { | 
|  | 28 | $PreprocessOnly = 1; | 
|  | 29 | } elsif ($ARGV[$i] eq "-c") { | 
|  | 30 | $GCCOptions .= " " . $ARGV[$i]; | 
|  | 31 | $CompileDontLink = 1; | 
|  | 32 | } elsif ($ARGV[$i] eq "-v") { | 
|  | 33 | $GCCOptions .= " " . $ARGV[$i]; | 
|  | 34 | $Verbose = 1; | 
|  | 35 | } elsif ($ARGV[$i] eq "-o") { | 
|  | 36 | $OutputFile = $ARGV[$i + 1]; | 
|  | 37 | } elsif ($ARGV[$i] eq "-save-temps") { | 
|  | 38 | $GCCOptions .= " " . $ARGV[$i]; | 
|  | 39 | $SaveTemps = 1; | 
|  | 40 | } elsif ($ARGV[$i] =~ /\.bc$/) { | 
|  | 41 | push (@BytecodeFiles, $ARGV[$i]); | 
|  | 42 | } elsif ($ARGV[$i] =~ /^-L/) { | 
|  | 43 | $GCCOptions .= " " . $ARGV[$i]; | 
|  | 44 | push (@LibDirs, $ARGV[$i]); | 
|  | 45 | } elsif ($ARGV[$i] =~ /^-l/) { | 
|  | 46 | $GCCOptions .= " " . $ARGV[$i]; | 
|  | 47 | push (@Libs, $ARGV[$i]); | 
|  | 48 | } elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) { | 
|  | 49 | $LastCFile = $ARGV[$i]; | 
|  | 50 | } | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | sub GetDefaultOutputFileName { | 
|  | 54 | my $DefaultOutputFileBase; | 
|  | 55 |  | 
|  | 56 | if ($ProgramName =~ /llvm-native-gcc/) { | 
|  | 57 | $DefaultOutputFileBase = $LastCFile; | 
|  | 58 | } elsif ($ProgramName =~ /native-build/) { | 
|  | 59 | $DefaultOutputFileBase = $BytecodeFiles[0]; | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | my $def = $DefaultOutputFileBase; | 
|  | 63 |  | 
|  | 64 | die "Can't figure out name of output file.\n" | 
|  | 65 | unless $DefaultOutputFileBase | 
|  | 66 | && (($ProgramName !~ /native-build/) | 
|  | 67 | || $#BytecodeFiles == 0); | 
|  | 68 |  | 
|  | 69 | print "Warning: defaulting output file name ", | 
|  | 70 | "based on '$DefaultOutputFileBase'\n" if $Verbose; | 
|  | 71 |  | 
|  | 72 | if ($ProgramName =~ /llvm-native-gcc/) { | 
|  | 73 | $def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/; | 
|  | 74 | } elsif ($ProgramName =~ /native-build/) { | 
|  | 75 | $def =~ s/\.bc$/.$Backend/; | 
|  | 76 | if ($CompileDontLink) { | 
|  | 77 | $def .= ".o"; | 
|  | 78 | } | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | return $def; | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | # run a command, optionally echoing, and quitting if it fails: | 
|  | 85 | sub run { | 
|  | 86 | my $command = join(" ", @_); | 
|  | 87 | print "$command\n" if $Verbose; | 
|  | 88 | $command =~ s/\"/\\\"/g; | 
|  | 89 | system $command and die "$0: $command failed"; | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | sub LinkBytecodeFilesIntoTemporary { | 
|  | 93 | my $FinalOutputFileName = shift @_; | 
|  | 94 | my @BytecodeFiles = @_; | 
|  | 95 |  | 
|  | 96 | my $BCFiles = join (" ", @BytecodeFiles); | 
|  | 97 | my $LinkedBCFile; | 
|  | 98 | if ($SaveTemps) { | 
|  | 99 | $LinkedBCFile = "${FinalOutputFileName}.llvm.bc"; | 
|  | 100 | } else { | 
|  | 101 | $LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc"; | 
|  | 102 | } | 
|  | 103 | run "llvm-link -o $LinkedBCFile $BCFiles"; | 
|  | 104 | return $LinkedBCFile; | 
|  | 105 | } | 
|  | 106 |  | 
|  | 107 | sub CompileBytecodeToNative { | 
|  | 108 | my ($BCFile, $Backend, $OutputFile) = @_; | 
|  | 109 |  | 
|  | 110 | my $GeneratedCode; | 
|  | 111 | if ($Backend eq 'cbe') { | 
|  | 112 | if ($SaveTemps) { | 
|  | 113 | $GeneratedCode = "${OutputFile}.c"; | 
|  | 114 | } else { | 
|  | 115 | $GeneratedCode = "/tmp/nativebuild-$$.c"; | 
|  | 116 | } | 
| John Criswell | 626f47f | 2004-03-02 15:54:25 +0000 | [diff] [blame] | 117 | run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile"; | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 118 | } elsif ($Backend eq 'llc') { | 
|  | 119 | if ($SaveTemps) { | 
|  | 120 | $GeneratedCode = "${OutputFile}.s"; | 
|  | 121 | } else { | 
|  | 122 | $GeneratedCode = "/tmp/nativebuild-$$.s"; | 
|  | 123 | } | 
| John Criswell | 626f47f | 2004-03-02 15:54:25 +0000 | [diff] [blame] | 124 | run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile"; | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 125 | } | 
|  | 126 | my $LibDirs = join (" ", @LibDirs); | 
|  | 127 | my $Libs = join (" ", @Libs); | 
|  | 128 | run "gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs"; | 
|  | 129 | run "rm $BCFile $GeneratedCode" | 
|  | 130 | unless $SaveTemps; | 
|  | 131 | } | 
|  | 132 |  | 
|  | 133 | sub CompileCToNative { | 
|  | 134 | my ($LLVMGCCCommand, $Backend, $OutputFile) = @_; | 
|  | 135 | run $LLVMGCCCommand; | 
|  | 136 | if ($PreprocessOnly) { | 
|  | 137 | return; | 
|  | 138 | } | 
|  | 139 | my $BCFile = "${OutputFile}.llvm.bc"; | 
|  | 140 | if ($CompileDontLink) { | 
|  | 141 | run "mv ${OutputFile} $BCFile"; | 
|  | 142 | } else { # gccld messes with the output file name | 
|  | 143 | run "mv ${OutputFile}.bc $BCFile"; | 
|  | 144 | } | 
|  | 145 | my $GeneratedCode; | 
|  | 146 | if ($Backend eq 'cbe') { | 
|  | 147 | $GeneratedCode = "${OutputFile}.cbe.c"; | 
| John Criswell | 626f47f | 2004-03-02 15:54:25 +0000 | [diff] [blame] | 148 | run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile"; | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 149 | } elsif ($Backend eq 'llc') { | 
|  | 150 | $GeneratedCode = "${OutputFile}.llc.s"; | 
| John Criswell | 626f47f | 2004-03-02 15:54:25 +0000 | [diff] [blame] | 151 | run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile"; | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 152 | } | 
|  | 153 | my $NativeGCCOptions = ""; | 
|  | 154 | if ($CompileDontLink) { | 
|  | 155 | $NativeGCCOptions = "-c"; | 
|  | 156 | } | 
|  | 157 | run "gcc $NativeGCCOptions $GeneratedCode -o $OutputFile"; | 
|  | 158 | run "rm ${OutputFile}.llvm.bc $GeneratedCode" | 
|  | 159 | unless $SaveTemps; | 
|  | 160 | } | 
|  | 161 |  | 
|  | 162 | # guess the name of the output file, if -o was not specified. | 
|  | 163 | $OutputFile = GetDefaultOutputFileName () unless $OutputFile; | 
|  | 164 | print "Output file is $OutputFile\n" if $Verbose; | 
|  | 165 | # do all the dirty work: | 
|  | 166 | if ($ProgramName eq /native-build/) { | 
|  | 167 | my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles); | 
|  | 168 | CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile); | 
|  | 169 | } elsif ($ProgramName =~ /llvm-native-gcc/) { | 
|  | 170 | # build the llvm-gcc command line. | 
|  | 171 | $LLVMGCCCommand = join (" ", ("llvm-gcc", @ARGV)); | 
|  | 172 | CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile); | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | # we're done. | 
|  | 176 | exit 0; | 
|  | 177 |  | 
|  | 178 | __END__ | 
|  | 179 |  | 
|  | 180 | =pod | 
|  | 181 |  | 
|  | 182 | =head1 NAME | 
|  | 183 |  | 
|  | 184 | llvm-native-gcc | 
|  | 185 |  | 
|  | 186 | =head1 SYNOPSIS | 
|  | 187 |  | 
|  | 188 | llvm-native-gcc [OPTIONS...] FILE | 
|  | 189 |  | 
|  | 190 | native-build [OPTIONS...] FILE | 
|  | 191 |  | 
|  | 192 | =head1 DESCRIPTION | 
|  | 193 |  | 
|  | 194 | llvm-native-gcc is a wrapper around the LLVM command-line tools which generates | 
|  | 195 | a native object (.o) file by compiling FILE with llvm-gcc, and then running | 
| Duncan Sands | e9da6db | 2010-09-29 20:09:55 +0000 | [diff] [blame] | 196 | an LLVM back-end (CBE by default) over the resulting bitcode, and then | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 197 | compiling the resulting code to a native object file. | 
|  | 198 |  | 
| Duncan Sands | e9da6db | 2010-09-29 20:09:55 +0000 | [diff] [blame] | 199 | If called as "native-build", it compiles bitcode to native code, and takes | 
| Brian Gaeke | ddc088a | 2003-12-09 22:23:24 +0000 | [diff] [blame] | 200 | different options. | 
|  | 201 |  | 
|  | 202 | =head1 OPTIONS | 
|  | 203 |  | 
|  | 204 | llvm-native-gcc takes the same options as llvm-gcc. All options | 
|  | 205 | except -mllvm-backend=... are passed on to llvm-gcc. | 
|  | 206 |  | 
|  | 207 | =over 4 | 
|  | 208 |  | 
|  | 209 | =item -mllvm-backend=BACKEND | 
|  | 210 |  | 
|  | 211 | Use BACKEND for native code generation. | 
|  | 212 |  | 
|  | 213 | =item -v | 
|  | 214 |  | 
|  | 215 | Print command lines that llvm-native-gcc runs. | 
|  | 216 |  | 
|  | 217 | =item -o FILE | 
|  | 218 |  | 
|  | 219 | llvm-native-gcc tries to guess the name of the llvm-gcc output file by looking | 
|  | 220 | for this option in the command line. If it can't find it, it finds the last C | 
|  | 221 | or C++ source file named on the command line, and turns its suffix into .o. See | 
|  | 222 | BUGS. | 
|  | 223 |  | 
|  | 224 | =item -save-temps | 
|  | 225 |  | 
|  | 226 | Save temporary files used by llvm-native-gcc (and llvm-gcc, and gcc). | 
|  | 227 |  | 
|  | 228 | =back | 
|  | 229 |  | 
|  | 230 | =head1 BUGS | 
|  | 231 |  | 
|  | 232 | llvm-native-gcc only handles the case where llvm-gcc compiles a single | 
|  | 233 | file per invocation.  llvm-native-gcc has weak command-line argument | 
|  | 234 | parsing and is a poor substitute for making gcc/gcc.c do this stuff. | 
|  | 235 |  | 
|  | 236 | This manual page does not adequately document native-build mode. | 
|  | 237 |  | 
|  | 238 | llvm-native-gcc is pretty gross because it represents the blind merging of two | 
|  | 239 | other scripts that predated it. It could use some code clean-up. | 
|  | 240 |  | 
|  | 241 | =head1 SEE ALSO | 
|  | 242 |  | 
|  | 243 | gcc(1) | 
|  | 244 |  | 
|  | 245 | =head1 AUTHOR | 
|  | 246 |  | 
|  | 247 | Brian R. Gaeke | 
|  | 248 |  | 
|  | 249 | =cut |