blob: 2348d56bce582b39a460bf82d12d12d2bc88fd98 [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
Stephen Hinesdb169182012-01-05 18:46:36 -08002 * Copyright 2010-2012, The Android Open Source Project
Logan1f028c02010-11-27 01:02:48 +08003 *
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
Loganc4395232010-11-27 18:54:17 +080017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Zonr Changfef9a1b2012-04-13 15:58:24 +080019#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>
Logan35849002011-01-15 07:30:43 +080029
Zonr Changfef9a1b2012-04-13 15:58:24 +080030#include "CompilerConfig.h"
Logan4dcd6792011-02-28 05:12:00 +080031#include "DebugHelper.h"
Zonr Changfef9a1b2012-04-13 15:58:24 +080032#include "OutputFile.h"
33#include "Script.h"
34#include "Source.h"
Loganeb3d12b2010-12-16 06:20:18 +080035
Zonr Changfef9a1b2012-04-13 15:58:24 +080036using namespace bcc;
Logan Chienda5e0c32011-06-13 03:47:21 +080037
Zonr Changfef9a1b2012-04-13 15:58:24 +080038const 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.",
Stephen Hinesdb169182012-01-05 18:46:36 -080062
Zonr Changfef9a1b2012-04-13 15:58:24 +080063 /* 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.",
Logan1f028c02010-11-27 01:02:48 +080071
Zonr Changfef9a1b2012-04-13 15:58:24 +080072 /* 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.",
Logan1f028c02010-11-27 01:02:48 +080080
Zonr Changfef9a1b2012-04-13 15:58:24 +080081 /* kMaxErrorCode */
82 "(Unknown error code)"
83 };
Logan1f028c02010-11-27 01:02:48 +080084
Zonr Changfef9a1b2012-04-13 15:58:24 +080085 if (pErrCode > kMaxErrorCode) {
86 pErrCode = kMaxErrorCode;
Shih-wei Liao40bcd662011-10-22 17:51:01 -070087 }
88
Zonr Changfef9a1b2012-04-13 15:58:24 +080089 return ErrorString[ static_cast<size_t>(pErrCode) ];
Logan1f028c02010-11-27 01:02:48 +080090}
91
Zonr Changfef9a1b2012-04-13 15:58:24 +080092//===----------------------------------------------------------------------===//
93// Instance Methods
94//===----------------------------------------------------------------------===//
95Compiler::Compiler() : mTarget(NULL), mEnableLTO(true) {
Logan1f028c02010-11-27 01:02:48 +080096 return;
97}
98
Zonr Changfef9a1b2012-04-13 15:58:24 +080099Compiler::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;
Logan1f028c02010-11-27 01:02:48 +0800108 }
Zonr Changfef9a1b2012-04-13 15:58:24 +0800109
110 return;
Logan1f028c02010-11-27 01:02:48 +0800111}
112
Zonr Changfef9a1b2012-04-13 15:58:24 +0800113enum Compiler::ErrorCode Compiler::config(const CompilerConfig &pConfig) {
114 if (pConfig.getTarget() == NULL) {
115 return kInvalidConfigNoTarget;
Daniel Malea094881f2011-12-14 17:39:16 -0500116 }
117
Zonr Changfef9a1b2012-04-13 15:58:24 +0800118 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());
Daniel Malea094881f2011-12-14 17:39:16 -0500126
Zonr Changfef9a1b2012-04-13 15:58:24 +0800127 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.
Daniel Malea094881f2011-12-14 17:39:16 -0500137 // createFastRegisterAllocator: fast but bad quality
138 // createLinearScanRegisterAllocator: not so fast but good quality
Zonr Changfef9a1b2012-04-13 15:58:24 +0800139 if ((pConfig.getOptimizationLevel() == llvm::CodeGenOpt::None)) {
140 llvm::RegisterRegAlloc::setDefault(llvm::createFastRegisterAllocator);
141 } else {
142 llvm::RegisterRegAlloc::setDefault(llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800143 }
144
Zonr Changfef9a1b2012-04-13 15:58:24 +0800145 // Relax all machine instructions.
146 mTarget->setMCRelaxAll(true);
Logan Chienbe81e102011-12-16 13:31:39 +0800147
Zonr Changfef9a1b2012-04-13 15:58:24 +0800148 return kSuccess;
Logan Chienda5e0c32011-06-13 03:47:21 +0800149}
150
Zonr Changfef9a1b2012-04-13 15:58:24 +0800151Compiler::~Compiler() {
152 delete mTarget;
153}
Logan Chienda5e0c32011-06-13 03:47:21 +0800154
Zonr Changfef9a1b2012-04-13 15:58:24 +0800155enum Compiler::ErrorCode Compiler::runLTO(Script &pScript) {
156 llvm::TargetData *target_data = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800157
Zonr Changfef9a1b2012-04-13 15:58:24 +0800158 // Pass manager for link-time optimization
159 llvm::PassManager lto_passes;
Logan Chienda5e0c32011-06-13 03:47:21 +0800160
Zonr Changfef9a1b2012-04-13 15:58:24 +0800161 // Prepare TargetData target data from Module
162 target_data = new (std::nothrow) llvm::TargetData(*mTarget->getTargetData());
163 if (target_data == NULL) {
164 return kErrTargetDataNoMemory;
Logan Chienda5e0c32011-06-13 03:47:21 +0800165 }
166
Zonr Changfef9a1b2012-04-13 15:58:24 +0800167 // Add TargetData to the pass manager.
168 lto_passes.add(target_data);
Logan Chienda5e0c32011-06-13 03:47:21 +0800169
Zonr Changfef9a1b2012-04-13 15:58:24 +0800170 // Invokde "beforeAddLTOPasses" before adding the first pass.
171 if (!beforeAddLTOPasses(pScript, lto_passes)) {
172 return kErrHookBeforeAddLTOPasses;
173 }
Daniel Malea094881f2011-12-14 17:39:16 -0500174
Logan Chien4cc00332011-06-12 14:00:46 +0800175 // We now create passes list performing LTO. These are copied from
Zonr Changfef9a1b2012-04-13 15:58:24 +0800176 // (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 {
Daniel Malea094881f2011-12-14 17:39:16 -0500186 // 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.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800189 lto_passes.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800190
Daniel Malea094881f2011-12-14 17:39:16 -0500191 // Now that we internalized some globals, see if we can hack on them!
Zonr Changfef9a1b2012-04-13 15:58:24 +0800192 lto_passes.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800193
Daniel Malea094881f2011-12-14 17:39:16 -0500194 // Linking modules together can lead to duplicated global constants, only
195 // keep one copy of each constant...
Zonr Changfef9a1b2012-04-13 15:58:24 +0800196 lto_passes.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800197
Daniel Malea094881f2011-12-14 17:39:16 -0500198 // Remove unused arguments from functions...
Zonr Changfef9a1b2012-04-13 15:58:24 +0800199 lto_passes.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800200
Daniel Malea094881f2011-12-14 17:39:16 -0500201 // 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.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800205 lto_passes.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800206
Daniel Malea094881f2011-12-14 17:39:16 -0500207 // Inline small functions
Zonr Changfef9a1b2012-04-13 15:58:24 +0800208 lto_passes.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800209
Daniel Malea094881f2011-12-14 17:39:16 -0500210 // Remove dead EH info.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800211 lto_passes.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800212
Daniel Malea094881f2011-12-14 17:39:16 -0500213 // Internalize the globals again after inlining
Zonr Changfef9a1b2012-04-13 15:58:24 +0800214 lto_passes.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800215
Daniel Malea094881f2011-12-14 17:39:16 -0500216 // Remove dead functions.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800217 lto_passes.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800218
Daniel Malea094881f2011-12-14 17:39:16 -0500219 // 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.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800221 lto_passes.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800222
Daniel Malea094881f2011-12-14 17:39:16 -0500223 // The IPO passes may leave cruft around. Clean up after them.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800224 lto_passes.add(llvm::createInstructionCombiningPass());
225 lto_passes.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800226
Daniel Malea094881f2011-12-14 17:39:16 -0500227 // Break up allocas
Zonr Changfef9a1b2012-04-13 15:58:24 +0800228 lto_passes.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800229
Daniel Malea094881f2011-12-14 17:39:16 -0500230 // Run a few AA driven optimizations here and now, to cleanup the code.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800231 lto_passes.add(llvm::createFunctionAttrsPass()); // Add nocapture.
232 lto_passes.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800233
Daniel Malea094881f2011-12-14 17:39:16 -0500234 // Hoist loop invariants.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800235 lto_passes.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800236
Daniel Malea094881f2011-12-14 17:39:16 -0500237 // Remove redundancies.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800238 lto_passes.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800239
Daniel Malea094881f2011-12-14 17:39:16 -0500240 // Remove dead memcpys.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800241 lto_passes.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800242
Daniel Malea094881f2011-12-14 17:39:16 -0500243 // Nuke dead stores.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800244 lto_passes.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800245
Daniel Malea094881f2011-12-14 17:39:16 -0500246 // Cleanup and simplify the code after the scalar optimizations.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800247 lto_passes.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800248
Zonr Changfef9a1b2012-04-13 15:58:24 +0800249 lto_passes.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800250
Daniel Malea094881f2011-12-14 17:39:16 -0500251 // Delete basic blocks, which optimization passes may have killed.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800252 lto_passes.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800253
Daniel Malea094881f2011-12-14 17:39:16 -0500254 // Now that we have optimized the program, discard unreachable functions.
Zonr Changfef9a1b2012-04-13 15:58:24 +0800255 lto_passes.add(llvm::createGlobalDCEPass());
Daniel Malea094881f2011-12-14 17:39:16 -0500256 }
Logan Chien4cc00332011-06-12 14:00:46 +0800257
Zonr Changfef9a1b2012-04-13 15:58:24 +0800258 // Invokde "afterAddLTOPasses" after pass manager finished its
259 // construction.
260 if (!afterAddLTOPasses(pScript, lto_passes)) {
261 return kErrHookAfterAddLTOPasses;
Daniel Malea094881f2011-12-14 17:39:16 -0500262 }
Daniel Malea094881f2011-12-14 17:39:16 -0500263
Zonr Changfef9a1b2012-04-13 15:58:24 +0800264 // 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;
Logan Chien4cc00332011-06-12 14:00:46 +0800277}
278
Zonr Changfef9a1b2012-04-13 15:58:24 +0800279enum Compiler::ErrorCode Compiler::runCodeGen(Script &pScript,
280 llvm::raw_ostream &pResult) {
281 llvm::TargetData *target_data;
282 llvm::MCContext *mc_context = NULL;
Logan Chien4cc00332011-06-12 14:00:46 +0800283
Zonr Changfef9a1b2012-04-13 15:58:24 +0800284 // 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;
Logan Chienda5e0c32011-06-13 03:47:21 +0800327}
Logan Chienda5e0c32011-06-13 03:47:21 +0800328
Zonr Changfef9a1b2012-04-13 15:58:24 +0800329enum Compiler::ErrorCode Compiler::compile(Script &pScript,
330 llvm::raw_ostream &pResult) {
331 llvm::Module &module = pScript.getSource().getModule();
332 enum ErrorCode err;
Logan Chienda5e0c32011-06-13 03:47:21 +0800333
Zonr Changfef9a1b2012-04-13 15:58:24 +0800334 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;
Logan1f028c02010-11-27 01:02:48 +0800360}
361
Zonr Changfef9a1b2012-04-13 15:58:24 +0800362enum 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 }
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700368
Zonr Changfef9a1b2012-04-13 15:58:24 +0800369 // 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}