blob: 46dbd89fc95cb00f2c9c51af90d15ba53f51a475 [file] [log] [blame]
Reid Spencera3f18552004-08-13 20:25:54 +00001//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
Reid Spencer5c56dc12004-08-13 20:22:43 +00002//
Misha Brukman3da94ae2005-04-22 00:00:37 +00003//
Reid Spencer5c56dc12004-08-13 20:22:43 +00004// The LLVM Compiler Infrastructure
5//
Misha Brukman3da94ae2005-04-22 00:00:37 +00006// This file was developed by Reid Spencer and is distributed under the
Reid Spencer5c56dc12004-08-13 20:22:43 +00007// University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukman3da94ae2005-04-22 00:00:37 +00008//
Reid Spencer5c56dc12004-08-13 20:22:43 +00009//===----------------------------------------------------------------------===//
10//
Reid Spencera3f18552004-08-13 20:25:54 +000011// This file implements the bulk of the LLVM Compiler Driver (llvmc).
Reid Spencer5c56dc12004-08-13 20:22:43 +000012//
Chris Lattner74f48d12006-05-29 18:52:05 +000013//===----------------------------------------------------------------------===//
Reid Spencer5c56dc12004-08-13 20:22:43 +000014
15#include "CompilerDriver.h"
Reid Spencerbf437722004-08-15 08:19:46 +000016#include "ConfigLexer.h"
Reid Spencera01439a2004-08-24 13:55:17 +000017#include "llvm/Module.h"
Reid Spencer52c2dc12004-08-29 19:26:56 +000018#include "llvm/Bytecode/Reader.h"
Reid Spencer54fafe42004-09-14 01:58:45 +000019#include "llvm/Support/Timer.h"
Reid Spencer93426ba2004-08-29 20:02:28 +000020#include "llvm/System/Signals.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000021#include "llvm/ADT/SetVector.h"
22#include "llvm/ADT/StringExtras.h"
Brian Gaekefabf41f2004-12-20 04:02:01 +000023#include "llvm/Config/alloca.h"
Misha Brukmanbaec07c2005-04-20 04:51:29 +000024#include <iostream>
Reid Spencer5c56dc12004-08-13 20:22:43 +000025using namespace llvm;
26
27namespace {
Reid Spencer5c56dc12004-08-13 20:22:43 +000028
Reid Spenceraf77d742004-10-28 04:05:06 +000029void WriteAction(CompilerDriver::Action* action ) {
30 std::cerr << action->program.c_str();
Reid Spencerf6358c72004-12-19 18:00:56 +000031 std::vector<std::string>::const_iterator I = action->args.begin();
Reid Spenceraf77d742004-10-28 04:05:06 +000032 while (I != action->args.end()) {
Misha Brukman0b861482005-05-03 20:30:34 +000033 std::cerr << ' ' << *I;
Reid Spenceraf77d742004-10-28 04:05:06 +000034 ++I;
35 }
Misha Brukman0b861482005-05-03 20:30:34 +000036 std::cerr << '\n';
Reid Spenceraf77d742004-10-28 04:05:06 +000037}
38
39void DumpAction(CompilerDriver::Action* action) {
40 std::cerr << "command = " << action->program.c_str();
Reid Spencerf6358c72004-12-19 18:00:56 +000041 std::vector<std::string>::const_iterator I = action->args.begin();
Reid Spenceraf77d742004-10-28 04:05:06 +000042 while (I != action->args.end()) {
Misha Brukman0b861482005-05-03 20:30:34 +000043 std::cerr << ' ' << *I;
Reid Spenceraf77d742004-10-28 04:05:06 +000044 ++I;
45 }
Misha Brukman0b861482005-05-03 20:30:34 +000046 std::cerr << '\n';
47 std::cerr << "flags = " << action->flags << '\n';
Reid Spenceraf77d742004-10-28 04:05:06 +000048}
49
50void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
Misha Brukman3da94ae2005-04-22 00:00:37 +000051 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
Reid Spenceraf77d742004-10-28 04:05:06 +000052 << ")\n";
53 std::cerr << "PreProcessor: ";
54 DumpAction(&cd->PreProcessor);
55 std::cerr << "Translator: ";
56 DumpAction(&cd->Translator);
57 std::cerr << "Optimizer: ";
58 DumpAction(&cd->Optimizer);
59 std::cerr << "Assembler: ";
60 DumpAction(&cd->Assembler);
61 std::cerr << "Linker: ";
62 DumpAction(&cd->Linker);
63}
64
65/// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
66/// which should reduce the volume of code and make compilation
Misha Brukman3da94ae2005-04-22 00:00:37 +000067/// faster. This is also safe on any llvm module.
Reid Spenceraf77d742004-10-28 04:05:06 +000068static const char* DefaultFastCompileOptimizations[] = {
69 "-simplifycfg", "-mem2reg", "-instcombine"
70};
71
72class CompilerDriverImpl : public CompilerDriver {
73/// @name Constructors
74/// @{
75public:
76 CompilerDriverImpl(ConfigDataProvider& confDatProv )
77 : cdp(&confDatProv)
78 , finalPhase(LINKING)
Misha Brukman3da94ae2005-04-22 00:00:37 +000079 , optLevel(OPT_FAST_COMPILE)
Reid Spenceraf77d742004-10-28 04:05:06 +000080 , Flags(0)
81 , machine()
82 , LibraryPaths()
83 , TempDir()
84 , AdditionalArgs()
85 {
Reid Spenceraf77d742004-10-28 04:05:06 +000086 AdditionalArgs.reserve(NUM_PHASES);
87 StringVector emptyVec;
88 for (unsigned i = 0; i < NUM_PHASES; ++i)
89 AdditionalArgs.push_back(emptyVec);
90 }
91
92 virtual ~CompilerDriverImpl() {
93 cleanup();
94 cdp = 0;
95 LibraryPaths.clear();
96 IncludePaths.clear();
97 Defines.clear();
98 TempDir.clear();
99 AdditionalArgs.clear();
100 fOptions.clear();
101 MOptions.clear();
102 WOptions.clear();
103 }
104
105/// @}
106/// @name Methods
107/// @{
108public:
Misha Brukman0b861482005-05-03 20:30:34 +0000109 virtual void setFinalPhase(Phases phase) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000110 finalPhase = phase;
Reid Spenceraf77d742004-10-28 04:05:06 +0000111 }
112
Misha Brukman0b861482005-05-03 20:30:34 +0000113 virtual void setOptimization(OptimizationLevels level) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000114 optLevel = level;
Reid Spenceraf77d742004-10-28 04:05:06 +0000115 }
116
Misha Brukman0b861482005-05-03 20:30:34 +0000117 virtual void setDriverFlags(unsigned flags) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000118 Flags = flags & DRIVER_FLAGS_MASK;
Reid Spenceraf77d742004-10-28 04:05:06 +0000119 }
120
Misha Brukman0b861482005-05-03 20:30:34 +0000121 virtual void setOutputMachine(const std::string& machineName) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000122 machine = machineName;
123 }
124
125 virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
126 assert(phase <= LINKING && phase >= PREPROCESSING);
127 AdditionalArgs[phase] = opts;
128 }
129
130 virtual void setIncludePaths(const StringVector& paths) {
131 StringVector::const_iterator I = paths.begin();
132 StringVector::const_iterator E = paths.end();
133 while (I != E) {
134 sys::Path tmp;
Reid Spencerdd04df02005-07-07 23:21:43 +0000135 tmp.set(*I);
Reid Spenceraf77d742004-10-28 04:05:06 +0000136 IncludePaths.push_back(tmp);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000137 ++I;
138 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000139 }
140
Reid Spenceraf77d742004-10-28 04:05:06 +0000141 virtual void setSymbolDefines(const StringVector& defs) {
142 Defines = defs;
143 }
144
145 virtual void setLibraryPaths(const StringVector& paths) {
146 StringVector::const_iterator I = paths.begin();
147 StringVector::const_iterator E = paths.end();
148 while (I != E) {
149 sys::Path tmp;
Reid Spencerdd04df02005-07-07 23:21:43 +0000150 tmp.set(*I);
Reid Spenceraf77d742004-10-28 04:05:06 +0000151 LibraryPaths.push_back(tmp);
Reid Spencerbf437722004-08-15 08:19:46 +0000152 ++I;
153 }
Reid Spencerbf437722004-08-15 08:19:46 +0000154 }
155
Misha Brukman0b861482005-05-03 20:30:34 +0000156 virtual void addLibraryPath(const sys::Path& libPath) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000157 LibraryPaths.push_back(libPath);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000158 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000159
Misha Brukman0b861482005-05-03 20:30:34 +0000160 virtual void addToolPath(const sys::Path& toolPath) {
Reid Spencer07adb282004-11-05 22:15:36 +0000161 ToolPaths.push_back(toolPath);
162 }
163
Reid Spenceraf77d742004-10-28 04:05:06 +0000164 virtual void setfPassThrough(const StringVector& fOpts) {
165 fOptions = fOpts;
166 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000167
Reid Spenceraf77d742004-10-28 04:05:06 +0000168 /// @brief Set the list of -M options to be passed through
169 virtual void setMPassThrough(const StringVector& MOpts) {
170 MOptions = MOpts;
171 }
Reid Spencerbae68252004-08-19 04:49:47 +0000172
Reid Spenceraf77d742004-10-28 04:05:06 +0000173 /// @brief Set the list of -W options to be passed through
174 virtual void setWPassThrough(const StringVector& WOpts) {
175 WOptions = WOpts;
176 }
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000177
Reid Spenceraf77d742004-10-28 04:05:06 +0000178/// @}
179/// @name Functions
180/// @{
181private:
182 bool isSet(DriverFlags flag) {
183 return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
184 }
Reid Spencerbae68252004-08-19 04:49:47 +0000185
Reid Spenceraf77d742004-10-28 04:05:06 +0000186 void cleanup() {
187 if (!isSet(KEEP_TEMPS_FLAG)) {
Chris Lattner33b0e9c2006-08-01 18:12:29 +0000188 sys::FileStatus Status;
189 if (!TempDir.getFileStatus(Status) && Status.isDir)
Reid Spencera229c5c2005-07-08 03:08:58 +0000190 TempDir.eraseFromDisk(/*remove_contents=*/true);
Reid Spenceraf77d742004-10-28 04:05:06 +0000191 } else {
Reid Spencer12786d52004-12-13 08:53:36 +0000192 std::cout << "Temporary files are in " << TempDir << "\n";
Reid Spenceraf77d742004-10-28 04:05:06 +0000193 }
194 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000195
Misha Brukman3da94ae2005-04-22 00:00:37 +0000196 sys::Path MakeTempFile(const std::string& basename,
Reid Spencer48744762006-08-22 19:01:30 +0000197 const std::string& suffix,
198 std::string* ErrMsg) {
199 if (TempDir.isEmpty()) {
200 TempDir = sys::Path::GetTemporaryDirectory(ErrMsg);
201 if (TempDir.isEmpty())
202 return sys::Path();
203 sys::RemoveDirectoryOnSignal(TempDir);
204 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000205 sys::Path result(TempDir);
Reid Spencer48744762006-08-22 19:01:30 +0000206 if (!result.appendComponent(basename)) {
207 if (ErrMsg)
208 *ErrMsg = basename + ": can't use this file name";
209 return sys::Path();
210 }
211 if (!result.appendSuffix(suffix)) {
212 if (ErrMsg)
213 *ErrMsg = suffix + ": can't use this file suffix";
214 return sys::Path();
215 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000216 return result;
217 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000218
Misha Brukman3da94ae2005-04-22 00:00:37 +0000219 Action* GetAction(ConfigData* cd,
220 const sys::Path& input,
Reid Spenceraf77d742004-10-28 04:05:06 +0000221 const sys::Path& output,
222 Phases phase)
223 {
224 Action* pat = 0; ///< The pattern/template for the action
225 Action* action = new Action; ///< The actual action to execute
Reid Spencer52c2dc12004-08-29 19:26:56 +0000226
Reid Spenceraf77d742004-10-28 04:05:06 +0000227 // Get the action pattern
228 switch (phase) {
229 case PREPROCESSING: pat = &cd->PreProcessor; break;
230 case TRANSLATION: pat = &cd->Translator; break;
231 case OPTIMIZATION: pat = &cd->Optimizer; break;
232 case ASSEMBLY: pat = &cd->Assembler; break;
233 case LINKING: pat = &cd->Linker; break;
234 default:
235 assert(!"Invalid driver phase!");
236 break;
237 }
238 assert(pat != 0 && "Invalid command pattern");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000239
Reid Spenceraf77d742004-10-28 04:05:06 +0000240 // Copy over some pattern things that don't need to change
Reid Spenceraf77d742004-10-28 04:05:06 +0000241 action->flags = pat->flags;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000242
Reid Spencer3b4c5d72006-08-16 20:31:44 +0000243 // See if program starts with wildcard...
244 std::string programName=pat->program.toString();
245 if (programName[0] == '%' && programName.length() >2) {
246 switch(programName[1]){
247 case 'b':
248 if (programName.substr(0,8) == "%bindir%") {
249 std::string tmp(LLVM_BINDIR);
250 tmp.append(programName.substr(8));
251 pat->program.set(tmp);
252 }
253 break;
254 case 'l':
255 if (programName.substr(0,12) == "%llvmgccdir%"){
256 std::string tmp(LLVMGCCDIR);
257 tmp.append(programName.substr(12));
258 pat->program.set(tmp);
259 }else if (programName.substr(0,13) == "%llvmgccarch%"){
260 std::string tmp(LLVMGCCARCH);
261 tmp.append(programName.substr(13));
262 pat->program.set(tmp);
263 }else if (programName.substr(0,9) == "%llvmgcc%"){
264 std::string tmp(LLVMGCC);
265 tmp.append(programName.substr(9));
266 pat->program.set(tmp);
267 }else if (programName.substr(0,9) == "%llvmgxx%"){
268 std::string tmp(LLVMGXX);
269 tmp.append(programName.substr(9));
270 pat->program.set(tmp);
271 }else if (programName.substr(0,9) == "%llvmcc1%"){
272 std::string tmp(LLVMCC1);
273 tmp.append(programName.substr(9));
274 pat->program.set(tmp);
275 }else if (programName.substr(0,13) == "%llvmcc1plus%"){
276 std::string tmp(LLVMCC1PLUS);
277 tmp.append(programName.substr(13));
278 pat->program.set(tmp);
279 }else if (programName.substr(0,8) == "%libdir%") {
280 std::string tmp(LLVM_LIBDIR);
281 tmp.append(programName.substr(8));
282 pat->program.set(tmp);
283 }
284 break;
285 }
286 }
287 action->program = pat->program;
288
Reid Spenceraf77d742004-10-28 04:05:06 +0000289 // Do the substitutions from the pattern to the actual
290 StringVector::iterator PI = pat->args.begin();
291 StringVector::iterator PE = pat->args.end();
292 while (PI != PE) {
293 if ((*PI)[0] == '%' && PI->length() >2) {
294 bool found = true;
295 switch ((*PI)[1]) {
296 case 'a':
297 if (*PI == "%args%") {
298 if (AdditionalArgs.size() > unsigned(phase))
299 if (!AdditionalArgs[phase].empty()) {
300 // Get specific options for each kind of action type
301 StringVector& addargs = AdditionalArgs[phase];
302 // Add specific options for each kind of action type
Misha Brukman3da94ae2005-04-22 00:00:37 +0000303 action->args.insert(action->args.end(), addargs.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000304 addargs.end());
305 }
306 } else
307 found = false;
308 break;
Reid Spencercc97cfc2005-05-19 00:52:28 +0000309 case 'b':
310 if (*PI == "%bindir%") {
311 std::string tmp(*PI);
312 tmp.replace(0,8,LLVM_BINDIR);
313 action->args.push_back(tmp);
314 } else
315 found = false;
316 break;
Reid Spenceraf77d742004-10-28 04:05:06 +0000317 case 'd':
318 if (*PI == "%defs%") {
319 StringVector::iterator I = Defines.begin();
320 StringVector::iterator E = Defines.end();
321 while (I != E) {
322 action->args.push_back( std::string("-D") + *I);
323 ++I;
324 }
325 } else
326 found = false;
327 break;
328 case 'f':
329 if (*PI == "%fOpts%") {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000330 if (!fOptions.empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000331 action->args.insert(action->args.end(), fOptions.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000332 fOptions.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000333 } else
334 found = false;
335 break;
336 case 'i':
337 if (*PI == "%in%") {
Reid Spencer1fce0912004-12-11 00:14:15 +0000338 action->args.push_back(input.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000339 } else if (*PI == "%incls%") {
340 PathVector::iterator I = IncludePaths.begin();
341 PathVector::iterator E = IncludePaths.end();
342 while (I != E) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000343 action->args.push_back( std::string("-I") + I->toString() );
Reid Spenceraf77d742004-10-28 04:05:06 +0000344 ++I;
345 }
346 } else
347 found = false;
348 break;
349 case 'l':
Reid Spencercc97cfc2005-05-19 00:52:28 +0000350 if ((*PI)[1] == 'l') {
351 std::string tmp(*PI);
352 if (*PI == "%llvmgccdir%")
353 tmp.replace(0,12,LLVMGCCDIR);
354 else if (*PI == "%llvmgccarch%")
355 tmp.replace(0,13,LLVMGCCARCH);
356 else if (*PI == "%llvmgcc%")
357 tmp.replace(0,9,LLVMGCC);
358 else if (*PI == "%llvmgxx%")
359 tmp.replace(0,9,LLVMGXX);
360 else if (*PI == "%llvmcc1%")
361 tmp.replace(0,9,LLVMCC1);
Jeff Cohen00b168892005-07-27 06:12:32 +0000362 else if (*PI == "%llvmcc1plus%")
Reid Spencercc97cfc2005-05-19 00:52:28 +0000363 tmp.replace(0,9,LLVMCC1);
364 else
365 found = false;
366 if (found)
367 action->args.push_back(tmp);
368 } else if (*PI == "%libs%") {
Reid Spenceraf77d742004-10-28 04:05:06 +0000369 PathVector::iterator I = LibraryPaths.begin();
370 PathVector::iterator E = LibraryPaths.end();
371 while (I != E) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000372 action->args.push_back( std::string("-L") + I->toString() );
Reid Spenceraf77d742004-10-28 04:05:06 +0000373 ++I;
374 }
Reid Spencercc97cfc2005-05-19 00:52:28 +0000375 } else if (*PI == "%libdir%") {
376 std::string tmp(*PI);
377 tmp.replace(0,8,LLVM_LIBDIR);
378 action->args.push_back(tmp);
Reid Spenceraf77d742004-10-28 04:05:06 +0000379 } else
380 found = false;
381 break;
382 case 'o':
383 if (*PI == "%out%") {
Reid Spencer1fce0912004-12-11 00:14:15 +0000384 action->args.push_back(output.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000385 } else if (*PI == "%opt%") {
386 if (!isSet(EMIT_RAW_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000387 if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
Reid Spenceraf77d742004-10-28 04:05:06 +0000388 !cd->opts[optLevel].empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000389 action->args.insert(action->args.end(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000390 cd->opts[optLevel].begin(),
391 cd->opts[optLevel].end());
392 else
Misha Brukman3da94ae2005-04-22 00:00:37 +0000393 throw std::string("Optimization options for level ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000394 utostr(unsigned(optLevel)) + " were not specified";
395 }
396 } else
397 found = false;
398 break;
399 case 's':
400 if (*PI == "%stats%") {
401 if (isSet(SHOW_STATS_FLAG))
402 action->args.push_back("-stats");
403 } else
404 found = false;
405 break;
406 case 't':
407 if (*PI == "%target%") {
408 action->args.push_back(std::string("-march=") + machine);
409 } else if (*PI == "%time%") {
410 if (isSet(TIME_PASSES_FLAG))
411 action->args.push_back("-time-passes");
412 } else
413 found = false;
414 break;
415 case 'v':
416 if (*PI == "%verbose%") {
417 if (isSet(VERBOSE_FLAG))
418 action->args.push_back("-v");
419 } else
420 found = false;
421 break;
422 case 'M':
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000423 if (*PI == "%Mopts%") {
424 if (!MOptions.empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000425 action->args.insert(action->args.end(), MOptions.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000426 MOptions.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000427 } else
428 found = false;
429 break;
430 case 'W':
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000431 if (*PI == "%Wopts%") {
432 for (StringVector::iterator I = WOptions.begin(),
433 E = WOptions.end(); I != E ; ++I ) {
Misha Brukman0b861482005-05-03 20:30:34 +0000434 action->args.push_back(std::string("-W") + *I);
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000435 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000436 } else
437 found = false;
438 break;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000439 default:
Reid Spenceraf77d742004-10-28 04:05:06 +0000440 found = false;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000441 break;
442 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000443 if (!found) {
444 // Did it even look like a substitution?
Misha Brukman3da94ae2005-04-22 00:00:37 +0000445 if (PI->length()>1 && (*PI)[0] == '%' &&
Reid Spenceraf77d742004-10-28 04:05:06 +0000446 (*PI)[PI->length()-1] == '%') {
447 throw std::string("Invalid substitution token: '") + *PI +
Reid Spencer1fce0912004-12-11 00:14:15 +0000448 "' for command '" + pat->program.toString() + "'";
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000449 } else if (!PI->empty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000450 // It's not a legal substitution, just pass it through
Reid Spencer52c2dc12004-08-29 19:26:56 +0000451 action->args.push_back(*PI);
452 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000453 }
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000454 } else if (!PI->empty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000455 // Its not a substitution, just put it in the action
456 action->args.push_back(*PI);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000457 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000458 PI++;
459 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000460
Reid Spenceraf77d742004-10-28 04:05:06 +0000461 // Finally, we're done
462 return action;
463 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000464
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000465 int DoAction(Action*action, std::string& ErrMsg) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000466 assert(action != 0 && "Invalid Action!");
467 if (isSet(VERBOSE_FLAG))
468 WriteAction(action);
469 if (!isSet(DRY_RUN_FLAG)) {
470 sys::Path progpath = sys::Program::FindProgramByName(
Reid Spencer1fce0912004-12-11 00:14:15 +0000471 action->program.toString());
Reid Spencer07adb282004-11-05 22:15:36 +0000472 if (progpath.isEmpty())
Reid Spencer1fce0912004-12-11 00:14:15 +0000473 throw std::string("Can't find program '" +
474 action->program.toString()+"'");
Reid Spencerc7f08322005-07-07 18:21:42 +0000475 else if (progpath.canExecute())
Reid Spenceraf77d742004-10-28 04:05:06 +0000476 action->program = progpath;
477 else
Reid Spencer1fce0912004-12-11 00:14:15 +0000478 throw std::string("Program '"+action->program.toString()+
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000479 "' is not executable.");
Reid Spenceraf77d742004-10-28 04:05:06 +0000480
481 // Invoke the program
Misha Brukman3da94ae2005-04-22 00:00:37 +0000482 const char** Args = (const char**)
Reid Spencerc30088f2005-04-11 05:48:04 +0000483 alloca(sizeof(const char*)*(action->args.size()+2));
484 Args[0] = action->program.toString().c_str();
Reid Spencer3b4c5d72006-08-16 20:31:44 +0000485 for (unsigned i = 1; i <= action->args.size(); ++i)
486 Args[i] = action->args[i-1].c_str();
487 Args[action->args.size()+1] = 0; // null terminate list.
Reid Spenceraf77d742004-10-28 04:05:06 +0000488 if (isSet(TIME_ACTIONS_FLAG)) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000489 Timer timer(action->program.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000490 timer.startTimer();
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000491 int resultCode =
492 sys::Program::ExecuteAndWait(action->program, Args,0,0,0,&ErrMsg);
Reid Spenceraf77d742004-10-28 04:05:06 +0000493 timer.stopTimer();
494 timer.print(timer,std::cerr);
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000495 return resultCode;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000496 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000497 else
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000498 return
499 sys::Program::ExecuteAndWait(action->program, Args, 0,0,0, &ErrMsg);
Reid Spenceraf77d742004-10-28 04:05:06 +0000500 }
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000501 return 0;
Reid Spenceraf77d742004-10-28 04:05:06 +0000502 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000503
Reid Spenceraf77d742004-10-28 04:05:06 +0000504 /// This method tries various variants of a linkage item's file
505 /// name to see if it can find an appropriate file to link with
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000506 /// in the directories of the LibraryPaths.
Reid Spenceraf77d742004-10-28 04:05:06 +0000507 llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
Reid Spenceraf77d742004-10-28 04:05:06 +0000508 bool native = false) {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000509 sys::Path fullpath;
Reid Spencerdd04df02005-07-07 23:21:43 +0000510 fullpath.set(link_item);
Reid Spencerc7f08322005-07-07 18:21:42 +0000511 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000512 return fullpath;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000513 for (PathVector::iterator PI = LibraryPaths.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000514 PE = LibraryPaths.end(); PI != PE; ++PI) {
Reid Spencerdd04df02005-07-07 23:21:43 +0000515 fullpath.set(PI->toString());
516 fullpath.appendComponent(link_item);
Reid Spencerc7f08322005-07-07 18:21:42 +0000517 if (fullpath.canRead())
Reid Spenceraf77d742004-10-28 04:05:06 +0000518 return fullpath;
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000519 if (native) {
520 fullpath.appendSuffix("a");
521 } else {
522 fullpath.appendSuffix("bc");
Reid Spencerc7f08322005-07-07 18:21:42 +0000523 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000524 return fullpath;
Reid Spencerdd04df02005-07-07 23:21:43 +0000525 fullpath.eraseSuffix();
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000526 fullpath.appendSuffix("o");
Reid Spencerc7f08322005-07-07 18:21:42 +0000527 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000528 return fullpath;
529 fullpath = *PI;
Reid Spencerdd04df02005-07-07 23:21:43 +0000530 fullpath.appendComponent(std::string("lib") + link_item);
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000531 fullpath.appendSuffix("a");
Reid Spencerc7f08322005-07-07 18:21:42 +0000532 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000533 return fullpath;
Reid Spencerdd04df02005-07-07 23:21:43 +0000534 fullpath.eraseSuffix();
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000535 fullpath.appendSuffix("so");
Reid Spencerc7f08322005-07-07 18:21:42 +0000536 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000537 return fullpath;
538 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000539 }
540
541 // Didn't find one.
542 fullpath.clear();
543 return fullpath;
544 }
545
546 /// This method processes a linkage item. The item could be a
547 /// Bytecode file needing translation to native code and that is
548 /// dependent on other bytecode libraries, or a native code
549 /// library that should just be linked into the program.
550 bool ProcessLinkageItem(const llvm::sys::Path& link_item,
551 SetVector<sys::Path>& set,
552 std::string& err) {
553 // First, see if the unadorned file name is not readable. If so,
554 // we must track down the file in the lib search path.
555 sys::Path fullpath;
Reid Spencerc7f08322005-07-07 18:21:42 +0000556 if (!link_item.canRead()) {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000557 // look for the library using the -L arguments specified
Reid Spenceraf77d742004-10-28 04:05:06 +0000558 // on the command line.
Reid Spencer1fce0912004-12-11 00:14:15 +0000559 fullpath = GetPathForLinkageItem(link_item.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000560
Reid Spenceraf77d742004-10-28 04:05:06 +0000561 // If we didn't find the file in any of the library search paths
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000562 // we have to bail. No where else to look.
Reid Spencer07adb282004-11-05 22:15:36 +0000563 if (fullpath.isEmpty()) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000564 err =
Reid Spencer1fce0912004-12-11 00:14:15 +0000565 std::string("Can't find linkage item '") + link_item.toString() + "'";
Reid Spenceraf77d742004-10-28 04:05:06 +0000566 return false;
567 }
568 } else {
569 fullpath = link_item;
570 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000571
Reid Spenceraf77d742004-10-28 04:05:06 +0000572 // If we got here fullpath is the path to the file, and its readable.
573 set.insert(fullpath);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000574
Reid Spenceraf77d742004-10-28 04:05:06 +0000575 // If its an LLVM bytecode file ...
Reid Spencer07adb282004-11-05 22:15:36 +0000576 if (fullpath.isBytecodeFile()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000577 // Process the dependent libraries recursively
578 Module::LibraryListType modlibs;
Reid Spencer0b5a5042006-08-25 17:43:11 +0000579 if (GetBytecodeDependentLibraries(fullpath.toString(),modlibs,&err)) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000580 // Traverse the dependent libraries list
581 Module::lib_iterator LI = modlibs.begin();
582 Module::lib_iterator LE = modlibs.end();
583 while ( LI != LE ) {
584 if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
585 if (err.empty()) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000586 err = std::string("Library '") + *LI +
Reid Spenceraf77d742004-10-28 04:05:06 +0000587 "' is not valid for linking but is required by file '" +
Reid Spencer1fce0912004-12-11 00:14:15 +0000588 fullpath.toString() + "'";
Reid Spenceraf77d742004-10-28 04:05:06 +0000589 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000590 err += " which is required by file '" + fullpath.toString() + "'";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000591 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000592 return false;
593 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000594 ++LI;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000595 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000596 } else if (err.empty()) {
597 err = std::string(
Misha Brukman3da94ae2005-04-22 00:00:37 +0000598 "The dependent libraries could not be extracted from '") +
Reid Spencer1fce0912004-12-11 00:14:15 +0000599 fullpath.toString();
Reid Spenceraf77d742004-10-28 04:05:06 +0000600 return false;
Reid Spencer0b5a5042006-08-25 17:43:11 +0000601 } else
602 return false;
Reid Spenceraf77d742004-10-28 04:05:06 +0000603 }
604 return true;
605 }
606
607/// @}
608/// @name Methods
609/// @{
610public:
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000611 virtual int execute(const InputList& InpList, const sys::Path& Output, std::string& ErrMsg ) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000612 try {
613 // Echo the configuration of options if we're running verbose
614 if (isSet(DEBUG_FLAG)) {
615 std::cerr << "Compiler Driver Options:\n";
616 std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
617 std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
618 std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
619 std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
620 std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
621 std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
622 std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
623 std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
624 std::cerr << "OutputMachine = " << machine << "\n";
625 InputList::const_iterator I = InpList.begin();
626 while ( I != InpList.end() ) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000627 std::cerr << "Input: " << I->first << "(" << I->second
Reid Spenceraf77d742004-10-28 04:05:06 +0000628 << ")\n";
629 ++I;
630 }
Reid Spencer12786d52004-12-13 08:53:36 +0000631 std::cerr << "Output: " << Output << "\n";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000632 }
633
Reid Spenceraf77d742004-10-28 04:05:06 +0000634 // If there's no input, we're done.
635 if (InpList.empty())
636 throw std::string("Nothing to compile.");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000637
Reid Spenceraf77d742004-10-28 04:05:06 +0000638 // If they are asking for linking and didn't provide an output
639 // file then its an error (no way for us to "make up" a meaningful
640 // file name based on the various linker input files).
Reid Spencer07adb282004-11-05 22:15:36 +0000641 if (finalPhase == LINKING && Output.isEmpty())
Reid Spenceraf77d742004-10-28 04:05:06 +0000642 throw std::string(
643 "An output file name must be specified for linker output");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000644
Reid Spenceraf77d742004-10-28 04:05:06 +0000645 // If they are not asking for linking, provided an output file and
646 // there is more than one input file, its an error
Reid Spencer07adb282004-11-05 22:15:36 +0000647 if (finalPhase != LINKING && !Output.isEmpty() && InpList.size() > 1)
Reid Spenceraf77d742004-10-28 04:05:06 +0000648 throw std::string("An output file name cannot be specified ") +
649 "with more than one input file name when not linking";
650
651 // This vector holds all the resulting actions of the following loop.
652 std::vector<Action*> actions;
653
654 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
655 // for each input item
656 SetVector<sys::Path> LinkageItems;
Reid Spencerf6358c72004-12-19 18:00:56 +0000657 StringVector LibFiles;
Reid Spenceraf77d742004-10-28 04:05:06 +0000658 InputList::const_iterator I = InpList.begin();
Reid Spencer679a7232004-11-20 20:39:33 +0000659 for (InputList::const_iterator I = InpList.begin(), E = InpList.end();
660 I != E; ++I ) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000661 // Get the suffix of the file name
662 const std::string& ftype = I->second;
663
Misha Brukman3da94ae2005-04-22 00:00:37 +0000664 // If its a library, bytecode file, or object file, save
665 // it for linking below and short circuit the
Reid Spenceraf77d742004-10-28 04:05:06 +0000666 // pre-processing/translation/assembly phases
667 if (ftype.empty() || ftype == "o" || ftype == "bc" || ftype=="a") {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000668 // We shouldn't get any of these types of files unless we're
Reid Spenceraf77d742004-10-28 04:05:06 +0000669 // later going to link. Enforce this limit now.
670 if (finalPhase != LINKING) {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000671 throw std::string(
Reid Spenceraf77d742004-10-28 04:05:06 +0000672 "Pre-compiled objects found but linking not requested");
673 }
674 if (ftype.empty())
Reid Spencer1fce0912004-12-11 00:14:15 +0000675 LibFiles.push_back(I->first.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000676 else
677 LinkageItems.insert(I->first);
Reid Spencer679a7232004-11-20 20:39:33 +0000678 continue; // short circuit remainder of loop
Reid Spenceraf77d742004-10-28 04:05:06 +0000679 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000680
Reid Spenceraf77d742004-10-28 04:05:06 +0000681 // At this point, we know its something we need to translate
682 // and/or optimize. See if we can get the configuration data
683 // for this kind of file.
684 ConfigData* cd = cdp->ProvideConfigData(I->second);
685 if (cd == 0)
Misha Brukman3da94ae2005-04-22 00:00:37 +0000686 throw std::string("Files of type '") + I->second +
687 "' are not recognized.";
Reid Spenceraf77d742004-10-28 04:05:06 +0000688 if (isSet(DEBUG_FLAG))
689 DumpConfigData(cd,I->second);
Reid Spencer54fafe42004-09-14 01:58:45 +0000690
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000691 // Add the config data's library paths to the end of the list
692 for (StringVector::iterator LPI = cd->libpaths.begin(),
693 LPE = cd->libpaths.end(); LPI != LPE; ++LPI){
694 LibraryPaths.push_back(sys::Path(*LPI));
695 }
696
Reid Spenceraf77d742004-10-28 04:05:06 +0000697 // Initialize the input and output files
698 sys::Path InFile(I->first);
Reid Spencer07adb282004-11-05 22:15:36 +0000699 sys::Path OutFile(I->first.getBasename());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000700
Reid Spenceraf77d742004-10-28 04:05:06 +0000701 // PRE-PROCESSING PHASE
702 Action& action = cd->PreProcessor;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000703
Reid Spenceraf77d742004-10-28 04:05:06 +0000704 // Get the preprocessing action, if needed, or error if appropriate
Reid Spencer07adb282004-11-05 22:15:36 +0000705 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000706 if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
707 if (finalPhase == PREPROCESSING) {
Reid Spencer679a7232004-11-20 20:39:33 +0000708 if (Output.isEmpty()) {
709 OutFile.appendSuffix("E");
710 actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
711 } else {
712 actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING));
713 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000714 } else {
Reid Spencer48744762006-08-22 19:01:30 +0000715 sys::Path TempFile(
716 MakeTempFile(I->first.getBasename(),"E",&ErrMsg));
717 if (TempFile.isEmpty())
718 return 1;
Reid Spenceraf77d742004-10-28 04:05:06 +0000719 actions.push_back(GetAction(cd,InFile,TempFile,
720 PREPROCESSING));
721 InFile = TempFile;
722 }
723 }
724 } else if (finalPhase == PREPROCESSING) {
725 throw cd->langName + " does not support pre-processing";
726 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000727 throw std::string("Don't know how to pre-process ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000728 cd->langName + " files";
729 }
730
Misha Brukman3da94ae2005-04-22 00:00:37 +0000731 // Short-circuit remaining actions if all they want is
Reid Spenceraf77d742004-10-28 04:05:06 +0000732 // pre-processing
Reid Spencer679a7232004-11-20 20:39:33 +0000733 if (finalPhase == PREPROCESSING) { continue; };
Reid Spenceraf77d742004-10-28 04:05:06 +0000734
735 /// TRANSLATION PHASE
736 action = cd->Translator;
737
738 // Get the translation action, if needed, or error if appropriate
Reid Spencer07adb282004-11-05 22:15:36 +0000739 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000740 if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
741 if (finalPhase == TRANSLATION) {
Reid Spencer679a7232004-11-20 20:39:33 +0000742 if (Output.isEmpty()) {
743 OutFile.appendSuffix("o");
744 actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
745 } else {
746 actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
747 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000748 } else {
Reid Spencer48744762006-08-22 19:01:30 +0000749 sys::Path TempFile(
750 MakeTempFile(I->first.getBasename(),"trans", &ErrMsg));
751 if (TempFile.isEmpty())
752 return 1;
Reid Spenceraf77d742004-10-28 04:05:06 +0000753 actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
754 InFile = TempFile;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000755 }
756
Reid Spenceraf77d742004-10-28 04:05:06 +0000757 // ll -> bc Helper
758 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
759 /// The output of the translator is an LLVM Assembly program
760 /// We need to translate it to bytecode
761 Action* action = new Action();
Reid Spencerdd04df02005-07-07 23:21:43 +0000762 action->program.set("llvm-as");
Reid Spencer1fce0912004-12-11 00:14:15 +0000763 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000764 action->args.push_back("-o");
Reid Spencer07adb282004-11-05 22:15:36 +0000765 InFile.appendSuffix("bc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000766 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000767 actions.push_back(action);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000768 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000769 }
770 } else if (finalPhase == TRANSLATION) {
771 throw cd->langName + " does not support translation";
772 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000773 throw std::string("Don't know how to translate ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000774 cd->langName + " files";
775 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000776
Reid Spenceraf77d742004-10-28 04:05:06 +0000777 // Short-circuit remaining actions if all they want is translation
Reid Spencer679a7232004-11-20 20:39:33 +0000778 if (finalPhase == TRANSLATION) { continue; }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000779
Reid Spenceraf77d742004-10-28 04:05:06 +0000780 /// OPTIMIZATION PHASE
781 action = cd->Optimizer;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000782
Reid Spenceraf77d742004-10-28 04:05:06 +0000783 // Get the optimization action, if needed, or error if appropriate
784 if (!isSet(EMIT_RAW_FLAG)) {
Reid Spencer07adb282004-11-05 22:15:36 +0000785 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000786 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
787 if (finalPhase == OPTIMIZATION) {
Reid Spencer679a7232004-11-20 20:39:33 +0000788 if (Output.isEmpty()) {
789 OutFile.appendSuffix("o");
790 actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
791 } else {
792 actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION));
793 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000794 } else {
Reid Spencer48744762006-08-22 19:01:30 +0000795 sys::Path TempFile(
796 MakeTempFile(I->first.getBasename(),"opt", &ErrMsg));
797 if (TempFile.isEmpty())
798 return 1;
Reid Spenceraf77d742004-10-28 04:05:06 +0000799 actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
800 InFile = TempFile;
801 }
802 // ll -> bc Helper
803 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
804 /// The output of the optimizer is an LLVM Assembly program
805 /// We need to translate it to bytecode with llvm-as
Reid Spencer52c2dc12004-08-29 19:26:56 +0000806 Action* action = new Action();
Reid Spencerdd04df02005-07-07 23:21:43 +0000807 action->program.set("llvm-as");
Reid Spencer1fce0912004-12-11 00:14:15 +0000808 action->args.push_back(InFile.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000809 action->args.push_back("-f");
810 action->args.push_back("-o");
Reid Spencer07adb282004-11-05 22:15:36 +0000811 InFile.appendSuffix("bc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000812 action->args.push_back(InFile.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000813 actions.push_back(action);
814 }
815 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000816 } else if (finalPhase == OPTIMIZATION) {
817 throw cd->langName + " does not support optimization";
818 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000819 throw std::string("Don't know how to optimize ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000820 cd->langName + " files";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000821 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000822 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000823
824 // Short-circuit remaining actions if all they want is optimization
Reid Spencer679a7232004-11-20 20:39:33 +0000825 if (finalPhase == OPTIMIZATION) { continue; }
Reid Spenceraf77d742004-10-28 04:05:06 +0000826
827 /// ASSEMBLY PHASE
828 action = cd->Assembler;
829
830 if (finalPhase == ASSEMBLY) {
Reid Spencer679a7232004-11-20 20:39:33 +0000831
832 // Build either a native compilation action or a disassembly action
833 Action* action = new Action();
Reid Spenceraf77d742004-10-28 04:05:06 +0000834 if (isSet(EMIT_NATIVE_FLAG)) {
835 // Use llc to get the native assembly file
Reid Spencerdd04df02005-07-07 23:21:43 +0000836 action->program.set("llc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000837 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000838 action->args.push_back("-f");
839 action->args.push_back("-o");
Reid Spencer679a7232004-11-20 20:39:33 +0000840 if (Output.isEmpty()) {
841 OutFile.appendSuffix("o");
Reid Spencer1fce0912004-12-11 00:14:15 +0000842 action->args.push_back(OutFile.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000843 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000844 action->args.push_back(Output.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000845 }
846 actions.push_back(action);
Reid Spenceraf77d742004-10-28 04:05:06 +0000847 } else {
848 // Just convert back to llvm assembly with llvm-dis
Reid Spencerdd04df02005-07-07 23:21:43 +0000849 action->program.set("llvm-dis");
Reid Spencer1fce0912004-12-11 00:14:15 +0000850 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000851 action->args.push_back("-f");
852 action->args.push_back("-o");
Reid Spencer679a7232004-11-20 20:39:33 +0000853 if (Output.isEmpty()) {
854 OutFile.appendSuffix("ll");
Reid Spencer1fce0912004-12-11 00:14:15 +0000855 action->args.push_back(OutFile.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000856 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000857 action->args.push_back(Output.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000858 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000859 }
860
Reid Spencer679a7232004-11-20 20:39:33 +0000861 // Put the action on the list
862 actions.push_back(action);
863
Misha Brukman3da94ae2005-04-22 00:00:37 +0000864 // Short circuit the rest of the loop, we don't want to link
Reid Spenceraf77d742004-10-28 04:05:06 +0000865 continue;
866 }
867
868 // Register the result of the actions as a link candidate
869 LinkageItems.insert(InFile);
870
Reid Spenceraf77d742004-10-28 04:05:06 +0000871 } // end while loop over each input file
872
873 /// RUN THE COMPILATION ACTIONS
874 std::vector<Action*>::iterator AI = actions.begin();
875 std::vector<Action*>::iterator AE = actions.end();
876 while (AI != AE) {
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000877 int ActionResult = DoAction(*AI, ErrMsg);
878 if (ActionResult != 0)
879 return ActionResult;
Reid Spenceraf77d742004-10-28 04:05:06 +0000880 AI++;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000881 }
882
Reid Spenceraf77d742004-10-28 04:05:06 +0000883 /// LINKING PHASE
884 if (finalPhase == LINKING) {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000885
Reid Spenceraf77d742004-10-28 04:05:06 +0000886 // Insert the platform-specific system libraries to the path list
Reid Spencer11db4b82004-12-13 03:01:26 +0000887 std::vector<sys::Path> SysLibs;
888 sys::Path::GetSystemLibraryPaths(SysLibs);
889 LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000890
891 // Set up the linking action with llvm-ld
892 Action* link = new Action();
Reid Spencerdd04df02005-07-07 23:21:43 +0000893 link->program.set("llvm-ld");
Reid Spenceraf77d742004-10-28 04:05:06 +0000894
895 // Add in the optimization level requested
896 switch (optLevel) {
897 case OPT_FAST_COMPILE:
898 link->args.push_back("-O1");
899 break;
900 case OPT_SIMPLE:
901 link->args.push_back("-O2");
902 break;
903 case OPT_AGGRESSIVE:
904 link->args.push_back("-O3");
905 break;
906 case OPT_LINK_TIME:
907 link->args.push_back("-O4");
908 break;
909 case OPT_AGGRESSIVE_LINK_TIME:
910 link->args.push_back("-O5");
911 break;
912 case OPT_NONE:
913 break;
914 }
915
916 // Add in all the linkage items we generated. This includes the
917 // output from the translation/optimization phases as well as any
918 // -l arguments specified.
Misha Brukman3da94ae2005-04-22 00:00:37 +0000919 for (PathVector::const_iterator I=LinkageItems.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000920 E=LinkageItems.end(); I != E; ++I )
Reid Spencer1fce0912004-12-11 00:14:15 +0000921 link->args.push_back(I->toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000922
923 // Add in all the libraries we found.
Reid Spencerf6358c72004-12-19 18:00:56 +0000924 for (StringVector::const_iterator I=LibFiles.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000925 E=LibFiles.end(); I != E; ++I )
926 link->args.push_back(std::string("-l")+*I);
927
928 // Add in all the library paths to the command line
929 for (PathVector::const_iterator I=LibraryPaths.begin(),
930 E=LibraryPaths.end(); I != E; ++I)
Reid Spencer1fce0912004-12-11 00:14:15 +0000931 link->args.push_back( std::string("-L") + I->toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000932
933 // Add in the additional linker arguments requested
934 for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
935 E=AdditionalArgs[LINKING].end(); I != E; ++I)
936 link->args.push_back( *I );
937
938 // Add in other optional flags
939 if (isSet(EMIT_NATIVE_FLAG))
940 link->args.push_back("-native");
941 if (isSet(VERBOSE_FLAG))
942 link->args.push_back("-v");
943 if (isSet(TIME_PASSES_FLAG))
944 link->args.push_back("-time-passes");
945 if (isSet(SHOW_STATS_FLAG))
946 link->args.push_back("-stats");
947 if (isSet(STRIP_OUTPUT_FLAG))
948 link->args.push_back("-s");
949 if (isSet(DEBUG_FLAG)) {
950 link->args.push_back("-debug");
951 link->args.push_back("-debug-pass=Details");
952 }
953
954 // Add in mandatory flags
955 link->args.push_back("-o");
Reid Spencer1fce0912004-12-11 00:14:15 +0000956 link->args.push_back(Output.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000957
958 // Execute the link
Reid Spencer8ea5ecb2006-08-21 06:04:45 +0000959 int ActionResult = DoAction(link, ErrMsg);
960 if (ActionResult != 0)
961 return ActionResult;
Reid Spenceraf77d742004-10-28 04:05:06 +0000962 }
963 } catch (std::string& msg) {
964 cleanup();
965 throw;
966 } catch (...) {
967 cleanup();
968 throw std::string("Unspecified error");
969 }
970 cleanup();
971 return 0;
972 }
973
974/// @}
975/// @name Data
976/// @{
977private:
978 ConfigDataProvider* cdp; ///< Where we get configuration data from
979 Phases finalPhase; ///< The final phase of compilation
980 OptimizationLevels optLevel; ///< The optimization level to apply
981 unsigned Flags; ///< The driver flags
982 std::string machine; ///< Target machine name
983 PathVector LibraryPaths; ///< -L options
984 PathVector IncludePaths; ///< -I options
Reid Spencer07adb282004-11-05 22:15:36 +0000985 PathVector ToolPaths; ///< -B options
Reid Spenceraf77d742004-10-28 04:05:06 +0000986 StringVector Defines; ///< -D options
987 sys::Path TempDir; ///< Name of the temporary directory.
988 StringTable AdditionalArgs; ///< The -Txyz options
989 StringVector fOptions; ///< -f options
990 StringVector MOptions; ///< -M options
991 StringVector WOptions; ///< -W options
992
993/// @}
994};
Reid Spencer5c56dc12004-08-13 20:22:43 +0000995}
996
997CompilerDriver::~CompilerDriver() {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000998}
999
Reid Spencercc97cfc2005-05-19 00:52:28 +00001000CompilerDriver::ConfigDataProvider::~ConfigDataProvider() {}
1001
Reid Spencer52c2dc12004-08-29 19:26:56 +00001002CompilerDriver*
1003CompilerDriver::Get(ConfigDataProvider& CDP) {
1004 return new CompilerDriverImpl(CDP);
Reid Spencerbae68252004-08-19 04:49:47 +00001005}
1006
1007CompilerDriver::ConfigData::ConfigData()
1008 : langName()
1009 , PreProcessor()
1010 , Translator()
1011 , Optimizer()
1012 , Assembler()
1013 , Linker()
1014{
1015 StringVector emptyVec;
1016 for (unsigned i = 0; i < NUM_PHASES; ++i)
1017 opts.push_back(emptyVec);
Reid Spencer5c56dc12004-08-13 20:22:43 +00001018}