blob: 1e9bdb82577f649f69b5cf10e6bc79588651286e [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
Andrew Hsieh998ec832011-11-21 02:36:11 -080094
95#if !defined(__HOST__)
96 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
97#else
98// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
99 #if defined(__cplusplus)
100 extern "C" {
101 #endif
102 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
103 #if defined(__cplusplus)
104 };
105 #endif
106#endif
107
Logan1f028c02010-11-27 01:02:48 +0800108// Code generation optimization level for the compiler
109llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
110
111std::string Compiler::Triple;
112
113std::string Compiler::CPU;
114
115std::vector<std::string> Compiler::Features;
116
Stephen Hines071288a2011-01-27 14:38:26 -0800117// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800118// slang.cpp)
119const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
120
Stephen Hines071288a2011-01-27 14:38:26 -0800121// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800122// synced with slang_rs_metadata.h)
123const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
124
Stephen Hines071288a2011-01-27 14:38:26 -0800125// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800126// synced with slang_rs_metadata.h)
127const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
128
Stephen Hines071288a2011-01-27 14:38:26 -0800129// Name of metadata node where RS object slot info resides (should be
130// synced with slang_rs_metadata.h)
131const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800132
133//////////////////////////////////////////////////////////////////////////////
134// Compiler
135//////////////////////////////////////////////////////////////////////////////
136
137void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700138 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800139 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700140 }
141
Logan1f028c02010-11-27 01:02:48 +0800142 // if (!llvm::llvm_is_multithreaded())
143 // llvm::llvm_start_multithreaded();
144
145 // Set Triple, CPU and Features here
146 Triple = TARGET_TRIPLE_STRING;
147
Logan Chien3bb77072011-09-17 16:53:53 +0800148#if defined(DEFAULT_ARM_CODEGEN)
149
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700150#if defined(ARCH_ARM_HAVE_VFP)
151 Features.push_back("+vfp3");
152#if !defined(ARCH_ARM_HAVE_VFP_D32)
153 Features.push_back("+d16");
154#endif
155#endif
156
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700157#if defined(ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700158 Features.push_back("+neon");
159 Features.push_back("+neonfp");
Stephen Hines7f079eb2011-11-09 15:19:03 -0800160#else
161 Features.push_back("-neon");
162 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700163#endif
164
165#if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Joseph Wen51001b82011-06-23 18:56:45 -0700166 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800167 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700168#endif
169
Logan Chien3bb77072011-09-17 16:53:53 +0800170#endif // DEFAULT_ARM_CODEGEN
Joseph Wen51001b82011-06-23 18:56:45 -0700171
Logan Chien3bb77072011-09-17 16:53:53 +0800172#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800173 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800174 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800175 LLVMInitializeARMTargetInfo();
176 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800177#endif
178
Logan Chien21392f02011-11-26 20:32:01 +0800179#if defined(PROVIDE_MIPS_CODEGEN)
180 LLVMInitializeMipsAsmPrinter();
181 LLVMInitializeMipsTargetMC();
182 LLVMInitializeMipsTargetInfo();
183 LLVMInitializeMipsTarget();
184#endif
185
Logan Chien3bb77072011-09-17 16:53:53 +0800186#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800187 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800188 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800189 LLVMInitializeX86TargetInfo();
190 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800191#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800192
193#if USE_DISASSEMBLER
194 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800195#endif
196
197 // -O0: llvm::CodeGenOpt::None
198 // -O1: llvm::CodeGenOpt::Less
199 // -O2: llvm::CodeGenOpt::Default
200 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800201 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800202
Logan1f028c02010-11-27 01:02:48 +0800203 // Register the scheduler
204 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
205
206 // Register allocation policy:
207 // createFastRegisterAllocator: fast but bad quality
208 // createLinearScanRegisterAllocator: not so fast but good quality
209 llvm::RegisterRegAlloc::setDefault
210 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
211 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800212 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800213
Logan35849002011-01-15 07:30:43 +0800214#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700215 // Read in SHA1 checksum of libbcc and libRS.
216 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700217
218 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800219#endif
Logan75cc8a52011-01-07 06:06:52 +0800220
Logan1f028c02010-11-27 01:02:48 +0800221 GlobalInitialized = true;
222}
223
224
225void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
226 std::string *Error = static_cast<std::string*>(UserData);
227 Error->assign(Message);
228 LOGE("%s", Message.c_str());
229 exit(1);
230}
231
232
Logan Chienda5e0c32011-06-13 03:47:21 +0800233#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800234CodeMemoryManager *Compiler::createCodeMemoryManager() {
235 mCodeMemMgr.reset(new CodeMemoryManager());
236 return mCodeMemMgr.get();
237}
Logan Chienda5e0c32011-06-13 03:47:21 +0800238#endif
Logan1f028c02010-11-27 01:02:48 +0800239
240
Logan Chienda5e0c32011-06-13 03:47:21 +0800241#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800242CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800243 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800244 return mCodeEmitter.get();
245}
Logan Chienda5e0c32011-06-13 03:47:21 +0800246#endif
Logan1f028c02010-11-27 01:02:48 +0800247
248
Logan2a6dc822011-01-06 04:05:20 +0800249Compiler::Compiler(ScriptCompiled *result)
250 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800251#if USE_MCJIT
252 mRSExecutable(NULL),
253#endif
Logan1f028c02010-11-27 01:02:48 +0800254 mpSymbolLookupFn(NULL),
255 mpSymbolLookupContext(NULL),
256 mContext(NULL),
257 mModule(NULL),
258 mHasLinked(false) /* Turn off linker */ {
259 llvm::remove_fatal_error_handler();
260 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
261 mContext = new llvm::LLVMContext();
262 return;
263}
264
Logan1f028c02010-11-27 01:02:48 +0800265
Logan474cbd22011-01-31 01:47:44 +0800266llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
267 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800268
Logan474cbd22011-01-31 01:47:44 +0800269 if (!result) {
270 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
271 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800272 }
273
Logan474cbd22011-01-31 01:47:44 +0800274 return result;
Logan1f028c02010-11-27 01:02:48 +0800275}
276
277
Logan474cbd22011-01-31 01:47:44 +0800278int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800279 if (llvm::Linker::LinkModules(mModule, moduleWith,
280 llvm::Linker::DestroySource,
281 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800282 return hasError();
283 }
284
Logan1f028c02010-11-27 01:02:48 +0800285 // Everything for linking should be settled down here with no error occurs
286 mHasLinked = true;
287 return hasError();
288}
289
290
Joseph Wen34c600a2011-07-25 17:59:17 -0700291int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800292 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800293 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800294 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800295
Logan1f028c02010-11-27 01:02:48 +0800296 std::string FeaturesStr;
297
Logan Chienda5e0c32011-06-13 03:47:21 +0800298 llvm::NamedMDNode const *PragmaMetadata;
299 llvm::NamedMDNode const *ExportVarMetadata;
300 llvm::NamedMDNode const *ExportFuncMetadata;
301 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800302
Logan Chienbe81e102011-12-16 13:31:39 +0800303 llvm::TargetOptions Options;
304
305 llvm::CodeModel::Model CM;
306 llvm::Reloc::Model RM;
307
Logan1f028c02010-11-27 01:02:48 +0800308 if (mModule == NULL) // No module was loaded
309 return 0;
310
Logan Chienbe81e102011-12-16 13:31:39 +0800311 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800312 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
313 if (hasError())
314 goto on_bcc_compile_error;
315
316 if (!CPU.empty() || !Features.empty()) {
317 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800318
319 for (std::vector<std::string>::const_iterator
320 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800321 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800322 }
323
Logan1f028c02010-11-27 01:02:48 +0800324 FeaturesStr = F.getString();
325 }
326
Logan Chienbe81e102011-12-16 13:31:39 +0800327 // Setup LLVM Target Machine Options
328 // Disable frame pointer elimination optimization
329 Options.NoFramePointerElim = false;
330
331 // Use hardfloat ABI
332 //
333 // TODO(all): Need to detect the CPU capability and decide whether to use
334 // softfp. To use softfp, change following 2 lines to
335 //
336 // options.FloatABIType = llvm::FloatABI::Soft;
337 // options.UseSoftFloat = true;
338 Options.FloatABIType = llvm::FloatABI::Soft;
339 Options.UseSoftFloat = false;
340
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800341#if defined(DEFAULT_X86_64_CODEGEN)
342 // Data address in X86_64 architecture may reside in a far-away place
Logan Chienbe81e102011-12-16 13:31:39 +0800343 CM = llvm::CodeModel::Medium;
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800344#else
345 // This is set for the linker (specify how large of the virtual addresses
346 // we can access for all unknown symbols.)
Logan Chienbe81e102011-12-16 13:31:39 +0800347 CM = llvm::CodeModel::Small;
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800348#endif
Logan Chienbe81e102011-12-16 13:31:39 +0800349
350 RM = llvm::Reloc::Static;
351
352 // Create LLVM Target Machine
353 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr, Options, RM, CM);
354
Logan1f028c02010-11-27 01:02:48 +0800355 if (TM == NULL) {
356 setError("Failed to create target machine implementation for the"
357 " specified triple '" + Triple + "'");
358 goto on_bcc_compile_error;
359 }
360
Logan Chienda5e0c32011-06-13 03:47:21 +0800361 // Get target data from Module
362 TD = new llvm::TargetData(mModule);
363
364 // Load named metadata
365 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
366 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
367 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
368 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
369
370 // Perform link-time optimization if we have multiple modules
371 if (mHasLinked) {
372 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
373 }
374
375 // Perform code generation
376#if USE_OLD_JIT
377 if (runCodeGen(new llvm::TargetData(*TD), TM,
378 ExportVarMetadata, ExportFuncMetadata) != 0) {
379 goto on_bcc_compile_error;
380 }
381#endif
382
383#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700384 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800385 goto on_bcc_compile_error;
386 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800387
Joseph Wen34c600a2011-07-25 17:59:17 -0700388 if (compileOnly)
389 return 0;
390
391 // Load the ELF Object
392 mRSExecutable =
393 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
394 mEmittedELFExecutable.size(),
395 &resolveSymbolAdapter, this);
396
397 if (!mRSExecutable) {
398 setError("Fail to load emitted ELF relocatable file");
399 goto on_bcc_compile_error;
400 }
401
402 if (ExportVarMetadata) {
403 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
404 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
405
406 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
407 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
408 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
409 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
410 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
411 llvm::StringRef ExportVarName =
412 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
413
414 varList.push_back(
415 rsloaderGetSymbolAddress(mRSExecutable,
416 ExportVarName.str().c_str()));
417 varNameList.push_back(ExportVarName.str());
418#if DEBUG_MCJIT_REFLECT
419 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
420 varList.back());
421#endif
422 continue;
423 }
424 }
425
426 varList.push_back(NULL);
427 }
428 }
429
430 if (ExportFuncMetadata) {
431 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
432 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
433
434 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
435 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
436 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
437 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
438 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
439 llvm::StringRef ExportFuncName =
440 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
441
442 funcList.push_back(
443 rsloaderGetSymbolAddress(mRSExecutable,
444 ExportFuncName.str().c_str()));
445 funcNameList.push_back(ExportFuncName.str());
446#if DEBUG_MCJIT_RELECT
447 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
448 funcList.back());
449#endif
450 }
451 }
452 }
453 }
454
Logan Chien4885cf82011-07-20 10:18:05 +0800455#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700456 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700457 // Get MC codegen emitted function name list
458 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
459 std::vector<char const *> func_list(func_list_size, NULL);
460 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700461
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700462 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700463 for (size_t i = 0; i < func_list_size; ++i) {
464 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
465 if (func) {
466 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800467 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
468 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700469 }
470 }
471 }
472#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800473#endif
474
475 // Read pragma information from the metadata node of the module.
476 if (PragmaMetadata) {
477 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
478
479 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
480 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
481 if (Pragma != NULL &&
482 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
483 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
484 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
485
486 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
487 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
488 llvm::StringRef PragmaName =
489 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
490 llvm::StringRef PragmaValue =
491 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
492
493 pragmaList.push_back(
494 std::make_pair(std::string(PragmaName.data(),
495 PragmaName.size()),
496 std::string(PragmaValue.data(),
497 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700498#if DEBUG_BCC_REFLECT
499 LOGD("compile(): Pragma: %s -> %s\n",
500 pragmaList.back().first.c_str(),
501 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700502#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800503 }
504 }
505 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800506 }
507
508 if (ObjectSlotMetadata) {
509 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
510
511 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
512 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
513 if (ObjectSlot != NULL &&
514 ObjectSlot->getNumOperands() == 1) {
515 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
516 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
517 llvm::StringRef Slot =
518 static_cast<llvm::MDString*>(SlotMDS)->getString();
519 uint32_t USlot = 0;
520 if (Slot.getAsInteger(10, USlot)) {
521 setError("Non-integer object slot value '" + Slot.str() + "'");
522 goto on_bcc_compile_error;
523 }
524 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700525#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700526 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
527#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800528 }
529 }
530 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800531 }
532
533on_bcc_compile_error:
534 // LOGE("on_bcc_compiler_error");
535 if (TD) {
536 delete TD;
537 }
538
539 if (TM) {
540 delete TM;
541 }
542
543 if (mError.empty()) {
544 return 0;
545 }
546
547 // LOGE(getErrorMessage());
548 return 1;
549}
550
551
552#if USE_OLD_JIT
553int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
554 llvm::NamedMDNode const *ExportVarMetadata,
555 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800556 // Create memory manager for creation of code emitter later.
557 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
558 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800559 return 1;
Logan1f028c02010-11-27 01:02:48 +0800560 }
Logan02286cb2011-01-07 00:30:47 +0800561
562 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800563
564 // Create code emitter
565 if (!mCodeEmitter.get()) {
566 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800567 setError("Failed to create machine code emitter for compilation");
568 return 1;
Logan1f028c02010-11-27 01:02:48 +0800569 }
570 } else {
571 // Reuse the code emitter
572 mCodeEmitter->reset();
573 }
574
575 mCodeEmitter->setTargetMachine(*TM);
576 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
577 mpSymbolLookupContext);
578
Logan1f028c02010-11-27 01:02:48 +0800579 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800580 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
581 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800582
Logan Chienda5e0c32011-06-13 03:47:21 +0800583 // Add TargetData to code generation pass manager
584 CodeGenPasses->add(TD);
585
586 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800587 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
588 *mCodeEmitter,
589 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800590 setError("The machine code emission is not supported on '" + Triple + "'");
591 return 1;
Logan1f028c02010-11-27 01:02:48 +0800592 }
593
Logan Chienda5e0c32011-06-13 03:47:21 +0800594 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800595 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800596 for (llvm::Module::iterator
597 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800598 if (!I->isDeclaration()) {
599 CodeGenPasses->run(*I);
600 }
601 }
602
603 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800604
Logan1f028c02010-11-27 01:02:48 +0800605 // Copy the global address mapping from code emitter and remapping
606 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800607 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
608
Logan1f028c02010-11-27 01:02:48 +0800609 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
610 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
611 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
612 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
613 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
614 llvm::StringRef ExportVarName =
615 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
616
617 CodeEmitter::global_addresses_const_iterator I, E;
618 for (I = mCodeEmitter->global_address_begin(),
619 E = mCodeEmitter->global_address_end();
620 I != E; I++) {
621 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
622 continue;
623 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800624 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700625#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700626 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
627#endif
Logan1f028c02010-11-27 01:02:48 +0800628 break;
629 }
630 }
631 if (I != mCodeEmitter->global_address_end())
632 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800633
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 VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800636 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700637#endif
Logan1f028c02010-11-27 01:02:48 +0800638 }
639 }
640 // if reaching here, we know the global variable record in metadata is
641 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800642 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800643 }
Logan2a6dc822011-01-06 04:05:20 +0800644
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700645 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
646 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800647 }
648
649 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800650 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
651
Logan1f028c02010-11-27 01:02:48 +0800652 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
653 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
654 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
655 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
656 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
657 llvm::StringRef ExportFuncName =
658 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800659 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700660#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700661 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800662 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700663#endif
Logan1f028c02010-11-27 01:02:48 +0800664 }
665 }
666 }
667 }
668
669 // Tell code emitter now can release the memory using during the JIT since
670 // we have done the code emission
671 mCodeEmitter->releaseUnnecessary();
672
Logan Chienda5e0c32011-06-13 03:47:21 +0800673 return 0;
Logan1f028c02010-11-27 01:02:48 +0800674}
Logan Chienda5e0c32011-06-13 03:47:21 +0800675#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800676
677
Logan Chienda5e0c32011-06-13 03:47:21 +0800678#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700679int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800680 // Decorate mEmittedELFExecutable with formatted ostream
681 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
682
683 // Relax all machine instructions
684 TM->setMCRelaxAll(/* RelaxAll= */ true);
685
686 // Create MC code generation pass manager
687 llvm::PassManager MCCodeGenPasses;
688
689 // Add TargetData to MC code generation pass manager
690 MCCodeGenPasses.add(TD);
691
692 // Add MC code generation passes to pass manager
693 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800694 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800695 setError("Fail to add passes to emit file");
696 return 1;
697 }
698
699 MCCodeGenPasses.run(*mModule);
700 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800701 return 0;
702}
703#endif // USE_MCJIT
704
705
706int Compiler::runLTO(llvm::TargetData *TD,
707 llvm::NamedMDNode const *ExportVarMetadata,
708 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800709 llvm::PassManager LTOPasses;
710
711 // Add TargetData to LTO passes
712 LTOPasses.add(TD);
713
714 // Collect All Exported Symbols
715 std::vector<const char*> ExportSymbols;
716
717 // Note: This is a workaround for getting export variable and function name.
718 // We should refine it soon.
719 if (ExportVarMetadata) {
720 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
721 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
722 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
723 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
724 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
725 llvm::StringRef ExportVarName =
726 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
727 ExportSymbols.push_back(ExportVarName.data());
728 }
729 }
730 }
731 }
732
733 if (ExportFuncMetadata) {
734 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
735 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
736 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
737 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
738 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
739 llvm::StringRef ExportFuncName =
740 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
741 ExportSymbols.push_back(ExportFuncName.data());
742 }
743 }
744 }
745 }
746
Logan Chien7890d432011-08-03 14:55:17 +0800747 // TODO(logan): Remove this after we have finished the
748 // bccMarkExternalSymbol API.
749
Stephen Hines64160102011-09-01 17:30:26 -0700750 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800751 ExportSymbols.push_back("root");
752 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700753 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800754
Logan Chien7890d432011-08-03 14:55:17 +0800755 // User-defined exporting symbols
756 std::vector<char const *> const &UserDefinedExternalSymbols =
757 mpResult->getUserDefinedExternalSymbols();
758
759 std::copy(UserDefinedExternalSymbols.begin(),
760 UserDefinedExternalSymbols.end(),
761 std::back_inserter(ExportSymbols));
762
Logan Chien4cc00332011-06-12 14:00:46 +0800763 // We now create passes list performing LTO. These are copied from
764 // (including comments) llvm::createStandardLTOPasses().
765
766 // Internalize all other symbols not listed in ExportSymbols
767 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
768
769 // Propagate constants at call sites into the functions they call. This
770 // opens opportunities for globalopt (and inlining) by substituting
771 // function pointers passed as arguments to direct uses of functions.
772 LTOPasses.add(llvm::createIPSCCPPass());
773
774 // Now that we internalized some globals, see if we can hack on them!
775 LTOPasses.add(llvm::createGlobalOptimizerPass());
776
777 // Linking modules together can lead to duplicated global constants, only
778 // keep one copy of each constant...
779 LTOPasses.add(llvm::createConstantMergePass());
780
781 // Remove unused arguments from functions...
782 LTOPasses.add(llvm::createDeadArgEliminationPass());
783
784 // Reduce the code after globalopt and ipsccp. Both can open up
785 // significant simplification opportunities, and both can propagate
786 // functions through function pointers. When this happens, we often have
787 // to resolve varargs calls, etc, so let instcombine do this.
788 LTOPasses.add(llvm::createInstructionCombiningPass());
789
790 // Inline small functions
791 LTOPasses.add(llvm::createFunctionInliningPass());
792
793 // Remove dead EH info.
794 LTOPasses.add(llvm::createPruneEHPass());
795
796 // Internalize the globals again after inlining
797 LTOPasses.add(llvm::createGlobalOptimizerPass());
798
799 // Remove dead functions.
800 LTOPasses.add(llvm::createGlobalDCEPass());
801
802 // If we didn't decide to inline a function, check to see if we can
803 // transform it to pass arguments by value instead of by reference.
804 LTOPasses.add(llvm::createArgumentPromotionPass());
805
806 // The IPO passes may leave cruft around. Clean up after them.
807 LTOPasses.add(llvm::createInstructionCombiningPass());
808 LTOPasses.add(llvm::createJumpThreadingPass());
809
810 // Break up allocas
811 LTOPasses.add(llvm::createScalarReplAggregatesPass());
812
813 // Run a few AA driven optimizations here and now, to cleanup the code.
814 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
815 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
816
817 // Hoist loop invariants.
818 LTOPasses.add(llvm::createLICMPass());
819
820 // Remove redundancies.
821 LTOPasses.add(llvm::createGVNPass());
822
823 // Remove dead memcpys.
824 LTOPasses.add(llvm::createMemCpyOptPass());
825
826 // Nuke dead stores.
827 LTOPasses.add(llvm::createDeadStoreEliminationPass());
828
829 // Cleanup and simplify the code after the scalar optimizations.
830 LTOPasses.add(llvm::createInstructionCombiningPass());
831
832 LTOPasses.add(llvm::createJumpThreadingPass());
833
834 // Delete basic blocks, which optimization passes may have killed.
835 LTOPasses.add(llvm::createCFGSimplificationPass());
836
837 // Now that we have optimized the program, discard unreachable functions.
838 LTOPasses.add(llvm::createGlobalDCEPass());
839
840 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800841
842 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800843}
844
845
Logan Chienda5e0c32011-06-13 03:47:21 +0800846#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800847void *Compiler::getSymbolAddress(char const *name) {
848 return rsloaderGetSymbolAddress(mRSExecutable, name);
849}
850#endif
851
852
853#if USE_MCJIT
854void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
855 Compiler *self = reinterpret_cast<Compiler *>(context);
856
857 if (void *Addr = FindRuntimeFunction(name)) {
858 return Addr;
859 }
860
861 if (self->mpSymbolLookupFn) {
862 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
863 return Addr;
864 }
865 }
866
867 LOGE("Unable to resolve symbol: %s\n", name);
868 return NULL;
869}
870#endif
871
872
Logan1f028c02010-11-27 01:02:48 +0800873Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800874 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800875 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800876
Logan Chienda5e0c32011-06-13 03:47:21 +0800877#if USE_MCJIT
878 rsloaderDisposeExec(mRSExecutable);
879#endif
880
Logana4994f52010-11-27 14:06:02 +0800881 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800882}
883
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700884
Logan1f028c02010-11-27 01:02:48 +0800885} // namespace bcc