blob: 3892f39fc478f90a69c67141cb8b993fe9a99a0d [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");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700146#endif
147
148#if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700149 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800150 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700151#endif
152
Logan Chien3bb77072011-09-17 16:53:53 +0800153#endif // DEFAULT_ARM_CODEGEN
Joseph Wen51001b82011-06-23 18:56:45 -0700154
Logan Chien3bb77072011-09-17 16:53:53 +0800155#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800156 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800157 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800158 LLVMInitializeARMTargetInfo();
159 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800160#endif
161
Logan Chien3bb77072011-09-17 16:53:53 +0800162#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800163 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800164 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800165 LLVMInitializeX86TargetInfo();
166 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800167#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800168
169#if USE_DISASSEMBLER
170 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800171#endif
172
173 // -O0: llvm::CodeGenOpt::None
174 // -O1: llvm::CodeGenOpt::Less
175 // -O2: llvm::CodeGenOpt::Default
176 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800177 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800178
179 // Below are the global settings to LLVM
180
181 // Disable frame pointer elimination optimization
182 llvm::NoFramePointerElim = false;
183
184 // Use hardfloat ABI
185 //
186 // TODO(all): Need to detect the CPU capability and decide whether to use
187 // softfp. To use softfp, change following 2 lines to
188 //
189 // llvm::FloatABIType = llvm::FloatABI::Soft;
190 // llvm::UseSoftFloat = true;
191 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800192 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800193 llvm::UseSoftFloat = false;
194
Logan1f028c02010-11-27 01:02:48 +0800195 // Register the scheduler
196 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
197
198 // Register allocation policy:
199 // createFastRegisterAllocator: fast but bad quality
200 // createLinearScanRegisterAllocator: not so fast but good quality
201 llvm::RegisterRegAlloc::setDefault
202 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
203 llvm::createFastRegisterAllocator :
204 llvm::createLinearScanRegisterAllocator);
205
Logan35849002011-01-15 07:30:43 +0800206#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700207 // Read in SHA1 checksum of libbcc and libRS.
208 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700209
210 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800211#endif
Logan75cc8a52011-01-07 06:06:52 +0800212
Logan1f028c02010-11-27 01:02:48 +0800213 GlobalInitialized = true;
214}
215
216
217void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
218 std::string *Error = static_cast<std::string*>(UserData);
219 Error->assign(Message);
220 LOGE("%s", Message.c_str());
221 exit(1);
222}
223
224
Logan Chienda5e0c32011-06-13 03:47:21 +0800225#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800226CodeMemoryManager *Compiler::createCodeMemoryManager() {
227 mCodeMemMgr.reset(new CodeMemoryManager());
228 return mCodeMemMgr.get();
229}
Logan Chienda5e0c32011-06-13 03:47:21 +0800230#endif
Logan1f028c02010-11-27 01:02:48 +0800231
232
Logan Chienda5e0c32011-06-13 03:47:21 +0800233#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800234CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800235 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800236 return mCodeEmitter.get();
237}
Logan Chienda5e0c32011-06-13 03:47:21 +0800238#endif
Logan1f028c02010-11-27 01:02:48 +0800239
240
Logan2a6dc822011-01-06 04:05:20 +0800241Compiler::Compiler(ScriptCompiled *result)
242 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800243#if USE_MCJIT
244 mRSExecutable(NULL),
245#endif
Logan1f028c02010-11-27 01:02:48 +0800246 mpSymbolLookupFn(NULL),
247 mpSymbolLookupContext(NULL),
248 mContext(NULL),
249 mModule(NULL),
250 mHasLinked(false) /* Turn off linker */ {
251 llvm::remove_fatal_error_handler();
252 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
253 mContext = new llvm::LLVMContext();
254 return;
255}
256
Logan1f028c02010-11-27 01:02:48 +0800257
Logan474cbd22011-01-31 01:47:44 +0800258llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
259 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800260
Logan474cbd22011-01-31 01:47:44 +0800261 if (!result) {
262 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
263 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800264 }
265
Logan474cbd22011-01-31 01:47:44 +0800266 return result;
Logan1f028c02010-11-27 01:02:48 +0800267}
268
269
Logan474cbd22011-01-31 01:47:44 +0800270int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800271 if (llvm::Linker::LinkModules(mModule, moduleWith,
272 llvm::Linker::DestroySource,
273 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800274 return hasError();
275 }
276
Logan1f028c02010-11-27 01:02:48 +0800277 // Everything for linking should be settled down here with no error occurs
278 mHasLinked = true;
279 return hasError();
280}
281
282
Joseph Wen34c600a2011-07-25 17:59:17 -0700283int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800284 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800285 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800286 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800287
Logan1f028c02010-11-27 01:02:48 +0800288 std::string FeaturesStr;
289
Logan Chienda5e0c32011-06-13 03:47:21 +0800290 llvm::NamedMDNode const *PragmaMetadata;
291 llvm::NamedMDNode const *ExportVarMetadata;
292 llvm::NamedMDNode const *ExportFuncMetadata;
293 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800294
Logan1f028c02010-11-27 01:02:48 +0800295 if (mModule == NULL) // No module was loaded
296 return 0;
297
298 // Create TargetMachine
299 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
300 if (hasError())
301 goto on_bcc_compile_error;
302
303 if (!CPU.empty() || !Features.empty()) {
304 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800305
306 for (std::vector<std::string>::const_iterator
307 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800308 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800309 }
310
Logan1f028c02010-11-27 01:02:48 +0800311 FeaturesStr = F.getString();
312 }
313
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800314#if defined(DEFAULT_X86_64_CODEGEN)
315 // Data address in X86_64 architecture may reside in a far-away place
Logan Chiend3fe15c2011-07-20 22:08:39 +0800316 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800317 llvm::Reloc::Static,
318 llvm::CodeModel::Medium);
319#else
320 // This is set for the linker (specify how large of the virtual addresses
321 // we can access for all unknown symbols.)
322 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
323 llvm::Reloc::Static,
324 llvm::CodeModel::Small);
325#endif
Logan1f028c02010-11-27 01:02:48 +0800326 if (TM == NULL) {
327 setError("Failed to create target machine implementation for the"
328 " specified triple '" + Triple + "'");
329 goto on_bcc_compile_error;
330 }
331
Logan Chienda5e0c32011-06-13 03:47:21 +0800332 // Get target data from Module
333 TD = new llvm::TargetData(mModule);
334
335 // Load named metadata
336 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
337 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
338 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
339 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
340
341 // Perform link-time optimization if we have multiple modules
342 if (mHasLinked) {
343 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
344 }
345
346 // Perform code generation
347#if USE_OLD_JIT
348 if (runCodeGen(new llvm::TargetData(*TD), TM,
349 ExportVarMetadata, ExportFuncMetadata) != 0) {
350 goto on_bcc_compile_error;
351 }
352#endif
353
354#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700355 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800356 goto on_bcc_compile_error;
357 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800358
Joseph Wen34c600a2011-07-25 17:59:17 -0700359 if (compileOnly)
360 return 0;
361
362 // Load the ELF Object
363 mRSExecutable =
364 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
365 mEmittedELFExecutable.size(),
366 &resolveSymbolAdapter, this);
367
368 if (!mRSExecutable) {
369 setError("Fail to load emitted ELF relocatable file");
370 goto on_bcc_compile_error;
371 }
372
373 if (ExportVarMetadata) {
374 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
375 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
376
377 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
378 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
379 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
380 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
381 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
382 llvm::StringRef ExportVarName =
383 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
384
385 varList.push_back(
386 rsloaderGetSymbolAddress(mRSExecutable,
387 ExportVarName.str().c_str()));
388 varNameList.push_back(ExportVarName.str());
389#if DEBUG_MCJIT_REFLECT
390 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
391 varList.back());
392#endif
393 continue;
394 }
395 }
396
397 varList.push_back(NULL);
398 }
399 }
400
401 if (ExportFuncMetadata) {
402 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
403 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
404
405 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
406 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
407 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
408 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
409 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
410 llvm::StringRef ExportFuncName =
411 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
412
413 funcList.push_back(
414 rsloaderGetSymbolAddress(mRSExecutable,
415 ExportFuncName.str().c_str()));
416 funcNameList.push_back(ExportFuncName.str());
417#if DEBUG_MCJIT_RELECT
418 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
419 funcList.back());
420#endif
421 }
422 }
423 }
424 }
425
Logan Chien4885cf82011-07-20 10:18:05 +0800426#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700427 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700428 // Get MC codegen emitted function name list
429 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
430 std::vector<char const *> func_list(func_list_size, NULL);
431 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700432
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700433 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700434 for (size_t i = 0; i < func_list_size; ++i) {
435 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
436 if (func) {
437 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800438 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
439 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700440 }
441 }
442 }
443#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800444#endif
445
446 // Read pragma information from the metadata node of the module.
447 if (PragmaMetadata) {
448 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
449
450 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
451 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
452 if (Pragma != NULL &&
453 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
454 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
455 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
456
457 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
458 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
459 llvm::StringRef PragmaName =
460 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
461 llvm::StringRef PragmaValue =
462 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
463
464 pragmaList.push_back(
465 std::make_pair(std::string(PragmaName.data(),
466 PragmaName.size()),
467 std::string(PragmaValue.data(),
468 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700469#if DEBUG_BCC_REFLECT
470 LOGD("compile(): Pragma: %s -> %s\n",
471 pragmaList.back().first.c_str(),
472 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700473#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800474 }
475 }
476 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800477 }
478
479 if (ObjectSlotMetadata) {
480 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
481
482 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
483 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
484 if (ObjectSlot != NULL &&
485 ObjectSlot->getNumOperands() == 1) {
486 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
487 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
488 llvm::StringRef Slot =
489 static_cast<llvm::MDString*>(SlotMDS)->getString();
490 uint32_t USlot = 0;
491 if (Slot.getAsInteger(10, USlot)) {
492 setError("Non-integer object slot value '" + Slot.str() + "'");
493 goto on_bcc_compile_error;
494 }
495 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700496#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700497 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
498#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800499 }
500 }
501 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800502 }
503
504on_bcc_compile_error:
505 // LOGE("on_bcc_compiler_error");
506 if (TD) {
507 delete TD;
508 }
509
510 if (TM) {
511 delete TM;
512 }
513
514 if (mError.empty()) {
515 return 0;
516 }
517
518 // LOGE(getErrorMessage());
519 return 1;
520}
521
522
523#if USE_OLD_JIT
524int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
525 llvm::NamedMDNode const *ExportVarMetadata,
526 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800527 // Create memory manager for creation of code emitter later.
528 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
529 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800530 return 1;
Logan1f028c02010-11-27 01:02:48 +0800531 }
Logan02286cb2011-01-07 00:30:47 +0800532
533 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800534
535 // Create code emitter
536 if (!mCodeEmitter.get()) {
537 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800538 setError("Failed to create machine code emitter for compilation");
539 return 1;
Logan1f028c02010-11-27 01:02:48 +0800540 }
541 } else {
542 // Reuse the code emitter
543 mCodeEmitter->reset();
544 }
545
546 mCodeEmitter->setTargetMachine(*TM);
547 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
548 mpSymbolLookupContext);
549
Logan1f028c02010-11-27 01:02:48 +0800550 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800551 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
552 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800553
Logan Chienda5e0c32011-06-13 03:47:21 +0800554 // Add TargetData to code generation pass manager
555 CodeGenPasses->add(TD);
556
557 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800558 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
559 *mCodeEmitter,
560 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800561 setError("The machine code emission is not supported on '" + Triple + "'");
562 return 1;
Logan1f028c02010-11-27 01:02:48 +0800563 }
564
Logan Chienda5e0c32011-06-13 03:47:21 +0800565 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800566 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800567 for (llvm::Module::iterator
568 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800569 if (!I->isDeclaration()) {
570 CodeGenPasses->run(*I);
571 }
572 }
573
574 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800575
Logan1f028c02010-11-27 01:02:48 +0800576 // Copy the global address mapping from code emitter and remapping
577 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800578 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
579
Logan1f028c02010-11-27 01:02:48 +0800580 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
581 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
582 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
583 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
584 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
585 llvm::StringRef ExportVarName =
586 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
587
588 CodeEmitter::global_addresses_const_iterator I, E;
589 for (I = mCodeEmitter->global_address_begin(),
590 E = mCodeEmitter->global_address_end();
591 I != E; I++) {
592 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
593 continue;
594 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800595 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700596#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700597 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
598#endif
Logan1f028c02010-11-27 01:02:48 +0800599 break;
600 }
601 }
602 if (I != mCodeEmitter->global_address_end())
603 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800604
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700605#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700606 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800607 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700608#endif
Logan1f028c02010-11-27 01:02:48 +0800609 }
610 }
611 // if reaching here, we know the global variable record in metadata is
612 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800613 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800614 }
Logan2a6dc822011-01-06 04:05:20 +0800615
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700616 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
617 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800618 }
619
620 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800621 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
622
Logan1f028c02010-11-27 01:02:48 +0800623 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
624 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
625 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
626 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
627 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
628 llvm::StringRef ExportFuncName =
629 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800630 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700631#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700632 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800633 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700634#endif
Logan1f028c02010-11-27 01:02:48 +0800635 }
636 }
637 }
638 }
639
640 // Tell code emitter now can release the memory using during the JIT since
641 // we have done the code emission
642 mCodeEmitter->releaseUnnecessary();
643
Logan Chienda5e0c32011-06-13 03:47:21 +0800644 return 0;
Logan1f028c02010-11-27 01:02:48 +0800645}
Logan Chienda5e0c32011-06-13 03:47:21 +0800646#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800647
648
Logan Chienda5e0c32011-06-13 03:47:21 +0800649#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700650int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800651 // Decorate mEmittedELFExecutable with formatted ostream
652 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
653
654 // Relax all machine instructions
655 TM->setMCRelaxAll(/* RelaxAll= */ true);
656
657 // Create MC code generation pass manager
658 llvm::PassManager MCCodeGenPasses;
659
660 // Add TargetData to MC code generation pass manager
661 MCCodeGenPasses.add(TD);
662
663 // Add MC code generation passes to pass manager
664 llvm::MCContext *Ctx;
665 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
666 CodeGenOptLevel, false)) {
667 setError("Fail to add passes to emit file");
668 return 1;
669 }
670
671 MCCodeGenPasses.run(*mModule);
672 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800673 return 0;
674}
675#endif // USE_MCJIT
676
677
678int Compiler::runLTO(llvm::TargetData *TD,
679 llvm::NamedMDNode const *ExportVarMetadata,
680 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800681 llvm::PassManager LTOPasses;
682
683 // Add TargetData to LTO passes
684 LTOPasses.add(TD);
685
686 // Collect All Exported Symbols
687 std::vector<const char*> ExportSymbols;
688
689 // Note: This is a workaround for getting export variable and function name.
690 // We should refine it soon.
691 if (ExportVarMetadata) {
692 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
693 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
694 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
695 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
696 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
697 llvm::StringRef ExportVarName =
698 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
699 ExportSymbols.push_back(ExportVarName.data());
700 }
701 }
702 }
703 }
704
705 if (ExportFuncMetadata) {
706 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
707 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
708 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
709 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
710 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
711 llvm::StringRef ExportFuncName =
712 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
713 ExportSymbols.push_back(ExportFuncName.data());
714 }
715 }
716 }
717 }
718
Logan Chien7890d432011-08-03 14:55:17 +0800719 // TODO(logan): Remove this after we have finished the
720 // bccMarkExternalSymbol API.
721
Stephen Hines64160102011-09-01 17:30:26 -0700722 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800723 ExportSymbols.push_back("root");
724 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700725 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800726
Logan Chien7890d432011-08-03 14:55:17 +0800727 // User-defined exporting symbols
728 std::vector<char const *> const &UserDefinedExternalSymbols =
729 mpResult->getUserDefinedExternalSymbols();
730
731 std::copy(UserDefinedExternalSymbols.begin(),
732 UserDefinedExternalSymbols.end(),
733 std::back_inserter(ExportSymbols));
734
Logan Chien4cc00332011-06-12 14:00:46 +0800735 // We now create passes list performing LTO. These are copied from
736 // (including comments) llvm::createStandardLTOPasses().
737
738 // Internalize all other symbols not listed in ExportSymbols
739 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
740
741 // Propagate constants at call sites into the functions they call. This
742 // opens opportunities for globalopt (and inlining) by substituting
743 // function pointers passed as arguments to direct uses of functions.
744 LTOPasses.add(llvm::createIPSCCPPass());
745
746 // Now that we internalized some globals, see if we can hack on them!
747 LTOPasses.add(llvm::createGlobalOptimizerPass());
748
749 // Linking modules together can lead to duplicated global constants, only
750 // keep one copy of each constant...
751 LTOPasses.add(llvm::createConstantMergePass());
752
753 // Remove unused arguments from functions...
754 LTOPasses.add(llvm::createDeadArgEliminationPass());
755
756 // Reduce the code after globalopt and ipsccp. Both can open up
757 // significant simplification opportunities, and both can propagate
758 // functions through function pointers. When this happens, we often have
759 // to resolve varargs calls, etc, so let instcombine do this.
760 LTOPasses.add(llvm::createInstructionCombiningPass());
761
762 // Inline small functions
763 LTOPasses.add(llvm::createFunctionInliningPass());
764
765 // Remove dead EH info.
766 LTOPasses.add(llvm::createPruneEHPass());
767
768 // Internalize the globals again after inlining
769 LTOPasses.add(llvm::createGlobalOptimizerPass());
770
771 // Remove dead functions.
772 LTOPasses.add(llvm::createGlobalDCEPass());
773
774 // If we didn't decide to inline a function, check to see if we can
775 // transform it to pass arguments by value instead of by reference.
776 LTOPasses.add(llvm::createArgumentPromotionPass());
777
778 // The IPO passes may leave cruft around. Clean up after them.
779 LTOPasses.add(llvm::createInstructionCombiningPass());
780 LTOPasses.add(llvm::createJumpThreadingPass());
781
782 // Break up allocas
783 LTOPasses.add(llvm::createScalarReplAggregatesPass());
784
785 // Run a few AA driven optimizations here and now, to cleanup the code.
786 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
787 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
788
789 // Hoist loop invariants.
790 LTOPasses.add(llvm::createLICMPass());
791
792 // Remove redundancies.
793 LTOPasses.add(llvm::createGVNPass());
794
795 // Remove dead memcpys.
796 LTOPasses.add(llvm::createMemCpyOptPass());
797
798 // Nuke dead stores.
799 LTOPasses.add(llvm::createDeadStoreEliminationPass());
800
801 // Cleanup and simplify the code after the scalar optimizations.
802 LTOPasses.add(llvm::createInstructionCombiningPass());
803
804 LTOPasses.add(llvm::createJumpThreadingPass());
805
806 // Delete basic blocks, which optimization passes may have killed.
807 LTOPasses.add(llvm::createCFGSimplificationPass());
808
809 // Now that we have optimized the program, discard unreachable functions.
810 LTOPasses.add(llvm::createGlobalDCEPass());
811
812 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800813
814 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800815}
816
817
Logan Chienda5e0c32011-06-13 03:47:21 +0800818#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800819void *Compiler::getSymbolAddress(char const *name) {
820 return rsloaderGetSymbolAddress(mRSExecutable, name);
821}
822#endif
823
824
825#if USE_MCJIT
826void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
827 Compiler *self = reinterpret_cast<Compiler *>(context);
828
829 if (void *Addr = FindRuntimeFunction(name)) {
830 return Addr;
831 }
832
833 if (self->mpSymbolLookupFn) {
834 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
835 return Addr;
836 }
837 }
838
839 LOGE("Unable to resolve symbol: %s\n", name);
840 return NULL;
841}
842#endif
843
844
Logan1f028c02010-11-27 01:02:48 +0800845Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800846 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800847 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800848
Logan Chienda5e0c32011-06-13 03:47:21 +0800849#if USE_MCJIT
850 rsloaderDisposeExec(mRSExecutable);
851#endif
852
Logana4994f52010-11-27 14:06:02 +0800853 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800854}
855
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700856
Logan1f028c02010-11-27 01:02:48 +0800857} // namespace bcc