blob: 8f29e2729cefee2a8b9009b8eabc936a6e8f3e5f [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
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
Stephen Hines569986d2012-03-09 19:58:45 -080020#include <bcinfo/MetadataExtractor.h>
Logan35849002011-01-15 07:30:43 +080021
Logan Chien4885cf82011-07-20 10:18:05 +080022#if USE_DISASSEMBLER
23#include "Disassembler/Disassembler.h"
24#endif
25
Logan4dcd6792011-02-28 05:12:00 +080026#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070027#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080028#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080029#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080030#include "Sha1Helper.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080031#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080032
Shih-wei Liao320b5492011-06-20 22:53:33 -070033#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080034#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070035#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080036
Stephen Hinesdb169182012-01-05 18:46:36 -080037#include "Transforms/BCCTransforms.h"
38
Logandf23afa2010-11-27 11:04:54 +080039#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080040
Logandf23afa2010-11-27 11:04:54 +080041#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080042
Logan1f028c02010-11-27 01:02:48 +080043#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080044#include "llvm/CodeGen/RegAllocRegistry.h"
45#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080046
Daniel Malea094881f2011-12-14 17:39:16 -050047#include "llvm/MC/MCContext.h"
Logan Chien9347e0b2011-07-07 19:51:47 +080048#include "llvm/MC/SubtargetFeature.h"
49
Logandf23afa2010-11-27 11:04:54 +080050#include "llvm/Transforms/IPO.h"
51#include "llvm/Transforms/Scalar.h"
52
Logandf23afa2010-11-27 11:04:54 +080053#include "llvm/Target/TargetData.h"
54#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080055
56#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070057#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080058#include "llvm/Support/TargetRegistry.h"
59#include "llvm/Support/TargetSelect.h"
Daniel Malea094881f2011-12-14 17:39:16 -050060#include "llvm/Support/raw_ostream.h"
Logandf23afa2010-11-27 11:04:54 +080061
Daniel Malea094881f2011-12-14 17:39:16 -050062#include "llvm/Constants.h"
Logandf23afa2010-11-27 11:04:54 +080063#include "llvm/GlobalValue.h"
64#include "llvm/Linker.h"
65#include "llvm/LLVMContext.h"
Logandf23afa2010-11-27 11:04:54 +080066#include "llvm/Module.h"
67#include "llvm/PassManager.h"
Daniel Malea094881f2011-12-14 17:39:16 -050068#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080069#include "llvm/Value.h"
70
71#include <errno.h>
72#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080073#include <sys/stat.h>
74#include <sys/types.h>
75#include <unistd.h>
76
Logan75cc8a52011-01-07 06:06:52 +080077#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080078
Logan Chien7890d432011-08-03 14:55:17 +080079#include <algorithm>
80#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080081#include <string>
82#include <vector>
Logan1f028c02010-11-27 01:02:48 +080083
Daniel Malea094881f2011-12-14 17:39:16 -050084extern char* gDebugDumpDirectory;
85
Logan1f028c02010-11-27 01:02:48 +080086namespace bcc {
87
88//////////////////////////////////////////////////////////////////////////////
89// BCC Compiler Static Variables
90//////////////////////////////////////////////////////////////////////////////
91
92bool Compiler::GlobalInitialized = false;
93
Andrew Hsieh998ec832011-11-21 02:36:11 -080094
95#if !defined(__HOST__)
96 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
97#else
98// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
99 #if defined(__cplusplus)
100 extern "C" {
101 #endif
102 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
103 #if defined(__cplusplus)
104 };
105 #endif
106#endif
107
Logan1f028c02010-11-27 01:02:48 +0800108// Code generation optimization level for the compiler
109llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
110
111std::string Compiler::Triple;
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800112llvm::Triple::ArchType Compiler::ArchType;
Logan1f028c02010-11-27 01:02:48 +0800113
114std::string Compiler::CPU;
115
116std::vector<std::string> Compiler::Features;
117
Daniel Malea094881f2011-12-14 17:39:16 -0500118
Logan1f028c02010-11-27 01:02:48 +0800119//////////////////////////////////////////////////////////////////////////////
120// Compiler
121//////////////////////////////////////////////////////////////////////////////
122
123void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700124 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800125 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700126 }
127
Shih-wei Liao22705912012-03-06 19:13:26 -0800128#if defined(PROVIDE_ARM_CODEGEN)
129 LLVMInitializeARMAsmPrinter();
130 LLVMInitializeARMTargetMC();
131 LLVMInitializeARMTargetInfo();
132 LLVMInitializeARMTarget();
133#endif
134
135#if defined(PROVIDE_MIPS_CODEGEN)
136 LLVMInitializeMipsAsmPrinter();
137 LLVMInitializeMipsTargetMC();
138 LLVMInitializeMipsTargetInfo();
139 LLVMInitializeMipsTarget();
140#endif
141
142#if defined(PROVIDE_X86_CODEGEN)
143 LLVMInitializeX86AsmPrinter();
144 LLVMInitializeX86TargetMC();
145 LLVMInitializeX86TargetInfo();
146 LLVMInitializeX86Target();
147#endif
148
149#if USE_DISASSEMBLER
150 InitializeDisassembler();
151#endif
152
Logan1f028c02010-11-27 01:02:48 +0800153 // if (!llvm::llvm_is_multithreaded())
154 // llvm::llvm_start_multithreaded();
155
156 // Set Triple, CPU and Features here
157 Triple = TARGET_TRIPLE_STRING;
158
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800159 // Determine ArchType
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800160#if defined(__HOST__)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800161 {
162 std::string Err;
163 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
Stephen Hinescc366e52012-02-21 17:22:04 -0800164 if (Target != NULL) {
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800165 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
166 } else {
167 ArchType = llvm::Triple::UnknownArch;
168 ALOGE("%s", Err.c_str());
169 }
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800170 }
171#elif defined(DEFAULT_ARM_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800172 ArchType = llvm::Triple::arm;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800173#elif defined(DEFAULT_MIPS_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800174 ArchType = llvm::Triple::mipsel;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800175#elif defined(DEFAULT_X86_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800176 ArchType = llvm::Triple::x86;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800177#elif defined(DEFAULT_X86_64_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800178 ArchType = llvm::Triple::x86_64;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800179#else
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800180 ArchType = llvm::Triple::UnknownArch;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800181#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800182
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800183 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800184# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800185 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800186# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800187 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800188# endif
189# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700190
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800191# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800192 Features.push_back("+neon");
193 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800194# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800195 Features.push_back("-neon");
196 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800197# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700198
Stephen Hinesf6b202b2012-03-06 17:45:41 -0800199// FIXME(all): Turn NEON back on after debugging the rebase.
200# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800201 Features.push_back("-neon");
202 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800203# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800204 }
Joseph Wen51001b82011-06-23 18:56:45 -0700205
Logan1f028c02010-11-27 01:02:48 +0800206 // Register the scheduler
207 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
208
Logan35849002011-01-15 07:30:43 +0800209#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700210 // Read in SHA1 checksum of libbcc and libRS.
211 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700212
213 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800214#endif
Logan75cc8a52011-01-07 06:06:52 +0800215
Logan1f028c02010-11-27 01:02:48 +0800216 GlobalInitialized = true;
217}
218
219
220void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
221 std::string *Error = static_cast<std::string*>(UserData);
222 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000223 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800224 exit(1);
225}
226
227
Logan2a6dc822011-01-06 04:05:20 +0800228Compiler::Compiler(ScriptCompiled *result)
229 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800230#if USE_MCJIT
231 mRSExecutable(NULL),
232#endif
Logan1f028c02010-11-27 01:02:48 +0800233 mpSymbolLookupFn(NULL),
234 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800235 mModule(NULL),
236 mHasLinked(false) /* Turn off linker */ {
237 llvm::remove_fatal_error_handler();
238 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800239 return;
240}
241
Logan1f028c02010-11-27 01:02:48 +0800242
Logan474cbd22011-01-31 01:47:44 +0800243int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800244 if (llvm::Linker::LinkModules(mModule, moduleWith,
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800245 llvm::Linker::PreserveSource,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800246 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800247 return hasError();
248 }
249
Logan1f028c02010-11-27 01:02:48 +0800250 // Everything for linking should be settled down here with no error occurs
251 mHasLinked = true;
252 return hasError();
253}
254
255
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800256int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800257 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800258 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800259 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800260
Logan1f028c02010-11-27 01:02:48 +0800261 std::string FeaturesStr;
262
Daniel Malea094881f2011-12-14 17:39:16 -0500263 if (mModule == NULL) // No module was loaded
264 return 0;
265
Stephen Hines569986d2012-03-09 19:58:45 -0800266 bcinfo::MetadataExtractor ME(mModule);
267 ME.extract();
Logan1f028c02010-11-27 01:02:48 +0800268
Stephen Hines569986d2012-03-09 19:58:45 -0800269 size_t VarCount = ME.getExportVarCount();
270 size_t FuncCount = ME.getExportFuncCount();
271 size_t ForEachSigCount = ME.getExportForEachSignatureCount();
272 size_t ObjectSlotCount = ME.getObjectSlotCount();
273 size_t PragmaCount = ME.getPragmaCount();
274
275 std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
276 std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
277 std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
Stephen Hinescc366e52012-02-21 17:22:04 -0800278 std::vector<std::string> ForEachNameList;
Stephen Hines569986d2012-03-09 19:58:45 -0800279 std::vector<uint32_t> ForEachSigList;
280 std::vector<const char*> ExportSymbols;
Stephen Hinescc366e52012-02-21 17:22:04 -0800281
Stephen Hines569986d2012-03-09 19:58:45 -0800282 // Defaults to maximum optimization level from MetadataExtractor.
283 int OptimizationLevel = ME.getOptimizationLevel();
Daniel Malea094881f2011-12-14 17:39:16 -0500284
285 if (OptimizationLevel == 0) {
286 CodeGenOptLevel = llvm::CodeGenOpt::None;
287 } else if (OptimizationLevel == 1) {
288 CodeGenOptLevel = llvm::CodeGenOpt::Less;
289 } else if (OptimizationLevel == 2) {
290 CodeGenOptLevel = llvm::CodeGenOpt::Default;
291 } else if (OptimizationLevel == 3) {
292 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
293 }
294
295 // not the best place for this, but we need to set the register allocation
296 // policy after we read the optimization_level metadata from the bitcode
297
298 // Register allocation policy:
299 // createFastRegisterAllocator: fast but bad quality
300 // createLinearScanRegisterAllocator: not so fast but good quality
301 llvm::RegisterRegAlloc::setDefault
302 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
303 llvm::createFastRegisterAllocator :
Stephen Hinese0918ac2012-03-01 23:28:09 -0800304 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800305
Logan Chienbe81e102011-12-16 13:31:39 +0800306 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800307 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
308 if (hasError())
309 goto on_bcc_compile_error;
310
311 if (!CPU.empty() || !Features.empty()) {
312 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800313
314 for (std::vector<std::string>::const_iterator
315 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800316 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800317 }
318
Logan1f028c02010-11-27 01:02:48 +0800319 FeaturesStr = F.getString();
320 }
321
Logan Chienbe81e102011-12-16 13:31:39 +0800322 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800323 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
324 option.TargetOpt,
325 option.RelocModelOpt,
326 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800327
Logan1f028c02010-11-27 01:02:48 +0800328 if (TM == NULL) {
329 setError("Failed to create target machine implementation for the"
330 " specified triple '" + Triple + "'");
331 goto on_bcc_compile_error;
332 }
333
Logan Chienda5e0c32011-06-13 03:47:21 +0800334 // Get target data from Module
335 TD = new llvm::TargetData(mModule);
336
Stephen Hines569986d2012-03-09 19:58:45 -0800337 // Read pragma information from MetadataExtractor
338 if (PragmaCount) {
339 ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
340 const char **PragmaKeys = ME.getPragmaKeyList();
341 const char **PragmaValues = ME.getPragmaValueList();
342 for (size_t i = 0; i < PragmaCount; i++) {
343 PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
Stephen Hinescc366e52012-02-21 17:22:04 -0800344 }
345 }
346
Stephen Hines569986d2012-03-09 19:58:45 -0800347 if (VarCount) {
348 const char **VarNames = ME.getExportVarNameList();
349 for (size_t i = 0; i < VarCount; i++) {
350 VarNameList.push_back(VarNames[i]);
351 ExportSymbols.push_back(VarNames[i]);
Stephen Hinescc366e52012-02-21 17:22:04 -0800352 }
353 }
354
Stephen Hines569986d2012-03-09 19:58:45 -0800355 if (FuncCount) {
356 const char **FuncNames = ME.getExportFuncNameList();
357 for (size_t i = 0; i < FuncCount; i++) {
358 FuncNameList.push_back(FuncNames[i]);
359 ExportSymbols.push_back(FuncNames[i]);
360 }
361 }
362
363 if (ForEachSigCount) {
364 const char **ForEachNames = ME.getExportForEachNameList();
365 const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
366 for (size_t i = 0; i < ForEachSigCount; i++) {
367 std::string Name(ForEachNames[i]);
368 ForEachNameList.push_back(Name);
369 ForEachExpandList.push_back(Name + ".expand");
370 ForEachSigList.push_back(ForEachSigs[i]);
371 }
372
373 // Need to wait until ForEachExpandList is fully populated to fill in
374 // exported symbols.
375 for (size_t i = 0; i < ForEachSigCount; i++) {
376 ExportSymbols.push_back(ForEachExpandList[i].c_str());
377 }
378 }
379
380 if (ObjectSlotCount) {
381 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
382 const uint32_t *ObjectSlots = ME.getObjectSlotList();
383 for (size_t i = 0; i < ObjectSlotCount; i++) {
384 objectSlotList.push_back(ObjectSlots[i]);
385 }
386 }
387
388 runInternalPasses(ForEachNameList, ForEachSigList);
Stephen Hinesdb169182012-01-05 18:46:36 -0800389
Logan Chienda5e0c32011-06-13 03:47:21 +0800390 // Perform link-time optimization if we have multiple modules
391 if (mHasLinked) {
Stephen Hines569986d2012-03-09 19:58:45 -0800392 runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
Logan Chienda5e0c32011-06-13 03:47:21 +0800393 }
394
395 // Perform code generation
Logan Chienda5e0c32011-06-13 03:47:21 +0800396#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700397 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800398 goto on_bcc_compile_error;
399 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800400
Zonr Chang2fcbd022012-01-06 21:04:31 +0800401 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700402 return 0;
403
404 // Load the ELF Object
405 mRSExecutable =
Stephen Hines569986d2012-03-09 19:58:45 -0800406 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
407 mEmittedELFExecutable.size(),
408 &resolveSymbolAdapter, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700409
410 if (!mRSExecutable) {
411 setError("Fail to load emitted ELF relocatable file");
412 goto on_bcc_compile_error;
413 }
414
Daniel Malea094881f2011-12-14 17:39:16 -0500415 rsloaderUpdateSectionHeaders(mRSExecutable,
Stephen Hines569986d2012-03-09 19:58:45 -0800416 (unsigned char*) mEmittedELFExecutable.begin());
Daniel Malea094881f2011-12-14 17:39:16 -0500417
Stephen Hines569986d2012-03-09 19:58:45 -0800418 // Once the ELF object has been loaded, populate the various slots for RS
419 // with the appropriate relocated addresses.
420 if (VarCount) {
421 ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
422 for (size_t i = 0; i < VarCount; i++) {
423 VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
424 VarNameList[i].c_str()));
Joseph Wen34c600a2011-07-25 17:59:17 -0700425 }
426 }
427
Stephen Hines569986d2012-03-09 19:58:45 -0800428 if (FuncCount) {
429 ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
430 for (size_t i = 0; i < FuncCount; i++) {
431 FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
432 FuncNameList[i].c_str()));
Joseph Wen34c600a2011-07-25 17:59:17 -0700433 }
434 }
435
Stephen Hines569986d2012-03-09 19:58:45 -0800436 if (ForEachSigCount) {
437 ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
438 for (size_t i = 0; i < ForEachSigCount; i++) {
439 ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
440 ForEachExpandList[i].c_str()));
Stephen Hinescc366e52012-02-21 17:22:04 -0800441 }
442 }
443
Logan Chien4885cf82011-07-20 10:18:05 +0800444#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700445 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700446 // Get MC codegen emitted function name list
447 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
448 std::vector<char const *> func_list(func_list_size, NULL);
449 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700450
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700451 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700452 for (size_t i = 0; i < func_list_size; ++i) {
453 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
454 if (func) {
455 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800456 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
457 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700458 }
459 }
460 }
461#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800462#endif
463
Logan Chienda5e0c32011-06-13 03:47:21 +0800464on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000465 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800466 if (TD) {
467 delete TD;
468 }
469
470 if (TM) {
471 delete TM;
472 }
473
474 if (mError.empty()) {
475 return 0;
476 }
477
Steve Block10c14122012-01-08 10:15:06 +0000478 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800479 return 1;
480}
481
482
Logan Chienda5e0c32011-06-13 03:47:21 +0800483#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700484int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800485 // Decorate mEmittedELFExecutable with formatted ostream
486 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
487
488 // Relax all machine instructions
489 TM->setMCRelaxAll(/* RelaxAll= */ true);
490
491 // Create MC code generation pass manager
492 llvm::PassManager MCCodeGenPasses;
493
494 // Add TargetData to MC code generation pass manager
495 MCCodeGenPasses.add(TD);
496
497 // Add MC code generation passes to pass manager
Daniel Malea094881f2011-12-14 17:39:16 -0500498 llvm::MCContext *Ctx = NULL;
Logan Chien4e4485d2011-11-25 18:12:33 +0800499 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800500 setError("Fail to add passes to emit file");
501 return 1;
502 }
503
504 MCCodeGenPasses.run(*mModule);
505 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800506 return 0;
507}
508#endif // USE_MCJIT
509
Stephen Hinescc366e52012-02-21 17:22:04 -0800510int Compiler::runInternalPasses(std::vector<std::string>& Names,
511 std::vector<uint32_t>& Signatures) {
Stephen Hinesdb169182012-01-05 18:46:36 -0800512 llvm::PassManager BCCPasses;
513
514 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hinescc366e52012-02-21 17:22:04 -0800515 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Stephen Hinesdb169182012-01-05 18:46:36 -0800516
517 BCCPasses.run(*mModule);
518
519 return 0;
520}
Logan Chienda5e0c32011-06-13 03:47:21 +0800521
522int Compiler::runLTO(llvm::TargetData *TD,
Stephen Hines569986d2012-03-09 19:58:45 -0800523 std::vector<const char*>& ExportSymbols,
Daniel Malea094881f2011-12-14 17:39:16 -0500524 llvm::CodeGenOpt::Level OptimizationLevel) {
Stephen Hines569986d2012-03-09 19:58:45 -0800525 // Note: ExportSymbols is a workaround for getting all exported variable,
526 // function, and kernel names.
Logan Chien4cc00332011-06-12 14:00:46 +0800527 // We should refine it soon.
Stephen Hinescc366e52012-02-21 17:22:04 -0800528
Logan Chien7890d432011-08-03 14:55:17 +0800529 // TODO(logan): Remove this after we have finished the
530 // bccMarkExternalSymbol API.
531
Stephen Hines64160102011-09-01 17:30:26 -0700532 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800533 ExportSymbols.push_back("root");
534 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700535 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800536
Logan Chien7890d432011-08-03 14:55:17 +0800537 // User-defined exporting symbols
538 std::vector<char const *> const &UserDefinedExternalSymbols =
539 mpResult->getUserDefinedExternalSymbols();
540
541 std::copy(UserDefinedExternalSymbols.begin(),
542 UserDefinedExternalSymbols.end(),
543 std::back_inserter(ExportSymbols));
544
Daniel Malea094881f2011-12-14 17:39:16 -0500545 llvm::PassManager LTOPasses;
546
547 // Add TargetData to LTO passes
548 LTOPasses.add(TD);
549
Logan Chien4cc00332011-06-12 14:00:46 +0800550 // We now create passes list performing LTO. These are copied from
551 // (including comments) llvm::createStandardLTOPasses().
Daniel Malea094881f2011-12-14 17:39:16 -0500552 // Only a subset of these LTO passes are enabled in optimization level 0
553 // as they interfere with interactive debugging.
554 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
Logan Chien4cc00332011-06-12 14:00:46 +0800555
Daniel Malea094881f2011-12-14 17:39:16 -0500556 if (OptimizationLevel != llvm::CodeGenOpt::None) {
557 // Internalize all other symbols not listed in ExportSymbols
558 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Logan Chien4cc00332011-06-12 14:00:46 +0800559
Daniel Malea094881f2011-12-14 17:39:16 -0500560 // Propagate constants at call sites into the functions they call. This
561 // opens opportunities for globalopt (and inlining) by substituting
562 // function pointers passed as arguments to direct uses of functions.
563 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800564
Daniel Malea094881f2011-12-14 17:39:16 -0500565 // Now that we internalized some globals, see if we can hack on them!
566 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800567
Daniel Malea094881f2011-12-14 17:39:16 -0500568 // Linking modules together can lead to duplicated global constants, only
569 // keep one copy of each constant...
570 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800571
Daniel Malea094881f2011-12-14 17:39:16 -0500572 // Remove unused arguments from functions...
573 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800574
Daniel Malea094881f2011-12-14 17:39:16 -0500575 // Reduce the code after globalopt and ipsccp. Both can open up
576 // significant simplification opportunities, and both can propagate
577 // functions through function pointers. When this happens, we often have
578 // to resolve varargs calls, etc, so let instcombine do this.
579 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800580
Daniel Malea094881f2011-12-14 17:39:16 -0500581 // Inline small functions
582 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800583
Daniel Malea094881f2011-12-14 17:39:16 -0500584 // Remove dead EH info.
585 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800586
Daniel Malea094881f2011-12-14 17:39:16 -0500587 // Internalize the globals again after inlining
588 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800589
Daniel Malea094881f2011-12-14 17:39:16 -0500590 // Remove dead functions.
591 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800592
Daniel Malea094881f2011-12-14 17:39:16 -0500593 // If we didn't decide to inline a function, check to see if we can
594 // transform it to pass arguments by value instead of by reference.
595 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800596
Daniel Malea094881f2011-12-14 17:39:16 -0500597 // The IPO passes may leave cruft around. Clean up after them.
598 LTOPasses.add(llvm::createInstructionCombiningPass());
599 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800600
Daniel Malea094881f2011-12-14 17:39:16 -0500601 // Break up allocas
602 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800603
Daniel Malea094881f2011-12-14 17:39:16 -0500604 // Run a few AA driven optimizations here and now, to cleanup the code.
605 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
606 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800607
Daniel Malea094881f2011-12-14 17:39:16 -0500608 // Hoist loop invariants.
609 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800610
Daniel Malea094881f2011-12-14 17:39:16 -0500611 // Remove redundancies.
612 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800613
Daniel Malea094881f2011-12-14 17:39:16 -0500614 // Remove dead memcpys.
615 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800616
Daniel Malea094881f2011-12-14 17:39:16 -0500617 // Nuke dead stores.
618 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800619
Daniel Malea094881f2011-12-14 17:39:16 -0500620 // Cleanup and simplify the code after the scalar optimizations.
621 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800622
Daniel Malea094881f2011-12-14 17:39:16 -0500623 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800624
Daniel Malea094881f2011-12-14 17:39:16 -0500625 // Delete basic blocks, which optimization passes may have killed.
626 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800627
Daniel Malea094881f2011-12-14 17:39:16 -0500628 // Now that we have optimized the program, discard unreachable functions.
629 LTOPasses.add(llvm::createGlobalDCEPass());
630
631 } else {
632 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
633 LTOPasses.add(llvm::createGlobalOptimizerPass());
634 LTOPasses.add(llvm::createConstantMergePass());
635 }
Logan Chien4cc00332011-06-12 14:00:46 +0800636
637 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800638
Daniel Malea094881f2011-12-14 17:39:16 -0500639#if ANDROID_ENGINEERING_BUILD
640 if (0 != gDebugDumpDirectory) {
641 std::string errs;
642 std::string Filename(gDebugDumpDirectory);
643 Filename += "/post-lto-module.ll";
644 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
645 mModule->print(FS, 0);
646 FS.close();
647 }
648#endif
649
Logan Chienda5e0c32011-06-13 03:47:21 +0800650 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800651}
652
653
Logan Chienda5e0c32011-06-13 03:47:21 +0800654#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800655void *Compiler::getSymbolAddress(char const *name) {
656 return rsloaderGetSymbolAddress(mRSExecutable, name);
657}
658#endif
659
660
661#if USE_MCJIT
662void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
663 Compiler *self = reinterpret_cast<Compiler *>(context);
664
665 if (void *Addr = FindRuntimeFunction(name)) {
666 return Addr;
667 }
668
669 if (self->mpSymbolLookupFn) {
670 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
671 return Addr;
672 }
673 }
674
Steve Block10c14122012-01-08 10:15:06 +0000675 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800676 return NULL;
677}
678#endif
679
680
Logan1f028c02010-11-27 01:02:48 +0800681Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800682#if USE_MCJIT
683 rsloaderDisposeExec(mRSExecutable);
684#endif
685
Logana4994f52010-11-27 14:06:02 +0800686 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800687}
688
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700689
Logan1f028c02010-11-27 01:02:48 +0800690} // namespace bcc