• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "Compiler.h"
18 
19 #include "Config.h"
20 
21 #if USE_OLD_JIT
22 #include "OldJIT/ContextManager.h"
23 #endif
24 
25 #if USE_DISASSEMBLER
26 #include "Disassembler/Disassembler.h"
27 #endif
28 
29 #include "DebugHelper.h"
30 #include "FileHandle.h"
31 #include "Runtime.h"
32 #include "ScriptCompiled.h"
33 #include "Sha1Helper.h"
34 
35 #if USE_MCJIT
36 #include "librsloader.h"
37 #endif
38 
39 #include "llvm/ADT/StringRef.h"
40 
41 #include "llvm/Analysis/Passes.h"
42 
43 #include "llvm/Bitcode/ReaderWriter.h"
44 
45 #include "llvm/CodeGen/Passes.h"
46 #include "llvm/CodeGen/RegAllocRegistry.h"
47 #include "llvm/CodeGen/SchedulerRegistry.h"
48 
49 #include "llvm/MC/SubtargetFeature.h"
50 
51 #include "llvm/Transforms/IPO.h"
52 #include "llvm/Transforms/Scalar.h"
53 
54 #include "llvm/Target/TargetData.h"
55 #include "llvm/Target/TargetMachine.h"
56 #include "llvm/Target/TargetOptions.h"
57 #include "llvm/Target/TargetRegistry.h"
58 #include "llvm/Target/TargetSelect.h"
59 
60 #include "llvm/Support/ErrorHandling.h"
61 #include "llvm/Support/FormattedStream.h"
62 #include "llvm/Support/MemoryBuffer.h"
63 
64 #include "llvm/Type.h"
65 #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>
75 #include <sys/stat.h>
76 #include <sys/types.h>
77 #include <unistd.h>
78 
79 #include <string.h>
80 
81 #include <algorithm>
82 #include <iterator>
83 #include <string>
84 #include <vector>
85 
86 namespace bcc {
87 
88 //////////////////////////////////////////////////////////////////////////////
89 // BCC Compiler Static Variables
90 //////////////////////////////////////////////////////////////////////////////
91 
92 bool Compiler::GlobalInitialized = false;
93 
94 // Code generation optimization level for the compiler
95 llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
96 
97 std::string Compiler::Triple;
98 
99 std::string Compiler::CPU;
100 
101 std::vector<std::string> Compiler::Features;
102 
103 // Name of metadata node where pragma info resides (should be synced with
104 // slang.cpp)
105 const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
106 
107 // Name of metadata node where exported variable names reside (should be
108 // synced with slang_rs_metadata.h)
109 const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
110 
111 // Name of metadata node where exported function names reside (should be
112 // synced with slang_rs_metadata.h)
113 const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
114 
115 // Name of metadata node where RS object slot info resides (should be
116 // synced with slang_rs_metadata.h)
117 const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
118 
119 //////////////////////////////////////////////////////////////////////////////
120 // Compiler
121 //////////////////////////////////////////////////////////////////////////////
122 
GlobalInitialization()123 void Compiler::GlobalInitialization() {
124   if (GlobalInitialized)
125     return;
126   // if (!llvm::llvm_is_multithreaded())
127   //   llvm::llvm_start_multithreaded();
128 
129   // Set Triple, CPU and Features here
130   Triple = TARGET_TRIPLE_STRING;
131 
132   // NOTE: Currently, we have to turn off the support for NEON explicitly.
133   // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
134   // instructions.
135 #if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
136 #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 
143 // FIXME - Temporarily disable NEON
144 #if 0 && defined(ARCH_ARM_HAVE_NEON)
145   Features.push_back("+neon");
146   Features.push_back("+neonfp");
147 #else
148   Features.push_back("-neon");
149   Features.push_back("-neonfp");
150 #endif
151 
152   LLVMInitializeARMMCAsmInfo();
153   LLVMInitializeARMMCCodeGenInfo();
154   LLVMInitializeARMMCSubtargetInfo();
155   LLVMInitializeARMAsmPrinter();
156   LLVMInitializeARMTargetInfo();
157   LLVMInitializeARMTarget();
158 #endif
159 
160 #if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN) || \
161     defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
162   LLVMInitializeX86MCAsmInfo();
163   LLVMInitializeX86MCCodeGenInfo();
164   LLVMInitializeX86MCSubtargetInfo();
165   LLVMInitializeX86AsmPrinter();
166   LLVMInitializeX86TargetInfo();
167   LLVMInitializeX86Target();
168 #endif
169 
170 #if USE_DISASSEMBLER
171   InitializeDisassembler();
172 #endif
173 
174   // -O0: llvm::CodeGenOpt::None
175   // -O1: llvm::CodeGenOpt::Less
176   // -O2: llvm::CodeGenOpt::Default
177   // -O3: llvm::CodeGenOpt::Aggressive
178   CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
179 
180   // Below are the global settings to LLVM
181 
182   // Disable frame pointer elimination optimization
183   llvm::NoFramePointerElim = false;
184 
185   // Use hardfloat ABI
186   //
187   // TODO(all): Need to detect the CPU capability and decide whether to use
188   // softfp. To use softfp, change following 2 lines to
189   //
190   // llvm::FloatABIType = llvm::FloatABI::Soft;
191   // llvm::UseSoftFloat = true;
192   //
193   llvm::FloatABIType = llvm::FloatABI::Soft;
194   llvm::UseSoftFloat = false;
195 
196 #if defined(DEFAULT_X64_CODEGEN)
197   // Data address in X86_64 architecture may reside in a far-away place
198   llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
199 #else
200   // This is set for the linker (specify how large of the virtual addresses
201   // we can access for all unknown symbols.)
202   llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
203 #endif
204 
205   // Register the scheduler
206   llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
207 
208   // Register allocation policy:
209   //  createFastRegisterAllocator: fast but bad quality
210   //  createLinearScanRegisterAllocator: not so fast but good quality
211   llvm::RegisterRegAlloc::setDefault
212     ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
213      llvm::createFastRegisterAllocator :
214      llvm::createLinearScanRegisterAllocator);
215 
216 #if USE_CACHE
217   // Read in SHA1 checksum of libbcc and libRS.
218   readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
219 
220   calcFileSHA1(sha1LibRS, pathLibRS);
221 #endif
222 
223   GlobalInitialized = true;
224 }
225 
226 
LLVMErrorHandler(void * UserData,const std::string & Message)227 void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
228   std::string *Error = static_cast<std::string*>(UserData);
229   Error->assign(Message);
230   LOGE("%s", Message.c_str());
231   exit(1);
232 }
233 
234 
235 #if USE_OLD_JIT
createCodeMemoryManager()236 CodeMemoryManager *Compiler::createCodeMemoryManager() {
237   mCodeMemMgr.reset(new CodeMemoryManager());
238   return mCodeMemMgr.get();
239 }
240 #endif
241 
242 
243 #if USE_OLD_JIT
createCodeEmitter()244 CodeEmitter *Compiler::createCodeEmitter() {
245   mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
246   return mCodeEmitter.get();
247 }
248 #endif
249 
250 
Compiler(ScriptCompiled * result)251 Compiler::Compiler(ScriptCompiled *result)
252   : mpResult(result),
253 #if USE_MCJIT
254     mRSExecutable(NULL),
255 #endif
256     mpSymbolLookupFn(NULL),
257     mpSymbolLookupContext(NULL),
258     mContext(NULL),
259     mModule(NULL),
260     mHasLinked(false) /* Turn off linker */ {
261   llvm::remove_fatal_error_handler();
262   llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
263   mContext = new llvm::LLVMContext();
264   return;
265 }
266 
267 
parseBitcodeFile(llvm::MemoryBuffer * MEM)268 llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
269   llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
270 
271   if (!result) {
272     LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
273     return NULL;
274   }
275 
276   return result;
277 }
278 
279 
linkModule(llvm::Module * moduleWith)280 int Compiler::linkModule(llvm::Module *moduleWith) {
281   if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
282     return hasError();
283   }
284 
285   // Everything for linking should be settled down here with no error occurs
286   mHasLinked = true;
287   return hasError();
288 }
289 
290 
compile(bool compileOnly)291 int Compiler::compile(bool compileOnly) {
292   llvm::Target const *Target = NULL;
293   llvm::TargetData *TD = NULL;
294   llvm::TargetMachine *TM = NULL;
295 
296   std::string FeaturesStr;
297 
298   llvm::NamedMDNode const *PragmaMetadata;
299   llvm::NamedMDNode const *ExportVarMetadata;
300   llvm::NamedMDNode const *ExportFuncMetadata;
301   llvm::NamedMDNode const *ObjectSlotMetadata;
302 
303   if (mModule == NULL)  // No module was loaded
304     return 0;
305 
306   // Create TargetMachine
307   Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
308   if (hasError())
309     goto on_bcc_compile_error;
310 
311   if (!CPU.empty() || !Features.empty()) {
312     llvm::SubtargetFeatures F;
313 
314     for (std::vector<std::string>::const_iterator
315          I = Features.begin(), E = Features.end(); I != E; I++) {
316       F.AddFeature(*I);
317     }
318 
319     FeaturesStr = F.getString();
320   }
321 
322   TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
323                                    llvm::Reloc::Static);
324   if (TM == NULL) {
325     setError("Failed to create target machine implementation for the"
326              " specified triple '" + Triple + "'");
327     goto on_bcc_compile_error;
328   }
329 
330   // Get target data from Module
331   TD = new llvm::TargetData(mModule);
332 
333   // Load named metadata
334   ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
335   ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
336   PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
337   ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
338 
339   // Perform link-time optimization if we have multiple modules
340   if (mHasLinked) {
341     runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
342   }
343 
344   // Perform code generation
345 #if USE_OLD_JIT
346   if (runCodeGen(new llvm::TargetData(*TD), TM,
347                  ExportVarMetadata, ExportFuncMetadata) != 0) {
348     goto on_bcc_compile_error;
349   }
350 #endif
351 
352 #if USE_MCJIT
353   if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
354     goto on_bcc_compile_error;
355   }
356 
357   if (compileOnly)
358     return 0;
359 
360   // Load the ELF Object
361   mRSExecutable =
362     rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
363                        mEmittedELFExecutable.size(),
364                        &resolveSymbolAdapter, this);
365 
366   if (!mRSExecutable) {
367     setError("Fail to load emitted ELF relocatable file");
368     goto on_bcc_compile_error;
369   }
370 
371   if (ExportVarMetadata) {
372     ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
373     std::vector<std::string> &varNameList = mpResult->mExportVarsName;
374 
375     for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
376       llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
377       if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
378         llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
379         if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
380           llvm::StringRef ExportVarName =
381             static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
382 
383           varList.push_back(
384             rsloaderGetSymbolAddress(mRSExecutable,
385                                      ExportVarName.str().c_str()));
386           varNameList.push_back(ExportVarName.str());
387 #if DEBUG_MCJIT_REFLECT
388           LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
389                varList.back());
390 #endif
391           continue;
392         }
393       }
394 
395       varList.push_back(NULL);
396     }
397   }
398 
399   if (ExportFuncMetadata) {
400     ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
401     std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
402 
403     for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
404       llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
405       if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
406         llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
407         if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
408           llvm::StringRef ExportFuncName =
409             static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
410 
411           funcList.push_back(
412             rsloaderGetSymbolAddress(mRSExecutable,
413                                      ExportFuncName.str().c_str()));
414           funcNameList.push_back(ExportFuncName.str());
415 #if DEBUG_MCJIT_RELECT
416           LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
417                funcList.back());
418 #endif
419         }
420       }
421     }
422   }
423 
424 #if DEBUG_MCJIT_DISASSEMBLER
425   {
426     // Get MC codegen emitted function name list
427     size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
428     std::vector<char const *> func_list(func_list_size, NULL);
429     rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
430 
431     // Disassemble each function
432     for (size_t i = 0; i < func_list_size; ++i) {
433       void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
434       if (func) {
435         size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
436         Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
437                     Target, TM, func_list[i], (unsigned char const *)func, size);
438       }
439     }
440   }
441 #endif
442 #endif
443 
444   // Read pragma information from the metadata node of the module.
445   if (PragmaMetadata) {
446     ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
447 
448     for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
449       llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
450       if (Pragma != NULL &&
451           Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
452         llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
453         llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
454 
455         if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
456             (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
457           llvm::StringRef PragmaName =
458             static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
459           llvm::StringRef PragmaValue =
460             static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
461 
462           pragmaList.push_back(
463             std::make_pair(std::string(PragmaName.data(),
464                                        PragmaName.size()),
465                            std::string(PragmaValue.data(),
466                                        PragmaValue.size())));
467 #if DEBUG_BCC_REFLECT
468           LOGD("compile(): Pragma: %s -> %s\n",
469                pragmaList.back().first.c_str(),
470                pragmaList.back().second.c_str());
471 #endif
472         }
473       }
474     }
475   }
476 
477   if (ObjectSlotMetadata) {
478     ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
479 
480     for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
481       llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
482       if (ObjectSlot != NULL &&
483           ObjectSlot->getNumOperands() == 1) {
484         llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
485         if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
486           llvm::StringRef Slot =
487               static_cast<llvm::MDString*>(SlotMDS)->getString();
488           uint32_t USlot = 0;
489           if (Slot.getAsInteger(10, USlot)) {
490             setError("Non-integer object slot value '" + Slot.str() + "'");
491             goto on_bcc_compile_error;
492           }
493           objectSlotList.push_back(USlot);
494 #if DEBUG_BCC_REFLECT
495           LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
496 #endif
497         }
498       }
499     }
500   }
501 
502 on_bcc_compile_error:
503   // LOGE("on_bcc_compiler_error");
504   if (TD) {
505     delete TD;
506   }
507 
508   if (TM) {
509     delete TM;
510   }
511 
512   if (mError.empty()) {
513     return 0;
514   }
515 
516   // LOGE(getErrorMessage());
517   return 1;
518 }
519 
520 
521 #if USE_OLD_JIT
runCodeGen(llvm::TargetData * TD,llvm::TargetMachine * TM,llvm::NamedMDNode const * ExportVarMetadata,llvm::NamedMDNode const * ExportFuncMetadata)522 int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
523                          llvm::NamedMDNode const *ExportVarMetadata,
524                          llvm::NamedMDNode const *ExportFuncMetadata) {
525   // Create memory manager for creation of code emitter later.
526   if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
527     setError("Failed to startup memory management for further compilation");
528     return 1;
529   }
530 
531   mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
532 
533   // Create code emitter
534   if (!mCodeEmitter.get()) {
535     if (!createCodeEmitter()) {
536       setError("Failed to create machine code emitter for compilation");
537       return 1;
538     }
539   } else {
540     // Reuse the code emitter
541     mCodeEmitter->reset();
542   }
543 
544   mCodeEmitter->setTargetMachine(*TM);
545   mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
546                                        mpSymbolLookupContext);
547 
548   // Create code-gen pass to run the code emitter
549   llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
550     new llvm::FunctionPassManager(mModule));
551 
552   // Add TargetData to code generation pass manager
553   CodeGenPasses->add(TD);
554 
555   // Add code emit passes
556   if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
557                                      *mCodeEmitter,
558                                      CodeGenOptLevel)) {
559     setError("The machine code emission is not supported on '" + Triple + "'");
560     return 1;
561   }
562 
563   // Run the code emitter on every non-declaration function in the module
564   CodeGenPasses->doInitialization();
565   for (llvm::Module::iterator
566        I = mModule->begin(), E = mModule->end(); I != E; I++) {
567     if (!I->isDeclaration()) {
568       CodeGenPasses->run(*I);
569     }
570   }
571 
572   CodeGenPasses->doFinalization();
573 
574   // Copy the global address mapping from code emitter and remapping
575   if (ExportVarMetadata) {
576     ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
577 
578     for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
579       llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
580       if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
581         llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
582         if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
583           llvm::StringRef ExportVarName =
584             static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
585 
586           CodeEmitter::global_addresses_const_iterator I, E;
587           for (I = mCodeEmitter->global_address_begin(),
588                E = mCodeEmitter->global_address_end();
589                I != E; I++) {
590             if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
591               continue;
592             if (ExportVarName == I->first->getName()) {
593               varList.push_back(I->second);
594 #if DEBUG_BCC_REFLECT
595               LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
596 #endif
597               break;
598             }
599           }
600           if (I != mCodeEmitter->global_address_end())
601             continue;  // found
602 
603 #if DEBUG_BCC_REFLECT
604           LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
605                ExportVarName.str().c_str(), (void *)0);
606 #endif
607         }
608       }
609       // if reaching here, we know the global variable record in metadata is
610       // not found. So we make an empty slot
611       varList.push_back(NULL);
612     }
613 
614     bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
615               "Number of slots doesn't match the number of export variables!");
616   }
617 
618   if (ExportFuncMetadata) {
619     ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
620 
621     for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
622       llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
623       if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
624         llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
625         if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
626           llvm::StringRef ExportFuncName =
627             static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
628           funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
629 #if DEBUG_BCC_REFLECT
630           LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
631                funcList.back());
632 #endif
633         }
634       }
635     }
636   }
637 
638   // Tell code emitter now can release the memory using during the JIT since
639   // we have done the code emission
640   mCodeEmitter->releaseUnnecessary();
641 
642   return 0;
643 }
644 #endif // USE_OLD_JIT
645 
646 
647 #if USE_MCJIT
runMCCodeGen(llvm::TargetData * TD,llvm::TargetMachine * TM)648 int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
649   // Decorate mEmittedELFExecutable with formatted ostream
650   llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
651 
652   // Relax all machine instructions
653   TM->setMCRelaxAll(/* RelaxAll= */ true);
654 
655   // Create MC code generation pass manager
656   llvm::PassManager MCCodeGenPasses;
657 
658   // Add TargetData to MC code generation pass manager
659   MCCodeGenPasses.add(TD);
660 
661   // Add MC code generation passes to pass manager
662   llvm::MCContext *Ctx;
663   if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
664                             CodeGenOptLevel, false)) {
665     setError("Fail to add passes to emit file");
666     return 1;
667   }
668 
669   MCCodeGenPasses.run(*mModule);
670   OutSVOS.flush();
671   return 0;
672 }
673 #endif // USE_MCJIT
674 
675 
runLTO(llvm::TargetData * TD,llvm::NamedMDNode const * ExportVarMetadata,llvm::NamedMDNode const * ExportFuncMetadata)676 int Compiler::runLTO(llvm::TargetData *TD,
677                      llvm::NamedMDNode const *ExportVarMetadata,
678                      llvm::NamedMDNode const *ExportFuncMetadata) {
679   llvm::PassManager LTOPasses;
680 
681   // Add TargetData to LTO passes
682   LTOPasses.add(TD);
683 
684   // Collect All Exported Symbols
685   std::vector<const char*> ExportSymbols;
686 
687   // Note: This is a workaround for getting export variable and function name.
688   // We should refine it soon.
689   if (ExportVarMetadata) {
690     for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
691       llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
692       if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
693         llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
694         if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
695           llvm::StringRef ExportVarName =
696             static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
697           ExportSymbols.push_back(ExportVarName.data());
698         }
699       }
700     }
701   }
702 
703   if (ExportFuncMetadata) {
704     for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
705       llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
706       if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
707         llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
708         if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
709           llvm::StringRef ExportFuncName =
710             static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
711           ExportSymbols.push_back(ExportFuncName.data());
712         }
713       }
714     }
715   }
716 
717   // TODO(logan): Remove this after we have finished the
718   // bccMarkExternalSymbol API.
719 
720   // root(), init(), and .rs.dtor() are born to be exported
721   ExportSymbols.push_back("root");
722   ExportSymbols.push_back("init");
723   ExportSymbols.push_back(".rs.dtor");
724 
725   // User-defined exporting symbols
726   std::vector<char const *> const &UserDefinedExternalSymbols =
727     mpResult->getUserDefinedExternalSymbols();
728 
729   std::copy(UserDefinedExternalSymbols.begin(),
730             UserDefinedExternalSymbols.end(),
731             std::back_inserter(ExportSymbols));
732 
733   // We now create passes list performing LTO. These are copied from
734   // (including comments) llvm::createStandardLTOPasses().
735 
736   // Internalize all other symbols not listed in ExportSymbols
737   LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
738 
739   // Propagate constants at call sites into the functions they call. This
740   // opens opportunities for globalopt (and inlining) by substituting
741   // function pointers passed as arguments to direct uses of functions.
742   LTOPasses.add(llvm::createIPSCCPPass());
743 
744   // Now that we internalized some globals, see if we can hack on them!
745   LTOPasses.add(llvm::createGlobalOptimizerPass());
746 
747   // Linking modules together can lead to duplicated global constants, only
748   // keep one copy of each constant...
749   LTOPasses.add(llvm::createConstantMergePass());
750 
751   // Remove unused arguments from functions...
752   LTOPasses.add(llvm::createDeadArgEliminationPass());
753 
754   // Reduce the code after globalopt and ipsccp. Both can open up
755   // significant simplification opportunities, and both can propagate
756   // functions through function pointers. When this happens, we often have
757   // to resolve varargs calls, etc, so let instcombine do this.
758   LTOPasses.add(llvm::createInstructionCombiningPass());
759 
760   // Inline small functions
761   LTOPasses.add(llvm::createFunctionInliningPass());
762 
763   // Remove dead EH info.
764   LTOPasses.add(llvm::createPruneEHPass());
765 
766   // Internalize the globals again after inlining
767   LTOPasses.add(llvm::createGlobalOptimizerPass());
768 
769   // Remove dead functions.
770   LTOPasses.add(llvm::createGlobalDCEPass());
771 
772   // If we didn't decide to inline a function, check to see if we can
773   // transform it to pass arguments by value instead of by reference.
774   LTOPasses.add(llvm::createArgumentPromotionPass());
775 
776   // The IPO passes may leave cruft around.  Clean up after them.
777   LTOPasses.add(llvm::createInstructionCombiningPass());
778   LTOPasses.add(llvm::createJumpThreadingPass());
779 
780   // Break up allocas
781   LTOPasses.add(llvm::createScalarReplAggregatesPass());
782 
783   // Run a few AA driven optimizations here and now, to cleanup the code.
784   LTOPasses.add(llvm::createFunctionAttrsPass());  // Add nocapture.
785   LTOPasses.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
786 
787   // Hoist loop invariants.
788   LTOPasses.add(llvm::createLICMPass());
789 
790   // Remove redundancies.
791   LTOPasses.add(llvm::createGVNPass());
792 
793   // Remove dead memcpys.
794   LTOPasses.add(llvm::createMemCpyOptPass());
795 
796   // Nuke dead stores.
797   LTOPasses.add(llvm::createDeadStoreEliminationPass());
798 
799   // Cleanup and simplify the code after the scalar optimizations.
800   LTOPasses.add(llvm::createInstructionCombiningPass());
801 
802   LTOPasses.add(llvm::createJumpThreadingPass());
803 
804   // Delete basic blocks, which optimization passes may have killed.
805   LTOPasses.add(llvm::createCFGSimplificationPass());
806 
807   // Now that we have optimized the program, discard unreachable functions.
808   LTOPasses.add(llvm::createGlobalDCEPass());
809 
810   LTOPasses.run(*mModule);
811 
812   return 0;
813 }
814 
815 
816 #if USE_MCJIT
getSymbolAddress(char const * name)817 void *Compiler::getSymbolAddress(char const *name) {
818   return rsloaderGetSymbolAddress(mRSExecutable, name);
819 }
820 #endif
821 
822 
823 #if USE_MCJIT
resolveSymbolAdapter(void * context,char const * name)824 void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
825   Compiler *self = reinterpret_cast<Compiler *>(context);
826 
827   if (void *Addr = FindRuntimeFunction(name)) {
828     return Addr;
829   }
830 
831   if (self->mpSymbolLookupFn) {
832     if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
833       return Addr;
834     }
835   }
836 
837   LOGE("Unable to resolve symbol: %s\n", name);
838   return NULL;
839 }
840 #endif
841 
842 
~Compiler()843 Compiler::~Compiler() {
844   delete mModule;
845   delete mContext;
846 
847 #if USE_MCJIT
848   rsloaderDisposeExec(mRSExecutable);
849 #endif
850 
851   // llvm::llvm_shutdown();
852 }
853 
854 
855 }  // namespace bcc
856