blob: dd370d9f86607f900fad0e882c89e0a271b0541c [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"
Logandf23afa2010-11-27 11:04:54 +080057
58#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070059#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080060#include "llvm/Support/MemoryBuffer.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080061#include "llvm/Support/TargetRegistry.h"
62#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080063
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() {
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
Logan1f028c02010-11-27 01:02:48 +0800128 // if (!llvm::llvm_is_multithreaded())
129 // llvm::llvm_start_multithreaded();
130
131 // Set Triple, CPU and Features here
132 Triple = TARGET_TRIPLE_STRING;
133
Logan Chien3bb77072011-09-17 16:53:53 +0800134#if defined(DEFAULT_ARM_CODEGEN)
135
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700136#if defined(ARCH_ARM_HAVE_VFP)
137 Features.push_back("+vfp3");
138#if !defined(ARCH_ARM_HAVE_VFP_D32)
139 Features.push_back("+d16");
140#endif
141#endif
142
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700143#if defined(ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700144 Features.push_back("+neon");
145 Features.push_back("+neonfp");
Stephen Hines7f079eb2011-11-09 15:19:03 -0800146#else
147 Features.push_back("-neon");
148 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700149#endif
150
151#if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700152 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800153 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700154#endif
155
Logan Chien3bb77072011-09-17 16:53:53 +0800156#endif // DEFAULT_ARM_CODEGEN
Joseph Wen51001b82011-06-23 18:56:45 -0700157
Logan Chien3bb77072011-09-17 16:53:53 +0800158#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800159 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800160 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800161 LLVMInitializeARMTargetInfo();
162 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800163#endif
164
Logan Chien3bb77072011-09-17 16:53:53 +0800165#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800166 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800167 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800168 LLVMInitializeX86TargetInfo();
169 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800170#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800171
172#if USE_DISASSEMBLER
173 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800174#endif
175
176 // -O0: llvm::CodeGenOpt::None
177 // -O1: llvm::CodeGenOpt::Less
178 // -O2: llvm::CodeGenOpt::Default
179 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800180 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800181
182 // Below are the global settings to LLVM
183
184 // Disable frame pointer elimination optimization
185 llvm::NoFramePointerElim = false;
186
187 // Use hardfloat ABI
188 //
189 // TODO(all): Need to detect the CPU capability and decide whether to use
190 // softfp. To use softfp, change following 2 lines to
191 //
192 // llvm::FloatABIType = llvm::FloatABI::Soft;
193 // llvm::UseSoftFloat = true;
194 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800195 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800196 llvm::UseSoftFloat = false;
197
Logan1f028c02010-11-27 01:02:48 +0800198 // Register the scheduler
199 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
200
201 // Register allocation policy:
202 // createFastRegisterAllocator: fast but bad quality
203 // createLinearScanRegisterAllocator: not so fast but good quality
204 llvm::RegisterRegAlloc::setDefault
205 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
206 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800207 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800208
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);
223 LOGE("%s", Message.c_str());
224 exit(1);
225}
226
227
Logan Chienda5e0c32011-06-13 03:47:21 +0800228#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800229CodeMemoryManager *Compiler::createCodeMemoryManager() {
230 mCodeMemMgr.reset(new CodeMemoryManager());
231 return mCodeMemMgr.get();
232}
Logan Chienda5e0c32011-06-13 03:47:21 +0800233#endif
Logan1f028c02010-11-27 01:02:48 +0800234
235
Logan Chienda5e0c32011-06-13 03:47:21 +0800236#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800237CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800238 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800239 return mCodeEmitter.get();
240}
Logan Chienda5e0c32011-06-13 03:47:21 +0800241#endif
Logan1f028c02010-11-27 01:02:48 +0800242
243
Logan2a6dc822011-01-06 04:05:20 +0800244Compiler::Compiler(ScriptCompiled *result)
245 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800246#if USE_MCJIT
247 mRSExecutable(NULL),
248#endif
Logan1f028c02010-11-27 01:02:48 +0800249 mpSymbolLookupFn(NULL),
250 mpSymbolLookupContext(NULL),
251 mContext(NULL),
252 mModule(NULL),
253 mHasLinked(false) /* Turn off linker */ {
254 llvm::remove_fatal_error_handler();
255 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
256 mContext = new llvm::LLVMContext();
257 return;
258}
259
Logan1f028c02010-11-27 01:02:48 +0800260
Logan474cbd22011-01-31 01:47:44 +0800261llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
262 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800263
Logan474cbd22011-01-31 01:47:44 +0800264 if (!result) {
265 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
266 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800267 }
268
Logan474cbd22011-01-31 01:47:44 +0800269 return result;
Logan1f028c02010-11-27 01:02:48 +0800270}
271
272
Logan474cbd22011-01-31 01:47:44 +0800273int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800274 if (llvm::Linker::LinkModules(mModule, moduleWith,
275 llvm::Linker::DestroySource,
276 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800277 return hasError();
278 }
279
Logan1f028c02010-11-27 01:02:48 +0800280 // Everything for linking should be settled down here with no error occurs
281 mHasLinked = true;
282 return hasError();
283}
284
285
Joseph Wen34c600a2011-07-25 17:59:17 -0700286int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800287 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800288 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800289 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800290
Logan1f028c02010-11-27 01:02:48 +0800291 std::string FeaturesStr;
292
Logan Chienda5e0c32011-06-13 03:47:21 +0800293 llvm::NamedMDNode const *PragmaMetadata;
294 llvm::NamedMDNode const *ExportVarMetadata;
295 llvm::NamedMDNode const *ExportFuncMetadata;
296 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800297
Logan1f028c02010-11-27 01:02:48 +0800298 if (mModule == NULL) // No module was loaded
299 return 0;
300
301 // Create TargetMachine
302 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
303 if (hasError())
304 goto on_bcc_compile_error;
305
306 if (!CPU.empty() || !Features.empty()) {
307 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800308
309 for (std::vector<std::string>::const_iterator
310 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800311 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800312 }
313
Logan1f028c02010-11-27 01:02:48 +0800314 FeaturesStr = F.getString();
315 }
316
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800317#if defined(DEFAULT_X86_64_CODEGEN)
318 // Data address in X86_64 architecture may reside in a far-away place
Logan Chiend3fe15c2011-07-20 22:08:39 +0800319 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800320 llvm::Reloc::Static,
321 llvm::CodeModel::Medium);
322#else
323 // This is set for the linker (specify how large of the virtual addresses
324 // we can access for all unknown symbols.)
325 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
326 llvm::Reloc::Static,
327 llvm::CodeModel::Small);
328#endif
Logan1f028c02010-11-27 01:02:48 +0800329 if (TM == NULL) {
330 setError("Failed to create target machine implementation for the"
331 " specified triple '" + Triple + "'");
332 goto on_bcc_compile_error;
333 }
334
Logan Chienda5e0c32011-06-13 03:47:21 +0800335 // Get target data from Module
336 TD = new llvm::TargetData(mModule);
337
338 // Load named metadata
339 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
340 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
341 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
342 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
343
344 // Perform link-time optimization if we have multiple modules
345 if (mHasLinked) {
346 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
347 }
348
349 // Perform code generation
350#if USE_OLD_JIT
351 if (runCodeGen(new llvm::TargetData(*TD), TM,
352 ExportVarMetadata, ExportFuncMetadata) != 0) {
353 goto on_bcc_compile_error;
354 }
355#endif
356
357#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700358 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800359 goto on_bcc_compile_error;
360 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800361
Joseph Wen34c600a2011-07-25 17:59:17 -0700362 if (compileOnly)
363 return 0;
364
365 // Load the ELF Object
366 mRSExecutable =
367 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
368 mEmittedELFExecutable.size(),
369 &resolveSymbolAdapter, this);
370
371 if (!mRSExecutable) {
372 setError("Fail to load emitted ELF relocatable file");
373 goto on_bcc_compile_error;
374 }
375
376 if (ExportVarMetadata) {
377 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
378 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
379
380 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
381 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
382 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
383 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
384 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
385 llvm::StringRef ExportVarName =
386 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
387
388 varList.push_back(
389 rsloaderGetSymbolAddress(mRSExecutable,
390 ExportVarName.str().c_str()));
391 varNameList.push_back(ExportVarName.str());
392#if DEBUG_MCJIT_REFLECT
393 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
394 varList.back());
395#endif
396 continue;
397 }
398 }
399
400 varList.push_back(NULL);
401 }
402 }
403
404 if (ExportFuncMetadata) {
405 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
406 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
407
408 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
409 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
410 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
411 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
412 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
413 llvm::StringRef ExportFuncName =
414 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
415
416 funcList.push_back(
417 rsloaderGetSymbolAddress(mRSExecutable,
418 ExportFuncName.str().c_str()));
419 funcNameList.push_back(ExportFuncName.str());
420#if DEBUG_MCJIT_RELECT
421 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
422 funcList.back());
423#endif
424 }
425 }
426 }
427 }
428
Logan Chien4885cf82011-07-20 10:18:05 +0800429#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700430 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700431 // Get MC codegen emitted function name list
432 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
433 std::vector<char const *> func_list(func_list_size, NULL);
434 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700435
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700436 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700437 for (size_t i = 0; i < func_list_size; ++i) {
438 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
439 if (func) {
440 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800441 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
442 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700443 }
444 }
445 }
446#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800447#endif
448
449 // Read pragma information from the metadata node of the module.
450 if (PragmaMetadata) {
451 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
452
453 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
454 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
455 if (Pragma != NULL &&
456 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
457 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
458 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
459
460 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
461 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
462 llvm::StringRef PragmaName =
463 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
464 llvm::StringRef PragmaValue =
465 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
466
467 pragmaList.push_back(
468 std::make_pair(std::string(PragmaName.data(),
469 PragmaName.size()),
470 std::string(PragmaValue.data(),
471 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700472#if DEBUG_BCC_REFLECT
473 LOGD("compile(): Pragma: %s -> %s\n",
474 pragmaList.back().first.c_str(),
475 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700476#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800477 }
478 }
479 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800480 }
481
482 if (ObjectSlotMetadata) {
483 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
484
485 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
486 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
487 if (ObjectSlot != NULL &&
488 ObjectSlot->getNumOperands() == 1) {
489 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
490 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
491 llvm::StringRef Slot =
492 static_cast<llvm::MDString*>(SlotMDS)->getString();
493 uint32_t USlot = 0;
494 if (Slot.getAsInteger(10, USlot)) {
495 setError("Non-integer object slot value '" + Slot.str() + "'");
496 goto on_bcc_compile_error;
497 }
498 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700499#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700500 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
501#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800502 }
503 }
504 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800505 }
506
507on_bcc_compile_error:
508 // LOGE("on_bcc_compiler_error");
509 if (TD) {
510 delete TD;
511 }
512
513 if (TM) {
514 delete TM;
515 }
516
517 if (mError.empty()) {
518 return 0;
519 }
520
521 // LOGE(getErrorMessage());
522 return 1;
523}
524
525
526#if USE_OLD_JIT
527int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
528 llvm::NamedMDNode const *ExportVarMetadata,
529 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800530 // Create memory manager for creation of code emitter later.
531 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
532 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800533 return 1;
Logan1f028c02010-11-27 01:02:48 +0800534 }
Logan02286cb2011-01-07 00:30:47 +0800535
536 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800537
538 // Create code emitter
539 if (!mCodeEmitter.get()) {
540 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800541 setError("Failed to create machine code emitter for compilation");
542 return 1;
Logan1f028c02010-11-27 01:02:48 +0800543 }
544 } else {
545 // Reuse the code emitter
546 mCodeEmitter->reset();
547 }
548
549 mCodeEmitter->setTargetMachine(*TM);
550 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
551 mpSymbolLookupContext);
552
Logan1f028c02010-11-27 01:02:48 +0800553 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800554 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
555 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800556
Logan Chienda5e0c32011-06-13 03:47:21 +0800557 // Add TargetData to code generation pass manager
558 CodeGenPasses->add(TD);
559
560 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800561 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
562 *mCodeEmitter,
563 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800564 setError("The machine code emission is not supported on '" + Triple + "'");
565 return 1;
Logan1f028c02010-11-27 01:02:48 +0800566 }
567
Logan Chienda5e0c32011-06-13 03:47:21 +0800568 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800569 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800570 for (llvm::Module::iterator
571 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800572 if (!I->isDeclaration()) {
573 CodeGenPasses->run(*I);
574 }
575 }
576
577 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800578
Logan1f028c02010-11-27 01:02:48 +0800579 // Copy the global address mapping from code emitter and remapping
580 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800581 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
582
Logan1f028c02010-11-27 01:02:48 +0800583 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
584 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
585 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
586 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
587 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
588 llvm::StringRef ExportVarName =
589 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
590
591 CodeEmitter::global_addresses_const_iterator I, E;
592 for (I = mCodeEmitter->global_address_begin(),
593 E = mCodeEmitter->global_address_end();
594 I != E; I++) {
595 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
596 continue;
597 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800598 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700599#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700600 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
601#endif
Logan1f028c02010-11-27 01:02:48 +0800602 break;
603 }
604 }
605 if (I != mCodeEmitter->global_address_end())
606 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800607
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700608#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700609 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800610 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700611#endif
Logan1f028c02010-11-27 01:02:48 +0800612 }
613 }
614 // if reaching here, we know the global variable record in metadata is
615 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800616 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800617 }
Logan2a6dc822011-01-06 04:05:20 +0800618
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700619 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
620 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800621 }
622
623 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800624 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
625
Logan1f028c02010-11-27 01:02:48 +0800626 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
627 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
628 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
629 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
630 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
631 llvm::StringRef ExportFuncName =
632 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800633 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700634#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700635 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800636 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700637#endif
Logan1f028c02010-11-27 01:02:48 +0800638 }
639 }
640 }
641 }
642
643 // Tell code emitter now can release the memory using during the JIT since
644 // we have done the code emission
645 mCodeEmitter->releaseUnnecessary();
646
Logan Chienda5e0c32011-06-13 03:47:21 +0800647 return 0;
Logan1f028c02010-11-27 01:02:48 +0800648}
Logan Chienda5e0c32011-06-13 03:47:21 +0800649#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800650
651
Logan Chienda5e0c32011-06-13 03:47:21 +0800652#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700653int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800654 // Decorate mEmittedELFExecutable with formatted ostream
655 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
656
657 // Relax all machine instructions
658 TM->setMCRelaxAll(/* RelaxAll= */ true);
659
660 // Create MC code generation pass manager
661 llvm::PassManager MCCodeGenPasses;
662
663 // Add TargetData to MC code generation pass manager
664 MCCodeGenPasses.add(TD);
665
666 // Add MC code generation passes to pass manager
667 llvm::MCContext *Ctx;
668 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
669 CodeGenOptLevel, false)) {
670 setError("Fail to add passes to emit file");
671 return 1;
672 }
673
674 MCCodeGenPasses.run(*mModule);
675 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800676 return 0;
677}
678#endif // USE_MCJIT
679
680
681int Compiler::runLTO(llvm::TargetData *TD,
682 llvm::NamedMDNode const *ExportVarMetadata,
683 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800684 llvm::PassManager LTOPasses;
685
686 // Add TargetData to LTO passes
687 LTOPasses.add(TD);
688
689 // Collect All Exported Symbols
690 std::vector<const char*> ExportSymbols;
691
692 // Note: This is a workaround for getting export variable and function name.
693 // We should refine it soon.
694 if (ExportVarMetadata) {
695 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
696 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
697 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
698 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
699 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
700 llvm::StringRef ExportVarName =
701 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
702 ExportSymbols.push_back(ExportVarName.data());
703 }
704 }
705 }
706 }
707
708 if (ExportFuncMetadata) {
709 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
710 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
711 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
712 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
713 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
714 llvm::StringRef ExportFuncName =
715 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
716 ExportSymbols.push_back(ExportFuncName.data());
717 }
718 }
719 }
720 }
721
Logan Chien7890d432011-08-03 14:55:17 +0800722 // TODO(logan): Remove this after we have finished the
723 // bccMarkExternalSymbol API.
724
Stephen Hines64160102011-09-01 17:30:26 -0700725 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800726 ExportSymbols.push_back("root");
727 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700728 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800729
Logan Chien7890d432011-08-03 14:55:17 +0800730 // User-defined exporting symbols
731 std::vector<char const *> const &UserDefinedExternalSymbols =
732 mpResult->getUserDefinedExternalSymbols();
733
734 std::copy(UserDefinedExternalSymbols.begin(),
735 UserDefinedExternalSymbols.end(),
736 std::back_inserter(ExportSymbols));
737
Logan Chien4cc00332011-06-12 14:00:46 +0800738 // We now create passes list performing LTO. These are copied from
739 // (including comments) llvm::createStandardLTOPasses().
740
741 // Internalize all other symbols not listed in ExportSymbols
742 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
743
744 // Propagate constants at call sites into the functions they call. This
745 // opens opportunities for globalopt (and inlining) by substituting
746 // function pointers passed as arguments to direct uses of functions.
747 LTOPasses.add(llvm::createIPSCCPPass());
748
749 // Now that we internalized some globals, see if we can hack on them!
750 LTOPasses.add(llvm::createGlobalOptimizerPass());
751
752 // Linking modules together can lead to duplicated global constants, only
753 // keep one copy of each constant...
754 LTOPasses.add(llvm::createConstantMergePass());
755
756 // Remove unused arguments from functions...
757 LTOPasses.add(llvm::createDeadArgEliminationPass());
758
759 // Reduce the code after globalopt and ipsccp. Both can open up
760 // significant simplification opportunities, and both can propagate
761 // functions through function pointers. When this happens, we often have
762 // to resolve varargs calls, etc, so let instcombine do this.
763 LTOPasses.add(llvm::createInstructionCombiningPass());
764
765 // Inline small functions
766 LTOPasses.add(llvm::createFunctionInliningPass());
767
768 // Remove dead EH info.
769 LTOPasses.add(llvm::createPruneEHPass());
770
771 // Internalize the globals again after inlining
772 LTOPasses.add(llvm::createGlobalOptimizerPass());
773
774 // Remove dead functions.
775 LTOPasses.add(llvm::createGlobalDCEPass());
776
777 // If we didn't decide to inline a function, check to see if we can
778 // transform it to pass arguments by value instead of by reference.
779 LTOPasses.add(llvm::createArgumentPromotionPass());
780
781 // The IPO passes may leave cruft around. Clean up after them.
782 LTOPasses.add(llvm::createInstructionCombiningPass());
783 LTOPasses.add(llvm::createJumpThreadingPass());
784
785 // Break up allocas
786 LTOPasses.add(llvm::createScalarReplAggregatesPass());
787
788 // Run a few AA driven optimizations here and now, to cleanup the code.
789 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
790 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
791
792 // Hoist loop invariants.
793 LTOPasses.add(llvm::createLICMPass());
794
795 // Remove redundancies.
796 LTOPasses.add(llvm::createGVNPass());
797
798 // Remove dead memcpys.
799 LTOPasses.add(llvm::createMemCpyOptPass());
800
801 // Nuke dead stores.
802 LTOPasses.add(llvm::createDeadStoreEliminationPass());
803
804 // Cleanup and simplify the code after the scalar optimizations.
805 LTOPasses.add(llvm::createInstructionCombiningPass());
806
807 LTOPasses.add(llvm::createJumpThreadingPass());
808
809 // Delete basic blocks, which optimization passes may have killed.
810 LTOPasses.add(llvm::createCFGSimplificationPass());
811
812 // Now that we have optimized the program, discard unreachable functions.
813 LTOPasses.add(llvm::createGlobalDCEPass());
814
815 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800816
817 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800818}
819
820
Logan Chienda5e0c32011-06-13 03:47:21 +0800821#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800822void *Compiler::getSymbolAddress(char const *name) {
823 return rsloaderGetSymbolAddress(mRSExecutable, name);
824}
825#endif
826
827
828#if USE_MCJIT
829void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
830 Compiler *self = reinterpret_cast<Compiler *>(context);
831
832 if (void *Addr = FindRuntimeFunction(name)) {
833 return Addr;
834 }
835
836 if (self->mpSymbolLookupFn) {
837 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
838 return Addr;
839 }
840 }
841
842 LOGE("Unable to resolve symbol: %s\n", name);
843 return NULL;
844}
845#endif
846
847
Logan1f028c02010-11-27 01:02:48 +0800848Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800849 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800850 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800851
Logan Chienda5e0c32011-06-13 03:47:21 +0800852#if USE_MCJIT
853 rsloaderDisposeExec(mRSExecutable);
854#endif
855
Logana4994f52010-11-27 14:06:02 +0800856 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800857}
858
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700859
Logan1f028c02010-11-27 01:02:48 +0800860} // namespace bcc