b9f7f3b8e155feef4f44680b8ac020ec7adc9ccb
[oota-llvm.git] / tools / gccld / GenerateCode.cpp
1 //===- genexec.cpp - Functions for generating executable files  ------------===//
2 //
3 // This file contains functions for generating executable files once linking
4 // has finished.  This includes generating a shell script to run the JIT or
5 // a native executable derived from the bytecode.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Transforms/Utils/Linker.h"
10 #include "llvm/Transforms/IPO.h"
11 #include "llvm/Transforms/Scalar.h"
12 #include "llvm/Target/TargetData.h"
13 #include "llvm/Module.h"
14 #include "llvm/PassManager.h"
15 #include "llvm/Bytecode/WriteBytecodePass.h"
16 #include "Support/SystemUtils.h"
17 #include "util.h"
18
19 #include <fstream>
20 #include <string>
21 #include <vector>
22
23 //
24 // Function: GenerateBytecode ()
25 //
26 // Description:
27 //  This function generates a bytecode file from the specified module.
28 //
29 // Inputs:
30 //  M           - The module for which bytecode should be generated.
31 //  Strip       - Flags whether symbols should be stripped from the output.
32 //  Internalize - Flags whether all symbols should be marked internal.
33 //  Out         - Pointer to file stream to which to write the output.
34 //
35 // Outputs:
36 //  None.
37 //
38 // Return value:
39 //  0 - No error.
40 //  1 - Error.
41 //
42 int
43 GenerateBytecode (Module * M,
44                   bool Strip,
45                   bool Internalize,
46                   std::ofstream * Out)
47 {
48   // In addition to just linking the input from GCC, we also want to spiff it up
49   // a little bit.  Do this now.
50   PassManager Passes;
51
52   // Add an appropriate TargetData instance for this module...
53   Passes.add(new TargetData("gccld", M));
54
55   // Linking modules together can lead to duplicated global constants, only keep
56   // one copy of each constant...
57   //
58   Passes.add(createConstantMergePass());
59
60   // If the -s command line option was specified, strip the symbols out of the
61   // resulting program to make it smaller.  -s is a GCC option that we are
62   // supporting.
63   //
64   if (Strip)
65     Passes.add(createSymbolStrippingPass());
66
67   // Often if the programmer does not specify proper prototypes for the
68   // functions they are calling, they end up calling a vararg version of the
69   // function that does not get a body filled in (the real function has typed
70   // arguments).  This pass merges the two functions.
71   //
72   Passes.add(createFunctionResolvingPass());
73
74   if (Internalize) {
75     // Now that composite has been compiled, scan through the module, looking
76     // for a main function.  If main is defined, mark all other functions
77     // internal.
78     //
79     Passes.add(createInternalizePass());
80   }
81
82   // Remove unused arguments from functions...
83   //
84   Passes.add(createDeadArgEliminationPass());
85
86   // The FuncResolve pass may leave cruft around if functions were prototyped
87   // differently than they were defined.  Remove this cruft.
88   //
89   Passes.add(createInstructionCombiningPass());
90
91   // Delete basic blocks, which optimization passes may have killed...
92   //
93   Passes.add(createCFGSimplificationPass());
94
95   // Now that we have optimized the program, discard unreachable functions...
96   //
97   Passes.add(createGlobalDCEPass());
98
99   // Add the pass that writes bytecode to the output file...
100   Passes.add(new WriteBytecodePass(Out));
101
102   // Run our queue of passes all at once now, efficiently.
103   Passes.run(*M);
104
105   return 0;
106 }
107
108 //
109 // Function: generate_assembly ()
110 //
111 // Description:
112 //  This function generates a native assembly language source file from the
113 //  specified bytecode file.
114 //
115 // Inputs:
116 //  InputFilename  - The name of the output bytecode file.
117 //  OutputFilename - The name of the file to generate.
118 //  llc            - The pathname to use for LLC.
119 //  envp           - The environment to use when running LLC.
120 //
121 // Outputs:
122 //  None.
123 //
124 // Return value:
125 //  0 - Success
126 //  1 - Failure
127 //
128 int
129 generate_assembly (std::string OutputFilename,
130                    std::string InputFilename,
131                    std::string llc,
132                    char ** const envp)
133 {
134   //
135   // Run LLC to convert the bytecode file into assembly code.
136   //
137   const char * cmd[8];
138
139   cmd[0] =  llc.c_str();
140   cmd[1] =  "-f";
141   cmd[2] =  "-o";
142   cmd[3] =  OutputFilename.c_str();
143   cmd[4] =  InputFilename.c_str();
144   cmd[5] =  NULL;
145   if ((ExecWait (cmd, envp)) == -1)
146   {
147     return 1;
148   }
149
150   return 0;
151 }
152
153 //
154 // Function: generate_native ()
155 //
156 // Description:
157 //  This function generates a native assembly language source file from the
158 //  specified assembly source file.
159 //
160 // Inputs:
161 //  InputFilename  - The name of the output bytecode file.
162 //  OutputFilename - The name of the file to generate.
163 //  Libraries      - The list of libraries with which to link.
164 //  gcc            - The pathname to use for GGC.
165 //  envp           - A copy of the process's current environment.
166 //
167 // Outputs:
168 //  None.
169 //
170 // Return value:
171 //  0 - Success
172 //  1 - Failure
173 //
174 int
175 generate_native (std::string OutputFilename,
176                  std::string InputFilename,
177                  std::vector<std::string> Libraries,
178                  std::string gcc,
179                  char ** const envp)
180 {
181   //
182   // Remove these environment variables from the environment of the
183   // programs that we will execute.  It appears that GCC sets these
184   // environment variables so that the programs it uses can configure
185   // themselves identically.
186   //
187   // However, when we invoke GCC below, we want it to use its  normal
188   // configuration.  Hence, we must sanitize it's environment.
189   //
190   char ** clean_env = copy_env (envp);
191   if (clean_env == NULL)
192   {
193     return 1;
194   }
195   remove_env ("LIBRARY_PATH", clean_env);
196   remove_env ("COLLECT_GCC_OPTIONS", clean_env);
197   remove_env ("GCC_EXEC_PREFIX", clean_env);
198   remove_env ("COMPILER_PATH", clean_env);
199   remove_env ("COLLECT_GCC", clean_env);
200
201   const char * cmd[8 + Libraries.size()];
202
203   //
204   // Run GCC to assemble and link the program into native code.
205   //
206   // Note:
207   //  We can't just assemble and link the file with the system assembler
208   //  and linker because we don't know where to put the _start symbol.
209   //  GCC mysteriously knows how to do it.
210   //
211   unsigned int index=0;
212   cmd[index++] =  gcc.c_str();
213   cmd[index++] =  "-o";
214   cmd[index++] =  OutputFilename.c_str();
215   cmd[index++] =  InputFilename.c_str();
216   for (; (index - 4) < Libraries.size(); index++)
217   {
218     Libraries[index - 4] = "-l" + Libraries[index - 4];
219     cmd[index] = Libraries[index-4].c_str();
220   }
221   cmd[index++] =  NULL;
222   if ((ExecWait (cmd, clean_env)) == -1)
223   {
224     return 1;
225   }
226
227   return 0;
228 }