blob: ac00552f2178403a5f917482800321f4c653dfa1 [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"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/ContextManager.h"
23#endif
24
Logan Chien4885cf82011-07-20 10:18:05 +080025#if USE_DISASSEMBLER
26#include "Disassembler/Disassembler.h"
27#endif
28
Logan4dcd6792011-02-28 05:12:00 +080029#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070030#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080031#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080032#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080033#include "Sha1Helper.h"
Loganeb3d12b2010-12-16 06:20:18 +080034
Shih-wei Liao320b5492011-06-20 22:53:33 -070035#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080036#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070037#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080038
Stephen Hinesdb169182012-01-05 18:46:36 -080039#include "Transforms/BCCTransforms.h"
40
Logandf23afa2010-11-27 11:04:54 +080041#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080042
Logandf23afa2010-11-27 11:04:54 +080043#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080044
Logan1f028c02010-11-27 01:02:48 +080045#include "llvm/Bitcode/ReaderWriter.h"
46
Logan1f028c02010-11-27 01:02:48 +080047#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080048#include "llvm/CodeGen/RegAllocRegistry.h"
49#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080050
Logan Chien9347e0b2011-07-07 19:51:47 +080051#include "llvm/MC/SubtargetFeature.h"
52
Logandf23afa2010-11-27 11:04:54 +080053#include "llvm/Transforms/IPO.h"
54#include "llvm/Transforms/Scalar.h"
55
Logandf23afa2010-11-27 11:04:54 +080056#include "llvm/Target/TargetData.h"
57#include "llvm/Target/TargetMachine.h"
58#include "llvm/Target/TargetOptions.h"
Logandf23afa2010-11-27 11:04:54 +080059
60#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070061#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080062#include "llvm/Support/MemoryBuffer.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080063#include "llvm/Support/TargetRegistry.h"
64#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080065
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070066#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080067#include "llvm/GlobalValue.h"
68#include "llvm/Linker.h"
69#include "llvm/LLVMContext.h"
70#include "llvm/Metadata.h"
71#include "llvm/Module.h"
72#include "llvm/PassManager.h"
73#include "llvm/Value.h"
74
75#include <errno.h>
76#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080077#include <sys/stat.h>
78#include <sys/types.h>
79#include <unistd.h>
80
Logan75cc8a52011-01-07 06:06:52 +080081#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080082
Logan Chien7890d432011-08-03 14:55:17 +080083#include <algorithm>
84#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080085#include <string>
86#include <vector>
Logan1f028c02010-11-27 01:02:48 +080087
Logan1f028c02010-11-27 01:02:48 +080088namespace bcc {
89
90//////////////////////////////////////////////////////////////////////////////
91// BCC Compiler Static Variables
92//////////////////////////////////////////////////////////////////////////////
93
94bool Compiler::GlobalInitialized = false;
95
Andrew Hsieh998ec832011-11-21 02:36:11 -080096
97#if !defined(__HOST__)
98 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
99#else
100// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
101 #if defined(__cplusplus)
102 extern "C" {
103 #endif
104 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
105 #if defined(__cplusplus)
106 };
107 #endif
108#endif
109
Logan1f028c02010-11-27 01:02:48 +0800110// Code generation optimization level for the compiler
111llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
112
113std::string Compiler::Triple;
114
115std::string Compiler::CPU;
116
117std::vector<std::string> Compiler::Features;
118
Stephen Hines071288a2011-01-27 14:38:26 -0800119// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800120// slang.cpp)
121const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
122
Stephen Hines071288a2011-01-27 14:38:26 -0800123// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800124// synced with slang_rs_metadata.h)
125const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
126
Stephen Hines071288a2011-01-27 14:38:26 -0800127// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800128// synced with slang_rs_metadata.h)
129const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
130
Stephen Hines071288a2011-01-27 14:38:26 -0800131// Name of metadata node where RS object slot info resides (should be
132// synced with slang_rs_metadata.h)
133const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800134
135//////////////////////////////////////////////////////////////////////////////
136// Compiler
137//////////////////////////////////////////////////////////////////////////////
138
139void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700140 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800141 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700142 }
143
Logan1f028c02010-11-27 01:02:48 +0800144 // if (!llvm::llvm_is_multithreaded())
145 // llvm::llvm_start_multithreaded();
146
147 // Set Triple, CPU and Features here
148 Triple = TARGET_TRIPLE_STRING;
149
Logan Chien3bb77072011-09-17 16:53:53 +0800150#if defined(DEFAULT_ARM_CODEGEN)
151
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700152#if defined(ARCH_ARM_HAVE_VFP)
153 Features.push_back("+vfp3");
154#if !defined(ARCH_ARM_HAVE_VFP_D32)
155 Features.push_back("+d16");
156#endif
157#endif
158
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700159#if defined(ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700160 Features.push_back("+neon");
161 Features.push_back("+neonfp");
Stephen Hines7f079eb2011-11-09 15:19:03 -0800162#else
163 Features.push_back("-neon");
164 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700165#endif
166
167#if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700168 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800169 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700170#endif
171
Logan Chien3bb77072011-09-17 16:53:53 +0800172#endif // DEFAULT_ARM_CODEGEN
Joseph Wen51001b82011-06-23 18:56:45 -0700173
Logan Chien3bb77072011-09-17 16:53:53 +0800174#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800175 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800176 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800177 LLVMInitializeARMTargetInfo();
178 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800179#endif
180
Logan Chien21392f02011-11-26 20:32:01 +0800181#if defined(PROVIDE_MIPS_CODEGEN)
182 LLVMInitializeMipsAsmPrinter();
183 LLVMInitializeMipsTargetMC();
184 LLVMInitializeMipsTargetInfo();
185 LLVMInitializeMipsTarget();
186#endif
187
Logan Chien3bb77072011-09-17 16:53:53 +0800188#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800189 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800190 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800191 LLVMInitializeX86TargetInfo();
192 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800193#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800194
195#if USE_DISASSEMBLER
196 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800197#endif
198
199 // -O0: llvm::CodeGenOpt::None
200 // -O1: llvm::CodeGenOpt::Less
201 // -O2: llvm::CodeGenOpt::Default
202 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800203 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800204
Logan1f028c02010-11-27 01:02:48 +0800205 // Register the scheduler
206 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
207
208 // Register allocation policy:
209 // createFastRegisterAllocator: fast but bad quality
210 // createLinearScanRegisterAllocator: not so fast but good quality
211 llvm::RegisterRegAlloc::setDefault
212 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
213 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800214 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800215
Logan35849002011-01-15 07:30:43 +0800216#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700217 // Read in SHA1 checksum of libbcc and libRS.
218 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700219
220 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800221#endif
Logan75cc8a52011-01-07 06:06:52 +0800222
Logan1f028c02010-11-27 01:02:48 +0800223 GlobalInitialized = true;
224}
225
226
227void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
228 std::string *Error = static_cast<std::string*>(UserData);
229 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000230 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800231 exit(1);
232}
233
234
Logan Chienda5e0c32011-06-13 03:47:21 +0800235#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800236CodeMemoryManager *Compiler::createCodeMemoryManager() {
237 mCodeMemMgr.reset(new CodeMemoryManager());
238 return mCodeMemMgr.get();
239}
Logan Chienda5e0c32011-06-13 03:47:21 +0800240#endif
Logan1f028c02010-11-27 01:02:48 +0800241
242
Logan Chienda5e0c32011-06-13 03:47:21 +0800243#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800244CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800245 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800246 return mCodeEmitter.get();
247}
Logan Chienda5e0c32011-06-13 03:47:21 +0800248#endif
Logan1f028c02010-11-27 01:02:48 +0800249
250
Logan2a6dc822011-01-06 04:05:20 +0800251Compiler::Compiler(ScriptCompiled *result)
252 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800253#if USE_MCJIT
254 mRSExecutable(NULL),
255#endif
Logan1f028c02010-11-27 01:02:48 +0800256 mpSymbolLookupFn(NULL),
257 mpSymbolLookupContext(NULL),
258 mContext(NULL),
259 mModule(NULL),
260 mHasLinked(false) /* Turn off linker */ {
261 llvm::remove_fatal_error_handler();
262 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
263 mContext = new llvm::LLVMContext();
264 return;
265}
266
Logan1f028c02010-11-27 01:02:48 +0800267
Logan474cbd22011-01-31 01:47:44 +0800268llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
269 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800270
Logan474cbd22011-01-31 01:47:44 +0800271 if (!result) {
Steve Block10c14122012-01-08 10:15:06 +0000272 ALOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
Logan474cbd22011-01-31 01:47:44 +0800273 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800274 }
275
Logan474cbd22011-01-31 01:47:44 +0800276 return result;
Logan1f028c02010-11-27 01:02:48 +0800277}
278
279
Logan474cbd22011-01-31 01:47:44 +0800280int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800281 if (llvm::Linker::LinkModules(mModule, moduleWith,
282 llvm::Linker::DestroySource,
283 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800284 return hasError();
285 }
286
Logan1f028c02010-11-27 01:02:48 +0800287 // Everything for linking should be settled down here with no error occurs
288 mHasLinked = true;
289 return hasError();
290}
291
292
Joseph Wen34c600a2011-07-25 17:59:17 -0700293int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800294 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800295 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800296 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800297
Logan1f028c02010-11-27 01:02:48 +0800298 std::string FeaturesStr;
299
Logan Chienda5e0c32011-06-13 03:47:21 +0800300 llvm::NamedMDNode const *PragmaMetadata;
301 llvm::NamedMDNode const *ExportVarMetadata;
302 llvm::NamedMDNode const *ExportFuncMetadata;
303 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800304
Logan Chienbe81e102011-12-16 13:31:39 +0800305 llvm::TargetOptions Options;
306
307 llvm::CodeModel::Model CM;
308 llvm::Reloc::Model RM;
309
Logan1f028c02010-11-27 01:02:48 +0800310 if (mModule == NULL) // No module was loaded
311 return 0;
312
Logan Chienbe81e102011-12-16 13:31:39 +0800313 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800314 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
315 if (hasError())
316 goto on_bcc_compile_error;
317
318 if (!CPU.empty() || !Features.empty()) {
319 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800320
321 for (std::vector<std::string>::const_iterator
322 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800323 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800324 }
325
Logan1f028c02010-11-27 01:02:48 +0800326 FeaturesStr = F.getString();
327 }
328
Logan Chienbe81e102011-12-16 13:31:39 +0800329 // Setup LLVM Target Machine Options
330 // Disable frame pointer elimination optimization
331 Options.NoFramePointerElim = false;
332
333 // Use hardfloat ABI
334 //
335 // TODO(all): Need to detect the CPU capability and decide whether to use
336 // softfp. To use softfp, change following 2 lines to
337 //
338 // options.FloatABIType = llvm::FloatABI::Soft;
339 // options.UseSoftFloat = true;
340 Options.FloatABIType = llvm::FloatABI::Soft;
341 Options.UseSoftFloat = false;
342
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800343#if defined(DEFAULT_X86_64_CODEGEN)
344 // Data address in X86_64 architecture may reside in a far-away place
Logan Chienbe81e102011-12-16 13:31:39 +0800345 CM = llvm::CodeModel::Medium;
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800346#else
347 // This is set for the linker (specify how large of the virtual addresses
348 // we can access for all unknown symbols.)
Logan Chienbe81e102011-12-16 13:31:39 +0800349 CM = llvm::CodeModel::Small;
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800350#endif
Logan Chienbe81e102011-12-16 13:31:39 +0800351
352 RM = llvm::Reloc::Static;
353
354 // Create LLVM Target Machine
355 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr, Options, RM, CM);
356
Logan1f028c02010-11-27 01:02:48 +0800357 if (TM == NULL) {
358 setError("Failed to create target machine implementation for the"
359 " specified triple '" + Triple + "'");
360 goto on_bcc_compile_error;
361 }
362
Logan Chienda5e0c32011-06-13 03:47:21 +0800363 // Get target data from Module
364 TD = new llvm::TargetData(mModule);
365
366 // Load named metadata
367 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
368 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
369 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
370 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
371
Stephen Hinesdb169182012-01-05 18:46:36 -0800372 runInternalPasses();
373
Logan Chienda5e0c32011-06-13 03:47:21 +0800374 // Perform link-time optimization if we have multiple modules
375 if (mHasLinked) {
376 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
377 }
378
379 // Perform code generation
380#if USE_OLD_JIT
381 if (runCodeGen(new llvm::TargetData(*TD), TM,
382 ExportVarMetadata, ExportFuncMetadata) != 0) {
383 goto on_bcc_compile_error;
384 }
385#endif
386
387#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700388 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800389 goto on_bcc_compile_error;
390 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800391
Joseph Wen34c600a2011-07-25 17:59:17 -0700392 if (compileOnly)
393 return 0;
394
395 // Load the ELF Object
396 mRSExecutable =
397 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
398 mEmittedELFExecutable.size(),
399 &resolveSymbolAdapter, this);
400
401 if (!mRSExecutable) {
402 setError("Fail to load emitted ELF relocatable file");
403 goto on_bcc_compile_error;
404 }
405
406 if (ExportVarMetadata) {
407 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
408 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
409
410 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
411 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
412 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
413 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
414 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
415 llvm::StringRef ExportVarName =
416 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
417
418 varList.push_back(
419 rsloaderGetSymbolAddress(mRSExecutable,
420 ExportVarName.str().c_str()));
421 varNameList.push_back(ExportVarName.str());
422#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000423 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700424 varList.back());
425#endif
426 continue;
427 }
428 }
429
430 varList.push_back(NULL);
431 }
432 }
433
434 if (ExportFuncMetadata) {
435 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
436 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
437
438 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
439 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
440 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
441 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
442 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
443 llvm::StringRef ExportFuncName =
444 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
445
446 funcList.push_back(
447 rsloaderGetSymbolAddress(mRSExecutable,
448 ExportFuncName.str().c_str()));
449 funcNameList.push_back(ExportFuncName.str());
450#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000451 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700452 funcList.back());
453#endif
454 }
455 }
456 }
457 }
458
Logan Chien4885cf82011-07-20 10:18:05 +0800459#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700460 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700461 // Get MC codegen emitted function name list
462 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
463 std::vector<char const *> func_list(func_list_size, NULL);
464 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700465
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700466 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700467 for (size_t i = 0; i < func_list_size; ++i) {
468 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
469 if (func) {
470 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800471 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
472 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700473 }
474 }
475 }
476#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800477#endif
478
479 // Read pragma information from the metadata node of the module.
480 if (PragmaMetadata) {
481 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
482
483 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
484 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
485 if (Pragma != NULL &&
486 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
487 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
488 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
489
490 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
491 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
492 llvm::StringRef PragmaName =
493 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
494 llvm::StringRef PragmaValue =
495 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
496
497 pragmaList.push_back(
498 std::make_pair(std::string(PragmaName.data(),
499 PragmaName.size()),
500 std::string(PragmaValue.data(),
501 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700502#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000503 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700504 pragmaList.back().first.c_str(),
505 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700506#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800507 }
508 }
509 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800510 }
511
512 if (ObjectSlotMetadata) {
513 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
514
515 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
516 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
517 if (ObjectSlot != NULL &&
518 ObjectSlot->getNumOperands() == 1) {
519 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
520 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
521 llvm::StringRef Slot =
522 static_cast<llvm::MDString*>(SlotMDS)->getString();
523 uint32_t USlot = 0;
524 if (Slot.getAsInteger(10, USlot)) {
525 setError("Non-integer object slot value '" + Slot.str() + "'");
526 goto on_bcc_compile_error;
527 }
528 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700529#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000530 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700531#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800532 }
533 }
534 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800535 }
536
537on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000538 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800539 if (TD) {
540 delete TD;
541 }
542
543 if (TM) {
544 delete TM;
545 }
546
547 if (mError.empty()) {
548 return 0;
549 }
550
Steve Block10c14122012-01-08 10:15:06 +0000551 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800552 return 1;
553}
554
555
556#if USE_OLD_JIT
557int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
558 llvm::NamedMDNode const *ExportVarMetadata,
559 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800560 // Create memory manager for creation of code emitter later.
561 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
562 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800563 return 1;
Logan1f028c02010-11-27 01:02:48 +0800564 }
Logan02286cb2011-01-07 00:30:47 +0800565
566 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800567
568 // Create code emitter
569 if (!mCodeEmitter.get()) {
570 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800571 setError("Failed to create machine code emitter for compilation");
572 return 1;
Logan1f028c02010-11-27 01:02:48 +0800573 }
574 } else {
575 // Reuse the code emitter
576 mCodeEmitter->reset();
577 }
578
579 mCodeEmitter->setTargetMachine(*TM);
580 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
581 mpSymbolLookupContext);
582
Logan1f028c02010-11-27 01:02:48 +0800583 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800584 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
585 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800586
Logan Chienda5e0c32011-06-13 03:47:21 +0800587 // Add TargetData to code generation pass manager
588 CodeGenPasses->add(TD);
589
590 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800591 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
592 *mCodeEmitter,
593 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800594 setError("The machine code emission is not supported on '" + Triple + "'");
595 return 1;
Logan1f028c02010-11-27 01:02:48 +0800596 }
597
Logan Chienda5e0c32011-06-13 03:47:21 +0800598 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800599 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800600 for (llvm::Module::iterator
601 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800602 if (!I->isDeclaration()) {
603 CodeGenPasses->run(*I);
604 }
605 }
606
607 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800608
Logan1f028c02010-11-27 01:02:48 +0800609 // Copy the global address mapping from code emitter and remapping
610 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800611 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
612
Logan1f028c02010-11-27 01:02:48 +0800613 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
614 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
615 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
616 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
617 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
618 llvm::StringRef ExportVarName =
619 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
620
621 CodeEmitter::global_addresses_const_iterator I, E;
622 for (I = mCodeEmitter->global_address_begin(),
623 E = mCodeEmitter->global_address_end();
624 I != E; I++) {
625 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
626 continue;
627 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800628 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700629#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000630 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700631#endif
Logan1f028c02010-11-27 01:02:48 +0800632 break;
633 }
634 }
635 if (I != mCodeEmitter->global_address_end())
636 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800637
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700638#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000639 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800640 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700641#endif
Logan1f028c02010-11-27 01:02:48 +0800642 }
643 }
644 // if reaching here, we know the global variable record in metadata is
645 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800646 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800647 }
Logan2a6dc822011-01-06 04:05:20 +0800648
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700649 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
650 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800651 }
652
653 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800654 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
655
Logan1f028c02010-11-27 01:02:48 +0800656 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
657 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
658 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
659 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
660 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
661 llvm::StringRef ExportFuncName =
662 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800663 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700664#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000665 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800666 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700667#endif
Logan1f028c02010-11-27 01:02:48 +0800668 }
669 }
670 }
671 }
672
673 // Tell code emitter now can release the memory using during the JIT since
674 // we have done the code emission
675 mCodeEmitter->releaseUnnecessary();
676
Logan Chienda5e0c32011-06-13 03:47:21 +0800677 return 0;
Logan1f028c02010-11-27 01:02:48 +0800678}
Logan Chienda5e0c32011-06-13 03:47:21 +0800679#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800680
681
Logan Chienda5e0c32011-06-13 03:47:21 +0800682#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700683int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800684 // Decorate mEmittedELFExecutable with formatted ostream
685 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
686
687 // Relax all machine instructions
688 TM->setMCRelaxAll(/* RelaxAll= */ true);
689
690 // Create MC code generation pass manager
691 llvm::PassManager MCCodeGenPasses;
692
693 // Add TargetData to MC code generation pass manager
694 MCCodeGenPasses.add(TD);
695
696 // Add MC code generation passes to pass manager
697 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800698 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800699 setError("Fail to add passes to emit file");
700 return 1;
701 }
702
703 MCCodeGenPasses.run(*mModule);
704 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800705 return 0;
706}
707#endif // USE_MCJIT
708
Stephen Hinesdb169182012-01-05 18:46:36 -0800709int Compiler::runInternalPasses() {
710 llvm::PassManager BCCPasses;
711
712 // Expand ForEach on CPU path to reduce launch overhead.
713 BCCPasses.add(createForEachExpandPass());
714
715 BCCPasses.run(*mModule);
716
717 return 0;
718}
Logan Chienda5e0c32011-06-13 03:47:21 +0800719
720int Compiler::runLTO(llvm::TargetData *TD,
721 llvm::NamedMDNode const *ExportVarMetadata,
722 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800723 llvm::PassManager LTOPasses;
724
725 // Add TargetData to LTO passes
726 LTOPasses.add(TD);
727
728 // Collect All Exported Symbols
729 std::vector<const char*> ExportSymbols;
730
731 // Note: This is a workaround for getting export variable and function name.
732 // We should refine it soon.
733 if (ExportVarMetadata) {
734 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
735 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
736 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
737 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
738 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
739 llvm::StringRef ExportVarName =
740 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
741 ExportSymbols.push_back(ExportVarName.data());
742 }
743 }
744 }
745 }
746
747 if (ExportFuncMetadata) {
748 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
749 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
750 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
751 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
752 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
753 llvm::StringRef ExportFuncName =
754 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
755 ExportSymbols.push_back(ExportFuncName.data());
756 }
757 }
758 }
759 }
760
Logan Chien7890d432011-08-03 14:55:17 +0800761 // TODO(logan): Remove this after we have finished the
762 // bccMarkExternalSymbol API.
763
Stephen Hines64160102011-09-01 17:30:26 -0700764 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800765 ExportSymbols.push_back("root");
Stephen Hinesdb169182012-01-05 18:46:36 -0800766 ExportSymbols.push_back("root.expand");
Logan Chien4cc00332011-06-12 14:00:46 +0800767 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700768 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800769
Logan Chien7890d432011-08-03 14:55:17 +0800770 // User-defined exporting symbols
771 std::vector<char const *> const &UserDefinedExternalSymbols =
772 mpResult->getUserDefinedExternalSymbols();
773
774 std::copy(UserDefinedExternalSymbols.begin(),
775 UserDefinedExternalSymbols.end(),
776 std::back_inserter(ExportSymbols));
777
Logan Chien4cc00332011-06-12 14:00:46 +0800778 // We now create passes list performing LTO. These are copied from
779 // (including comments) llvm::createStandardLTOPasses().
780
781 // Internalize all other symbols not listed in ExportSymbols
782 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
783
784 // Propagate constants at call sites into the functions they call. This
785 // opens opportunities for globalopt (and inlining) by substituting
786 // function pointers passed as arguments to direct uses of functions.
787 LTOPasses.add(llvm::createIPSCCPPass());
788
789 // Now that we internalized some globals, see if we can hack on them!
790 LTOPasses.add(llvm::createGlobalOptimizerPass());
791
792 // Linking modules together can lead to duplicated global constants, only
793 // keep one copy of each constant...
794 LTOPasses.add(llvm::createConstantMergePass());
795
796 // Remove unused arguments from functions...
797 LTOPasses.add(llvm::createDeadArgEliminationPass());
798
799 // Reduce the code after globalopt and ipsccp. Both can open up
800 // significant simplification opportunities, and both can propagate
801 // functions through function pointers. When this happens, we often have
802 // to resolve varargs calls, etc, so let instcombine do this.
803 LTOPasses.add(llvm::createInstructionCombiningPass());
804
805 // Inline small functions
806 LTOPasses.add(llvm::createFunctionInliningPass());
807
808 // Remove dead EH info.
809 LTOPasses.add(llvm::createPruneEHPass());
810
811 // Internalize the globals again after inlining
812 LTOPasses.add(llvm::createGlobalOptimizerPass());
813
814 // Remove dead functions.
815 LTOPasses.add(llvm::createGlobalDCEPass());
816
817 // If we didn't decide to inline a function, check to see if we can
818 // transform it to pass arguments by value instead of by reference.
819 LTOPasses.add(llvm::createArgumentPromotionPass());
820
821 // The IPO passes may leave cruft around. Clean up after them.
822 LTOPasses.add(llvm::createInstructionCombiningPass());
823 LTOPasses.add(llvm::createJumpThreadingPass());
824
825 // Break up allocas
826 LTOPasses.add(llvm::createScalarReplAggregatesPass());
827
828 // Run a few AA driven optimizations here and now, to cleanup the code.
829 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
830 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
831
832 // Hoist loop invariants.
833 LTOPasses.add(llvm::createLICMPass());
834
835 // Remove redundancies.
836 LTOPasses.add(llvm::createGVNPass());
837
838 // Remove dead memcpys.
839 LTOPasses.add(llvm::createMemCpyOptPass());
840
841 // Nuke dead stores.
842 LTOPasses.add(llvm::createDeadStoreEliminationPass());
843
844 // Cleanup and simplify the code after the scalar optimizations.
845 LTOPasses.add(llvm::createInstructionCombiningPass());
846
847 LTOPasses.add(llvm::createJumpThreadingPass());
848
849 // Delete basic blocks, which optimization passes may have killed.
850 LTOPasses.add(llvm::createCFGSimplificationPass());
851
852 // Now that we have optimized the program, discard unreachable functions.
853 LTOPasses.add(llvm::createGlobalDCEPass());
854
855 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800856
857 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800858}
859
860
Logan Chienda5e0c32011-06-13 03:47:21 +0800861#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800862void *Compiler::getSymbolAddress(char const *name) {
863 return rsloaderGetSymbolAddress(mRSExecutable, name);
864}
865#endif
866
867
868#if USE_MCJIT
869void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
870 Compiler *self = reinterpret_cast<Compiler *>(context);
871
872 if (void *Addr = FindRuntimeFunction(name)) {
873 return Addr;
874 }
875
876 if (self->mpSymbolLookupFn) {
877 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
878 return Addr;
879 }
880 }
881
Steve Block10c14122012-01-08 10:15:06 +0000882 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800883 return NULL;
884}
885#endif
886
887
Logan1f028c02010-11-27 01:02:48 +0800888Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800889 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800890 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800891
Logan Chienda5e0c32011-06-13 03:47:21 +0800892#if USE_MCJIT
893 rsloaderDisposeExec(mRSExecutable);
894#endif
895
Logana4994f52010-11-27 14:06:02 +0800896 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800897}
898
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700899
Logan1f028c02010-11-27 01:02:48 +0800900} // namespace bcc