forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Check in the llvm-native-gcc script, which I use in the process of
debugging front-end miscompilations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10347 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Brian Gaeke
committed
Dec 9, 2003
1 parent
d0069a0
commit 73d8d55
Showing
1 changed file
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
#!/usr/bin/perl | ||
# Wrapper around LLVM tools to generate a native .o from llvm-gcc using an | ||
# LLVM back-end (CBE by default). | ||
|
||
# set up defaults. | ||
$Verbose = 0; | ||
$SaveTemps = 0; | ||
$PreprocessOnly = 0; | ||
$CompileDontLink = 0; | ||
$Backend = 'cbe'; | ||
chomp ($ProgramName = `basename $0`); | ||
|
||
sub boldprint { | ||
print "[1m", @_, "[0m"; | ||
} | ||
|
||
# process command-line options. | ||
# most of these are passed on to llvm-gcc. | ||
$GCCOptions = ""; | ||
for ($i = 0; $i <= $#ARGV; ++$i) { | ||
if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) { | ||
$Backend = $1; | ||
if ($ProgramName =~ /llvm-native-gcc/) { | ||
splice (@ARGV, $i, 1); | ||
--$i; | ||
} | ||
} elsif ($ARGV[$i] eq "-E") { | ||
$PreprocessOnly = 1; | ||
} elsif ($ARGV[$i] eq "-c") { | ||
$GCCOptions .= " " . $ARGV[$i]; | ||
$CompileDontLink = 1; | ||
} elsif ($ARGV[$i] eq "-v") { | ||
$GCCOptions .= " " . $ARGV[$i]; | ||
$Verbose = 1; | ||
} elsif ($ARGV[$i] eq "-o") { | ||
$OutputFile = $ARGV[$i + 1]; | ||
} elsif ($ARGV[$i] eq "-save-temps") { | ||
$GCCOptions .= " " . $ARGV[$i]; | ||
$SaveTemps = 1; | ||
} elsif ($ARGV[$i] =~ /\.bc$/) { | ||
push (@BytecodeFiles, $ARGV[$i]); | ||
} elsif ($ARGV[$i] =~ /^-L/) { | ||
$GCCOptions .= " " . $ARGV[$i]; | ||
push (@LibDirs, $ARGV[$i]); | ||
} elsif ($ARGV[$i] =~ /^-l/) { | ||
$GCCOptions .= " " . $ARGV[$i]; | ||
push (@Libs, $ARGV[$i]); | ||
} elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) { | ||
$LastCFile = $ARGV[$i]; | ||
} | ||
} | ||
|
||
sub GetDefaultOutputFileName { | ||
my $DefaultOutputFileBase; | ||
|
||
if ($ProgramName =~ /llvm-native-gcc/) { | ||
$DefaultOutputFileBase = $LastCFile; | ||
} elsif ($ProgramName =~ /native-build/) { | ||
$DefaultOutputFileBase = $BytecodeFiles[0]; | ||
} | ||
|
||
my $def = $DefaultOutputFileBase; | ||
|
||
die "Can't figure out name of output file.\n" | ||
unless $DefaultOutputFileBase | ||
&& (($ProgramName !~ /native-build/) | ||
|| $#BytecodeFiles == 0); | ||
|
||
print "Warning: defaulting output file name ", | ||
"based on '$DefaultOutputFileBase'\n" if $Verbose; | ||
|
||
if ($ProgramName =~ /llvm-native-gcc/) { | ||
$def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/; | ||
} elsif ($ProgramName =~ /native-build/) { | ||
$def =~ s/\.bc$/.$Backend/; | ||
if ($CompileDontLink) { | ||
$def .= ".o"; | ||
} | ||
} | ||
|
||
return $def; | ||
} | ||
|
||
# run a command, optionally echoing, and quitting if it fails: | ||
sub run { | ||
my $command = join(" ", @_); | ||
print "$command\n" if $Verbose; | ||
$command =~ s/\"/\\\"/g; | ||
system $command and die "$0: $command failed"; | ||
} | ||
|
||
sub LinkBytecodeFilesIntoTemporary { | ||
my $FinalOutputFileName = shift @_; | ||
my @BytecodeFiles = @_; | ||
|
||
my $BCFiles = join (" ", @BytecodeFiles); | ||
my $LinkedBCFile; | ||
if ($SaveTemps) { | ||
$LinkedBCFile = "${FinalOutputFileName}.llvm.bc"; | ||
} else { | ||
$LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc"; | ||
} | ||
run "llvm-link -o $LinkedBCFile $BCFiles"; | ||
return $LinkedBCFile; | ||
} | ||
|
||
sub CompileBytecodeToNative { | ||
my ($BCFile, $Backend, $OutputFile) = @_; | ||
|
||
my $GeneratedCode; | ||
if ($Backend eq 'cbe') { | ||
if ($SaveTemps) { | ||
$GeneratedCode = "${OutputFile}.c"; | ||
} else { | ||
$GeneratedCode = "/tmp/nativebuild-$$.c"; | ||
} | ||
run "llvm-dis -c -f -o $GeneratedCode $BCFile"; | ||
} elsif ($Backend eq 'llc') { | ||
if ($SaveTemps) { | ||
$GeneratedCode = "${OutputFile}.s"; | ||
} else { | ||
$GeneratedCode = "/tmp/nativebuild-$$.s"; | ||
} | ||
run "llc -f -o $GeneratedCode $BCFile"; | ||
} | ||
my $LibDirs = join (" ", @LibDirs); | ||
my $Libs = join (" ", @Libs); | ||
run "gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs"; | ||
run "rm $BCFile $GeneratedCode" | ||
unless $SaveTemps; | ||
} | ||
|
||
sub CompileCToNative { | ||
my ($LLVMGCCCommand, $Backend, $OutputFile) = @_; | ||
run $LLVMGCCCommand; | ||
if ($PreprocessOnly) { | ||
return; | ||
} | ||
my $BCFile = "${OutputFile}.llvm.bc"; | ||
if ($CompileDontLink) { | ||
run "mv ${OutputFile} $BCFile"; | ||
} else { # gccld messes with the output file name | ||
run "mv ${OutputFile}.bc $BCFile"; | ||
} | ||
my $GeneratedCode; | ||
if ($Backend eq 'cbe') { | ||
$GeneratedCode = "${OutputFile}.cbe.c"; | ||
run "llvm-dis -c -f -o $GeneratedCode $BCFile"; | ||
} elsif ($Backend eq 'llc') { | ||
$GeneratedCode = "${OutputFile}.llc.s"; | ||
run "llc -f -o $GeneratedCode $BCFile"; | ||
} | ||
my $NativeGCCOptions = ""; | ||
if ($CompileDontLink) { | ||
$NativeGCCOptions = "-c"; | ||
} | ||
run "gcc $NativeGCCOptions $GeneratedCode -o $OutputFile"; | ||
run "rm ${OutputFile}.llvm.bc $GeneratedCode" | ||
unless $SaveTemps; | ||
} | ||
|
||
# guess the name of the output file, if -o was not specified. | ||
$OutputFile = GetDefaultOutputFileName () unless $OutputFile; | ||
print "Output file is $OutputFile\n" if $Verbose; | ||
# do all the dirty work: | ||
if ($ProgramName eq /native-build/) { | ||
my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles); | ||
CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile); | ||
} elsif ($ProgramName =~ /llvm-native-gcc/) { | ||
# build the llvm-gcc command line. | ||
$LLVMGCCCommand = join (" ", ("llvm-gcc", @ARGV)); | ||
CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile); | ||
} | ||
|
||
# we're done. | ||
exit 0; | ||
|
||
__END__ | ||
=pod | ||
=head1 NAME | ||
llvm-native-gcc | ||
=head1 SYNOPSIS | ||
llvm-native-gcc [OPTIONS...] FILE | ||
native-build [OPTIONS...] FILE | ||
=head1 DESCRIPTION | ||
llvm-native-gcc is a wrapper around the LLVM command-line tools which generates | ||
a native object (.o) file by compiling FILE with llvm-gcc, and then running | ||
an LLVM back-end (CBE by default) over the resulting bytecode, and then | ||
compiling the resulting code to a native object file. | ||
If called as "native-build", it compiles bytecode to native code, and takes | ||
different options. | ||
=head1 OPTIONS | ||
llvm-native-gcc takes the same options as llvm-gcc. All options | ||
except -mllvm-backend=... are passed on to llvm-gcc. | ||
=over 4 | ||
=item -mllvm-backend=BACKEND | ||
Use BACKEND for native code generation. | ||
=item -v | ||
Print command lines that llvm-native-gcc runs. | ||
=item -o FILE | ||
llvm-native-gcc tries to guess the name of the llvm-gcc output file by looking | ||
for this option in the command line. If it can't find it, it finds the last C | ||
or C++ source file named on the command line, and turns its suffix into .o. See | ||
BUGS. | ||
=item -save-temps | ||
Save temporary files used by llvm-native-gcc (and llvm-gcc, and gcc). | ||
=back | ||
=head1 BUGS | ||
llvm-native-gcc only handles the case where llvm-gcc compiles a single | ||
file per invocation. llvm-native-gcc has weak command-line argument | ||
parsing and is a poor substitute for making gcc/gcc.c do this stuff. | ||
This manual page does not adequately document native-build mode. | ||
llvm-native-gcc is pretty gross because it represents the blind merging of two | ||
other scripts that predated it. It could use some code clean-up. | ||
=head1 SEE ALSO | ||
gcc(1) | ||
=head1 AUTHOR | ||
Brian R. Gaeke | ||
=cut |