From 9822de2ed15c18e60a235c3f80b7c8aefdb1abb0 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 20 Nov 2004 20:15:08 +0000 Subject: Content moved to llvm-ld.cpp git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18049 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-ld/GenerateCode.cpp | 352 ----------------------------------------- 1 file changed, 352 deletions(-) delete mode 100644 tools/llvm-ld/GenerateCode.cpp (limited to 'tools') diff --git a/tools/llvm-ld/GenerateCode.cpp b/tools/llvm-ld/GenerateCode.cpp deleted file mode 100644 index 4f94633a60..0000000000 --- a/tools/llvm-ld/GenerateCode.cpp +++ /dev/null @@ -1,352 +0,0 @@ -//===- GenerateCode.cpp - Functions for generating executable files ------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains functions for generating executable files once linking -// has finished. This includes generating a shell script to run the JIT or -// a native executable derived from the bytecode. -// -//===----------------------------------------------------------------------===// - -#include "llvm-ld.h" -#include "llvm/Linker.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Analysis/LoadValueNumbering.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Bytecode/WriteBytecodePass.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/CommandLine.h" -using namespace llvm; - -namespace { - cl::opt - DisableInline("disable-inlining", cl::desc("Do not run the inliner pass")); - - cl::opt - Verify("verify", cl::desc("Verify intermediate results of all passes")); - - cl::opt - DisableOptimizations("disable-opt", - cl::desc("Do not run any optimization passes")); -} - -/// CopyEnv - This function takes an array of environment variables and makes a -/// copy of it. This copy can then be manipulated any way the caller likes -/// without affecting the process's real environment. -/// -/// Inputs: -/// envp - An array of C strings containing an environment. -/// -/// Return value: -/// NULL - An error occurred. -/// -/// Otherwise, a pointer to a new array of C strings is returned. Every string -/// in the array is a duplicate of the one in the original array (i.e. we do -/// not copy the char *'s from one array to another). -/// -static char ** CopyEnv(char ** const envp) { - // Count the number of entries in the old list; - unsigned entries; // The number of entries in the old environment list - for (entries = 0; envp[entries] != NULL; entries++) - /*empty*/; - - // Add one more entry for the NULL pointer that ends the list. - ++entries; - - // If there are no entries at all, just return NULL. - if (entries == 0) - return NULL; - - // Allocate a new environment list. - char **newenv = new char* [entries]; - if ((newenv = new char* [entries]) == NULL) - return NULL; - - // Make a copy of the list. Don't forget the NULL that ends the list. - entries = 0; - while (envp[entries] != NULL) { - newenv[entries] = new char[strlen (envp[entries]) + 1]; - strcpy (newenv[entries], envp[entries]); - ++entries; - } - newenv[entries] = NULL; - - return newenv; -} - - -/// RemoveEnv - Remove the specified environment variable from the environment -/// array. -/// -/// Inputs: -/// name - The name of the variable to remove. It cannot be NULL. -/// envp - The array of environment variables. It cannot be NULL. -/// -/// Notes: -/// This is mainly done because functions to remove items from the environment -/// are not available across all platforms. In particular, Solaris does not -/// seem to have an unsetenv() function or a setenv() function (or they are -/// undocumented if they do exist). -/// -static void RemoveEnv(const char * name, char ** const envp) { - for (unsigned index=0; envp[index] != NULL; index++) { - // Find the first equals sign in the array and make it an EOS character. - char *p = strchr (envp[index], '='); - if (p == NULL) - continue; - else - *p = '\0'; - - // Compare the two strings. If they are equal, zap this string. - // Otherwise, restore it. - if (!strcmp(name, envp[index])) - *envp[index] = '\0'; - else - *p = '='; - } - - return; -} - -static inline void addPass(PassManager &PM, Pass *P) { - // Add the pass to the pass manager... - PM.add(P); - - // If we are verifying all of the intermediate steps, add the verifier... - if (Verify) PM.add(createVerifierPass()); -} - -/// GenerateBytecode - generates a bytecode file from the specified module. -/// -/// Inputs: -/// M - The module for which bytecode should be generated. -/// Strip - Flags whether symbols should be stripped from the output. -/// Internalize - Flags whether all symbols should be marked internal. -/// Out - Pointer to file stream to which to write the output. -/// -/// Returns non-zero value on error. -/// -int llvm::GenerateBytecode(Module *M, bool Strip, bool Internalize, - std::ostream *Out) { - // In addition to just linking the input from GCC, we also want to spiff it up - // a little bit. Do this now. - PassManager Passes; - - if (Verify) Passes.add(createVerifierPass()); - - // Add an appropriate TargetData instance for this module... - addPass(Passes, new TargetData("gccld", M)); - - // Often if the programmer does not specify proper prototypes for the - // functions they are calling, they end up calling a vararg version of the - // function that does not get a body filled in (the real function has typed - // arguments). This pass merges the two functions. - addPass(Passes, createFunctionResolvingPass()); - - if (!DisableOptimizations) { - if (Internalize) { - // Now that composite has been compiled, scan through the module, looking - // for a main function. If main is defined, mark all other functions - // internal. - addPass(Passes, createInternalizePass()); - } - - // Now that we internalized some globals, see if we can hack on them! - addPass(Passes, createGlobalOptimizerPass()); - - // Linking modules together can lead to duplicated global constants, only - // keep one copy of each constant... - addPass(Passes, createConstantMergePass()); - - // If the -s command line option was specified, strip the symbols out of the - // resulting program to make it smaller. -s is a GCC option that we are - // supporting. - if (Strip) - addPass(Passes, createSymbolStrippingPass()); - - // Propagate constants at call sites into the functions they call. - addPass(Passes, createIPConstantPropagationPass()); - - // Remove unused arguments from functions... - addPass(Passes, createDeadArgEliminationPass()); - - if (!DisableInline) - addPass(Passes, createFunctionInliningPass()); // Inline small functions - - addPass(Passes, createPruneEHPass()); // Remove dead EH info - addPass(Passes, createGlobalDCEPass()); // Remove dead functions - - // If we didn't decide to inline a function, check to see if we can - // transform it to pass arguments by value instead of by reference. - addPass(Passes, createArgumentPromotionPass()); - - // The IPO passes may leave cruft around. Clean up after them. - addPass(Passes, createInstructionCombiningPass()); - - addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas - - // Run a few AA driven optimizations here and now, to cleanup the code. - addPass(Passes, createGlobalsModRefPass()); // IP alias analysis - - addPass(Passes, createLICMPass()); // Hoist loop invariants - addPass(Passes, createLoadValueNumberingPass()); // GVN for load instrs - addPass(Passes, createGCSEPass()); // Remove common subexprs - addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores - - // Cleanup and simplify the code after the scalar optimizations. - addPass(Passes, createInstructionCombiningPass()); - - // Delete basic blocks, which optimization passes may have killed... - addPass(Passes, createCFGSimplificationPass()); - - // Now that we have optimized the program, discard unreachable functions... - addPass(Passes, createGlobalDCEPass()); - } - - // Make sure everything is still good. - Passes.add(createVerifierPass()); - - // Add the pass that writes bytecode to the output file... - addPass(Passes, new WriteBytecodePass(Out)); - - // Run our queue of passes all at once now, efficiently. - Passes.run(*M); - - return 0; -} - -/// GenerateAssembly - generates a native assembly language source file from the -/// specified bytecode file. -/// -/// Inputs: -/// InputFilename - The name of the output bytecode file. -/// OutputFilename - The name of the file to generate. -/// llc - The pathname to use for LLC. -/// envp - The environment to use when running LLC. -/// -/// Return non-zero value on error. -/// -int llvm::GenerateAssembly(const std::string &OutputFilename, - const std::string &InputFilename, - const std::string &llc, - char ** const envp) { - // Run LLC to convert the bytecode file into assembly code. - const char *cmd[6]; - cmd[0] = llc.c_str(); - cmd[1] = "-f"; - cmd[2] = "-o"; - cmd[3] = OutputFilename.c_str(); - cmd[4] = InputFilename.c_str(); - cmd[5] = 0; - - return ExecWait(cmd, envp); -} - -/// GenerateAssembly - generates a native assembly language source file from the -/// specified bytecode file. -int llvm::GenerateCFile(const std::string &OutputFile, - const std::string &InputFile, - const std::string &llc, char ** const envp) { - // Run LLC to convert the bytecode file into C. - const char *cmd[7]; - - cmd[0] = llc.c_str(); - cmd[1] = "-march=c"; - cmd[2] = "-f"; - cmd[3] = "-o"; - cmd[4] = OutputFile.c_str(); - cmd[5] = InputFile.c_str(); - cmd[6] = 0; - return ExecWait(cmd, envp); -} - -/// GenerateNative - generates a native assembly language source file from the -/// specified assembly source file. -/// -/// Inputs: -/// InputFilename - The name of the output bytecode file. -/// OutputFilename - The name of the file to generate. -/// Libraries - The list of libraries with which to link. -/// LibPaths - The list of directories in which to find libraries. -/// gcc - The pathname to use for GGC. -/// envp - A copy of the process's current environment. -/// -/// Outputs: -/// None. -/// -/// Returns non-zero value on error. -/// -int llvm::GenerateNative(const std::string &OutputFilename, - const std::string &InputFilename, - const std::vector &Libraries, - const std::vector &LibPaths, - const std::string &gcc, char ** const envp) { - // Remove these environment variables from the environment of the - // programs that we will execute. It appears that GCC sets these - // environment variables so that the programs it uses can configure - // themselves identically. - // - // However, when we invoke GCC below, we want it to use its normal - // configuration. Hence, we must sanitize its environment. - char ** clean_env = CopyEnv(envp); - if (clean_env == NULL) - return 1; - RemoveEnv("LIBRARY_PATH", clean_env); - RemoveEnv("COLLECT_GCC_OPTIONS", clean_env); - RemoveEnv("GCC_EXEC_PREFIX", clean_env); - RemoveEnv("COMPILER_PATH", clean_env); - RemoveEnv("COLLECT_GCC", clean_env); - - std::vector cmd; - - // Run GCC to assemble and link the program into native code. - // - // Note: - // We can't just assemble and link the file with the system assembler - // and linker because we don't know where to put the _start symbol. - // GCC mysteriously knows how to do it. - cmd.push_back(gcc.c_str()); - cmd.push_back("-fno-strict-aliasing"); - cmd.push_back("-O3"); - cmd.push_back("-o"); - cmd.push_back(OutputFilename.c_str()); - cmd.push_back(InputFilename.c_str()); - - // Adding the library paths creates a problem for native generation. If we - // include the search paths from llvmgcc, then we'll be telling normal gcc - // to look inside of llvmgcc's library directories for libraries. This is - // bad because those libraries hold only bytecode files (not native object - // files). In the end, we attempt to link the bytecode libgcc into a native - // program. -#if 0 - // Add in the library path options. - for (unsigned index=0; index < LibPaths.size(); index++) { - cmd.push_back("-L"); - cmd.push_back(LibPaths[index].c_str()); - } -#endif - - // Add in the libraries to link. - std::vector Libs(Libraries); - for (unsigned index = 0; index < Libs.size(); index++) { - if (Libs[index] != "crtend") { - Libs[index] = "-l" + Libs[index]; - cmd.push_back(Libs[index].c_str()); - } - } - cmd.push_back(NULL); - - // Run the compiler to assembly and link together the program. - return ExecWait(&(cmd[0]), clean_env); -} - -- cgit v1.2.3