1 //===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
4 // The LLVM Compiler Infrastructure
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.
9 //===----------------------------------------------------------------------===//
11 // This file implements the bulk of the LLVM Compiler Driver (llvmc).
13 //===------------------------------------------------------------------------===
15 #include "CompilerDriver.h"
16 #include "ConfigLexer.h"
17 #include "Support/SystemUtils.h"
23 inline std::string RemoveSuffix(const std::string& fullName) {
24 size_t dotpos = fullName.rfind('.',fullName.size());
25 if ( dotpos == std::string::npos ) return fullName;
26 return fullName.substr(0, dotpos);
29 inline std::string GetSuffix(const std::string& fullName) {
30 size_t dotpos = fullName.rfind('.',fullName.size());
31 if ( dotpos = std::string::npos ) return "";
32 return fullName.substr(dotpos+1);
35 const char OutputSuffix[] = ".o";
37 void WriteAction(CompilerDriver::Action* action ) {
38 std::cerr << action->program;
39 std::vector<std::string>::iterator I = action->args.begin();
40 while (I != action->args.end()) {
41 std::cerr << " " + *I;
47 void DumpAction(CompilerDriver::Action* action) {
48 std::cerr << "command = " << action->program;
49 std::vector<std::string>::iterator I = action->args.begin();
50 while (I != action->args.end()) {
51 std::cerr << " " + *I;
55 std::cerr << "flags = " << action->flags << "\n";
58 void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
59 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
61 std::cerr << "PreProcessor: ";
62 DumpAction(&cd->PreProcessor);
63 std::cerr << "Translator: ";
64 DumpAction(&cd->Translator);
65 std::cerr << "Optimizer: ";
66 DumpAction(&cd->Optimizer);
67 std::cerr << "Assembler: ";
68 DumpAction(&cd->Assembler);
69 std::cerr << "Linker: ";
70 DumpAction(&cd->Linker);
73 /// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
74 /// which should reduce the volume of code and make compilation
75 /// faster. This is also safe on any llvm module.
76 static const char* DefaultFastCompileOptimizations[] = {
77 "-simplifycfg", "-mem2reg", "-instcombine"
81 // Stuff in this namespace properly belongs in lib/System and needs
82 // to be portable but we're avoiding that for now.
85 bool FileReadable(const std::string& fname) {
86 return 0 == access(fname.c_str(), F_OK | R_OK);
89 void CleanupTempFile(const std::string& fname) {
90 if (FileReadable(fname))
91 unlink(fname.c_str());
94 std::string MakeTemporaryDirectory() {
96 strcpy(temp_name,"/tmp/llvm_XXXXXX");
97 if (0 == mkdtemp(temp_name))
98 throw std::string("Can't create temporary directory");
102 std::string FindExecutableInPath(const std::string& program) {
103 // First, just see if the program is already executable
104 if (isExecutableFile(program)) return program;
106 // Get the path. If its empty, we can't do anything
107 const char *PathStr = getenv("PATH");
108 if (PathStr == 0) return "";
110 // Now we have a colon separated list of directories to search; try them.
111 unsigned PathLen = strlen(PathStr);
113 // Find the first colon...
114 const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
116 // Check to see if this first directory contains the executable...
117 std::string FilePath = std::string(PathStr, Colon) + '/' + program;
118 if (isExecutableFile(FilePath))
119 return FilePath; // Found the executable!
121 // Nope it wasn't in this directory, check the next range!
122 PathLen -= Colon-PathStr;
125 // Advance past duplicate coons
126 while (*PathStr == ':') {
132 // If we fell out, we ran out of directories in PATH to search, return failure
137 CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
139 , finalPhase(LINKING)
140 , optLevel(OPT_FAST_COMPILE)
146 , emitNativeCode(false)
153 // FIXME: These libraries are platform specific
154 LibraryPaths.push_back("/lib");
155 LibraryPaths.push_back("/usr/lib");
156 AdditionalArgs.reserve(NUM_PHASES);
157 StringVector emptyVec;
158 for (unsigned i = 0; i < NUM_PHASES; ++i)
159 AdditionalArgs.push_back(emptyVec);
162 CompilerDriver::~CompilerDriver() {
164 LibraryPaths.clear();
165 AdditionalArgs.clear();
168 CompilerDriver::ConfigData::ConfigData()
176 StringVector emptyVec;
177 for (unsigned i = 0; i < NUM_PHASES; ++i)
178 opts.push_back(emptyVec);
181 void CompilerDriver::error( const std::string& errmsg ) {
182 std::cerr << "llvmc: Error: " << errmsg << ".\n";
186 CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
187 const std::string& input,
188 const std::string& output,
191 Action* pat = 0; ///< The pattern/template for the action
192 Action* action = new Action; ///< The actual action to execute
194 // Get the action pattern
196 case PREPROCESSING: pat = &cd->PreProcessor; break;
197 case TRANSLATION: pat = &cd->Translator; break;
198 case OPTIMIZATION: pat = &cd->Optimizer; break;
199 case ASSEMBLY: pat = &cd->Assembler; break;
200 case LINKING: pat = &cd->Linker; break;
202 assert(!"Invalid driver phase!");
205 assert(pat != 0 && "Invalid command pattern");
207 // Copy over some pattern things that don't need to change
208 action->program = pat->program;
209 action->flags = pat->flags;
211 // Do the substitutions from the pattern to the actual
212 StringVector::iterator PI = pat->args.begin();
213 StringVector::iterator PE = pat->args.end();
215 if ((*PI)[0] == '%') {
217 action->args.push_back(input);
218 } else if (*PI == "%out%") {
219 action->args.push_back(output);
220 } else if (*PI == "%time%") {
222 action->args.push_back("-time-passes");
223 } else if (*PI == "%stats%") {
225 action->args.push_back("-stats");
226 } else if (*PI == "%target%") {
227 // FIXME: Ignore for now
228 } else if (*PI == "%opt%") {
230 if (pat->isSet(GROKS_DASH_O)) {
231 if (optLevel != OPT_NONE) {
232 std::string optArg("-O");
234 case OPT_FAST_COMPILE : optArg.append("1"); break;
235 case OPT_SIMPLE: optArg.append("2"); break;
236 case OPT_AGGRESSIVE: optArg.append("3"); break;
237 case OPT_LINK_TIME: optArg.append("4"); break;
238 case OPT_AGGRESSIVE_LINK_TIME: optArg.append("5"); break;
240 assert(!"Invalid optimization argument!");
244 action->args.push_back(optArg);
247 if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
248 !cd->opts[optLevel].empty())
249 action->args.insert(action->args.end(), cd->opts[optLevel].begin(),
250 cd->opts[optLevel].end());
254 error("Invalid substitution name");
257 // Its not a substitution, just put it in the action
258 action->args.push_back(*PI);
263 // Get specific options for each kind of action type
264 StringVector& args = AdditionalArgs[phase];
266 // Add specific options for each kind of action type
267 action->args.insert(action->args.end(), args.begin(), args.end());
269 // Finally, we're done
273 bool CompilerDriver::DoAction(Action*action) {
274 assert(action != 0 && "Invalid Action!");
278 std::string prog(sys::FindExecutableInPath(action->program));
280 error("Can't find program '" + action->program + "'");
282 // Get the program's arguments
283 const char* argv[action->args.size() + 1];
284 argv[0] = prog.c_str();
286 for (; i <= action->args.size(); ++i)
287 argv[i] = action->args[i-1].c_str();
290 // Invoke the program
291 return !ExecWait(argv, environ);
296 int CompilerDriver::execute(const InputList& InpList,
297 const std::string& Output ) {
298 // Echo the configuration of options if we're running verbose
301 std::cerr << "Compiler Driver Options:\n";
302 std::cerr << "DryRun = " << isDryRun << "\n";
303 std::cerr << "Verbose = " << isVerbose << " \n";
304 std::cerr << "TimeActions = " << timeActions << "\n";
305 std::cerr << "EmitRawCode = " << emitRawCode << "\n";
306 std::cerr << "OutputMachine = " << machine << "\n";
307 std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
308 InputList::const_iterator I = InpList.begin();
309 while ( I != InpList.end() ) {
310 std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
313 std::cerr << "Output: " << Output << "\n";
316 // If there's no input, we're done.
318 error("Nothing to compile.");
320 // If they are asking for linking and didn't provide an output
321 // file then its an error (no way for us to "make up" a meaningful
322 // file name based on the various linker input files).
323 if (finalPhase == LINKING && Output.empty())
324 error("An output file name must be specified for linker output");
326 // This vector holds all the resulting actions of the following loop.
327 std::vector<Action*> actions;
329 // Create a temporary directory for our temporary files
330 std::string TempDir(sys::MakeTemporaryDirectory());
331 std::string TempPreprocessorOut(TempDir + "/preproc.o");
332 std::string TempTranslatorOut(TempDir + "/trans.o");
333 std::string TempOptimizerOut(TempDir + "/opt.o");
334 std::string TempAssemblerOut(TempDir + "/asm.o");
336 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
337 // for each input item
338 std::vector<std::string> LinkageItems;
339 InputList::const_iterator I = InpList.begin();
340 while ( I != InpList.end() ) {
341 // Get the suffix of the file name
342 std::string suffix = GetSuffix(I->first);
344 // If its a library, bytecode file, or object file, save
345 // it for linking below and short circuit the
346 // pre-processing/translation/assembly phases
347 if (I->second.empty() || suffix == "o" || suffix == "bc") {
348 // We shouldn't get any of these types of files unless we're
349 // later going to link. Enforce this limit now.
350 if (finalPhase != LINKING) {
351 error("Pre-compiled objects found but linking not requested");
353 LinkageItems.push_back(I->first);
354 continue; // short circuit remainder of loop
357 // At this point, we know its something we need to translate
358 // and/or optimize. See if we can get the configuration data
359 // for this kind of file.
360 ConfigData* cd = cdp->ProvideConfigData(I->second);
362 error(std::string("Files of type '") + I->second +
363 "' are not recognized." );
365 DumpConfigData(cd,I->second);
367 // We have valid configuration data, now figure out where the output
368 // of compilation should end up.
370 if (finalPhase != LINKING) {
371 if (InpList.size() == 1 && !Output.empty())
374 OutFile = RemoveSuffix(I->first) + OutputSuffix;
379 // Initialize the input file
380 std::string InFile(I->first);
382 // PRE-PROCESSING PHASE
383 Action& action = cd->PreProcessor;
385 // Get the preprocessing action, if needed, or error if appropriate
386 if (!action.program.empty()) {
387 if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
388 if (finalPhase == PREPROCESSING)
389 actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
391 actions.push_back(GetAction(cd,InFile,TempPreprocessorOut,
393 InFile = TempPreprocessorOut;
396 } else if (finalPhase == PREPROCESSING) {
397 error(cd->langName + " does not support pre-processing");
398 } else if (action.isSet(REQUIRED_FLAG)) {
399 error(std::string("Don't know how to pre-process ") +
400 cd->langName + " files");
403 // Short-circuit remaining actions if all they want is pre-processing
404 if (finalPhase == PREPROCESSING) { ++I; continue; };
406 /// TRANSLATION PHASE
407 action = cd->Translator;
409 // Get the translation action, if needed, or error if appropriate
410 if (!action.program.empty()) {
411 if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
412 if (finalPhase == TRANSLATION)
413 actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
415 actions.push_back(GetAction(cd,InFile,TempTranslatorOut,TRANSLATION));
416 InFile = TempTranslatorOut;
420 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
421 /// The output of the translator is an LLVM Assembly program
422 /// We need to translate it to bytecode
423 Action* action = new Action();
424 action->program = "llvm-as";
425 action->args.push_back(InFile);
426 action->args.push_back("-o");
428 action->args.push_back(InFile);
429 actions.push_back(action);
432 } else if (finalPhase == TRANSLATION) {
433 error(cd->langName + " does not support translation");
434 } else if (action.isSet(REQUIRED_FLAG)) {
435 error(std::string("Don't know how to translate ") +
436 cd->langName + " files");
439 // Short-circuit remaining actions if all they want is translation
440 if (finalPhase == TRANSLATION) { ++I; continue; }
442 /// OPTIMIZATION PHASE
443 action = cd->Optimizer;
445 // Get the optimization action, if needed, or error if appropriate
446 if (!action.program.empty() && !emitRawCode) {
447 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
448 if (finalPhase == OPTIMIZATION)
449 actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
451 actions.push_back(GetAction(cd,InFile,TempOptimizerOut,OPTIMIZATION));
452 InFile = TempOptimizerOut;
455 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
456 /// The output of the translator is an LLVM Assembly program
457 /// We need to translate it to bytecode
458 Action* action = new Action();
459 action->program = "llvm-as";
460 action->args.push_back(InFile);
461 action->args.push_back("-f");
462 action->args.push_back("-o");
464 action->args.push_back(InFile);
465 actions.push_back(action);
468 } else if (finalPhase == OPTIMIZATION) {
469 error(cd->langName + " does not support optimization");
470 } else if (action.isSet(REQUIRED_FLAG)) {
471 error(std::string("Don't know how to optimize ") +
472 cd->langName + " files");
475 // Short-circuit remaining actions if all they want is optimization
476 if (finalPhase == OPTIMIZATION) { ++I; continue; }
479 action = cd->Assembler;
481 if (finalPhase == ASSEMBLY) {
482 if (emitNativeCode) {
483 if (action.program.empty()) {
484 error(std::string("Native Assembler not specified for ") +
485 cd->langName + " files");
487 actions.push_back(GetAction(cd,InFile,OutFile,ASSEMBLY));
490 // Just convert back to llvm assembly with llvm-dis
491 Action* action = new Action();
492 action->program = "llvm-dis";
493 action->args.push_back(InFile);
494 action->args.push_back("-f");
495 action->args.push_back("-o");
496 action->args.push_back(OutFile);
497 actions.push_back(action);
501 // Go to next file to be processed
506 if (finalPhase == LINKING) {
507 if (emitNativeCode) {
513 std::vector<Action*>::iterator aIter = actions.begin();
514 while (aIter != actions.end()) {
515 if (!DoAction(*aIter))
516 error("Action failed");
522 ::sys::CleanupTempFile(TempPreprocessorOut);
523 ::sys::CleanupTempFile(TempTranslatorOut);
524 ::sys::CleanupTempFile(TempOptimizerOut);
526 // Cleanup temporary directory we created
527 if (::sys::FileReadable(TempDir))
528 rmdir(TempDir.c_str());
534 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab