blob: db547f654e2ff98ebdc43fecc91e9b36beb728a2 [file] [log] [blame]
John Criswell28ccd022004-02-26 23:01:21 +00001#!/usr/bin/perl
2# Wrapper around LLVM tools to generate a native .o from llvm-gxx using an
3# LLVM back-end (CBE by default).
4
5# set up defaults.
6$Verbose = 0;
7$SaveTemps = 1;
8$PreprocessOnly = 0;
9$CompileDontLink = 0;
10$Backend = 'cbe';
11chomp ($ProgramName = `basename $0`);
12
13sub boldprint {
14 print "", @_, "";
15}
16
17# process command-line options.
18# most of these are passed on to llvm-gxx.
19$GCCOptions = "";
20for ($i = 0; $i <= $#ARGV; ++$i) {
21 if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) {
22 $Backend = $1;
23 if ($ProgramName =~ /llvm-native-gxx/) {
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
53sub GetDefaultOutputFileName {
54 my $DefaultOutputFileBase;
55
56 if ($ProgramName =~ /llvm-native-gxx/) {
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-gxx/) {
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:
85sub 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
92sub 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
107sub 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 }
117 run "llc -march=c -f -o $GeneratedCode $BCFile";
118 } elsif ($Backend eq 'llc') {
119 if ($SaveTemps) {
120 $GeneratedCode = "${OutputFile}.s";
121 } else {
122 $GeneratedCode = "/tmp/nativebuild-$$.s";
123 }
124 run "llc -f -o $GeneratedCode $BCFile";
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
133sub 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";
148 run "llc -march=c -f -o $GeneratedCode $BCFile";
149 } elsif ($Backend eq 'llc') {
150 $GeneratedCode = "${OutputFile}.llc.s";
151 run "llc -f -o $GeneratedCode $BCFile";
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;
164print "Output file is $OutputFile\n" if $Verbose;
165# do all the dirty work:
166if ($ProgramName eq /native-build/) {
167 my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles);
168 CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile);
169} elsif ($ProgramName =~ /llvm-native-gxx/) {
170 # build the llvm-gxx command line.
171 $LLVMGCCCommand = join (" ", ("llvm-g++", @ARGV));
172 CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile);
173}
174
175# we're done.
176exit 0;
177
178__END__
179
180=pod
181
182=head1 NAME
183
184llvm-native-gxx
185
186=head1 SYNOPSIS
187
188llvm-native-g++ [OPTIONS...] FILE
189
190native-build [OPTIONS...] FILE
191
192=head1 DESCRIPTION
193
194llvm-native-g++ is a wrapper around the LLVM command-line tools which generates
195a native object (.o) file by compiling FILE with llvm-g++, and then running
Duncan Sands18d52f22010-09-29 20:09:55 +0000196an LLVM back-end (CBE by default) over the resulting bitcode, and then
John Criswell28ccd022004-02-26 23:01:21 +0000197compiling the resulting code to a native object file.
198
Duncan Sands18d52f22010-09-29 20:09:55 +0000199If called as "native-build", it compiles bitcode to native code, and takes
John Criswell28ccd022004-02-26 23:01:21 +0000200different options.
201
202=head1 OPTIONS
203
204llvm-native-g++ takes the same options as llvm-gcc. All options
205except -mllvm-backend=... are passed on to llvm-g++.
206
207=over 4
208
209=item -mllvm-backend=BACKEND
210
211Use BACKEND for native code generation.
212
213=item -v
214
215Print command lines that llvm-native-g++ runs.
216
217=item -o FILE
218
219llvm-native-g++ tries to guess the name of the llvm-g++ output file by looking
220for this option in the command line. If it can't find it, it finds the last C
221or C++ source file named on the command line, and turns its suffix into .o. See
222BUGS.
223
224=item -save-temps
225
226Save temporary files used by llvm-native-g++ (and llvm-g++, and g++).
227
228=back
229
230=head1 BUGS
231
232llvm-native-g++ only handles the case where llvm-g++ compiles a single
233file per invocation. llvm-native-g++ has weak command-line argument
234parsing and is a poor substitute for making g++/g++.c do this stuff.
235
236This manual page does not adequately document native-build mode.
237
238llvm-native-g++ is pretty gross because it represents the blind merging of two
239other scripts that predated it. It could use some code clean-up.
240
241=head1 SEE ALSO
242
243g++(1)
244
245=head1 AUTHOR
246
247Brian R. Gaeke
248
249=cut