blob: 7807194f44eef1b281a4c3d2b74613fb0e06721d [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
2 * Copyright 2010, 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
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
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/Bitcode/ReaderWriter.h"
44
Logan1f028c02010-11-27 01:02:48 +080045#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080046#include "llvm/CodeGen/RegAllocRegistry.h"
47#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080048
Logan Chien9347e0b2011-07-07 19:51:47 +080049#include "llvm/MC/SubtargetFeature.h"
50
Logandf23afa2010-11-27 11:04:54 +080051#include "llvm/Transforms/IPO.h"
52#include "llvm/Transforms/Scalar.h"
53
Logandf23afa2010-11-27 11:04:54 +080054#include "llvm/Target/TargetData.h"
55#include "llvm/Target/TargetMachine.h"
56#include "llvm/Target/TargetOptions.h"
57#include "llvm/Target/TargetRegistry.h"
58#include "llvm/Target/TargetSelect.h"
59
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"
63
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070064#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080065#include "llvm/GlobalValue.h"
66#include "llvm/Linker.h"
67#include "llvm/LLVMContext.h"
68#include "llvm/Metadata.h"
69#include "llvm/Module.h"
70#include "llvm/PassManager.h"
71#include "llvm/Value.h"
72
73#include <errno.h>
74#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080075#include <sys/stat.h>
76#include <sys/types.h>
77#include <unistd.h>
78
Logan75cc8a52011-01-07 06:06:52 +080079#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080080
Logan Chien7890d432011-08-03 14:55:17 +080081#include <algorithm>
82#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080083#include <string>
84#include <vector>
Logan1f028c02010-11-27 01:02:48 +080085
Logan1f028c02010-11-27 01:02:48 +080086namespace bcc {
87
88//////////////////////////////////////////////////////////////////////////////
89// BCC Compiler Static Variables
90//////////////////////////////////////////////////////////////////////////////
91
92bool Compiler::GlobalInitialized = false;
93
Logan1f028c02010-11-27 01:02:48 +080094// Code generation optimization level for the compiler
95llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
96
97std::string Compiler::Triple;
98
99std::string Compiler::CPU;
100
101std::vector<std::string> Compiler::Features;
102
Stephen Hines071288a2011-01-27 14:38:26 -0800103// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800104// slang.cpp)
105const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
106
Stephen Hines071288a2011-01-27 14:38:26 -0800107// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800108// synced with slang_rs_metadata.h)
109const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
110
Stephen Hines071288a2011-01-27 14:38:26 -0800111// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800112// synced with slang_rs_metadata.h)
113const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
114
Stephen Hines071288a2011-01-27 14:38:26 -0800115// Name of metadata node where RS object slot info resides (should be
116// synced with slang_rs_metadata.h)
117const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800118
119//////////////////////////////////////////////////////////////////////////////
120// Compiler
121//////////////////////////////////////////////////////////////////////////////
122
123void Compiler::GlobalInitialization() {
124 if (GlobalInitialized)
125 return;
Logan1f028c02010-11-27 01:02:48 +0800126 // if (!llvm::llvm_is_multithreaded())
127 // llvm::llvm_start_multithreaded();
128
129 // Set Triple, CPU and Features here
130 Triple = TARGET_TRIPLE_STRING;
131
Logan1f028c02010-11-27 01:02:48 +0800132 Features.push_back("+vfp3");
Logan1f028c02010-11-27 01:02:48 +0800133
Logan4fe966f2011-02-27 08:26:40 +0800134 // NOTE: Currently, we have to turn off the support for NEON explicitly.
135 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
136 // instructions.
Joseph Wen51001b82011-06-23 18:56:45 -0700137#if ARCH_ARM_HAVE_NEON
138 Features.push_back("+d32");
139 Features.push_back("+neon");
140 Features.push_back("+neonfp");
141#else
142 Features.push_back("+d16");
143 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800144 Features.push_back("-neonfp");
Joseph Wen51001b82011-06-23 18:56:45 -0700145#endif
146
Logan4fe966f2011-02-27 08:26:40 +0800147 Features.push_back("-vmlx");
148
Logan1f028c02010-11-27 01:02:48 +0800149#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
Shih-wei Liaoc2e23c32011-07-19 05:20:58 -0700150 LLVMInitializeARMMCAsmInfo();
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800151 LLVMInitializeARMAsmPrinter();
Logan1f028c02010-11-27 01:02:48 +0800152 LLVMInitializeARMTargetInfo();
153 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800154#endif
155
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800156#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN) || \
157 defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
Shih-wei Liaoc2e23c32011-07-19 05:20:58 -0700158 LLVMInitializeX86MCAsmInfo();
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800159 LLVMInitializeX86AsmPrinter();
Logan1f028c02010-11-27 01:02:48 +0800160 LLVMInitializeX86TargetInfo();
161 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800162#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800163
164#if USE_DISASSEMBLER
165 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800166#endif
167
168 // -O0: llvm::CodeGenOpt::None
169 // -O1: llvm::CodeGenOpt::Less
170 // -O2: llvm::CodeGenOpt::Default
171 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800172 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800173
174 // Below are the global settings to LLVM
175
176 // Disable frame pointer elimination optimization
177 llvm::NoFramePointerElim = false;
178
179 // Use hardfloat ABI
180 //
181 // TODO(all): Need to detect the CPU capability and decide whether to use
182 // softfp. To use softfp, change following 2 lines to
183 //
184 // llvm::FloatABIType = llvm::FloatABI::Soft;
185 // llvm::UseSoftFloat = true;
186 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800187 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800188 llvm::UseSoftFloat = false;
189
Logan1f028c02010-11-27 01:02:48 +0800190#if defined(DEFAULT_X64_CODEGEN)
191 // Data address in X86_64 architecture may reside in a far-away place
192 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
193#else
194 // This is set for the linker (specify how large of the virtual addresses
195 // we can access for all unknown symbols.)
196 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
197#endif
198
199 // Register the scheduler
200 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
201
202 // Register allocation policy:
203 // createFastRegisterAllocator: fast but bad quality
204 // createLinearScanRegisterAllocator: not so fast but good quality
205 llvm::RegisterRegAlloc::setDefault
206 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
207 llvm::createFastRegisterAllocator :
208 llvm::createLinearScanRegisterAllocator);
209
Logan35849002011-01-15 07:30:43 +0800210#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700211 // Read in SHA1 checksum of libbcc and libRS.
212 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700213
214 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800215#endif
Logan75cc8a52011-01-07 06:06:52 +0800216
Logan1f028c02010-11-27 01:02:48 +0800217 GlobalInitialized = true;
218}
219
220
221void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
222 std::string *Error = static_cast<std::string*>(UserData);
223 Error->assign(Message);
224 LOGE("%s", Message.c_str());
225 exit(1);
226}
227
228
Logan Chienda5e0c32011-06-13 03:47:21 +0800229#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800230CodeMemoryManager *Compiler::createCodeMemoryManager() {
231 mCodeMemMgr.reset(new CodeMemoryManager());
232 return mCodeMemMgr.get();
233}
Logan Chienda5e0c32011-06-13 03:47:21 +0800234#endif
Logan1f028c02010-11-27 01:02:48 +0800235
236
Logan Chienda5e0c32011-06-13 03:47:21 +0800237#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800238CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800239 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800240 return mCodeEmitter.get();
241}
Logan Chienda5e0c32011-06-13 03:47:21 +0800242#endif
Logan1f028c02010-11-27 01:02:48 +0800243
244
Logan2a6dc822011-01-06 04:05:20 +0800245Compiler::Compiler(ScriptCompiled *result)
246 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800247#if USE_MCJIT
248 mRSExecutable(NULL),
249#endif
Logan1f028c02010-11-27 01:02:48 +0800250 mpSymbolLookupFn(NULL),
251 mpSymbolLookupContext(NULL),
252 mContext(NULL),
253 mModule(NULL),
254 mHasLinked(false) /* Turn off linker */ {
255 llvm::remove_fatal_error_handler();
256 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
257 mContext = new llvm::LLVMContext();
258 return;
259}
260
Logan1f028c02010-11-27 01:02:48 +0800261
Logan474cbd22011-01-31 01:47:44 +0800262llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
263 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800264
Logan474cbd22011-01-31 01:47:44 +0800265 if (!result) {
266 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
267 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800268 }
269
Logan474cbd22011-01-31 01:47:44 +0800270 return result;
Logan1f028c02010-11-27 01:02:48 +0800271}
272
273
Logan474cbd22011-01-31 01:47:44 +0800274int Compiler::linkModule(llvm::Module *moduleWith) {
275 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800276 return hasError();
277 }
278
Logan1f028c02010-11-27 01:02:48 +0800279 // Everything for linking should be settled down here with no error occurs
280 mHasLinked = true;
281 return hasError();
282}
283
284
Joseph Wen34c600a2011-07-25 17:59:17 -0700285int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800286 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800287 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800288 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800289
Logan1f028c02010-11-27 01:02:48 +0800290 std::string FeaturesStr;
291
Logan Chienda5e0c32011-06-13 03:47:21 +0800292 llvm::NamedMDNode const *PragmaMetadata;
293 llvm::NamedMDNode const *ExportVarMetadata;
294 llvm::NamedMDNode const *ExportFuncMetadata;
295 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800296
Logan1f028c02010-11-27 01:02:48 +0800297 if (mModule == NULL) // No module was loaded
298 return 0;
299
300 // Create TargetMachine
301 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
302 if (hasError())
303 goto on_bcc_compile_error;
304
305 if (!CPU.empty() || !Features.empty()) {
306 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800307
308 for (std::vector<std::string>::const_iterator
309 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800310 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800311 }
312
Logan1f028c02010-11-27 01:02:48 +0800313 FeaturesStr = F.getString();
314 }
315
Logan Chiend3fe15c2011-07-20 22:08:39 +0800316 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
317 llvm::Reloc::Static);
Logan1f028c02010-11-27 01:02:48 +0800318 if (TM == NULL) {
319 setError("Failed to create target machine implementation for the"
320 " specified triple '" + Triple + "'");
321 goto on_bcc_compile_error;
322 }
323
Logan Chienda5e0c32011-06-13 03:47:21 +0800324 // Get target data from Module
325 TD = new llvm::TargetData(mModule);
326
327 // Load named metadata
328 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
329 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
330 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
331 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
332
333 // Perform link-time optimization if we have multiple modules
334 if (mHasLinked) {
335 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
336 }
337
338 // Perform code generation
339#if USE_OLD_JIT
340 if (runCodeGen(new llvm::TargetData(*TD), TM,
341 ExportVarMetadata, ExportFuncMetadata) != 0) {
342 goto on_bcc_compile_error;
343 }
344#endif
345
346#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700347 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800348 goto on_bcc_compile_error;
349 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800350
Joseph Wen34c600a2011-07-25 17:59:17 -0700351 if (compileOnly)
352 return 0;
353
354 // Load the ELF Object
355 mRSExecutable =
356 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
357 mEmittedELFExecutable.size(),
358 &resolveSymbolAdapter, this);
359
360 if (!mRSExecutable) {
361 setError("Fail to load emitted ELF relocatable file");
362 goto on_bcc_compile_error;
363 }
364
365 if (ExportVarMetadata) {
366 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
367 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
368
369 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
370 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
371 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
372 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
373 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
374 llvm::StringRef ExportVarName =
375 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
376
377 varList.push_back(
378 rsloaderGetSymbolAddress(mRSExecutable,
379 ExportVarName.str().c_str()));
380 varNameList.push_back(ExportVarName.str());
381#if DEBUG_MCJIT_REFLECT
382 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
383 varList.back());
384#endif
385 continue;
386 }
387 }
388
389 varList.push_back(NULL);
390 }
391 }
392
393 if (ExportFuncMetadata) {
394 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
395 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
396
397 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
398 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
399 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
400 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
401 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
402 llvm::StringRef ExportFuncName =
403 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
404
405 funcList.push_back(
406 rsloaderGetSymbolAddress(mRSExecutable,
407 ExportFuncName.str().c_str()));
408 funcNameList.push_back(ExportFuncName.str());
409#if DEBUG_MCJIT_RELECT
410 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
411 funcList.back());
412#endif
413 }
414 }
415 }
416 }
417
Logan Chien4885cf82011-07-20 10:18:05 +0800418#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700419 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700420 // Get MC codegen emitted function name list
421 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
422 std::vector<char const *> func_list(func_list_size, NULL);
423 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700424
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700425 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700426 for (size_t i = 0; i < func_list_size; ++i) {
427 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
428 if (func) {
429 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800430 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
431 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700432 }
433 }
434 }
435#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800436#endif
437
438 // Read pragma information from the metadata node of the module.
439 if (PragmaMetadata) {
440 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
441
442 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
443 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
444 if (Pragma != NULL &&
445 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
446 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
447 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
448
449 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
450 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
451 llvm::StringRef PragmaName =
452 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
453 llvm::StringRef PragmaValue =
454 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
455
456 pragmaList.push_back(
457 std::make_pair(std::string(PragmaName.data(),
458 PragmaName.size()),
459 std::string(PragmaValue.data(),
460 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700461#if DEBUG_BCC_REFLECT
462 LOGD("compile(): Pragma: %s -> %s\n",
463 pragmaList.back().first.c_str(),
464 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700465#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800466 }
467 }
468 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800469 }
470
471 if (ObjectSlotMetadata) {
472 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
473
474 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
475 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
476 if (ObjectSlot != NULL &&
477 ObjectSlot->getNumOperands() == 1) {
478 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
479 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
480 llvm::StringRef Slot =
481 static_cast<llvm::MDString*>(SlotMDS)->getString();
482 uint32_t USlot = 0;
483 if (Slot.getAsInteger(10, USlot)) {
484 setError("Non-integer object slot value '" + Slot.str() + "'");
485 goto on_bcc_compile_error;
486 }
487 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700488#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700489 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
490#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800491 }
492 }
493 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800494 }
495
496on_bcc_compile_error:
497 // LOGE("on_bcc_compiler_error");
498 if (TD) {
499 delete TD;
500 }
501
502 if (TM) {
503 delete TM;
504 }
505
506 if (mError.empty()) {
507 return 0;
508 }
509
510 // LOGE(getErrorMessage());
511 return 1;
512}
513
514
515#if USE_OLD_JIT
516int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
517 llvm::NamedMDNode const *ExportVarMetadata,
518 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800519 // Create memory manager for creation of code emitter later.
520 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
521 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800522 return 1;
Logan1f028c02010-11-27 01:02:48 +0800523 }
Logan02286cb2011-01-07 00:30:47 +0800524
525 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800526
527 // Create code emitter
528 if (!mCodeEmitter.get()) {
529 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800530 setError("Failed to create machine code emitter for compilation");
531 return 1;
Logan1f028c02010-11-27 01:02:48 +0800532 }
533 } else {
534 // Reuse the code emitter
535 mCodeEmitter->reset();
536 }
537
538 mCodeEmitter->setTargetMachine(*TM);
539 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
540 mpSymbolLookupContext);
541
Logan1f028c02010-11-27 01:02:48 +0800542 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800543 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
544 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800545
Logan Chienda5e0c32011-06-13 03:47:21 +0800546 // Add TargetData to code generation pass manager
547 CodeGenPasses->add(TD);
548
549 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800550 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
551 *mCodeEmitter,
552 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800553 setError("The machine code emission is not supported on '" + Triple + "'");
554 return 1;
Logan1f028c02010-11-27 01:02:48 +0800555 }
556
Logan Chienda5e0c32011-06-13 03:47:21 +0800557 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800558 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800559 for (llvm::Module::iterator
560 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800561 if (!I->isDeclaration()) {
562 CodeGenPasses->run(*I);
563 }
564 }
565
566 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800567
Logan1f028c02010-11-27 01:02:48 +0800568 // Copy the global address mapping from code emitter and remapping
569 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800570 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
571
Logan1f028c02010-11-27 01:02:48 +0800572 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
573 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
574 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
575 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
576 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
577 llvm::StringRef ExportVarName =
578 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
579
580 CodeEmitter::global_addresses_const_iterator I, E;
581 for (I = mCodeEmitter->global_address_begin(),
582 E = mCodeEmitter->global_address_end();
583 I != E; I++) {
584 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
585 continue;
586 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800587 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700588#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700589 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
590#endif
Logan1f028c02010-11-27 01:02:48 +0800591 break;
592 }
593 }
594 if (I != mCodeEmitter->global_address_end())
595 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800596
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700597#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700598 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800599 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700600#endif
Logan1f028c02010-11-27 01:02:48 +0800601 }
602 }
603 // if reaching here, we know the global variable record in metadata is
604 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800605 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800606 }
Logan2a6dc822011-01-06 04:05:20 +0800607
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700608 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
609 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800610 }
611
612 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800613 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
614
Logan1f028c02010-11-27 01:02:48 +0800615 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
616 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
617 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
618 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
619 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
620 llvm::StringRef ExportFuncName =
621 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800622 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700623#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700624 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800625 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700626#endif
Logan1f028c02010-11-27 01:02:48 +0800627 }
628 }
629 }
630 }
631
632 // Tell code emitter now can release the memory using during the JIT since
633 // we have done the code emission
634 mCodeEmitter->releaseUnnecessary();
635
Logan Chienda5e0c32011-06-13 03:47:21 +0800636 return 0;
Logan1f028c02010-11-27 01:02:48 +0800637}
Logan Chienda5e0c32011-06-13 03:47:21 +0800638#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800639
640
Logan Chienda5e0c32011-06-13 03:47:21 +0800641#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700642int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800643 // Decorate mEmittedELFExecutable with formatted ostream
644 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
645
646 // Relax all machine instructions
647 TM->setMCRelaxAll(/* RelaxAll= */ true);
648
649 // Create MC code generation pass manager
650 llvm::PassManager MCCodeGenPasses;
651
652 // Add TargetData to MC code generation pass manager
653 MCCodeGenPasses.add(TD);
654
655 // Add MC code generation passes to pass manager
656 llvm::MCContext *Ctx;
657 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
658 CodeGenOptLevel, false)) {
659 setError("Fail to add passes to emit file");
660 return 1;
661 }
662
663 MCCodeGenPasses.run(*mModule);
664 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800665 return 0;
666}
667#endif // USE_MCJIT
668
669
670int Compiler::runLTO(llvm::TargetData *TD,
671 llvm::NamedMDNode const *ExportVarMetadata,
672 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800673 llvm::PassManager LTOPasses;
674
675 // Add TargetData to LTO passes
676 LTOPasses.add(TD);
677
678 // Collect All Exported Symbols
679 std::vector<const char*> ExportSymbols;
680
681 // Note: This is a workaround for getting export variable and function name.
682 // We should refine it soon.
683 if (ExportVarMetadata) {
684 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
685 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
686 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
687 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
688 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
689 llvm::StringRef ExportVarName =
690 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
691 ExportSymbols.push_back(ExportVarName.data());
692 }
693 }
694 }
695 }
696
697 if (ExportFuncMetadata) {
698 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
699 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
700 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
701 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
702 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
703 llvm::StringRef ExportFuncName =
704 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
705 ExportSymbols.push_back(ExportFuncName.data());
706 }
707 }
708 }
709 }
710
Logan Chien7890d432011-08-03 14:55:17 +0800711 // TODO(logan): Remove this after we have finished the
712 // bccMarkExternalSymbol API.
713
Logan Chien4cc00332011-06-12 14:00:46 +0800714 // root() and init() are born to be exported
715 ExportSymbols.push_back("root");
716 ExportSymbols.push_back("init");
717
Logan Chien7890d432011-08-03 14:55:17 +0800718 // User-defined exporting symbols
719 std::vector<char const *> const &UserDefinedExternalSymbols =
720 mpResult->getUserDefinedExternalSymbols();
721
722 std::copy(UserDefinedExternalSymbols.begin(),
723 UserDefinedExternalSymbols.end(),
724 std::back_inserter(ExportSymbols));
725
Logan Chien4cc00332011-06-12 14:00:46 +0800726 // We now create passes list performing LTO. These are copied from
727 // (including comments) llvm::createStandardLTOPasses().
728
729 // Internalize all other symbols not listed in ExportSymbols
730 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
731
732 // Propagate constants at call sites into the functions they call. This
733 // opens opportunities for globalopt (and inlining) by substituting
734 // function pointers passed as arguments to direct uses of functions.
735 LTOPasses.add(llvm::createIPSCCPPass());
736
737 // Now that we internalized some globals, see if we can hack on them!
738 LTOPasses.add(llvm::createGlobalOptimizerPass());
739
740 // Linking modules together can lead to duplicated global constants, only
741 // keep one copy of each constant...
742 LTOPasses.add(llvm::createConstantMergePass());
743
744 // Remove unused arguments from functions...
745 LTOPasses.add(llvm::createDeadArgEliminationPass());
746
747 // Reduce the code after globalopt and ipsccp. Both can open up
748 // significant simplification opportunities, and both can propagate
749 // functions through function pointers. When this happens, we often have
750 // to resolve varargs calls, etc, so let instcombine do this.
751 LTOPasses.add(llvm::createInstructionCombiningPass());
752
753 // Inline small functions
754 LTOPasses.add(llvm::createFunctionInliningPass());
755
756 // Remove dead EH info.
757 LTOPasses.add(llvm::createPruneEHPass());
758
759 // Internalize the globals again after inlining
760 LTOPasses.add(llvm::createGlobalOptimizerPass());
761
762 // Remove dead functions.
763 LTOPasses.add(llvm::createGlobalDCEPass());
764
765 // If we didn't decide to inline a function, check to see if we can
766 // transform it to pass arguments by value instead of by reference.
767 LTOPasses.add(llvm::createArgumentPromotionPass());
768
769 // The IPO passes may leave cruft around. Clean up after them.
770 LTOPasses.add(llvm::createInstructionCombiningPass());
771 LTOPasses.add(llvm::createJumpThreadingPass());
772
773 // Break up allocas
774 LTOPasses.add(llvm::createScalarReplAggregatesPass());
775
776 // Run a few AA driven optimizations here and now, to cleanup the code.
777 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
778 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
779
780 // Hoist loop invariants.
781 LTOPasses.add(llvm::createLICMPass());
782
783 // Remove redundancies.
784 LTOPasses.add(llvm::createGVNPass());
785
786 // Remove dead memcpys.
787 LTOPasses.add(llvm::createMemCpyOptPass());
788
789 // Nuke dead stores.
790 LTOPasses.add(llvm::createDeadStoreEliminationPass());
791
792 // Cleanup and simplify the code after the scalar optimizations.
793 LTOPasses.add(llvm::createInstructionCombiningPass());
794
795 LTOPasses.add(llvm::createJumpThreadingPass());
796
797 // Delete basic blocks, which optimization passes may have killed.
798 LTOPasses.add(llvm::createCFGSimplificationPass());
799
800 // Now that we have optimized the program, discard unreachable functions.
801 LTOPasses.add(llvm::createGlobalDCEPass());
802
803 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800804
805 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800806}
807
808
Logan Chienda5e0c32011-06-13 03:47:21 +0800809#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800810void *Compiler::getSymbolAddress(char const *name) {
811 return rsloaderGetSymbolAddress(mRSExecutable, name);
812}
813#endif
814
815
816#if USE_MCJIT
817void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
818 Compiler *self = reinterpret_cast<Compiler *>(context);
819
820 if (void *Addr = FindRuntimeFunction(name)) {
821 return Addr;
822 }
823
824 if (self->mpSymbolLookupFn) {
825 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
826 return Addr;
827 }
828 }
829
830 LOGE("Unable to resolve symbol: %s\n", name);
831 return NULL;
832}
833#endif
834
835
Logan1f028c02010-11-27 01:02:48 +0800836Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800837 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800838 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800839
Logan Chienda5e0c32011-06-13 03:47:21 +0800840#if USE_MCJIT
841 rsloaderDisposeExec(mRSExecutable);
842#endif
843
Logana4994f52010-11-27 14:06:02 +0800844 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800845}
846
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700847
Logan1f028c02010-11-27 01:02:48 +0800848} // namespace bcc