1/*
2 * Copyright 2010-2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "bcc/Compiler.h"
18
19#include <llvm/Analysis/Passes.h>
20#include <llvm/CodeGen/RegAllocRegistry.h>
21#include <llvm/Module.h>
22#include <llvm/PassManager.h>
23#include <llvm/Support/TargetRegistry.h>
24#include <llvm/Support/raw_ostream.h>
25#include <llvm/Target/TargetData.h>
26#include <llvm/Target/TargetMachine.h>
27#include <llvm/Transforms/IPO.h>
28#include <llvm/Transforms/Scalar.h>
29
30#include "bcc/Script.h"
31#include "bcc/Source.h"
32#include "bcc/Support/CompilerConfig.h"
33#include "bcc/Support/Log.h"
34#include "bcc/Support/OutputFile.h"
35
36using namespace bcc;
37
38const char *Compiler::GetErrorString(enum ErrorCode pErrCode) {
39  static const char *ErrorString[] = {
40    /* kSuccess */
41    "Successfully compiled.",
42    /* kInvalidConfigNoTarget */
43    "Invalid compiler config supplied (getTarget() returns NULL.) "
44    "(missing call to CompilerConfig::initialize()?)",
45    /* kErrCreateTargetMachine */
46    "Failed to create llvm::TargetMachine.",
47    /* kErrSwitchTargetMachine */
48    "Failed to switch llvm::TargetMachine.",
49    /* kErrNoTargetMachine */
50    "Failed to compile the script since there's no available TargetMachine."
51    " (missing call to Compiler::config()?)",
52    /* kErrTargetDataNoMemory */
53    "Out of memory when create TargetData during compilation.",
54    /* kErrMaterialization */
55    "Failed to materialize the module.",
56    /* kErrInvalidOutputFileState */
57    "Supplied output file was invalid (in the error state.)",
58    /* kErrPrepareOutput */
59    "Failed to prepare file for output.",
60    /* kPrepareCodeGenPass */
61    "Failed to construct pass list for code-generation.",
62
63    /* kErrHookBeforeAddLTOPasses */
64    "Error occurred during beforeAddLTOPasses() in subclass.",
65    /* kErrHookAfterAddLTOPasses */
66    "Error occurred during afterAddLTOPasses() in subclass.",
67    /* kErrHookBeforeExecuteLTOPasses */
68    "Error occurred during beforeExecuteLTOPasses() in subclass.",
69    /* kErrHookAfterExecuteLTOPasses */
70    "Error occurred during afterExecuteLTOPasses() in subclass.",
71
72    /* kErrHookBeforeAddCodeGenPasses */
73    "Error occurred during beforeAddCodeGenPasses() in subclass.",
74    /* kErrHookAfterAddCodeGenPasses */
75    "Error occurred during afterAddCodeGenPasses() in subclass.",
76    /* kErrHookBeforeExecuteCodeGenPasses */
77    "Error occurred during beforeExecuteCodeGenPasses() in subclass.",
78    /* kErrHookAfterExecuteCodeGenPasses */
79    "Error occurred during afterExecuteCodeGenPasses() in subclass.",
80
81    /* kMaxErrorCode */
82    "(Unknown error code)"
83  };
84
85  if (pErrCode > kMaxErrorCode) {
86    pErrCode = kMaxErrorCode;
87  }
88
89  return ErrorString[ static_cast<size_t>(pErrCode) ];
90}
91
92//===----------------------------------------------------------------------===//
93// Instance Methods
94//===----------------------------------------------------------------------===//
95Compiler::Compiler() : mTarget(NULL), mEnableLTO(true) {
96  return;
97}
98
99Compiler::Compiler(const CompilerConfig &pConfig) : mTarget(NULL),
100                                                    mEnableLTO(true) {
101  const std::string &triple = pConfig.getTriple();
102
103  enum ErrorCode err = config(pConfig);
104  if (err != kSuccess) {
105    ALOGE("%s (%s, features: %s)", GetErrorString(err),
106          triple.c_str(), pConfig.getFeatureString().c_str());
107    return;
108  }
109
110  return;
111}
112
113enum Compiler::ErrorCode Compiler::config(const CompilerConfig &pConfig) {
114  if (pConfig.getTarget() == NULL) {
115    return kInvalidConfigNoTarget;
116  }
117
118  llvm::TargetMachine *new_target =
119      (pConfig.getTarget())->createTargetMachine(pConfig.getTriple(),
120                                                 pConfig.getCPU(),
121                                                 pConfig.getFeatureString(),
122                                                 pConfig.getTargetOptions(),
123                                                 pConfig.getRelocationModel(),
124                                                 pConfig.getCodeModel(),
125                                                 pConfig.getOptimizationLevel());
126
127  if (new_target == NULL) {
128    return ((mTarget != NULL) ? kErrSwitchTargetMachine :
129                                kErrCreateTargetMachine);
130  }
131
132  // Replace the old TargetMachine.
133  delete mTarget;
134  mTarget = new_target;
135
136  // Adjust register allocation policy according to the optimization level.
137  //  createFastRegisterAllocator: fast but bad quality
138  //  createLinearScanRegisterAllocator: not so fast but good quality
139  if ((pConfig.getOptimizationLevel() == llvm::CodeGenOpt::None)) {
140    llvm::RegisterRegAlloc::setDefault(llvm::createFastRegisterAllocator);
141  } else {
142    llvm::RegisterRegAlloc::setDefault(llvm::createGreedyRegisterAllocator);
143  }
144
145  // Relax all machine instructions.
146  mTarget->setMCRelaxAll(true);
147
148  return kSuccess;
149}
150
151Compiler::~Compiler() {
152  delete mTarget;
153}
154
155enum Compiler::ErrorCode Compiler::runLTO(Script &pScript) {
156  llvm::TargetData *target_data = NULL;
157
158  // Pass manager for link-time optimization
159  llvm::PassManager lto_passes;
160
161  // Prepare TargetData target data from Module
162  target_data = new (std::nothrow) llvm::TargetData(*mTarget->getTargetData());
163  if (target_data == NULL) {
164    return kErrTargetDataNoMemory;
165  }
166
167  // Add TargetData to the pass manager.
168  lto_passes.add(target_data);
169
170  // Invokde "beforeAddLTOPasses" before adding the first pass.
171  if (!beforeAddLTOPasses(pScript, lto_passes)) {
172    return kErrHookBeforeAddLTOPasses;
173  }
174
175  // We now create passes list performing LTO. These are copied from
176  // (including comments) llvm::PassManagerBuilder::populateLTOPassManager().
177  // Only a subset of these LTO passes are enabled in optimization level 0 as
178  // they interfere with interactive debugging.
179  //
180  // FIXME: Figure out which passes (if any) makes sense for levels 1 and 2.
181  //if ( != llvm::CodeGenOpt::None) {
182  if (mTarget->getOptLevel() == llvm::CodeGenOpt::None) {
183    lto_passes.add(llvm::createGlobalOptimizerPass());
184    lto_passes.add(llvm::createConstantMergePass());
185  } else {
186    // Propagate constants at call sites into the functions they call. This
187    // opens opportunities for globalopt (and inlining) by substituting
188    // function pointers passed as arguments to direct uses of functions.
189    lto_passes.add(llvm::createIPSCCPPass());
190
191    // Now that we internalized some globals, see if we can hack on them!
192    lto_passes.add(llvm::createGlobalOptimizerPass());
193
194    // Linking modules together can lead to duplicated global constants, only
195    // keep one copy of each constant...
196    lto_passes.add(llvm::createConstantMergePass());
197
198    // Remove unused arguments from functions...
199    lto_passes.add(llvm::createDeadArgEliminationPass());
200
201    // Reduce the code after globalopt and ipsccp. Both can open up
202    // significant simplification opportunities, and both can propagate
203    // functions through function pointers. When this happens, we often have
204    // to resolve varargs calls, etc, so let instcombine do this.
205    lto_passes.add(llvm::createInstructionCombiningPass());
206
207    // Inline small functions
208    lto_passes.add(llvm::createFunctionInliningPass());
209
210    // Remove dead EH info.
211    lto_passes.add(llvm::createPruneEHPass());
212
213    // Internalize the globals again after inlining
214    lto_passes.add(llvm::createGlobalOptimizerPass());
215
216    // Remove dead functions.
217    lto_passes.add(llvm::createGlobalDCEPass());
218
219    // If we didn't decide to inline a function, check to see if we can
220    // transform it to pass arguments by value instead of by reference.
221    lto_passes.add(llvm::createArgumentPromotionPass());
222
223    // The IPO passes may leave cruft around.  Clean up after them.
224    lto_passes.add(llvm::createInstructionCombiningPass());
225    lto_passes.add(llvm::createJumpThreadingPass());
226
227    // Break up allocas
228    lto_passes.add(llvm::createScalarReplAggregatesPass());
229
230    // Run a few AA driven optimizations here and now, to cleanup the code.
231    lto_passes.add(llvm::createFunctionAttrsPass());  // Add nocapture.
232    lto_passes.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
233
234    // Hoist loop invariants.
235    lto_passes.add(llvm::createLICMPass());
236
237    // Remove redundancies.
238    lto_passes.add(llvm::createGVNPass());
239
240    // Remove dead memcpys.
241    lto_passes.add(llvm::createMemCpyOptPass());
242
243    // Nuke dead stores.
244    lto_passes.add(llvm::createDeadStoreEliminationPass());
245
246    // Cleanup and simplify the code after the scalar optimizations.
247    lto_passes.add(llvm::createInstructionCombiningPass());
248
249    lto_passes.add(llvm::createJumpThreadingPass());
250
251    // Delete basic blocks, which optimization passes may have killed.
252    lto_passes.add(llvm::createCFGSimplificationPass());
253
254    // Now that we have optimized the program, discard unreachable functions.
255    lto_passes.add(llvm::createGlobalDCEPass());
256  }
257
258  // Invokde "afterAddLTOPasses" after pass manager finished its
259  // construction.
260  if (!afterAddLTOPasses(pScript, lto_passes)) {
261    return kErrHookAfterAddLTOPasses;
262  }
263
264  // Invokde "beforeExecuteLTOPasses" before executing the passes.
265  if (!beforeExecuteLTOPasses(pScript, lto_passes)) {
266    return kErrHookBeforeExecuteLTOPasses;
267  }
268
269  lto_passes.run(pScript.getSource().getModule());
270
271  // Invokde "afterExecuteLTOPasses" before returning.
272  if (!afterExecuteLTOPasses(pScript)) {
273    return kErrHookAfterExecuteLTOPasses;
274  }
275
276  return kSuccess;
277}
278
279enum Compiler::ErrorCode Compiler::runCodeGen(Script &pScript,
280                                              llvm::raw_ostream &pResult) {
281  llvm::TargetData *target_data;
282  llvm::MCContext *mc_context = NULL;
283
284  // Create pass manager for MC code generation.
285  llvm::PassManager codegen_passes;
286
287  // Prepare TargetData target data from Module
288  target_data = new (std::nothrow) llvm::TargetData(*mTarget->getTargetData());
289  if (target_data == NULL) {
290    return kErrTargetDataNoMemory;
291  }
292
293  // Add TargetData to the pass manager.
294  codegen_passes.add(target_data);
295
296  // Invokde "beforeAddCodeGenPasses" before adding the first pass.
297  if (!beforeAddCodeGenPasses(pScript, codegen_passes)) {
298    return kErrHookBeforeAddCodeGenPasses;
299  }
300
301  // Add passes to the pass manager to emit machine code through MC layer.
302  if (mTarget->addPassesToEmitMC(codegen_passes, mc_context, pResult,
303                                 /* DisableVerify */false)) {
304    return kPrepareCodeGenPass;
305  }
306
307  // Invokde "afterAddCodeGenPasses" after pass manager finished its
308  // construction.
309  if (!afterAddCodeGenPasses(pScript, codegen_passes)) {
310    return kErrHookAfterAddCodeGenPasses;
311  }
312
313  // Invokde "beforeExecuteCodeGenPasses" before executing the passes.
314  if (!beforeExecuteCodeGenPasses(pScript, codegen_passes)) {
315    return kErrHookBeforeExecuteCodeGenPasses;
316  }
317
318  // Execute the pass.
319  codegen_passes.run(pScript.getSource().getModule());
320
321  // Invokde "afterExecuteCodeGenPasses" before returning.
322  if (!afterExecuteCodeGenPasses(pScript)) {
323    return kErrHookAfterExecuteCodeGenPasses;
324  }
325
326  return kSuccess;
327}
328
329enum Compiler::ErrorCode Compiler::compile(Script &pScript,
330                                           llvm::raw_ostream &pResult) {
331  llvm::Module &module = pScript.getSource().getModule();
332  enum ErrorCode err;
333
334  if (mTarget == NULL) {
335    return kErrNoTargetMachine;
336  }
337
338  // Materialize the bitcode module.
339  if (module.getMaterializer() != NULL) {
340    std::string error;
341    // A module with non-null materializer means that it is a lazy-load module.
342    // Materialize it now via invoking MaterializeAllPermanently(). This
343    // function returns false when the materialization is successful.
344    if (module.MaterializeAllPermanently(&error)) {
345      ALOGE("Failed to materialize the module `%s'! (%s)",
346            module.getModuleIdentifier().c_str(), error.c_str());
347      return kErrMaterialization;
348    }
349  }
350
351  if (mEnableLTO && ((err = runLTO(pScript)) != kSuccess)) {
352    return err;
353  }
354
355  if ((err = runCodeGen(pScript, pResult)) != kSuccess) {
356    return err;
357  }
358
359  return kSuccess;
360}
361
362enum Compiler::ErrorCode Compiler::compile(Script &pScript,
363                                           OutputFile &pResult) {
364  // Check the state of the specified output file.
365  if (pResult.hasError()) {
366    return kErrInvalidOutputFileState;
367  }
368
369  // Open the output file decorated in llvm::raw_ostream.
370  llvm::raw_ostream *out = pResult.dup();
371  if (out == NULL) {
372    return kErrPrepareOutput;
373  }
374
375  // Delegate the request.
376  enum Compiler::ErrorCode err = compile(pScript, *out);
377
378  // Close the output before return.
379  delete out;
380
381  return err;
382}
383