Compiler.cpp revision 094881f513ab366f7ffd0b2c7778ab50281ca59e
11f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan/*
21f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Copyright 2010, The Android Open Source Project
31f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
41f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Licensed under the Apache License, Version 2.0 (the "License");
51f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * you may not use this file except in compliance with the License.
61f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * You may obtain a copy of the License at
71f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
81f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *     http://www.apache.org/licenses/LICENSE-2.0
91f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Unless required by applicable law or agreed to in writing, software
111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * distributed under the License is distributed on an "AS IS" BASIS,
121f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * See the License for the specific language governing permissions and
141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * limitations under the License.
151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan */
161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
17c4395235b212be7a626becb0c03020eab4859739Logan#include "Compiler.h"
181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
19358490082d8435aa36feaff8107aa55c3cf363adLogan#include "Config.h"
20358490082d8435aa36feaff8107aa55c3cf363adLogan
21d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#if USE_OLD_JIT
22d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#include "OldJIT/ContextManager.h"
23d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#endif
24d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien
254885cf8889f2290ecd04a02e067cb2f44c3cdf6cLogan Chien#if USE_DISASSEMBLER
264885cf8889f2290ecd04a02e067cb2f44c3cdf6cLogan Chien#include "Disassembler/Disassembler.h"
274885cf8889f2290ecd04a02e067cb2f44c3cdf6cLogan Chien#endif
284885cf8889f2290ecd04a02e067cb2f44c3cdf6cLogan Chien
294dcd6798f3db374a056ea6acc6b425f544c5207cLogan#include "DebugHelper.h"
306c0c7b03307a6e6dacb163df804a03b6bae36ce6Shih-wei Liao#include "FileHandle.h"
31da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "Runtime.h"
322a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan#include "ScriptCompiled.h"
3375cc8a5c58b3260e530eae9f2edd502b71d25373Logan#include "Sha1Helper.h"
34eb3d12b84ae215ec08de00f6f33228a823e20338Logan
35320b5499c78f8b94bc61f609a5fc9053a91d3c18Shih-wei Liao#if USE_MCJIT
36da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "librsloader.h"
37320b5499c78f8b94bc61f609a5fc9053a91d3c18Shih-wei Liao#endif
38da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
39df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/ADT/StringRef.h"
401f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
41df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Analysis/Passes.h"
421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/Bitcode/ReaderWriter.h"
441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
451f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/CodeGen/Passes.h"
461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/CodeGen/RegAllocRegistry.h"
471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/CodeGen/SchedulerRegistry.h"
481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
49094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#include "llvm/MC/MCContext.h"
509347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/SubtargetFeature.h"
519347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
52df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Transforms/IPO.h"
53df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Transforms/Scalar.h"
541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
55df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Target/TargetData.h"
56df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Target/TargetMachine.h"
57df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Target/TargetOptions.h"
58df23afaf4459778bade8c822d996865096ad033eLogan
59df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Support/ErrorHandling.h"
60898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao#include "llvm/Support/FormattedStream.h"
61df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Support/MemoryBuffer.h"
62bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien#include "llvm/Support/TargetRegistry.h"
63bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien#include "llvm/Support/TargetSelect.h"
64094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#include "llvm/Support/raw_ostream.h"
65df23afaf4459778bade8c822d996865096ad033eLogan
66094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#include "llvm/Constants.h"
67df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/GlobalValue.h"
68df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Linker.h"
69df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/LLVMContext.h"
70df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Metadata.h"
71df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Module.h"
72df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/PassManager.h"
73094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#include "llvm/Type.h"
74df23afaf4459778bade8c822d996865096ad033eLogan#include "llvm/Value.h"
75df23afaf4459778bade8c822d996865096ad033eLogan
76df23afaf4459778bade8c822d996865096ad033eLogan#include <errno.h>
77df23afaf4459778bade8c822d996865096ad033eLogan#include <sys/file.h>
78df23afaf4459778bade8c822d996865096ad033eLogan#include <sys/stat.h>
79df23afaf4459778bade8c822d996865096ad033eLogan#include <sys/types.h>
80df23afaf4459778bade8c822d996865096ad033eLogan#include <unistd.h>
81df23afaf4459778bade8c822d996865096ad033eLogan
8275cc8a5c58b3260e530eae9f2edd502b71d25373Logan#include <string.h>
838b77a77e785f0e25b13016ed60770e521dc60e0bLogan
847890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien#include <algorithm>
857890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien#include <iterator>
86df23afaf4459778bade8c822d996865096ad033eLogan#include <string>
87df23afaf4459778bade8c822d996865096ad033eLogan#include <vector>
881f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
89094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleaextern char* gDebugDumpDirectory;
90094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
911f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace bcc {
921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
931f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan//////////////////////////////////////////////////////////////////////////////
941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// BCC Compiler Static Variables
951f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan//////////////////////////////////////////////////////////////////////////////
961f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
971f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganbool Compiler::GlobalInitialized = false;
981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
991f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// Code generation optimization level for the compiler
1001f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganllvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
1011f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1021f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganstd::string Compiler::Triple;
1031f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1041f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganstd::string Compiler::CPU;
1051f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1061f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganstd::vector<std::string> Compiler::Features;
1071f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
108071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines// Name of metadata node where pragma info resides (should be synced with
1091f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// slang.cpp)
1101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganconst llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
1111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
112071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines// Name of metadata node where exported variable names reside (should be
1131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// synced with slang_rs_metadata.h)
1141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganconst llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
1151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
116071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines// Name of metadata node where exported function names reside (should be
1171f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// synced with slang_rs_metadata.h)
1181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganconst llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
1191f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
120071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines// Name of metadata node where RS object slot info resides (should be
121071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines// synced with slang_rs_metadata.h)
122071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hinesconst llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
1231f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
124094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// Name of metadata node where RS optimization level resides (should be
125094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// synced with slang_rs_metadata.h)
126094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleaconst llvm::StringRef OptimizationLevelMetadataName = "#optimization_level";
127094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
128094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
129094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
1301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan//////////////////////////////////////////////////////////////////////////////
1311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan// Compiler
1321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan//////////////////////////////////////////////////////////////////////////////
1331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganvoid Compiler::GlobalInitialization() {
1351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (GlobalInitialized)
1361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    return;
1371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // if (!llvm::llvm_is_multithreaded())
1381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  //   llvm::llvm_start_multithreaded();
1391f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1401f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Set Triple, CPU and Features here
1411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  Triple = TARGET_TRIPLE_STRING;
1421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1433bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#if defined(DEFAULT_ARM_CODEGEN)
1443bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien
145a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines#if defined(ARCH_ARM_HAVE_VFP)
146a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines  Features.push_back("+vfp3");
147a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines#if !defined(ARCH_ARM_HAVE_VFP_D32)
148a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines  Features.push_back("+d16");
149a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines#endif
150a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines#endif
151a12d2f3ee66366097ca59941eb91f75d97ab09b2Stephen Hines
1523bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien  // NOTE: Currently, we have to turn off the support for NEON explicitly.
1533bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien  // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
1543bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien  // instructions.
1553bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien
1563bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien  // FIXME: Re-enable NEON when ARMCodeEmitter supports NEON.
1573bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#define USE_ARM_NEON 0
1583bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#if USE_ARM_NEON
15951001b86751c1ca36307eddc44a65336079fb698Joseph Wen  Features.push_back("+neon");
16051001b86751c1ca36307eddc44a65336079fb698Joseph Wen  Features.push_back("+neonfp");
16151001b86751c1ca36307eddc44a65336079fb698Joseph Wen#else
16251001b86751c1ca36307eddc44a65336079fb698Joseph Wen  Features.push_back("-neon");
1634fe966f57524077720f1b729eecf5f320b19513bLogan  Features.push_back("-neonfp");
1643bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#endif // USE_ARM_NEON
1653bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#endif // DEFAULT_ARM_CODEGEN
16651001b86751c1ca36307eddc44a65336079fb698Joseph Wen
1673bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#if defined(PROVIDE_ARM_CODEGEN)
168b9ef9ab8e80b25fb26dfec11647629af887b260bLogan Chien  LLVMInitializeARMAsmPrinter();
169bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  LLVMInitializeARMTargetMC();
1701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  LLVMInitializeARMTargetInfo();
1711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  LLVMInitializeARMTarget();
1721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif
1731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1743bb77072f4dd09c26d7397f92b7eb8b5d0f79de7Logan Chien#if defined(PROVIDE_X86_CODEGEN)
175b9ef9ab8e80b25fb26dfec11647629af887b260bLogan Chien  LLVMInitializeX86AsmPrinter();
176bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  LLVMInitializeX86TargetMC();
1771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  LLVMInitializeX86TargetInfo();
1781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  LLVMInitializeX86Target();
1791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif
1809347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1819347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if USE_DISASSEMBLER
1829347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  InitializeDisassembler();
1831f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif
1841f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Below are the global settings to LLVM
1851f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1861f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Disable frame pointer elimination optimization
1871f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::NoFramePointerElim = false;
1881f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1891f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Use hardfloat ABI
1901f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  //
1911f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // TODO(all): Need to detect the CPU capability and decide whether to use
1921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // softfp. To use softfp, change following 2 lines to
1931f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  //
1941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // llvm::FloatABIType = llvm::FloatABI::Soft;
1951f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // llvm::UseSoftFloat = true;
1961f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  //
197e728cb8a96c7db39f4c6115d20865ab3bacf199bShih-wei Liao  llvm::FloatABIType = llvm::FloatABI::Soft;
1981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::UseSoftFloat = false;
1991f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2001f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Register the scheduler
2011f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
2021f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
203358490082d8435aa36feaff8107aa55c3cf363adLogan#if USE_CACHE
20426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang  // Read in SHA1 checksum of libbcc and libRS.
20526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang  readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
206769190765f7a920ac7f30ff6d424f3ae850b1c3aJoseph Wen
207769190765f7a920ac7f30ff6d424f3ae850b1c3aJoseph Wen  calcFileSHA1(sha1LibRS, pathLibRS);
208358490082d8435aa36feaff8107aa55c3cf363adLogan#endif
20975cc8a5c58b3260e530eae9f2edd502b71d25373Logan
2101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  GlobalInitialized = true;
2111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2121f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Loganvoid Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
2151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  std::string *Error = static_cast<std::string*>(UserData);
2161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  Error->assign(Message);
2171f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  LOGE("%s", Message.c_str());
2181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  exit(1);
2191f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2201f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2211f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
222da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
2231f028c027b1df7fde0cd1a1eef9730856e8e5ae9LoganCodeMemoryManager *Compiler::createCodeMemoryManager() {
2241f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mCodeMemMgr.reset(new CodeMemoryManager());
2251f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  return mCodeMemMgr.get();
2261f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
227da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
2281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
230da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
2311f028c027b1df7fde0cd1a1eef9730856e8e5ae9LoganCodeEmitter *Compiler::createCodeEmitter() {
2327dcaac9898741e701098537808296f4e2f2fb422Logan  mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
2331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  return mCodeEmitter.get();
2341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
235da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
2361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2382a6dc82a465631f82fc589c6bc68c15ed264f7ebLoganCompiler::Compiler(ScriptCompiled *result)
2392a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan  : mpResult(result),
240da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
241da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    mRSExecutable(NULL),
242da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
2431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mpSymbolLookupFn(NULL),
2441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mpSymbolLookupContext(NULL),
2451f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mContext(NULL),
2461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mModule(NULL),
2471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mHasLinked(false) /* Turn off linker */ {
2481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::remove_fatal_error_handler();
2491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
2501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mContext = new llvm::LLVMContext();
2511f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  return;
2521f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
255474cbd2fde362e63375f7a5099ca38b5c67835cfLoganllvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
256474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
2571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
258474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!result) {
259474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
260474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    return NULL;
2611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
2621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
263474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return result;
2641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2661f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
267474cbd2fde362e63375f7a5099ca38b5c67835cfLoganint Compiler::linkModule(llvm::Module *moduleWith) {
268bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  if (llvm::Linker::LinkModules(mModule, moduleWith,
269bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                llvm::Linker::DestroySource,
270bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                &mError) != 0) {
2711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    return hasError();
2721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
2731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Everything for linking should be settled down here with no error occurs
2751f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mHasLinked = true;
2761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  return hasError();
2771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
28034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wenint Compiler::compile(bool compileOnly) {
281da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::Target const *Target = NULL;
2821f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::TargetData *TD = NULL;
2831f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  llvm::TargetMachine *TM = NULL;
284de0ba06cf9f96118261e8d242c0ac08869a54442Shih-wei Liao
285da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  std::string FeaturesStr;
286898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
287094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  if (mModule == NULL)  // No module was loaded
288094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    return 0;
289094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
290da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::NamedMDNode const *PragmaMetadata;
291da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::NamedMDNode const *ExportVarMetadata;
292da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::NamedMDNode const *ExportFuncMetadata;
293da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::NamedMDNode const *ObjectSlotMetadata;
2941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
295094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  llvm::NamedMDNode const *OptimizationLevelMetadata =
296094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    mModule->getNamedMetadata(OptimizationLevelMetadataName);
297094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
298094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // Default to maximum optimization in the absence of named metadata node
299094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  int OptimizationLevel = 3;
300094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  if (OptimizationLevelMetadata) {
301094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
302094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea      OptimizationLevelMetadata->getOperand(0)->getOperand(0));
303094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    OptimizationLevel = OL->getZExtValue();
304094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
305094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
306094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  if (OptimizationLevel == 0) {
307094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    CodeGenOptLevel = llvm::CodeGenOpt::None;
308094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  } else if (OptimizationLevel == 1) {
309094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    CodeGenOptLevel = llvm::CodeGenOpt::Less;
310094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  } else if (OptimizationLevel == 2) {
311094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    CodeGenOptLevel = llvm::CodeGenOpt::Default;
312094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  } else if (OptimizationLevel == 3) {
313094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
314094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
315094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
316094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // not the best place for this, but we need to set the register allocation
317094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // policy after we read the optimization_level metadata from the bitcode
318094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
319094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // Register allocation policy:
320094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  //  createFastRegisterAllocator: fast but bad quality
321094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  //  createLinearScanRegisterAllocator: not so fast but good quality
322094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  llvm::RegisterRegAlloc::setDefault
323094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
324094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea     llvm::createFastRegisterAllocator :
325094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea     llvm::createLinearScanRegisterAllocator);
326094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
3271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
3281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Create TargetMachine
3291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
3301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (hasError())
3311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    goto on_bcc_compile_error;
3321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
3331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (!CPU.empty() || !Features.empty()) {
3341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::SubtargetFeatures F;
335a4994f55617d251575013a41d5f9267fd68ce110Logan
336a4994f55617d251575013a41d5f9267fd68ce110Logan    for (std::vector<std::string>::const_iterator
337a4994f55617d251575013a41d5f9267fd68ce110Logan         I = Features.begin(), E = Features.end(); I != E; I++) {
3381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      F.AddFeature(*I);
339a4994f55617d251575013a41d5f9267fd68ce110Logan    }
340a4994f55617d251575013a41d5f9267fd68ce110Logan
3411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    FeaturesStr = F.getString();
3421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
3431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
344bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien#if defined(DEFAULT_X86_64_CODEGEN)
345bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  // Data address in X86_64 architecture may reside in a far-away place
346d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien  TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
347bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                   llvm::Reloc::Static,
348bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                   llvm::CodeModel::Medium);
349bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien#else
350bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  // This is set for the linker (specify how large of the virtual addresses
351bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  // we can access for all unknown symbols.)
352bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien  TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
353bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                   llvm::Reloc::Static,
354bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien                                   llvm::CodeModel::Small);
355bc9eb8fa13ee44d7bb46285e4c30da1236aefddfLogan Chien#endif
3561f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (TM == NULL) {
3571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    setError("Failed to create target machine implementation for the"
3581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan             " specified triple '" + Triple + "'");
3591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    goto on_bcc_compile_error;
3601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
3611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
362da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Get target data from Module
363da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  TD = new llvm::TargetData(mModule);
364da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
365da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Load named metadata
366da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
367da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
368da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
369da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
370da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
371da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Perform link-time optimization if we have multiple modules
372da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (mHasLinked) {
373094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
374094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea      CodeGenOptLevel);
375da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
376da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
377da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Perform code generation
378da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
379da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (runCodeGen(new llvm::TargetData(*TD), TM,
380da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                 ExportVarMetadata, ExportFuncMetadata) != 0) {
381da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    goto on_bcc_compile_error;
382da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
383da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
384da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
385da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
38634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
387da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    goto on_bcc_compile_error;
388da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
3899347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
39034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  if (compileOnly)
39134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    return 0;
39234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
39334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  // Load the ELF Object
39434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  mRSExecutable =
39534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
39634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                       mEmittedELFExecutable.size(),
39734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                       &resolveSymbolAdapter, this);
39834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
39934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  if (!mRSExecutable) {
40034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    setError("Fail to load emitted ELF relocatable file");
40134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    goto on_bcc_compile_error;
40234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  }
40334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
404094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  rsloaderUpdateSectionHeaders(mRSExecutable,
405094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    (unsigned char*) mEmittedELFExecutable.begin());
406094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
40734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  if (ExportVarMetadata) {
40834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
40934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    std::vector<std::string> &varNameList = mpResult->mExportVarsName;
41034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
41134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
41234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
41334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
41434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
41534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
41634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          llvm::StringRef ExportVarName =
41734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
41834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
41934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          varList.push_back(
42034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen            rsloaderGetSymbolAddress(mRSExecutable,
42134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                                     ExportVarName.str().c_str()));
42234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          varNameList.push_back(ExportVarName.str());
42334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen#if DEBUG_MCJIT_REFLECT
42434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
42534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen               varList.back());
42634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen#endif
42734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          continue;
42834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        }
42934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      }
43034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
43134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      varList.push_back(NULL);
43234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    }
43334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  }
43434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
43534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  if (ExportFuncMetadata) {
43634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
43734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
43834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
43934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
44034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
44134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
44234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
44334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
44434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          llvm::StringRef ExportFuncName =
44534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
44634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
44734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          funcList.push_back(
44834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen            rsloaderGetSymbolAddress(mRSExecutable,
44934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                                     ExportFuncName.str().c_str()));
45034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          funcNameList.push_back(ExportFuncName.str());
45134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen#if DEBUG_MCJIT_RELECT
45234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen          LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
45334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen               funcList.back());
45434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen#endif
45534c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen        }
45634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen      }
45734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    }
45834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  }
45934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
4604885cf8889f2290ecd04a02e067cb2f44c3cdf6cLogan Chien#if DEBUG_MCJIT_DISASSEMBLER
46190cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao  {
462d3c551fbc76ad424577335b40491436cbc0dbd86Shih-wei Liao    // Get MC codegen emitted function name list
463d3c551fbc76ad424577335b40491436cbc0dbd86Shih-wei Liao    size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
464d3c551fbc76ad424577335b40491436cbc0dbd86Shih-wei Liao    std::vector<char const *> func_list(func_list_size, NULL);
465d3c551fbc76ad424577335b40491436cbc0dbd86Shih-wei Liao    rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
46690cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao
467d3c551fbc76ad424577335b40491436cbc0dbd86Shih-wei Liao    // Disassemble each function
46890cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao    for (size_t i = 0; i < func_list_size; ++i) {
46990cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao      void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
47090cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao      if (func) {
47190cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao        size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
4729347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien        Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
4739347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                    Target, TM, func_list[i], (unsigned char const *)func, size);
47490cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao      }
47590cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao    }
47690cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao  }
47790cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao#endif
478da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
479da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
480da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Read pragma information from the metadata node of the module.
481da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (PragmaMetadata) {
482da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
483da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
484da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
485da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
486da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      if (Pragma != NULL &&
487da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
488da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
489da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
490da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
491da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
492da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
493da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          llvm::StringRef PragmaName =
494da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
495da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          llvm::StringRef PragmaValue =
496da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
497da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
498da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          pragmaList.push_back(
499da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            std::make_pair(std::string(PragmaName.data(),
500da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                                       PragmaName.size()),
501da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                           std::string(PragmaValue.data(),
502da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                                       PragmaValue.size())));
5039f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
5049f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao          LOGD("compile(): Pragma: %s -> %s\n",
5059f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao               pragmaList.back().first.c_str(),
5069f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao               pragmaList.back().second.c_str());
507749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao#endif
508da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        }
509da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      }
510da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    }
511da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
512da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
513da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (ObjectSlotMetadata) {
514da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
515da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
516da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
517da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
518da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      if (ObjectSlot != NULL &&
519da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          ObjectSlot->getNumOperands() == 1) {
520da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
521da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
522da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          llvm::StringRef Slot =
523da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien              static_cast<llvm::MDString*>(SlotMDS)->getString();
524da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          uint32_t USlot = 0;
525da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          if (Slot.getAsInteger(10, USlot)) {
526da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            setError("Non-integer object slot value '" + Slot.str() + "'");
527da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien            goto on_bcc_compile_error;
528da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          }
529da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien          objectSlotList.push_back(USlot);
5309f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
531749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao          LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
532749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao#endif
533da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien        }
534da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      }
535da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    }
536da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
537da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
538da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chienon_bcc_compile_error:
539da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // LOGE("on_bcc_compiler_error");
540da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (TD) {
541da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    delete TD;
542da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
543da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
544da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (TM) {
545da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    delete TM;
546da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
547da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
548da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (mError.empty()) {
549da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    return 0;
550da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
551da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
552da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // LOGE(getErrorMessage());
553da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return 1;
554da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
555da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
556da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
557da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
558da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chienint Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
559da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                         llvm::NamedMDNode const *ExportVarMetadata,
560da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                         llvm::NamedMDNode const *ExportFuncMetadata) {
5611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Create memory manager for creation of code emitter later.
5621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
5631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    setError("Failed to startup memory management for further compilation");
564da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    return 1;
5651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
56602286cbd7505ed355cb9b301326db51639789049Logan
56702286cbd7505ed355cb9b301326db51639789049Logan  mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
5681f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
5691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Create code emitter
5701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (!mCodeEmitter.get()) {
5711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    if (!createCodeEmitter()) {
572da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      setError("Failed to create machine code emitter for compilation");
573da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      return 1;
5741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
5751f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  } else {
5761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // Reuse the code emitter
5771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    mCodeEmitter->reset();
5781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
5791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
5801f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mCodeEmitter->setTargetMachine(*TM);
5811f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
5821f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan                                       mpSymbolLookupContext);
5831f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
5841f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Create code-gen pass to run the code emitter
585da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
586da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    new llvm::FunctionPassManager(mModule));
5871f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
588da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Add TargetData to code generation pass manager
589da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  CodeGenPasses->add(TD);
590da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
591da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Add code emit passes
5921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
5931f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan                                     *mCodeEmitter,
5941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan                                     CodeGenOptLevel)) {
595da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    setError("The machine code emission is not supported on '" + Triple + "'");
596da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    return 1;
5971f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
5981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
599da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Run the code emitter on every non-declaration function in the module
6001f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  CodeGenPasses->doInitialization();
601da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  for (llvm::Module::iterator
602da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien       I = mModule->begin(), E = mModule->end(); I != E; I++) {
6031f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    if (!I->isDeclaration()) {
6041f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      CodeGenPasses->run(*I);
6051f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
6061f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
6071f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
6081f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  CodeGenPasses->doFinalization();
609b0ceca26bf000b6d18289b8491b174ad3d1fc93aLogan Chien
6101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Copy the global address mapping from code emitter and remapping
6111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (ExportVarMetadata) {
6122a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
6132a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
6141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
6151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
6161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
6171f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
6181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
6191f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          llvm::StringRef ExportVarName =
6201f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
6211f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
6221f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          CodeEmitter::global_addresses_const_iterator I, E;
6231f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          for (I = mCodeEmitter->global_address_begin(),
6241f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan               E = mCodeEmitter->global_address_end();
6251f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan               I != E; I++) {
6261f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
6271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan              continue;
6281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            if (ExportVarName == I->first->getName()) {
6292a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan              varList.push_back(I->second);
6309f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
631749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao              LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
632749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao#endif
6331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan              break;
6341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            }
6351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          }
6361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          if (I != mCodeEmitter->global_address_end())
6371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            continue;  // found
6387d1bf58649eb8ddc3431f104dbde8cb5711b6ec9Logan Chien
6399f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
640749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao          LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
6417d1bf58649eb8ddc3431f104dbde8cb5711b6ec9Logan Chien               ExportVarName.str().c_str(), (void *)0);
642749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao#endif
6431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        }
6441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      }
6451f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      // if reaching here, we know the global variable record in metadata is
6461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      // not found. So we make an empty slot
6472a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan      varList.push_back(NULL);
6481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
6492a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
650bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines    bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
651bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines              "Number of slots doesn't match the number of export variables!");
6521f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
6531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
6541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  if (ExportFuncMetadata) {
6552a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
6562a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
6571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
6581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
6591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
6601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
6611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
6621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan          llvm::StringRef ExportFuncName =
6631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
6647dcaac9898741e701098537808296f4e2f2fb422Logan          funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
6659f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
666749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao          LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
6677d1bf58649eb8ddc3431f104dbde8cb5711b6ec9Logan Chien               funcList.back());
668749a51ca883cf7b0e181ec5ae2fb7d0fabca7c90Shih-wei Liao#endif
6691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan        }
6701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      }
6711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
6721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
6731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
6741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // Tell code emitter now can release the memory using during the JIT since
6751f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  // we have done the code emission
6761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  mCodeEmitter->releaseUnnecessary();
6771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
678da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return 0;
679da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
680da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif // USE_OLD_JIT
6812a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
6821f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
683da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
68434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wenint Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
685da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Decorate mEmittedELFExecutable with formatted ostream
686da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
6871f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
688da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Relax all machine instructions
689da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  TM->setMCRelaxAll(/* RelaxAll= */ true);
690da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
691da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Create MC code generation pass manager
692da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  llvm::PassManager MCCodeGenPasses;
693da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
694da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Add TargetData to MC code generation pass manager
695da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  MCCodeGenPasses.add(TD);
696da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
697da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  // Add MC code generation passes to pass manager
698094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  llvm::MCContext *Ctx = NULL;
699da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
700da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                            CodeGenOptLevel, false)) {
701da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    setError("Fail to add passes to emit file");
702da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    return 1;
7032a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan  }
7041f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
705da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  MCCodeGenPasses.run(*mModule);
706da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  OutSVOS.flush();
707da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return 0;
7081f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
709da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif // USE_MCJIT
7101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
7111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
712da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chienint Compiler::runLTO(llvm::TargetData *TD,
713da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                     llvm::NamedMDNode const *ExportVarMetadata,
714094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea                     llvm::NamedMDNode const *ExportFuncMetadata,
715094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea                     llvm::CodeGenOpt::Level OptimizationLevel) {
7164cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // Collect All Exported Symbols
7174cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  std::vector<const char*> ExportSymbols;
7184cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
7194cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // Note: This is a workaround for getting export variable and function name.
7204cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // We should refine it soon.
7214cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  if (ExportVarMetadata) {
7224cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
7234cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
7244cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
7254cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
7264cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
7274cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien          llvm::StringRef ExportVarName =
7284cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
7294cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien          ExportSymbols.push_back(ExportVarName.data());
7304cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        }
7314cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      }
7324cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien    }
7334cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  }
7344cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
7354cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  if (ExportFuncMetadata) {
7364cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
7374cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
7384cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
7394cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
7404cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
7414cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien          llvm::StringRef ExportFuncName =
7424cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
7434cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien          ExportSymbols.push_back(ExportFuncName.data());
7444cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien        }
7454cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien      }
7464cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien    }
7474cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  }
7484cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
7497890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  // TODO(logan): Remove this after we have finished the
7507890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  // bccMarkExternalSymbol API.
7517890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
7526416010e183301fc4243a2a1e43d7bcbd9dd7527Stephen Hines  // root(), init(), and .rs.dtor() are born to be exported
7534cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  ExportSymbols.push_back("root");
7544cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  ExportSymbols.push_back("init");
7556416010e183301fc4243a2a1e43d7bcbd9dd7527Stephen Hines  ExportSymbols.push_back(".rs.dtor");
7564cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
7577890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  // User-defined exporting symbols
7587890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  std::vector<char const *> const &UserDefinedExternalSymbols =
7597890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien    mpResult->getUserDefinedExternalSymbols();
7607890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
7617890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  std::copy(UserDefinedExternalSymbols.begin(),
7627890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien            UserDefinedExternalSymbols.end(),
7637890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien            std::back_inserter(ExportSymbols));
7647890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
765094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  llvm::PassManager LTOPasses;
766094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
767094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // Add TargetData to LTO passes
768094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  LTOPasses.add(TD);
769094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
7704cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // We now create passes list performing LTO. These are copied from
7714cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // (including comments) llvm::createStandardLTOPasses().
772094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // Only a subset of these LTO passes are enabled in optimization level 0
773094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // as they interfere with interactive debugging.
774094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
7754cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
776094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  if (OptimizationLevel != llvm::CodeGenOpt::None) {
777094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Internalize all other symbols not listed in ExportSymbols
778094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
7794cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
780094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Propagate constants at call sites into the functions they call. This
781094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // opens opportunities for globalopt (and inlining) by substituting
782094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // function pointers passed as arguments to direct uses of functions.
783094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createIPSCCPPass());
7844cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
785094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Now that we internalized some globals, see if we can hack on them!
786094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalOptimizerPass());
7874cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
788094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Linking modules together can lead to duplicated global constants, only
789094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // keep one copy of each constant...
790094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createConstantMergePass());
7914cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
792094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove unused arguments from functions...
793094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createDeadArgEliminationPass());
7944cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
795094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Reduce the code after globalopt and ipsccp. Both can open up
796094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // significant simplification opportunities, and both can propagate
797094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // functions through function pointers. When this happens, we often have
798094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // to resolve varargs calls, etc, so let instcombine do this.
799094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createInstructionCombiningPass());
8004cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
801094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Inline small functions
802094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createFunctionInliningPass());
8034cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
804094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead EH info.
805094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createPruneEHPass());
8064cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
807094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Internalize the globals again after inlining
808094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalOptimizerPass());
8094cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
810094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead functions.
811094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalDCEPass());
8124cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
813094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // If we didn't decide to inline a function, check to see if we can
814094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // transform it to pass arguments by value instead of by reference.
815094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createArgumentPromotionPass());
8164cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
817094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // The IPO passes may leave cruft around.  Clean up after them.
818094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createInstructionCombiningPass());
819094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createJumpThreadingPass());
8204cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
821094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Break up allocas
822094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createScalarReplAggregatesPass());
8234cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
824094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Run a few AA driven optimizations here and now, to cleanup the code.
825094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createFunctionAttrsPass());  // Add nocapture.
826094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
8274cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
828094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Hoist loop invariants.
829094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createLICMPass());
8304cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
831094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove redundancies.
832094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGVNPass());
8334cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
834094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead memcpys.
835094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createMemCpyOptPass());
8364cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
837094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Nuke dead stores.
838094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createDeadStoreEliminationPass());
8394cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
840094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Cleanup and simplify the code after the scalar optimizations.
841094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createInstructionCombiningPass());
8424cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
843094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createJumpThreadingPass());
8444cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
845094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Delete basic blocks, which optimization passes may have killed.
846094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createCFGSimplificationPass());
8474cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
848094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Now that we have optimized the program, discard unreachable functions.
849094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalDCEPass());
850094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
851094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  } else {
852094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
853094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createGlobalOptimizerPass());
854094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    LTOPasses.add(llvm::createConstantMergePass());
855094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
8564cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
8574cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  LTOPasses.run(*mModule);
858da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
859094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#if ANDROID_ENGINEERING_BUILD
860094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  if (0 != gDebugDumpDirectory) {
861094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    std::string errs;
862094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    std::string Filename(gDebugDumpDirectory);
863094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    Filename += "/post-lto-module.ll";
864094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    llvm::raw_fd_ostream FS(Filename.c_str(), errs);
865094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    mModule->print(FS, 0);
866094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    FS.close();
867094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
868094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#endif
869094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
870da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return 0;
871da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
872da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
873da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
874da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
875da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chienvoid *Compiler::getSymbolAddress(char const *name) {
876da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return rsloaderGetSymbolAddress(mRSExecutable, name);
877da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
878da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
879da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
880da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
881da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
882da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chienvoid *Compiler::resolveSymbolAdapter(void *context, char const *name) {
883da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  Compiler *self = reinterpret_cast<Compiler *>(context);
884da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
885da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (void *Addr = FindRuntimeFunction(name)) {
886da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    return Addr;
887da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
888da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
889da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  if (self->mpSymbolLookupFn) {
890da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
891da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien      return Addr;
892da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    }
893da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
894da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
895da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  LOGE("Unable to resolve symbol: %s\n", name);
896da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  return NULL;
897da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
898da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
8994cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
9004cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
9011f028c027b1df7fde0cd1a1eef9730856e8e5ae9LoganCompiler::~Compiler() {
9021f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  delete mModule;
9031f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  delete mContext;
904a4994f55617d251575013a41d5f9267fd68ce110Logan
905da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
906da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  rsloaderDisposeExec(mRSExecutable);
907da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
908da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
909a4994f55617d251575013a41d5f9267fd68ce110Logan  // llvm::llvm_shutdown();
9101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
9111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
91290cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao
9131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}  // namespace bcc
914