blob: 08d60929a0169447b25171263bb01c5ceb281e0f [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
Reid Spencer198e8882004-08-24 22:54:32 +0000282/// This method tries various variants of a linkage item's file
283/// name to see if it can find an appropriate file to link with
284/// in the directory specified.
285std::string CompilerDriver::GetPathForLinkageItem(const std::string& link_item,
286 const std::string& dir) {
287 std::string fullpath(dir + "/" + link_item + ".o");
288 if (::sys::FileIsReadable(fullpath))
289 return fullpath;
290 fullpath = dir + "/" + link_item + ".bc";
291 if (::sys::FileIsReadable(fullpath))
292 return fullpath;
293 fullpath = dir + "/lib" + link_item + ".a";
294 if (::sys::FileIsReadable(fullpath))
295 return fullpath;
296 fullpath = dir + "/lib" + link_item + ".so";
297 if (::sys::FileIsReadable(fullpath))
298 return fullpath;
299 return "";
300}
301
302/// This method processes a linkage item. The item could be a
303/// Bytecode file needing translation to native code and that is
304/// dependent on other bytecode libraries, or a native code
305/// library that should just be linked into the program.
306bool CompilerDriver::ProcessLinkageItem(const std::string& link_item,
307 SetVector<std::string>& set,
308 std::string& err) {
309 // First, see if the unadorned file name is not readable. If so,
310 // we must track down the file in the lib search path.
311 std::string fullpath;
312 if (!sys::FileIsReadable(link_item)) {
313 // First, look for the library using the -L arguments specified
314 // on the command line.
315 StringVector::iterator PI = LibraryPaths.begin();
316 StringVector::iterator PE = LibraryPaths.end();
317 while (PI != PE && fullpath.empty()) {
318 fullpath = GetPathForLinkageItem(link_item,*PI);
319 ++PI;
320 }
321
322 // If we didn't find the file in any of the library search paths
323 // so we have to bail. No where else to look.
324 if (fullpath.empty()) {
325 err = std::string("Can't find linkage item '") + link_item + "'";
326 return false;
327 }
328 } else {
329 fullpath = link_item;
330 }
331
332 // If we got here fullpath is the path to the file, and its readable.
333 set.insert(fullpath);
334
335 // If its an LLVM bytecode file ...
336 if (CheckMagic(fullpath, "llvm")) {
337 // Process the dependent libraries recursively
338 Module::LibraryListType modlibs;
339 if (GetBytecodeDependentLibraries(fullpath,modlibs)) {
340 // Traverse the dependent libraries list
341 Module::lib_iterator LI = modlibs.begin();
342 Module::lib_iterator LE = modlibs.end();
343 while ( LI != LE ) {
344 if (!ProcessLinkageItem(*LI,set,err)) {
345 if (err.empty()) {
346 err = std::string("Library '") + *LI +
347 "' is not valid for linking but is required by file '" +
348 fullpath + "'";
349 } else {
350 err += " which is required by file '" + fullpath + "'";
351 }
352 return false;
353 }
354 ++LI;
355 }
356 } else if (err.empty()) {
357 err = std::string("The dependent libraries could not be extracted from '")
358 + fullpath;
359 return false;
360 }
361 }
362 return true;
363}
364
365
Reid Spencer5c56dc12004-08-13 20:22:43 +0000366int CompilerDriver::execute(const InputList& InpList,
Reid Spencer2a069fa2004-08-16 07:06:38 +0000367 const std::string& Output ) {
Reid Spencer5c56dc12004-08-13 20:22:43 +0000368 // Echo the configuration of options if we're running verbose
369 if (isDebug)
370 {
371 std::cerr << "Compiler Driver Options:\n";
372 std::cerr << "DryRun = " << isDryRun << "\n";
373 std::cerr << "Verbose = " << isVerbose << " \n";
374 std::cerr << "TimeActions = " << timeActions << "\n";
375 std::cerr << "EmitRawCode = " << emitRawCode << "\n";
376 std::cerr << "OutputMachine = " << machine << "\n";
377 std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
378 InputList::const_iterator I = InpList.begin();
379 while ( I != InpList.end() ) {
380 std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
381 ++I;
382 }
383 std::cerr << "Output: " << Output << "\n";
384 }
385
386 // If there's no input, we're done.
387 if (InpList.empty())
388 error("Nothing to compile.");
389
390 // If they are asking for linking and didn't provide an output
391 // file then its an error (no way for us to "make up" a meaningful
392 // file name based on the various linker input files).
393 if (finalPhase == LINKING && Output.empty())
394 error("An output file name must be specified for linker output");
395
Reid Spencerbf437722004-08-15 08:19:46 +0000396 // This vector holds all the resulting actions of the following loop.
Reid Spencer5c56dc12004-08-13 20:22:43 +0000397 std::vector<Action*> actions;
398
Reid Spencerbf437722004-08-15 08:19:46 +0000399 // Create a temporary directory for our temporary files
Reid Spencerbae68252004-08-19 04:49:47 +0000400 std::string TempDir(sys::MakeTemporaryDirectory());
401 std::string TempPreprocessorOut(TempDir + "/preproc.o");
402 std::string TempTranslatorOut(TempDir + "/trans.o");
403 std::string TempOptimizerOut(TempDir + "/opt.o");
404 std::string TempAssemblerOut(TempDir + "/asm.o");
Reid Spencerbf437722004-08-15 08:19:46 +0000405
Reid Spencer5c56dc12004-08-13 20:22:43 +0000406 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
407 // for each input item
408 std::vector<std::string> LinkageItems;
Reid Spencera01439a2004-08-24 13:55:17 +0000409 std::string OutFile(Output);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000410 InputList::const_iterator I = InpList.begin();
411 while ( I != InpList.end() ) {
412 // Get the suffix of the file name
Reid Spencera01439a2004-08-24 13:55:17 +0000413 const std::string& ftype = I->second;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000414
415 // If its a library, bytecode file, or object file, save
416 // it for linking below and short circuit the
417 // pre-processing/translation/assembly phases
Reid Spencera01439a2004-08-24 13:55:17 +0000418 if (ftype.empty() || ftype == "o" || ftype == "bc") {
Reid Spencer5c56dc12004-08-13 20:22:43 +0000419 // We shouldn't get any of these types of files unless we're
420 // later going to link. Enforce this limit now.
421 if (finalPhase != LINKING) {
422 error("Pre-compiled objects found but linking not requested");
423 }
424 LinkageItems.push_back(I->first);
Reid Spencera01439a2004-08-24 13:55:17 +0000425 ++I; continue; // short circuit remainder of loop
Reid Spencer5c56dc12004-08-13 20:22:43 +0000426 }
427
428 // At this point, we know its something we need to translate
429 // and/or optimize. See if we can get the configuration data
430 // for this kind of file.
431 ConfigData* cd = cdp->ProvideConfigData(I->second);
432 if (cd == 0)
433 error(std::string("Files of type '") + I->second +
434 "' are not recognized." );
Reid Spencer68fb37a2004-08-14 09:37:15 +0000435 if (isDebug)
436 DumpConfigData(cd,I->second);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000437
Reid Spencerbae68252004-08-19 04:49:47 +0000438 // Initialize the input file
439 std::string InFile(I->first);
440
Reid Spencerbf437722004-08-15 08:19:46 +0000441 // PRE-PROCESSING PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000442 Action& action = cd->PreProcessor;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000443
Reid Spencerbf437722004-08-15 08:19:46 +0000444 // Get the preprocessing action, if needed, or error if appropriate
Reid Spencerbae68252004-08-19 04:49:47 +0000445 if (!action.program.empty()) {
446 if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
447 if (finalPhase == PREPROCESSING)
448 actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
449 else {
450 actions.push_back(GetAction(cd,InFile,TempPreprocessorOut,
451 PREPROCESSING));
452 InFile = TempPreprocessorOut;
453 }
Reid Spencerbf437722004-08-15 08:19:46 +0000454 }
455 } else if (finalPhase == PREPROCESSING) {
456 error(cd->langName + " does not support pre-processing");
Reid Spencerbae68252004-08-19 04:49:47 +0000457 } else if (action.isSet(REQUIRED_FLAG)) {
Reid Spencerbf437722004-08-15 08:19:46 +0000458 error(std::string("Don't know how to pre-process ") +
459 cd->langName + " files");
460 }
Reid Spencerbae68252004-08-19 04:49:47 +0000461
Reid Spencer5c56dc12004-08-13 20:22:43 +0000462 // Short-circuit remaining actions if all they want is pre-processing
463 if (finalPhase == PREPROCESSING) { ++I; continue; };
464
465 /// TRANSLATION PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000466 action = cd->Translator;
Reid Spencerbf437722004-08-15 08:19:46 +0000467
468 // Get the translation action, if needed, or error if appropriate
Reid Spencerbae68252004-08-19 04:49:47 +0000469 if (!action.program.empty()) {
470 if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
471 if (finalPhase == TRANSLATION)
472 actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
473 else {
474 actions.push_back(GetAction(cd,InFile,TempTranslatorOut,TRANSLATION));
475 InFile = TempTranslatorOut;
476 }
477
478 // ll -> bc Helper
479 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
480 /// The output of the translator is an LLVM Assembly program
481 /// We need to translate it to bytecode
482 Action* action = new Action();
483 action->program = "llvm-as";
484 action->args.push_back(InFile);
485 action->args.push_back("-o");
486 InFile += ".bc";
487 action->args.push_back(InFile);
488 actions.push_back(action);
489 }
Reid Spencerbf437722004-08-15 08:19:46 +0000490 }
491 } else if (finalPhase == TRANSLATION) {
492 error(cd->langName + " does not support translation");
Reid Spencerbae68252004-08-19 04:49:47 +0000493 } else if (action.isSet(REQUIRED_FLAG)) {
Reid Spencerbf437722004-08-15 08:19:46 +0000494 error(std::string("Don't know how to translate ") +
495 cd->langName + " files");
496 }
Reid Spencerbae68252004-08-19 04:49:47 +0000497
Reid Spencer5c56dc12004-08-13 20:22:43 +0000498 // Short-circuit remaining actions if all they want is translation
499 if (finalPhase == TRANSLATION) { ++I; continue; }
500
501 /// OPTIMIZATION PHASE
Reid Spencerbae68252004-08-19 04:49:47 +0000502 action = cd->Optimizer;
Reid Spencerbf437722004-08-15 08:19:46 +0000503
504 // Get the optimization action, if needed, or error if appropriate
Reid Spencera01439a2004-08-24 13:55:17 +0000505 if (!emitRawCode) {
506 if (!action.program.empty()) {
507 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
508 if (finalPhase == OPTIMIZATION)
509 actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
510 else {
511 actions.push_back(GetAction(cd,InFile,TempOptimizerOut,OPTIMIZATION));
512 InFile = TempOptimizerOut;
513 }
514 // ll -> bc Helper
515 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
516 /// The output of the translator is an LLVM Assembly program
517 /// We need to translate it to bytecode
518 Action* action = new Action();
519 action->program = "llvm-as";
520 action->args.push_back(InFile);
521 action->args.push_back("-f");
522 action->args.push_back("-o");
523 InFile += ".bc";
524 action->args.push_back(InFile);
525 actions.push_back(action);
526 }
Reid Spencerbae68252004-08-19 04:49:47 +0000527 }
Reid Spencera01439a2004-08-24 13:55:17 +0000528 } else if (finalPhase == OPTIMIZATION) {
529 error(cd->langName + " does not support optimization");
530 } else if (action.isSet(REQUIRED_FLAG)) {
531 error(std::string("Don't know how to optimize ") +
Reid Spencerbf437722004-08-15 08:19:46 +0000532 cd->langName + " files");
Reid Spencera01439a2004-08-24 13:55:17 +0000533 }
Reid Spencerbf437722004-08-15 08:19:46 +0000534 }
Reid Spencerbae68252004-08-19 04:49:47 +0000535
Reid Spencer5c56dc12004-08-13 20:22:43 +0000536 // Short-circuit remaining actions if all they want is optimization
537 if (finalPhase == OPTIMIZATION) { ++I; continue; }
538
Reid Spencerbae68252004-08-19 04:49:47 +0000539 /// ASSEMBLY PHASE
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000540 action = cd->Assembler;
541
Reid Spencera01439a2004-08-24 13:55:17 +0000542 if (finalPhase == ASSEMBLY || emitNativeCode) {
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000543 if (emitNativeCode) {
544 if (action.program.empty()) {
545 error(std::string("Native Assembler not specified for ") +
546 cd->langName + " files");
Reid Spencera01439a2004-08-24 13:55:17 +0000547 } else if (finalPhase == ASSEMBLY) {
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000548 actions.push_back(GetAction(cd,InFile,OutFile,ASSEMBLY));
Reid Spencera01439a2004-08-24 13:55:17 +0000549 } else {
550 actions.push_back(GetAction(cd,InFile,TempAssemblerOut,ASSEMBLY));
551 InFile = TempAssemblerOut;
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000552 }
553 } else {
554 // Just convert back to llvm assembly with llvm-dis
555 Action* action = new Action();
556 action->program = "llvm-dis";
557 action->args.push_back(InFile);
558 action->args.push_back("-f");
559 action->args.push_back("-o");
560 action->args.push_back(OutFile);
561 actions.push_back(action);
562 }
Reid Spencerbae68252004-08-19 04:49:47 +0000563 }
Reid Spencera01439a2004-08-24 13:55:17 +0000564
565 // Short-circuit remaining actions if all they want is assembly output
566 if (finalPhase == ASSEMBLY) { ++I; continue; }
Reid Spencerbae68252004-08-19 04:49:47 +0000567
Reid Spencera01439a2004-08-24 13:55:17 +0000568 // Register the OutFile as a link candidate
569 LinkageItems.push_back(InFile);
570
Reid Spencerbae68252004-08-19 04:49:47 +0000571 // Go to next file to be processed
Reid Spencer5c56dc12004-08-13 20:22:43 +0000572 ++I;
573 }
574
Reid Spencer198e8882004-08-24 22:54:32 +0000575 /// RUN THE COMPILATION ACTIONS
576 std::vector<Action*>::iterator aIter = actions.begin();
577 while (aIter != actions.end()) {
578 if (!DoAction(*aIter))
579 error("Action failed");
580 aIter++;
581 }
582
Reid Spencer5c56dc12004-08-13 20:22:43 +0000583 /// LINKING PHASE
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000584 if (finalPhase == LINKING) {
585 if (emitNativeCode) {
Reid Spencera01439a2004-08-24 13:55:17 +0000586 error("llvmc doesn't know how to link native code yet");
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000587 } else {
Reid Spencera01439a2004-08-24 13:55:17 +0000588 // First, we need to examine the files to ensure that they all contain
589 // bytecode files. Since the final output is bytecode, we can only
590 // link bytecode.
591 StringVector::const_iterator I = LinkageItems.begin();
592 StringVector::const_iterator E = LinkageItems.end();
Reid Spencer198e8882004-08-24 22:54:32 +0000593 SetVector<std::string> link_items;
594 std::string errmsg;
595 while (I != E && ProcessLinkageItem(*I,link_items,errmsg))
Reid Spencera01439a2004-08-24 13:55:17 +0000596 ++I;
Reid Spencer198e8882004-08-24 22:54:32 +0000597
598 if (!errmsg.empty())
599 error(errmsg);
Reid Spencera01439a2004-08-24 13:55:17 +0000600
601 // We're emitting bytecode so let's build an llvm-link Action
602 Action* link = new Action();
603 link->program = "llvm-link";
604 link->args = LinkageItems;
Reid Spencer198e8882004-08-24 22:54:32 +0000605 link->args.insert(link->args.end(), link_items.begin(), link_items.end());
Reid Spencera01439a2004-08-24 13:55:17 +0000606 link->args.push_back("-f");
607 link->args.push_back("-o");
608 link->args.push_back(OutFile);
609 if (timePasses)
610 link->args.push_back("-time-passes");
611 if (showStats)
612 link->args.push_back("-stats");
613 actions.push_back(link);
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000614 }
Reid Spencerbae68252004-08-19 04:49:47 +0000615 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000616
Reid Spencerbae68252004-08-19 04:49:47 +0000617 if (!keepTemps) {
618 // Cleanup files
Reid Spencer9a8fedd2004-08-20 09:14:05 +0000619 ::sys::CleanupTempFile(TempPreprocessorOut);
620 ::sys::CleanupTempFile(TempTranslatorOut);
621 ::sys::CleanupTempFile(TempOptimizerOut);
Reid Spencer2a069fa2004-08-16 07:06:38 +0000622
Reid Spencerbae68252004-08-19 04:49:47 +0000623 // Cleanup temporary directory we created
Reid Spencera01439a2004-08-24 13:55:17 +0000624 if (::sys::FileIsReadable(TempDir))
Reid Spencerbae68252004-08-19 04:49:47 +0000625 rmdir(TempDir.c_str());
626 }
Reid Spencerbf437722004-08-15 08:19:46 +0000627
Reid Spencer5c56dc12004-08-13 20:22:43 +0000628 return 0;
629}
630
631// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab