blob: d84caad24812b54790e6943868bf93069668f33c [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//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file was developed by Reid Spencer and is distributed under the
7// University of Illinois Open Source License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
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//
13//===------------------------------------------------------------------------===
14
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/Bytecode/Reader.h"
18#include "llvm/Module.h"
19#include "Support/FileUtilities.h"
Reid Spencerbae68252004-08-19 04:49:47 +000020#include "Support/SystemUtils.h"
Reid Spencera01439a2004-08-24 13:55:17 +000021#include "Support/StringExtras.h"
Reid Spencer5c56dc12004-08-13 20:22:43 +000022#include <iostream>
23
24using namespace llvm;
25
26namespace {
27 inline std::string RemoveSuffix(const std::string& fullName) {
28 size_t dotpos = fullName.rfind('.',fullName.size());
29 if ( dotpos == std::string::npos ) return fullName;
30 return fullName.substr(0, dotpos);
31 }
32
Reid Spencer5c56dc12004-08-13 20:22:43 +000033 const char OutputSuffix[] = ".o";
34
Reid Spencerbae68252004-08-19 04:49:47 +000035 void WriteAction(CompilerDriver::Action* action ) {
36 std::cerr << action->program;
37 std::vector<std::string>::iterator I = action->args.begin();
38 while (I != action->args.end()) {
Reid Spencer68fb37a2004-08-14 09:37:15 +000039 std::cerr << " " + *I;
40 ++I;
41 }
42 std::cerr << "\n";
43 }
44
Reid Spencerbae68252004-08-19 04:49:47 +000045 void DumpAction(CompilerDriver::Action* action) {
46 std::cerr << "command = " << action->program;
47 std::vector<std::string>::iterator I = action->args.begin();
48 while (I != action->args.end()) {
Reid Spencerbf437722004-08-15 08:19:46 +000049 std::cerr << " " + *I;
50 ++I;
51 }
52 std::cerr << "\n";
Reid Spencerbae68252004-08-19 04:49:47 +000053 std::cerr << "flags = " << action->flags << "\n";
Reid Spencerbf437722004-08-15 08:19:46 +000054 }
55
Reid Spencer68fb37a2004-08-14 09:37:15 +000056 void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
57 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
58 << ")\n";
Reid Spencer68fb37a2004-08-14 09:37:15 +000059 std::cerr << "PreProcessor: ";
Reid Spencerbf437722004-08-15 08:19:46 +000060 DumpAction(&cd->PreProcessor);
Reid Spencer68fb37a2004-08-14 09:37:15 +000061 std::cerr << "Translator: ";
Reid Spencerbf437722004-08-15 08:19:46 +000062 DumpAction(&cd->Translator);
Reid Spencer68fb37a2004-08-14 09:37:15 +000063 std::cerr << "Optimizer: ";
Reid Spencerbf437722004-08-15 08:19:46 +000064 DumpAction(&cd->Optimizer);
Reid Spencer68fb37a2004-08-14 09:37:15 +000065 std::cerr << "Assembler: ";
Reid Spencerbf437722004-08-15 08:19:46 +000066 DumpAction(&cd->Assembler);
Reid Spencer68fb37a2004-08-14 09:37:15 +000067 std::cerr << "Linker: ";
Reid Spencerbf437722004-08-15 08:19:46 +000068 DumpAction(&cd->Linker);
Reid Spencer68fb37a2004-08-14 09:37:15 +000069 }
Reid Spencer5c56dc12004-08-13 20:22:43 +000070
Reid Spencer2a069fa2004-08-16 07:06:38 +000071 /// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
72 /// which should reduce the volume of code and make compilation
73 /// faster. This is also safe on any llvm module.
Reid Spencerbae68252004-08-19 04:49:47 +000074 static const char* DefaultFastCompileOptimizations[] = {
75 "-simplifycfg", "-mem2reg", "-instcombine"
Reid Spencer2a069fa2004-08-16 07:06:38 +000076 };
77}
Reid Spencer5c56dc12004-08-13 20:22:43 +000078
Reid Spencerbae68252004-08-19 04:49:47 +000079// Stuff in this namespace properly belongs in lib/System and needs
80// to be portable but we're avoiding that for now.
81namespace sys {
Reid Spencer9a8fedd2004-08-20 09:14:05 +000082
Reid Spencera01439a2004-08-24 13:55:17 +000083 bool FileIsReadable(const std::string& fname) {
Reid Spencer9a8fedd2004-08-20 09:14:05 +000084 return 0 == access(fname.c_str(), F_OK | R_OK);
85 }
86
87 void CleanupTempFile(const std::string& fname) {
Reid Spencera01439a2004-08-24 13:55:17 +000088 if (FileIsReadable(fname))
Reid Spencer9a8fedd2004-08-20 09:14:05 +000089 unlink(fname.c_str());
90 }
91
Reid Spencerbae68252004-08-19 04:49:47 +000092 std::string MakeTemporaryDirectory() {
93 char temp_name[64];
94 strcpy(temp_name,"/tmp/llvm_XXXXXX");
95 if (0 == mkdtemp(temp_name))
96 throw std::string("Can't create temporary directory");
97 return temp_name;
98 }
99
100 std::string FindExecutableInPath(const std::string& program) {
101 // First, just see if the program is already executable
102 if (isExecutableFile(program)) return program;
103
104 // Get the path. If its empty, we can't do anything
105 const char *PathStr = getenv("PATH");
106 if (PathStr == 0) return "";
107
108 // Now we have a colon separated list of directories to search; try them.
109 unsigned PathLen = strlen(PathStr);
110 while (PathLen) {
111 // Find the first colon...
112 const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
113
114 // Check to see if this first directory contains the executable...
115 std::string FilePath = std::string(PathStr, Colon) + '/' + program;
116 if (isExecutableFile(FilePath))
117 return FilePath; // Found the executable!
118
119 // Nope it wasn't in this directory, check the next range!
120 PathLen -= Colon-PathStr;
121 PathStr = Colon;
122
123 // Advance past duplicate coons
124 while (*PathStr == ':') {
125 PathStr++;
126 PathLen--;
127 }
128 }
129
130 // If we fell out, we ran out of directories in PATH to search, return failure
131 return "";
132 }
133}
134
Reid Spencer5c56dc12004-08-13 20:22:43 +0000135CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
136 : cdp(&confDatProv)
137 , finalPhase(LINKING)
138 , optLevel(OPT_FAST_COMPILE)
139 , isDryRun(false)
140 , isVerbose(false)
141 , isDebug(false)
142 , timeActions(false)
143 , emitRawCode(false)
144 , emitNativeCode(false)
Reid Spencerbae68252004-08-19 04:49:47 +0000145 , keepTemps(false)
Reid Spencer5c56dc12004-08-13 20:22:43 +0000146 , machine()
Reid Spencerbf437722004-08-15 08:19:46 +0000147 , LibraryPaths()
Reid Spencerbae68252004-08-19 04:49:47 +0000148 , AdditionalArgs()
149 , TempDir()
Reid Spencer5c56dc12004-08-13 20:22:43 +0000150{
151 // FIXME: These libraries are platform specific
Reid Spencerbf437722004-08-15 08:19:46 +0000152 LibraryPaths.push_back("/lib");
153 LibraryPaths.push_back("/usr/lib");
Reid Spencerbae68252004-08-19 04:49:47 +0000154 AdditionalArgs.reserve(NUM_PHASES);
155 StringVector emptyVec;
156 for (unsigned i = 0; i < NUM_PHASES; ++i)
157 AdditionalArgs.push_back(emptyVec);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000158}
159
160CompilerDriver::~CompilerDriver() {
161 cdp = 0;
Reid Spencerbf437722004-08-15 08:19:46 +0000162 LibraryPaths.clear();
Reid Spencerbae68252004-08-19 04:49:47 +0000163 AdditionalArgs.clear();
164}
165
166CompilerDriver::ConfigData::ConfigData()
167 : langName()
168 , PreProcessor()
169 , Translator()
170 , Optimizer()
171 , Assembler()
172 , Linker()
173{
174 StringVector emptyVec;
175 for (unsigned i = 0; i < NUM_PHASES; ++i)
176 opts.push_back(emptyVec);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000177}
178
179void CompilerDriver::error( const std::string& errmsg ) {
Reid Spencerbae68252004-08-19 04:49:47 +0000180 std::cerr << "llvmc: Error: " << errmsg << ".\n";
Reid Spencer5c56dc12004-08-13 20:22:43 +0000181 exit(1);
182}
183
184CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
185 const std::string& input,
186 const std::string& output,
187 Phases phase)
188{
Reid Spencerbae68252004-08-19 04:49:47 +0000189 Action* pat = 0; ///< The pattern/template for the action
190 Action* action = new Action; ///< The actual action to execute
191
Reid Spencerbf437722004-08-15 08:19:46 +0000192 // Get the action pattern
Reid Spencer5c56dc12004-08-13 20:22:43 +0000193 switch (phase) {
194 case PREPROCESSING: pat = &cd->PreProcessor; break;
195 case TRANSLATION: pat = &cd->Translator; break;
196 case OPTIMIZATION: pat = &cd->Optimizer; break;
197 case ASSEMBLY: pat = &cd->Assembler; break;
198 case LINKING: pat = &cd->Linker; break;
199 default:
200 assert(!"Invalid driver phase!");
201 break;
202 }
203 assert(pat != 0 && "Invalid command pattern");
Reid Spencerbf437722004-08-15 08:19:46 +0000204
Reid Spencerbae68252004-08-19 04:49:47 +0000205 // Copy over some pattern things that don't need to change
206 action->program = pat->program;
207 action->flags = pat->flags;
Reid Spencerbf437722004-08-15 08:19:46 +0000208
Reid Spencerbae68252004-08-19 04:49:47 +0000209 // Do the substitutions from the pattern to the actual
210 StringVector::iterator PI = pat->args.begin();
211 StringVector::iterator PE = pat->args.end();
212 while (PI != PE) {
Reid Spencer53aa7932004-08-20 22:53:11 +0000213 if ((*PI)[0] == '%') {
214 if (*PI == "%in%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000215 action->args.push_back(input);
Reid Spencer53aa7932004-08-20 22:53:11 +0000216 } else if (*PI == "%out%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000217 action->args.push_back(output);
Reid Spencer53aa7932004-08-20 22:53:11 +0000218 } else if (*PI == "%time%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000219 if (timePasses)
220 action->args.push_back("-time-passes");
Reid Spencer53aa7932004-08-20 22:53:11 +0000221 } else if (*PI == "%stats%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000222 if (showStats)
223 action->args.push_back("-stats");
Reid Spencer53aa7932004-08-20 22:53:11 +0000224 } else if (*PI == "%target%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000225 // FIXME: Ignore for now
Reid Spencer53aa7932004-08-20 22:53:11 +0000226 } else if (*PI == "%opt%") {
Reid Spencerbae68252004-08-19 04:49:47 +0000227 if (!emitRawCode) {
Reid Spencera01439a2004-08-24 13:55:17 +0000228 if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
229 !cd->opts[optLevel].empty())
230 action->args.insert(action->args.end(), cd->opts[optLevel].begin(),
Reid Spencerbae68252004-08-19 04:49:47 +0000231 cd->opts[optLevel].end());
Reid Spencera01439a2004-08-24 13:55:17 +0000232 else
233 error("Optimization options for level " + utostr(unsigned(optLevel)) +
234 " were not specified");
Reid Spencerbae68252004-08-19 04:49:47 +0000235 }
Reid Spencera01439a2004-08-24 13:55:17 +0000236 } else if (*PI == "%args%") {
237 if (AdditionalArgs.size() > unsigned(phase))
238 if (!AdditionalArgs[phase].empty()) {
239 // Get specific options for each kind of action type
240 StringVector& addargs = AdditionalArgs[phase];
241 // Add specific options for each kind of action type
242 action->args.insert(action->args.end(), addargs.begin(), addargs.end());
243 }
Reid Spencerbae68252004-08-19 04:49:47 +0000244 } else {
Reid Spencera01439a2004-08-24 13:55:17 +0000245 error("Invalid substitution name" + *PI);
Reid Spencerbae68252004-08-19 04:49:47 +0000246 }
247 } else {
248 // Its not a substitution, just put it in the action
249 action->args.push_back(*PI);
250 }
251 PI++;
Reid Spencerbf437722004-08-15 08:19:46 +0000252 }
Reid Spencerbae68252004-08-19 04:49:47 +0000253
Reid Spencerbae68252004-08-19 04:49:47 +0000254
255 // Finally, we're done
256 return action;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000257}
258
Reid Spencerbae68252004-08-19 04:49:47 +0000259bool CompilerDriver::DoAction(Action*action) {
260 assert(action != 0 && "Invalid Action!");
Reid Spencer5c56dc12004-08-13 20:22:43 +0000261 if (isVerbose)
Reid Spencerbae68252004-08-19 04:49:47 +0000262 WriteAction(action);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000263 if (!isDryRun) {
Reid Spencerbae68252004-08-19 04:49:47 +0000264 std::string prog(sys::FindExecutableInPath(action->program));
265 if (prog.empty())
266 error("Can't find program '" + action->program + "'");
267
268 // Get the program's arguments
269 const char* argv[action->args.size() + 1];
270 argv[0] = prog.c_str();
271 unsigned i = 1;
272 for (; i <= action->args.size(); ++i)
273 argv[i] = action->args[i-1].c_str();
274 argv[i] = 0;
275
276 // Invoke the program
277 return !ExecWait(argv, environ);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000278 }
Reid Spencerbae68252004-08-19 04:49:47 +0000279 return true;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000280}
281
282int CompilerDriver::execute(const InputList& InpList,
Reid Spencer2a069fa2004-08-16 07:06:38 +0000283 const std::string& Output ) {
Reid Spencer5c56dc12004-08-13 20:22:43 +0000284 // Echo the configuration of options if we're running verbose
285 if (isDebug)
286 {
287 std::cerr << "Compiler Driver Options:\n";
288 std::cerr << "DryRun = " << isDryRun << "\n";
289 std::cerr << "Verbose = " << isVerbose << " \n";
290 std::cerr << "TimeActions = " << timeActions << "\n";
291 std::cerr << "EmitRawCode = " << emitRawCode << "\n";
292 std::cerr << "OutputMachine = " << machine << "\n";
293 std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
294 InputList::const_iterator I = InpList.begin();
295 while ( I != InpList.end() ) {
296 std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
297 ++I;
298 }
299 std::cerr << "Output: " << Output << "\n";
300 }
301
302 // If there's no input, we're done.
303 if (InpList.empty())
304 error("Nothing to compile.");
305
306 // If they are asking for linking and didn't provide an output
307 // file then its an error (no way for us to "make up" a meaningful
308 // file name based on the various linker input files).
309 if (finalPhase == LINKING && Output.empty())
310 error("An output file name must be specified for linker output");
311
Reid Spencerbf437722004-08-15 08:19:46 +0000312 // This vector holds all the resulting actions of the following loop.
Reid Spencer5c56dc12004-08-13 20:22:43 +0000313 std::vector<Action*> actions;
314
Reid Spencerbf437722004-08-15 08:19:46 +0000315 // Create a temporary directory for our temporary files
Reid Spencerbae68252004-08-19 04:49:47 +0000316 std::string TempDir(sys::MakeTemporaryDirectory());
317 std::string TempPreprocessorOut(TempDir + "/preproc.o");
318 std::string TempTranslatorOut(TempDir + "/trans.o");
319 std::string TempOptimizerOut(TempDir + "/opt.o");
320 std::string TempAssemblerOut(TempDir + "/asm.o");
Reid Spencerbf437722004-08-15 08:19:46 +0000321
Reid Spencer5c56dc12004-08-13 20:22:43 +0000322 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
323 // for each input item
324 std::vector<std::string> LinkageItems;
Reid Spencera01439a2004-08-24 13:55:17 +0000325 std::string OutFile(Output);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000326 InputList::const_iterator I = InpList.begin();
327 while ( I != InpList.end() ) {
328 // Get the suffix of the file name
Reid Spencera01439a2004-08-24 13:55:17 +0000329 const std::string& ftype = I->second;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000330
331 // If its a library, bytecode file, or object file, save
332 // it for linking below and short circuit the
333 // pre-processing/translation/assembly phases
Reid Spencera01439a2004-08-24 13:55:17 +0000334 if (ftype.empty() || ftype == "o" || ftype == "bc") {
Reid Spencer5c56dc12004-08-13 20:22:43 +0000335 // We shouldn't get any of these types of files unless we're
336 // later going to link. Enforce this limit now.
337 if (finalPhase != LINKING) {
338 error("Pre-compiled objects found but linking not requested");
339 }
340 LinkageItems.push_back(I->first);
Reid Spencera01439a2004-08-24 13:55:17 +0000341 ++I; continue; // short circuit remainder of loop
Reid Spencer5c56dc12004-08-13 20:22:43 +0000342 }
343
344 // At this point, we know its something we need to translate
345 // and/or optimize. See if we can get the configuration data
346 // for this kind of file.
347 ConfigData* cd = cdp->ProvideConfigData(I->second);
348 if (cd == 0)
349 error(std::string("Files of type '") + I->second +
350 "' are not recognized." );
Reid Spencer68fb37a2004-08-14 09:37:15 +0000351 if (isDebug)
352 DumpConfigData(cd,I->second);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000353
Reid Spencerbae68252004-08-19 04:49:47 +0000354 // Initialize the input file
355 std::string InFile(I->first);
356
Reid Spencerbf437722004-08-15 08:19:46 +0000357 // PRE-PROCESSING PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000358 Action& action = cd->PreProcessor;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000359
Reid Spencerbf437722004-08-15 08:19:46 +0000360 // Get the preprocessing action, if needed, or error if appropriate
Reid Spencerbae68252004-08-19 04:49:47 +0000361 if (!action.program.empty()) {
362 if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
363 if (finalPhase == PREPROCESSING)
364 actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
365 else {
366 actions.push_back(GetAction(cd,InFile,TempPreprocessorOut,
367 PREPROCESSING));
368 InFile = TempPreprocessorOut;
369 }
Reid Spencerbf437722004-08-15 08:19:46 +0000370 }
371 } else if (finalPhase == PREPROCESSING) {
372 error(cd->langName + " does not support pre-processing");
Reid Spencerbae68252004-08-19 04:49:47 +0000373 } else if (action.isSet(REQUIRED_FLAG)) {
Reid Spencerbf437722004-08-15 08:19:46 +0000374 error(std::string("Don't know how to pre-process ") +
375 cd->langName + " files");
376 }
Reid Spencerbae68252004-08-19 04:49:47 +0000377
Reid Spencer5c56dc12004-08-13 20:22:43 +0000378 // Short-circuit remaining actions if all they want is pre-processing
379 if (finalPhase == PREPROCESSING) { ++I; continue; };
380
381 /// TRANSLATION PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000382 action = cd->Translator;
Reid Spencerbf437722004-08-15 08:19:46 +0000383
384 // Get the translation action, if needed, or error if appropriate
Reid Spencerbae68252004-08-19 04:49:47 +0000385 if (!action.program.empty()) {
386 if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
387 if (finalPhase == TRANSLATION)
388 actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
389 else {
390 actions.push_back(GetAction(cd,InFile,TempTranslatorOut,TRANSLATION));
391 InFile = TempTranslatorOut;
392 }
393
394 // ll -> bc Helper
395 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
396 /// The output of the translator is an LLVM Assembly program
397 /// We need to translate it to bytecode
398 Action* action = new Action();
399 action->program = "llvm-as";
400 action->args.push_back(InFile);
401 action->args.push_back("-o");
402 InFile += ".bc";
403 action->args.push_back(InFile);
404 actions.push_back(action);
405 }
Reid Spencerbf437722004-08-15 08:19:46 +0000406 }
407 } else if (finalPhase == TRANSLATION) {
408 error(cd->langName + " does not support translation");
Reid Spencerbae68252004-08-19 04:49:47 +0000409 } else if (action.isSet(REQUIRED_FLAG)) {
Reid Spencerbf437722004-08-15 08:19:46 +0000410 error(std::string("Don't know how to translate ") +
411 cd->langName + " files");
412 }
Reid Spencerbae68252004-08-19 04:49:47 +0000413
Reid Spencer5c56dc12004-08-13 20:22:43 +0000414 // Short-circuit remaining actions if all they want is translation
415 if (finalPhase == TRANSLATION) { ++I; continue; }
416
417 /// OPTIMIZATION PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000418 action = cd->Optimizer;
Reid Spencerbf437722004-08-15 08:19:46 +0000419
420 // Get the optimization action, if needed, or error if appropriate
Reid Spencera01439a2004-08-24 13:55:17 +0000421 if (!emitRawCode) {
422 if (!action.program.empty()) {
423 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
424 if (finalPhase == OPTIMIZATION)
425 actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
426 else {
427 actions.push_back(GetAction(cd,InFile,TempOptimizerOut,OPTIMIZATION));
428 InFile = TempOptimizerOut;
429 }
430 // ll -> bc Helper
431 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
432 /// The output of the translator is an LLVM Assembly program
433 /// We need to translate it to bytecode
434 Action* action = new Action();
435 action->program = "llvm-as";
436 action->args.push_back(InFile);
437 action->args.push_back("-f");
438 action->args.push_back("-o");
439 InFile += ".bc";
440 action->args.push_back(InFile);
441 actions.push_back(action);
442 }
Reid Spencerbae68252004-08-19 04:49:47 +0000443 }
Reid Spencera01439a2004-08-24 13:55:17 +0000444 } else if (finalPhase == OPTIMIZATION) {
445 error(cd->langName + " does not support optimization");
446 } else if (action.isSet(REQUIRED_FLAG)) {
447 error(std::string("Don't know how to optimize ") +
Reid Spencerbf437722004-08-15 08:19:46 +0000448 cd->langName + " files");
Reid Spencera01439a2004-08-24 13:55:17 +0000449 }
Reid Spencerbf437722004-08-15 08:19:46 +0000450 }
Reid Spencerbae68252004-08-19 04:49:47 +0000451
Reid Spencer5c56dc12004-08-13 20:22:43 +0000452 // Short-circuit remaining actions if all they want is optimization
453 if (finalPhase == OPTIMIZATION) { ++I; continue; }
454
Reid Spencerbae68252004-08-19 04:49:47 +0000455 /// ASSEMBLY PHASE
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000456 action = cd->Assembler;
457
Reid Spencera01439a2004-08-24 13:55:17 +0000458 if (finalPhase == ASSEMBLY || emitNativeCode) {
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000459 if (emitNativeCode) {
460 if (action.program.empty()) {
461 error(std::string("Native Assembler not specified for ") +
462 cd->langName + " files");
Reid Spencera01439a2004-08-24 13:55:17 +0000463 } else if (finalPhase == ASSEMBLY) {
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000464 actions.push_back(GetAction(cd,InFile,OutFile,ASSEMBLY));
Reid Spencera01439a2004-08-24 13:55:17 +0000465 } else {
466 actions.push_back(GetAction(cd,InFile,TempAssemblerOut,ASSEMBLY));
467 InFile = TempAssemblerOut;
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000468 }
469 } else {
470 // Just convert back to llvm assembly with llvm-dis
471 Action* action = new Action();
472 action->program = "llvm-dis";
473 action->args.push_back(InFile);
474 action->args.push_back("-f");
475 action->args.push_back("-o");
476 action->args.push_back(OutFile);
477 actions.push_back(action);
478 }
Reid Spencerbae68252004-08-19 04:49:47 +0000479 }
Reid Spencera01439a2004-08-24 13:55:17 +0000480
481 // Short-circuit remaining actions if all they want is assembly output
482 if (finalPhase == ASSEMBLY) { ++I; continue; }
Reid Spencerbae68252004-08-19 04:49:47 +0000483
Reid Spencera01439a2004-08-24 13:55:17 +0000484 // Register the OutFile as a link candidate
485 LinkageItems.push_back(InFile);
486
Reid Spencerbae68252004-08-19 04:49:47 +0000487 // Go to next file to be processed
Reid Spencer5c56dc12004-08-13 20:22:43 +0000488 ++I;
489 }
490
491 /// LINKING PHASE
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000492 if (finalPhase == LINKING) {
493 if (emitNativeCode) {
Reid Spencera01439a2004-08-24 13:55:17 +0000494 error("llvmc doesn't know how to link native code yet");
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000495 } else {
Reid Spencera01439a2004-08-24 13:55:17 +0000496 // First, we need to examine the files to ensure that they all contain
497 // bytecode files. Since the final output is bytecode, we can only
498 // link bytecode.
499 StringVector::const_iterator I = LinkageItems.begin();
500 StringVector::const_iterator E = LinkageItems.end();
501 StringVector lib_list;
502 while (I != E ) {
503 if (sys::FileIsReadable(*I)) {
504 if (CheckMagic(*I, "llvm")) {
505 // Examine the bytecode file for additional bytecode libraries to
506 // link in.
507 ModuleProvider* mp = getBytecodeModuleProvider(*I);
508 assert(mp!=0 && "Couldn't get module provider from bytecode file");
509 Module* M = mp->releaseModule();
510 assert(M!=0 && "Couldn't get module from module provider");
511 Module::lib_iterator LI = M->lib_begin();
512 Module::lib_iterator LE = M->lib_end();
513 while ( LI != LE ) {
514 if (sys::FileIsReadable(*LI)) {
515 if (CheckMagic(*I,"llvm")) {
516 lib_list.push_back(*LI);
517 } else {
518 error(std::string("Library '") + *LI + "' required by file '"
519 + *I + "' is not an LLVM bytecode file");
520 }
521 } else {
522 error(std::string("Library '") + *LI + "' required by file '"
523 + *I + "' is not readable");
524 }
525 ++I;
526 }
527 } else {
528 error(std::string("File '") + *I + " is not an LLVM byte code file");
529 }
530 } else {
531 error(std::string("File '") + *I + " is not readable");
532 }
533 ++I;
534 }
535
536 // We're emitting bytecode so let's build an llvm-link Action
537 Action* link = new Action();
538 link->program = "llvm-link";
539 link->args = LinkageItems;
540 link->args.insert(link->args.end(), lib_list.begin(), lib_list.end());
541 link->args.push_back("-f");
542 link->args.push_back("-o");
543 link->args.push_back(OutFile);
544 if (timePasses)
545 link->args.push_back("-time-passes");
546 if (showStats)
547 link->args.push_back("-stats");
548 actions.push_back(link);
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000549 }
Reid Spencerbae68252004-08-19 04:49:47 +0000550 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000551
552 /// RUN THE ACTIONS
553 std::vector<Action*>::iterator aIter = actions.begin();
554 while (aIter != actions.end()) {
Reid Spencerbae68252004-08-19 04:49:47 +0000555 if (!DoAction(*aIter))
556 error("Action failed");
Reid Spencer5c56dc12004-08-13 20:22:43 +0000557 aIter++;
558 }
559
Reid Spencerbae68252004-08-19 04:49:47 +0000560 if (!keepTemps) {
561 // Cleanup files
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000562 ::sys::CleanupTempFile(TempPreprocessorOut);
563 ::sys::CleanupTempFile(TempTranslatorOut);
564 ::sys::CleanupTempFile(TempOptimizerOut);
Reid Spencer2a069fa2004-08-16 07:06:38 +0000565
Reid Spencerbae68252004-08-19 04:49:47 +0000566 // Cleanup temporary directory we created
Reid Spencera01439a2004-08-24 13:55:17 +0000567 if (::sys::FileIsReadable(TempDir))
Reid Spencerbae68252004-08-19 04:49:47 +0000568 rmdir(TempDir.c_str());
569 }
Reid Spencerbf437722004-08-15 08:19:46 +0000570
Reid Spencer5c56dc12004-08-13 20:22:43 +0000571 return 0;
572}
573
574// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab