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"
22 inline std::string RemoveSuffix(const std::string& fullName) {
23 size_t dotpos = fullName.rfind('.',fullName.size());
24 if ( dotpos == std::string::npos ) return fullName;
25 return fullName.substr(0, dotpos);
28 inline std::string GetSuffix(const std::string& fullName) {
29 size_t dotpos = fullName.rfind('.',fullName.size());
30 if ( dotpos = std::string::npos ) return "";
31 return fullName.substr(dotpos+1);
34 const char OutputSuffix[] = ".o";
36 void WriteAction(CompilerDriver::Action* a ) {
37 std::cerr << a->program;
38 std::vector<std::string>::iterator I = a->args.begin();
39 while (I != a->args.end()) {
40 std::cerr << " " + *I;
46 void DumpAction(CompilerDriver::Action* a) {
47 std::cerr << "command = " << a->program;
48 std::vector<std::string>::iterator I = a->args.begin();
49 while (I != a->args.end()) {
50 std::cerr << " " + *I;
54 std::cerr << "flags = " << a->flags << "\n";
55 std::cerr << "inputAt = " << a->inputAt << "\n";
56 std::cerr << "outputAt = " << a->outputAt << "\n";
59 void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
60 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
62 std::cerr << "PreProcessor: ";
63 DumpAction(&cd->PreProcessor);
64 std::cerr << "Translator: ";
65 DumpAction(&cd->Translator);
66 std::cerr << "Optimizer: ";
67 DumpAction(&cd->Optimizer);
68 std::cerr << "Assembler: ";
69 DumpAction(&cd->Assembler);
70 std::cerr << "Linker: ";
71 DumpAction(&cd->Linker);
74 void CleanupTempFile(const char* fname) {
75 if (0 == access(fname, F_OK | R_OK))
79 /// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
80 /// which should reduce the volume of code and make compilation
81 /// faster. This is also safe on any llvm module.
82 static const char* DefaultOptimizations[] = {
83 "-simplifycfg", "-mem2reg", "-mergereturn", "-instcombine",
87 CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
90 , optLevel(OPT_FAST_COMPILE)
96 , emitNativeCode(false)
99 , PreprocessorOptions()
100 , TranslatorOptions()
105 // FIXME: These libraries are platform specific
106 LibraryPaths.push_back("/lib");
107 LibraryPaths.push_back("/usr/lib");
110 CompilerDriver::~CompilerDriver() {
112 LibraryPaths.clear();
113 PreprocessorOptions.clear();
114 TranslatorOptions.clear();
115 OptimizerOptions.clear();
116 AssemblerOptions.clear();
117 LinkerOptions.clear();
120 void CompilerDriver::error( const std::string& errmsg ) {
121 std::cerr << "Error: " << errmsg << ".\n";
125 inline std::string makeDashO(CompilerDriver::OptimizationLevels lev) {
126 if (lev == CompilerDriver::OPT_NONE) return "";
127 std::string result("-O");
129 case CompilerDriver::OPT_FAST_COMPILE : result.append("1"); break;
130 case CompilerDriver::OPT_SIMPLE: result.append("2"); break;
131 case CompilerDriver::OPT_AGGRESSIVE: result.append("3"); break;
132 case CompilerDriver::OPT_LINK_TIME: result.append("4"); break;
133 case CompilerDriver::OPT_AGGRESSIVE_LINK_TIME: result.append("5"); break;
134 default: assert(!"Invalid optimization level!");
139 CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
140 const std::string& input,
141 const std::string& output,
145 // Get the action pattern
147 case PREPROCESSING: pat = &cd->PreProcessor; break;
148 case TRANSLATION: pat = &cd->Translator; break;
149 case OPTIMIZATION: pat = &cd->Optimizer; break;
150 case ASSEMBLY: pat = &cd->Assembler; break;
151 case LINKING: pat = &cd->Linker; break;
153 assert(!"Invalid driver phase!");
156 assert(pat != 0 && "Invalid command pattern");
158 // Create the resulting action
159 Action* a = new Action(*pat);
161 // Replace the substitution arguments
162 if (pat->inputAt < a->args.size())
163 a->args[pat->inputAt] = input;
164 if (pat->outputAt < a->args.size())
165 a->args[pat->outputAt] = output;
167 // Insert specific options for each kind of action type
170 a->args.insert(a->args.begin(), PreprocessorOptions.begin(),
171 PreprocessorOptions.end());
174 a->args.insert(a->args.begin(), TranslatorOptions.begin(),
175 TranslatorOptions.end());
176 if (a->isSet(GROKS_DASH_O_FLAG))
177 a->args.insert(a->args.begin(), makeDashO(optLevel));
178 else if (a->isSet(GROKS_O10N_FLAG))
179 a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
180 cd->opts[optLevel].end());
183 a->args.insert(a->args.begin(), OptimizerOptions.begin(),
184 OptimizerOptions.end());
185 if (a->isSet(GROKS_DASH_O_FLAG))
186 a->args.insert(a->args.begin(), makeDashO(optLevel));
187 else if (a->isSet(GROKS_O10N_FLAG))
188 a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
189 cd->opts[optLevel].end());
192 a->args.insert(a->args.begin(), AssemblerOptions.begin(),
193 AssemblerOptions.end());
196 a->args.insert(a->args.begin(), LinkerOptions.begin(),
197 LinkerOptions.end());
198 if (a->isSet(GROKS_DASH_O_FLAG))
199 a->args.insert(a->args.begin(), makeDashO(optLevel));
200 else if (a->isSet(GROKS_O10N_FLAG))
201 a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
202 cd->opts[optLevel].end());
205 assert(!"Invalid driver phase!");
211 void CompilerDriver::DoAction(Action*a)
216 std::cerr << "execve(\"" << a->program << "\",[\"";
217 std::vector<std::string>::iterator I = a->args.begin();
218 while (I != a->args.end()) {
221 if (I != a->args.end())
222 std::cerr << "\",\"";
224 std::cerr << "\"],ENV);\n";
228 int CompilerDriver::execute(const InputList& InpList,
229 const std::string& Output ) {
230 // Echo the configuration of options if we're running verbose
233 std::cerr << "Compiler Driver Options:\n";
234 std::cerr << "DryRun = " << isDryRun << "\n";
235 std::cerr << "Verbose = " << isVerbose << " \n";
236 std::cerr << "TimeActions = " << timeActions << "\n";
237 std::cerr << "EmitRawCode = " << emitRawCode << "\n";
238 std::cerr << "OutputMachine = " << machine << "\n";
239 std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
240 InputList::const_iterator I = InpList.begin();
241 while ( I != InpList.end() ) {
242 std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
245 std::cerr << "Output: " << Output << "\n";
248 // If there's no input, we're done.
250 error("Nothing to compile.");
252 // If they are asking for linking and didn't provide an output
253 // file then its an error (no way for us to "make up" a meaningful
254 // file name based on the various linker input files).
255 if (finalPhase == LINKING && Output.empty())
256 error("An output file name must be specified for linker output");
258 // This vector holds all the resulting actions of the following loop.
259 std::vector<Action*> actions;
261 // Create a temporary directory for our temporary files
263 strcpy(temp_name,"/tmp/llvm_XXXXXX");
264 if (0 == mkdtemp(temp_name))
265 error("Can't create temporary directory");
266 std::string TempDir(temp_name);
267 std::string TempPreprocessorOut(TempDir + "/preproc.tmp");
268 std::string TempTranslatorOut(TempDir + "/trans.tmp");
269 std::string TempOptimizerOut(TempDir + "/opt.tmp");
270 std::string TempAssemblerOut(TempDir + "/asm.tmp");
272 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
273 // for each input item
274 std::vector<std::string> LinkageItems;
275 InputList::const_iterator I = InpList.begin();
276 while ( I != InpList.end() ) {
277 // Get the suffix of the file name
278 std::string suffix = GetSuffix(I->first);
280 // If its a library, bytecode file, or object file, save
281 // it for linking below and short circuit the
282 // pre-processing/translation/assembly phases
283 if (I->second.empty() || suffix == "o" || suffix == "bc") {
284 // We shouldn't get any of these types of files unless we're
285 // later going to link. Enforce this limit now.
286 if (finalPhase != LINKING) {
287 error("Pre-compiled objects found but linking not requested");
289 LinkageItems.push_back(I->first);
290 continue; // short circuit remainder of loop
293 // At this point, we know its something we need to translate
294 // and/or optimize. See if we can get the configuration data
295 // for this kind of file.
296 ConfigData* cd = cdp->ProvideConfigData(I->second);
298 error(std::string("Files of type '") + I->second +
299 "' are not recognized." );
301 DumpConfigData(cd,I->second);
303 // We have valid configuration data, now figure out where the output
304 // of compilation should end up.
306 if (finalPhase != LINKING) {
307 if (InpList.size() == 1 && !Output.empty())
310 OutFile = RemoveSuffix(I->first) + OutputSuffix;
315 // PRE-PROCESSING PHASE
316 Action& a = cd->PreProcessor;
318 // Get the preprocessing action, if needed, or error if appropriate
319 if (!a.program.empty()) {
320 if (a.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
321 actions.push_back(GetAction(cd,I->first,
322 TempPreprocessorOut,PREPROCESSING));
324 } else if (finalPhase == PREPROCESSING) {
325 error(cd->langName + " does not support pre-processing");
326 } else if (a.isSet(REQUIRED_FLAG)) {
327 error(std::string("Don't know how to pre-process ") +
328 cd->langName + " files");
330 // Short-circuit remaining actions if all they want is pre-processing
331 if (finalPhase == PREPROCESSING) { ++I; continue; };
333 /// TRANSLATION PHASE
336 // Get the translation action, if needed, or error if appropriate
337 if (!a.program.empty()) {
338 if (a.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
339 actions.push_back(GetAction(cd,I->first,TempTranslatorOut,TRANSLATION));
341 } else if (finalPhase == TRANSLATION) {
342 error(cd->langName + " does not support translation");
343 } else if (a.isSet(REQUIRED_FLAG)) {
344 error(std::string("Don't know how to translate ") +
345 cd->langName + " files");
347 // Short-circuit remaining actions if all they want is translation
348 if (finalPhase == TRANSLATION) { ++I; continue; }
350 /// OPTIMIZATION PHASE
353 // Get the optimization action, if needed, or error if appropriate
354 if (!a.program.empty()) {
355 actions.push_back(GetAction(cd,I->first,TempOptimizerOut,OPTIMIZATION));
356 } else if (finalPhase == OPTIMIZATION) {
357 error(cd->langName + " does not support optimization");
358 } else if (a.isSet(REQUIRED_FLAG)) {
359 error(std::string("Don't know how to optimize ") +
360 cd->langName + " files");
362 // Short-circuit remaining actions if all they want is optimization
363 if (finalPhase == OPTIMIZATION) { ++I; continue; }
371 std::vector<Action*>::iterator aIter = actions.begin();
372 while (aIter != actions.end()) {
378 CleanupTempFile(TempPreprocessorOut.c_str());
379 CleanupTempFile(TempTranslatorOut.c_str());
380 CleanupTempFile(TempOptimizerOut.c_str());
382 // Cleanup temporary directory we created
383 if (0 == access(TempDir.c_str(), F_OK | W_OK))
384 rmdir(TempDir.c_str());
389 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab