X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvmc%2FCompilerDriver.cpp;h=1a316c84390bbb471b9f35ede6495096a50257f1;hb=c30088f9612c949b047884deab045e2421690691;hp=b890220c9ca1eee1ae1a8452e5a956091423e7e7;hpb=af77d74e07cb63322829fdde579826abdab8ea36;p=oota-llvm.git diff --git a/tools/llvmc/CompilerDriver.cpp b/tools/llvmc/CompilerDriver.cpp index b890220c9ca..1a316c84390 100644 --- a/tools/llvmc/CompilerDriver.cpp +++ b/tools/llvmc/CompilerDriver.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringExtras.h" #include +#include "llvm/Config/alloca.h" using namespace llvm; @@ -28,9 +29,9 @@ namespace { void WriteAction(CompilerDriver::Action* action ) { std::cerr << action->program.c_str(); - std::vector::iterator I = action->args.begin(); + std::vector::const_iterator I = action->args.begin(); while (I != action->args.end()) { - std::cerr << " " + *I; + std::cerr << " " << *I; ++I; } std::cerr << "\n"; @@ -38,9 +39,9 @@ void WriteAction(CompilerDriver::Action* action ) { void DumpAction(CompilerDriver::Action* action) { std::cerr << "command = " << action->program.c_str(); - std::vector::iterator I = action->args.begin(); + std::vector::const_iterator I = action->args.begin(); while (I != action->args.end()) { - std::cerr << " " + *I; + std::cerr << " " << *I; ++I; } std::cerr << "\n"; @@ -134,7 +135,7 @@ public: StringVector::const_iterator E = paths.end(); while (I != E) { sys::Path tmp; - tmp.set_directory(*I); + tmp.setDirectory(*I); IncludePaths.push_back(tmp); ++I; } @@ -149,7 +150,7 @@ public: StringVector::const_iterator E = paths.end(); while (I != E) { sys::Path tmp; - tmp.set_directory(*I); + tmp.setDirectory(*I); LibraryPaths.push_back(tmp); ++I; } @@ -159,6 +160,10 @@ public: LibraryPaths.push_back(libPath); } + virtual void addToolPath( const sys::Path& toolPath ) { + ToolPaths.push_back(toolPath); + } + virtual void setfPassThrough(const StringVector& fOpts) { fOptions = fOpts; } @@ -172,6 +177,7 @@ public: virtual void setWPassThrough(const StringVector& WOpts) { WOptions = WOpts; } + /// @} /// @name Functions /// @{ @@ -182,19 +188,19 @@ private: void cleanup() { if (!isSet(KEEP_TEMPS_FLAG)) { - if (TempDir.is_directory() && TempDir.writable()) - TempDir.destroy_directory(/*remove_contents=*/true); + if (TempDir.isDirectory() && TempDir.writable()) + TempDir.destroyDirectory(/*remove_contents=*/true); } else { - std::cout << "Temporary files are in " << TempDir.get() << "\n"; + std::cout << "Temporary files are in " << TempDir << "\n"; } } sys::Path MakeTempFile(const std::string& basename, const std::string& suffix ) { sys::Path result(TempDir); - if (!result.append_file(basename)) + if (!result.appendFile(basename)) throw basename + ": can't use this file name"; - if (!result.append_suffix(suffix)) + if (!result.appendSuffix(suffix)) throw suffix + ": can't use this file suffix"; return result; } @@ -257,19 +263,20 @@ private: break; case 'f': if (*PI == "%fOpts%") { - action->args.insert(action->args.end(), fOptions.begin(), - fOptions.end()); + if (!fOptions.empty()) + action->args.insert(action->args.end(), fOptions.begin(), + fOptions.end()); } else found = false; break; case 'i': if (*PI == "%in%") { - action->args.push_back(input.get()); + action->args.push_back(input.toString()); } else if (*PI == "%incls%") { PathVector::iterator I = IncludePaths.begin(); PathVector::iterator E = IncludePaths.end(); while (I != E) { - action->args.push_back( std::string("-I") + I->get() ); + action->args.push_back( std::string("-I") + I->toString() ); ++I; } } else @@ -280,7 +287,7 @@ private: PathVector::iterator I = LibraryPaths.begin(); PathVector::iterator E = LibraryPaths.end(); while (I != E) { - action->args.push_back( std::string("-L") + I->get() ); + action->args.push_back( std::string("-L") + I->toString() ); ++I; } } else @@ -288,7 +295,7 @@ private: break; case 'o': if (*PI == "%out%") { - action->args.push_back(output.get()); + action->args.push_back(output.toString()); } else if (*PI == "%opt%") { if (!isSet(EMIT_RAW_FLAG)) { if (cd->opts.size() > static_cast(optLevel) && @@ -327,16 +334,19 @@ private: found = false; break; case 'M': - if (*PI == "%Mopts") { - action->args.insert(action->args.end(), MOptions.begin(), - MOptions.end()); + if (*PI == "%Mopts%") { + if (!MOptions.empty()) + action->args.insert(action->args.end(), MOptions.begin(), + MOptions.end()); } else found = false; break; case 'W': - if (*PI == "%Wopts") { - action->args.insert(action->args.end(), WOptions.begin(), - WOptions.end()); + if (*PI == "%Wopts%") { + for (StringVector::iterator I = WOptions.begin(), + E = WOptions.end(); I != E ; ++I ) { + action->args.push_back( std::string("-W") + *I ); + } } else found = false; break; @@ -349,13 +359,13 @@ private: if (PI->length()>1 && (*PI)[0] == '%' && (*PI)[PI->length()-1] == '%') { throw std::string("Invalid substitution token: '") + *PI + - "' for command '" + pat->program.get() + "'"; - } else { + "' for command '" + pat->program.toString() + "'"; + } else if (!PI->empty()) { // It's not a legal substitution, just pass it through action->args.push_back(*PI); } } - } else { + } else if (!PI->empty()) { // Its not a substitution, just put it in the action action->args.push_back(*PI); } @@ -372,58 +382,72 @@ private: WriteAction(action); if (!isSet(DRY_RUN_FLAG)) { sys::Path progpath = sys::Program::FindProgramByName( - action->program.get()); - if (progpath.is_empty()) - throw std::string("Can't find program '"+progpath.get()+"'"); + action->program.toString()); + if (progpath.isEmpty()) + throw std::string("Can't find program '" + + action->program.toString()+"'"); else if (progpath.executable()) action->program = progpath; else - throw std::string("Program '"+progpath.get()+"' is not executable."); + throw std::string("Program '"+action->program.toString()+ + "' is not executable."); // Invoke the program + const char** Args = (const char**) + alloca(sizeof(const char*)*(action->args.size()+2)); + Args[0] = action->program.toString().c_str(); + for (unsigned i = 1; i != action->args.size(); ++i) + Args[i] = action->args[i].c_str(); + Args[action->args.size()] = 0; // null terminate list. if (isSet(TIME_ACTIONS_FLAG)) { - Timer timer(action->program.get()); + Timer timer(action->program.toString()); timer.startTimer(); - int resultCode = - sys::Program::ExecuteAndWait(action->program,action->args); + int resultCode = sys::Program::ExecuteAndWait(action->program, Args); timer.stopTimer(); timer.print(timer,std::cerr); return resultCode == 0; } else - return 0 == - sys::Program::ExecuteAndWait(action->program, action->args); + return 0 == sys::Program::ExecuteAndWait(action->program, Args); } return true; } /// This method tries various variants of a linkage item's file /// name to see if it can find an appropriate file to link with - /// in the directory specified. + /// in the directories of the LibraryPaths. llvm::sys::Path GetPathForLinkageItem(const std::string& link_item, - const sys::Path& dir, bool native = false) { - sys::Path fullpath(dir); - fullpath.append_file(link_item); - if (native) { - fullpath.append_suffix("a"); - } else { - fullpath.append_suffix("bc"); - if (fullpath.readable()) - return fullpath; - fullpath.elide_suffix(); - fullpath.append_suffix("o"); - if (fullpath.readable()) - return fullpath; - fullpath = dir; - fullpath.append_file(std::string("lib") + link_item); - fullpath.append_suffix("a"); - if (fullpath.readable()) - return fullpath; - fullpath.elide_suffix(); - fullpath.append_suffix("so"); + sys::Path fullpath; + fullpath.setFile(link_item); + if (fullpath.readable()) + return fullpath; + for (PathVector::iterator PI = LibraryPaths.begin(), + PE = LibraryPaths.end(); PI != PE; ++PI) { + fullpath.setDirectory(PI->toString()); + fullpath.appendFile(link_item); if (fullpath.readable()) return fullpath; + if (native) { + fullpath.appendSuffix("a"); + } else { + fullpath.appendSuffix("bc"); + if (fullpath.readable()) + return fullpath; + fullpath.elideSuffix(); + fullpath.appendSuffix("o"); + if (fullpath.readable()) + return fullpath; + fullpath = *PI; + fullpath.appendFile(std::string("lib") + link_item); + fullpath.appendSuffix("a"); + if (fullpath.readable()) + return fullpath; + fullpath.elideSuffix(); + fullpath.appendSuffix("so"); + if (fullpath.readable()) + return fullpath; + } } // Didn't find one. @@ -442,20 +466,15 @@ private: // we must track down the file in the lib search path. sys::Path fullpath; if (!link_item.readable()) { - // First, look for the library using the -L arguments specified + // look for the library using the -L arguments specified // on the command line. - PathVector::iterator PI = LibraryPaths.begin(); - PathVector::iterator PE = LibraryPaths.end(); - while (PI != PE && fullpath.is_empty()) { - fullpath = GetPathForLinkageItem(link_item.get(),*PI); - ++PI; - } + fullpath = GetPathForLinkageItem(link_item.toString()); // If we didn't find the file in any of the library search paths - // so we have to bail. No where else to look. - if (fullpath.is_empty()) { + // we have to bail. No where else to look. + if (fullpath.isEmpty()) { err = - std::string("Can't find linkage item '") + link_item.get() + "'"; + std::string("Can't find linkage item '") + link_item.toString() + "'"; return false; } } else { @@ -466,10 +485,10 @@ private: set.insert(fullpath); // If its an LLVM bytecode file ... - if (fullpath.is_bytecode_file()) { + if (fullpath.isBytecodeFile()) { // Process the dependent libraries recursively Module::LibraryListType modlibs; - if (GetBytecodeDependentLibraries(fullpath.get(),modlibs)) { + if (GetBytecodeDependentLibraries(fullpath.toString(),modlibs)) { // Traverse the dependent libraries list Module::lib_iterator LI = modlibs.begin(); Module::lib_iterator LE = modlibs.end(); @@ -478,9 +497,9 @@ private: if (err.empty()) { err = std::string("Library '") + *LI + "' is not valid for linking but is required by file '" + - fullpath.get() + "'"; + fullpath.toString() + "'"; } else { - err += " which is required by file '" + fullpath.get() + "'"; + err += " which is required by file '" + fullpath.toString() + "'"; } return false; } @@ -489,7 +508,7 @@ private: } else if (err.empty()) { err = std::string( "The dependent libraries could not be extracted from '") + - fullpath.get(); + fullpath.toString(); return false; } } @@ -516,11 +535,11 @@ public: std::cerr << "OutputMachine = " << machine << "\n"; InputList::const_iterator I = InpList.begin(); while ( I != InpList.end() ) { - std::cerr << "Input: " << I->first.get() << "(" << I->second + std::cerr << "Input: " << I->first << "(" << I->second << ")\n"; ++I; } - std::cerr << "Output: " << Output.get() << "\n"; + std::cerr << "Output: " << Output << "\n"; } // If there's no input, we're done. @@ -530,13 +549,13 @@ public: // If they are asking for linking and didn't provide an output // file then its an error (no way for us to "make up" a meaningful // file name based on the various linker input files). - if (finalPhase == LINKING && Output.is_empty()) + if (finalPhase == LINKING && Output.isEmpty()) throw std::string( "An output file name must be specified for linker output"); // If they are not asking for linking, provided an output file and // there is more than one input file, its an error - if (finalPhase != LINKING && !Output.is_empty() && InpList.size() > 1) + if (finalPhase != LINKING && !Output.isEmpty() && InpList.size() > 1) throw std::string("An output file name cannot be specified ") + "with more than one input file name when not linking"; @@ -546,9 +565,10 @@ public: /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases // for each input item SetVector LinkageItems; - std::vector LibFiles; + StringVector LibFiles; InputList::const_iterator I = InpList.begin(); - while ( I != InpList.end() ) { + for (InputList::const_iterator I = InpList.begin(), E = InpList.end(); + I != E; ++I ) { // Get the suffix of the file name const std::string& ftype = I->second; @@ -563,10 +583,10 @@ public: "Pre-compiled objects found but linking not requested"); } if (ftype.empty()) - LibFiles.push_back(I->first.get()); + LibFiles.push_back(I->first.toString()); else LinkageItems.insert(I->first); - ++I; continue; // short circuit remainder of loop + continue; // short circuit remainder of loop } // At this point, we know its something we need to translate @@ -579,21 +599,31 @@ public: if (isSet(DEBUG_FLAG)) DumpConfigData(cd,I->second); + // Add the config data's library paths to the end of the list + for (StringVector::iterator LPI = cd->libpaths.begin(), + LPE = cd->libpaths.end(); LPI != LPE; ++LPI){ + LibraryPaths.push_back(sys::Path(*LPI)); + } + // Initialize the input and output files sys::Path InFile(I->first); - sys::Path OutFile(I->first.get_basename()); + sys::Path OutFile(I->first.getBasename()); // PRE-PROCESSING PHASE Action& action = cd->PreProcessor; // Get the preprocessing action, if needed, or error if appropriate - if (!action.program.is_empty()) { + if (!action.program.isEmpty()) { if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) { if (finalPhase == PREPROCESSING) { - OutFile.append_suffix("E"); - actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING)); + if (Output.isEmpty()) { + OutFile.appendSuffix("E"); + actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING)); + } else { + actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING)); + } } else { - sys::Path TempFile(MakeTempFile(I->first.get_basename(),"E")); + sys::Path TempFile(MakeTempFile(I->first.getBasename(),"E")); actions.push_back(GetAction(cd,InFile,TempFile, PREPROCESSING)); InFile = TempFile; @@ -608,19 +638,23 @@ public: // Short-circuit remaining actions if all they want is // pre-processing - if (finalPhase == PREPROCESSING) { ++I; continue; }; + if (finalPhase == PREPROCESSING) { continue; }; /// TRANSLATION PHASE action = cd->Translator; // Get the translation action, if needed, or error if appropriate - if (!action.program.is_empty()) { + if (!action.program.isEmpty()) { if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) { if (finalPhase == TRANSLATION) { - OutFile.append_suffix("o"); - actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION)); + if (Output.isEmpty()) { + OutFile.appendSuffix("o"); + actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION)); + } else { + actions.push_back(GetAction(cd,InFile,Output,TRANSLATION)); + } } else { - sys::Path TempFile(MakeTempFile(I->first.get_basename(),"trans")); + sys::Path TempFile(MakeTempFile(I->first.getBasename(),"trans")); actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION)); InFile = TempFile; } @@ -630,11 +664,11 @@ public: /// The output of the translator is an LLVM Assembly program /// We need to translate it to bytecode Action* action = new Action(); - action->program.set_file("llvm-as"); - action->args.push_back(InFile.get()); + action->program.setFile("llvm-as"); + action->args.push_back(InFile.toString()); action->args.push_back("-o"); - InFile.append_suffix("bc"); - action->args.push_back(InFile.get()); + InFile.appendSuffix("bc"); + action->args.push_back(InFile.toString()); actions.push_back(action); } } @@ -646,20 +680,24 @@ public: } // Short-circuit remaining actions if all they want is translation - if (finalPhase == TRANSLATION) { ++I; continue; } + if (finalPhase == TRANSLATION) { continue; } /// OPTIMIZATION PHASE action = cd->Optimizer; // Get the optimization action, if needed, or error if appropriate if (!isSet(EMIT_RAW_FLAG)) { - if (!action.program.is_empty()) { + if (!action.program.isEmpty()) { if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) { if (finalPhase == OPTIMIZATION) { - OutFile.append_suffix("o"); - actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION)); + if (Output.isEmpty()) { + OutFile.appendSuffix("o"); + actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION)); + } else { + actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION)); + } } else { - sys::Path TempFile(MakeTempFile(I->first.get_basename(),"opt")); + sys::Path TempFile(MakeTempFile(I->first.getBasename(),"opt")); actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION)); InFile = TempFile; } @@ -668,12 +706,12 @@ public: /// The output of the optimizer is an LLVM Assembly program /// We need to translate it to bytecode with llvm-as Action* action = new Action(); - action->program.set_file("llvm-as"); - action->args.push_back(InFile.get()); + action->program.setFile("llvm-as"); + action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); - InFile.append_suffix("bc"); - action->args.push_back(InFile.get()); + InFile.appendSuffix("bc"); + action->args.push_back(InFile.toString()); actions.push_back(action); } } @@ -686,43 +724,52 @@ public: } // Short-circuit remaining actions if all they want is optimization - if (finalPhase == OPTIMIZATION) { ++I; continue; } + if (finalPhase == OPTIMIZATION) { continue; } /// ASSEMBLY PHASE action = cd->Assembler; if (finalPhase == ASSEMBLY) { + + // Build either a native compilation action or a disassembly action + Action* action = new Action(); if (isSet(EMIT_NATIVE_FLAG)) { // Use llc to get the native assembly file - Action* action = new Action(); - action->program.set_file("llc"); - action->args.push_back(InFile.get()); + action->program.setFile("llc"); + action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); - OutFile.append_suffix("s"); - action->args.push_back(OutFile.get()); + if (Output.isEmpty()) { + OutFile.appendSuffix("o"); + action->args.push_back(OutFile.toString()); + } else { + action->args.push_back(Output.toString()); + } + actions.push_back(action); } else { // Just convert back to llvm assembly with llvm-dis - Action* action = new Action(); - action->program.set_file("llvm-dis"); - action->args.push_back(InFile.get()); + action->program.setFile("llvm-dis"); + action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); - OutFile.append_suffix("ll"); - action->args.push_back(OutFile.get()); - actions.push_back(action); + if (Output.isEmpty()) { + OutFile.appendSuffix("ll"); + action->args.push_back(OutFile.toString()); + } else { + action->args.push_back(Output.toString()); + } } + // Put the action on the list + actions.push_back(action); + // Short circuit the rest of the loop, we don't want to link - ++I; continue; } // Register the result of the actions as a link candidate LinkageItems.insert(InFile); - // Go to next file to be processed - ++I; } // end while loop over each input file /// RUN THE COMPILATION ACTIONS @@ -738,12 +785,13 @@ public: if (finalPhase == LINKING) { // Insert the platform-specific system libraries to the path list - LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1()); - LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2()); + std::vector SysLibs; + sys::Path::GetSystemLibraryPaths(SysLibs); + LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end()); // Set up the linking action with llvm-ld Action* link = new Action(); - link->program.set_file("llvm-ld"); + link->program.setFile("llvm-ld"); // Add in the optimization level requested switch (optLevel) { @@ -771,17 +819,17 @@ public: // -l arguments specified. for (PathVector::const_iterator I=LinkageItems.begin(), E=LinkageItems.end(); I != E; ++I ) - link->args.push_back(I->get()); + link->args.push_back(I->toString()); // Add in all the libraries we found. - for (std::vector::const_iterator I=LibFiles.begin(), + for (StringVector::const_iterator I=LibFiles.begin(), E=LibFiles.end(); I != E; ++I ) link->args.push_back(std::string("-l")+*I); // Add in all the library paths to the command line for (PathVector::const_iterator I=LibraryPaths.begin(), E=LibraryPaths.end(); I != E; ++I) - link->args.push_back( std::string("-L") + I->get()); + link->args.push_back( std::string("-L") + I->toString()); // Add in the additional linker arguments requested for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(), @@ -806,7 +854,7 @@ public: // Add in mandatory flags link->args.push_back("-o"); - link->args.push_back(Output.get()); + link->args.push_back(Output.toString()); // Execute the link if (!DoAction(link)) @@ -834,6 +882,7 @@ private: std::string machine; ///< Target machine name PathVector LibraryPaths; ///< -L options PathVector IncludePaths; ///< -I options + PathVector ToolPaths; ///< -B options StringVector Defines; ///< -D options sys::Path TempDir; ///< Name of the temporary directory. StringTable AdditionalArgs; ///< The -Txyz options