- std::auto_ptr<Module> Composite(TheLinker.releaseModule());
-
- // Optimize the module
- Optimize(Composite.get());
-
- // Generate the bytecode for the optimized module.
- std::string RealBytecodeOutput = OutputFilename;
- if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
- GenerateBytecode(Composite.get(), RealBytecodeOutput);
-
- // If we are not linking a library, generate either a native executable
- // or a JIT shell script, depending upon what the user wants.
- if (!LinkAsLibrary) {
- // If the user wants to run a post-link optimization, run it now.
- if (!PostLinkOpts.empty()) {
- std::vector<std::string> opts = PostLinkOpts;
- for (std::vector<std::string>::iterator I = opts.begin(),
- E = opts.end(); I != E; ++I) {
- sys::Path prog(*I);
- if (!prog.canExecute()) {
- prog = sys::Program::FindProgramByName(*I);
- if (prog.isEmpty())
- return PrintAndReturn(std::string("Optimization program '") + *I +
- "' is not found or not executable.");
- }
- // Get the program arguments
- sys::Path tmp_output("opt_result");
- std::string ErrMsg;
- if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) {
- return PrintAndReturn(ErrMsg);
- }
- const char* args[4];
- args[0] = I->c_str();
- args[1] = RealBytecodeOutput.c_str();
- args[2] = tmp_output.c_str();
- args[3] = 0;
- if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0, &ErrMsg)) {
- if (tmp_output.isBytecodeFile()) {
- sys::Path target(RealBytecodeOutput);
- target.eraseFromDisk();
- if (tmp_output.renamePathOnDisk(target, &ErrMsg)) {
- cerr << argv[0] << ": " << ErrMsg << "\n";
- return 2;
- }
- } else
- return PrintAndReturn(
- "Post-link optimization output is not bytecode");
- } else {
- cerr << argv[0] << ": " << ErrMsg << "\n";
- return 2;
- }
- }
- }
-
- // If the user wants to generate a native executable, compile it from the
- // bytecode file.
- //
- // Otherwise, create a script that will run the bytecode through the JIT.
- if (Native) {
- // Name of the Assembly Language output file
- sys::Path AssemblyFile ( OutputFilename);
- AssemblyFile.appendSuffix("s");
-
- // Mark the output files for removal if we get an interrupt.
- sys::RemoveFileOnSignal(AssemblyFile);
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
- // Determine the locations of the llc and gcc programs.
- sys::Path llc = FindExecutable("llc", argv[0]);
- if (llc.isEmpty())
- return PrintAndReturn("Failed to find llc");
-
- sys::Path gcc = FindExecutable("gcc", argv[0]);
- if (gcc.isEmpty())
- return PrintAndReturn("Failed to find gcc");
-
- // Generate an assembly language file for the bytecode.
- if (Verbose) cout << "Generating Assembly Code\n";
- std::string ErrMsg;
- if (0 != GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput,
- llc, ErrMsg)) {
- cerr << argv[0] << ": " << ErrMsg << "\n";
- return 1;
- }