Compiler.cpp revision 4a68b1cb89df9507584a51c3444aff99347afb74
11f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan/*
2db169187dea4602e4ad32058762d23d474753fd0Stephen Hines * Copyright 2010-2012, 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
172f6a493aea1b6e5ad318a759fedb58713a5a374cStephen Hines#include "Compiler.h"
181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "Config.h"
204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <bcinfo/MetadataExtractor.h>
214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if USE_DISASSEMBLER
234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "Disassembler/Disassembler.h"
244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "BCCRuntimeSymbolResolver.h"
272f6a493aea1b6e5ad318a759fedb58713a5a374cStephen Hines#include "DebugHelper.h"
284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "ScriptCompiled.h"
294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "Sha1Helper.h"
304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "CompilerOption.h"
314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "SymbolResolverProxy.h"
324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "SymbolResolvers.h"
3351001b86751c1ca36307eddc44a65336079fb698Joseph Wen
344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "librsloader.h"
351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "RSTransforms.h"
374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/ADT/StringRef.h"
394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Analysis/Passes.h"
414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/CodeGen/Passes.h"
434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/CodeGen/RegAllocRegistry.h"
444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/CodeGen/SchedulerRegistry.h"
454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/MC/MCContext.h"
474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/MC/SubtargetFeature.h"
484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Transforms/IPO.h"
504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Transforms/Scalar.h"
514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Target/TargetData.h"
534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Target/TargetMachine.h"
544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Support/ErrorHandling.h"
564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Support/FormattedStream.h"
574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Support/TargetRegistry.h"
584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Support/TargetSelect.h"
594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Support/raw_ostream.h"
604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Constants.h"
624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/GlobalValue.h"
634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Linker.h"
644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/LLVMContext.h"
654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Module.h"
664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/PassManager.h"
674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Type.h"
684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "llvm/Value.h"
694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <errno.h>
714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <sys/file.h>
724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <sys/stat.h>
734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <sys/types.h>
744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <unistd.h>
754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <string.h>
774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <algorithm>
794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <iterator>
804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <string>
814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <vector>
824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesextern char* gDebugDumpDirectory;
844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesnamespace bcc {
864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines//////////////////////////////////////////////////////////////////////////////
884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines// BCC Compiler Static Variables
894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines//////////////////////////////////////////////////////////////////////////////
904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool Compiler::GlobalInitialized = false;
921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
93fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang
944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if !defined(__HOST__)
954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  #define TARGET_TRIPLE_STRING  DEFAULT_TARGET_TRIPLE_STRING
964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#else
974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  #if defined(__cplusplus)
994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    extern "C" {
1004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  #endif
1014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
1024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  #if defined(__cplusplus)
1034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    };
1044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  #endif
1054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines// Code generation optimization level for the compiler
1084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesllvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
1094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesstd::string Compiler::Triple;
1114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesllvm::Triple::ArchType Compiler::ArchType;
1124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesstd::string Compiler::CPU;
1144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesstd::vector<std::string> Compiler::Features;
1164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines//////////////////////////////////////////////////////////////////////////////
1194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines// Compiler
1204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines//////////////////////////////////////////////////////////////////////////////
1214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesvoid Compiler::GlobalInitialization() {
1234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (GlobalInitialized) {
124fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang    return;
125fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang  }
1261f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if defined(PROVIDE_ARM_CODEGEN)
1284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeARMAsmPrinter();
1294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeARMTargetMC();
1304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeARMTargetInfo();
1314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeARMTarget();
1324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if defined(PROVIDE_MIPS_CODEGEN)
1354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeMipsAsmPrinter();
1364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeMipsTargetMC();
1374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeMipsTargetInfo();
1384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeMipsTarget();
1394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if defined(PROVIDE_X86_CODEGEN)
1424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeX86AsmPrinter();
1434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeX86TargetMC();
1444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeX86TargetInfo();
1454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LLVMInitializeX86Target();
1464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if USE_DISASSEMBLER
1494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  InitializeDisassembler();
1504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // if (!llvm::llvm_is_multithreaded())
1534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  //   llvm::llvm_start_multithreaded();
1544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Set Triple, CPU and Features here
1564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  Triple = TARGET_TRIPLE_STRING;
1574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Determine ArchType
1594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if defined(__HOST__)
1604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  {
1614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    std::string Err;
1624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
1634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    if (Target != NULL) {
1644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
1654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    } else {
1664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ArchType = llvm::Triple::UnknownArch;
1674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ALOGE("%s", Err.c_str());
1684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
1694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#elif defined(DEFAULT_ARM_CODEGEN)
1714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ArchType = llvm::Triple::arm;
1724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#elif defined(DEFAULT_MIPS_CODEGEN)
1734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ArchType = llvm::Triple::mipsel;
1744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#elif defined(DEFAULT_X86_CODEGEN)
1754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ArchType = llvm::Triple::x86;
1764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#elif defined(DEFAULT_X86_64_CODEGEN)
1774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ArchType = llvm::Triple::x86_64;
1784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#else
1794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ArchType = llvm::Triple::UnknownArch;
1804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
1814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
1834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  if defined(ARCH_ARM_HAVE_VFP)
1844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("+vfp3");
1854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  if !defined(ARCH_ARM_HAVE_VFP_D32)
1864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("+d16");
1874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  endif
1884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  endif
1894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  if defined(ARCH_ARM_HAVE_NEON)
1914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("+neon");
1924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("+neonfp");
1934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  else
1944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neon");
1954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neonfp");
1964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  endif
1974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines// FIXME(all): Turn NEON back on after debugging the rebase.
1994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
2004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neon");
2014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neonfp");
2024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#  endif
2034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Register the scheduler
2064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
2074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Read in SHA1 checksum of libbcc and libRS.
2094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
2104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  calcFileSHA1(sha1LibRS, pathLibRS);
2124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  GlobalInitialized = true;
2144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesvoid Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
2184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::string *Error = static_cast<std::string*>(UserData);
2194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  Error->assign(Message);
2204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ALOGE("%s", Message.c_str());
2214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  exit(1);
2224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2254a68b1cb89df9507584a51c3444aff99347afb74Stephen HinesCompiler::Compiler(ScriptCompiled *result)
2264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  : mpResult(result),
2274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mRSExecutable(NULL),
2284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mpSymbolLookupFn(NULL),
2294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mpSymbolLookupContext(NULL),
2304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mModule(NULL) {
2314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::remove_fatal_error_handler();
2324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
2331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  return;
2341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
2351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesint Compiler::readModule(llvm::Module &pModule) {
2374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mModule = &pModule;
2384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (pModule.getMaterializer() != NULL) {
2394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // A module with non-null materializer means that it is a lazy-load module.
2404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // Materialize it now via invoking MaterializeAllPermanently(). This
2414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // function returns false when the materialization is successful.
2424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    if (pModule.MaterializeAllPermanently(&mError)) {
2434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      setError("Failed to materialize the module `" +
2444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines               pModule.getModuleIdentifier() + "'! (" + mError + ")");
2454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      mModule = NULL;
2464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
2471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  }
2484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return hasError();
2494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesint Compiler::compile(const CompilerOption &option) {
2524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::Target const *Target = NULL;
2534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::TargetData *TD = NULL;
2544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::TargetMachine *TM = NULL;
2554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::string FeaturesStr;
2574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (mModule == NULL)  // No module was loaded
2594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return 0;
2604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  bcinfo::MetadataExtractor ME(mModule);
2624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ME.extract();
2634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t VarCount = ME.getExportVarCount();
2654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t FuncCount = ME.getExportFuncCount();
2664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t ForEachSigCount = ME.getExportForEachSignatureCount();
2674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t ObjectSlotCount = ME.getObjectSlotCount();
2684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t PragmaCount = ME.getPragmaCount();
2694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
2714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
2724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
2734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  RSInfo::ExportForeachFuncListTy ForEachFuncList;
2744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::vector<const char*> ExportSymbols;
2754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Defaults to maximum optimization level from MetadataExtractor.
2774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  uint32_t OptimizationLevel = ME.getOptimizationLevel();
2784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (OptimizationLevel == 0) {
2804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    CodeGenOptLevel = llvm::CodeGenOpt::None;
2814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } else if (OptimizationLevel == 1) {
2824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    CodeGenOptLevel = llvm::CodeGenOpt::Less;
2834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } else if (OptimizationLevel == 2) {
2844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    CodeGenOptLevel = llvm::CodeGenOpt::Default;
2854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } else if (OptimizationLevel == 3) {
2864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
287094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
288094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
2894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // not the best place for this, but we need to set the register allocation
2904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // policy after we read the optimization_level metadata from the bitcode
291094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
2924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Register allocation policy:
293094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  //  createFastRegisterAllocator: fast but bad quality
294094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  //  createLinearScanRegisterAllocator: not so fast but good quality
2954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::RegisterRegAlloc::setDefault
2964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
2974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines     llvm::createFastRegisterAllocator :
2984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines     llvm::createGreedyRegisterAllocator);
2994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Find LLVM Target
3014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
3024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (hasError())
3034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    goto on_bcc_compile_error;
3044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if defined(ARCH_ARM_HAVE_NEON)
3064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Full-precision means we have to disable NEON
3074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (ME.getRSFloatPrecision() == bcinfo::RS_FP_Full) {
3084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neon");
3094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Features.push_back("-neonfp");
310da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien  }
3114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
312da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
3134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!CPU.empty() || !Features.empty()) {
3144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    llvm::SubtargetFeatures F;
3151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
3164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (std::vector<std::string>::const_iterator
3174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines         I = Features.begin(), E = Features.end(); I != E; I++) {
3184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      F.AddFeature(*I);
3194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3201f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
3214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    FeaturesStr = F.getString();
3224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Create LLVM Target Machine
3254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
3264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                   option.TargetOpt,
3274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                   option.RelocModelOpt,
3284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                   option.CodeModelOpt);
3294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (TM == NULL) {
3314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    setError("Failed to create target machine implementation for the"
3324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             " specified triple '" + Triple + "'");
3334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    goto on_bcc_compile_error;
3344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Get target data from Module
3374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  TD = new llvm::TargetData(mModule);
3384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Read pragma information from MetadataExtractor
3404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (PragmaCount) {
3414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
3424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const char **PragmaKeys = ME.getPragmaKeyList();
3434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const char **PragmaValues = ME.getPragmaValueList();
3444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < PragmaCount; i++) {
3454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
3464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (VarCount) {
3504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const char **VarNames = ME.getExportVarNameList();
3514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < VarCount; i++) {
3524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      VarNameList.push_back(VarNames[i]);
3534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ExportSymbols.push_back(VarNames[i]);
3544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (FuncCount) {
3584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const char **FuncNames = ME.getExportFuncNameList();
3594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < FuncCount; i++) {
3604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      FuncNameList.push_back(FuncNames[i]);
3614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ExportSymbols.push_back(FuncNames[i]);
3624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (ForEachSigCount) {
3664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const char **ForEachNames = ME.getExportForEachNameList();
3674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
3684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < ForEachSigCount; i++) {
3694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ForEachFuncList.push_back(std::make_pair(ForEachNames[i],
3704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                               ForEachSigs[i]));
3714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ForEachExpandList.push_back(std::string(ForEachNames[i]) + ".expand");
3724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // Need to wait until ForEachExpandList is fully populated to fill in
3754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // exported symbols.
3764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < ForEachSigCount; i++) {
3774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ExportSymbols.push_back(ForEachExpandList[i].c_str());
3784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (ObjectSlotCount) {
3824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
3834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    const uint32_t *ObjectSlots = ME.getObjectSlotList();
3844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < ObjectSlotCount; i++) {
3854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      objectSlotList.push_back(ObjectSlots[i]);
3864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
3874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3881f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
3894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  runInternalPasses(ForEachFuncList);
390cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
3914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Perform link-time optimization if we have multiple modules
3924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (option.RunLTO) {
3934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
3944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3957890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
3964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Perform code generation
3974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
3984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    goto on_bcc_compile_error;
399fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang  }
4007890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
4014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!option.LoadAfterCompile)
4024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return 0;
4034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Load the ELF Object
4054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  {
4064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    BCCRuntimeSymbolResolver BCCRuntimesResolver;
4074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LookupFunctionSymbolResolver<void*> RSSymbolResolver(mpSymbolLookupFn,
4084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                                         mpSymbolLookupContext);
4094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    SymbolResolverProxy Resolver;
4114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Resolver.chainResolver(BCCRuntimesResolver);
4124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Resolver.chainResolver(RSSymbolResolver);
413094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
4144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mRSExecutable =
4154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines        rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
4164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                           mEmittedELFExecutable.size(),
4174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                           SymbolResolverProxy::LookupFunction, &Resolver);
418fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang  }
419094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
4204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!mRSExecutable) {
4214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    setError("Fail to load emitted ELF relocatable file");
4224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    goto on_bcc_compile_error;
4234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  rsloaderUpdateSectionHeaders(mRSExecutable,
4264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      (unsigned char*) mEmittedELFExecutable.begin());
4274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Once the ELF object has been loaded, populate the various slots for RS
4294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // with the appropriate relocated addresses.
4304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (VarCount) {
4314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
4324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < VarCount; i++) {
4334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
4344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                                 VarNameList[i].c_str()));
4354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
4364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (FuncCount) {
4394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
4404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < FuncCount; i++) {
4414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
4424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                                  FuncNameList[i].c_str()));
4434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
4444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (ForEachSigCount) {
4474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
4484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < ForEachSigCount; i++) {
4494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
4504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines          ForEachExpandList[i].c_str()));
4514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
4524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if DEBUG_MC_DISASSEMBLER
4554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  {
4564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // Get MC codegen emitted function name list
4574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
4584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    std::vector<char const *> func_list(func_list_size, NULL);
4594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
4604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // Disassemble each function
4624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    for (size_t i = 0; i < func_list_size; ++i) {
4634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
4644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      if (func) {
4654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines        size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
4664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines        Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
4674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                    Target, TM, func_list[i], (unsigned char const *)func, size);
4684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      }
4694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }
4704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
4724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hineson_bcc_compile_error:
4744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // ALOGE("on_bcc_compiler_error");
4754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (TD) {
4764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    delete TD;
4774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (TM) {
4804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    delete TM;
4814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (mError.empty()) {
4844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return 0;
4854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
4864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // ALOGE(getErrorMessage());
4884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return 1;
4894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
4904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesint Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
4934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Decorate mEmittedELFExecutable with formatted ostream
4944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
4954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Relax all machine instructions
4974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  TM->setMCRelaxAll(/* RelaxAll= */ true);
4984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
4994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Create MC code generation pass manager
5004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::PassManager MCCodeGenPasses;
5014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Add TargetData to MC code generation pass manager
5034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCCodeGenPasses.add(TD);
5044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Add MC code generation passes to pass manager
5064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::MCContext *Ctx = NULL;
5074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
5084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    setError("Fail to add passes to emit file");
5094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return 1;
5104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
5114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCCodeGenPasses.run(*mModule);
5134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OutSVOS.flush();
5144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return 0;
5154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
5164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesint Compiler::runInternalPasses(RSInfo::ExportForeachFuncListTy pForEachFuncs) {
5184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::PassManager BCCPasses;
5194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Expand ForEach on CPU path to reduce launch overhead.
5214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  BCCPasses.add(createRSForEachExpandPass(pForEachFuncs));
5224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  BCCPasses.run(*mModule);
5244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return 0;
5264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
5274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesint Compiler::runLTO(llvm::TargetData *TD,
5294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                     std::vector<const char*>& ExportSymbols,
5304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                     llvm::CodeGenOpt::Level OptimizationLevel) {
5314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Note: ExportSymbols is a workaround for getting all exported variable,
5324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // function, and kernel names.
5334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // We should refine it soon.
5344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // TODO(logan): Remove this after we have finished the
5364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // bccMarkExternalSymbol API.
5374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // root(), init(), and .rs.dtor() are born to be exported
5394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ExportSymbols.push_back("root");
5404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ExportSymbols.push_back("init");
5414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  ExportSymbols.push_back(".rs.dtor");
5424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // User-defined exporting symbols
5444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::vector<char const *> const &UserDefinedExternalSymbols =
5454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mpResult->getUserDefinedExternalSymbols();
5464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  std::copy(UserDefinedExternalSymbols.begin(),
5484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines            UserDefinedExternalSymbols.end(),
5494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines            std::back_inserter(ExportSymbols));
5504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  llvm::PassManager LTOPasses;
5524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Add TargetData to LTO passes
5544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LTOPasses.add(TD);
5554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5564cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  // We now create passes list performing LTO. These are copied from
5574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // (including comments) llvm::createStandardLTOPasses().
5584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Only a subset of these LTO passes are enabled in optimization level 0
5594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // as they interfere with interactive debugging.
5604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
5614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
5624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (OptimizationLevel != llvm::CodeGenOpt::None) {
5634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    // Internalize all other symbols not listed in ExportSymbols
5644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
5654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
566094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Propagate constants at call sites into the functions they call. This
567094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // opens opportunities for globalopt (and inlining) by substituting
568094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // function pointers passed as arguments to direct uses of functions.
5694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createIPSCCPPass());
5704cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
571094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Now that we internalized some globals, see if we can hack on them!
5724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalOptimizerPass());
5734cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
574094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Linking modules together can lead to duplicated global constants, only
575094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // keep one copy of each constant...
5764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createConstantMergePass());
5774cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
578094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove unused arguments from functions...
5794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createDeadArgEliminationPass());
5804cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
581094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Reduce the code after globalopt and ipsccp. Both can open up
582094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // significant simplification opportunities, and both can propagate
583094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // functions through function pointers. When this happens, we often have
584094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // to resolve varargs calls, etc, so let instcombine do this.
5854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createInstructionCombiningPass());
5864cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
587094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Inline small functions
5884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createFunctionInliningPass());
5894cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
590094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead EH info.
5914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createPruneEHPass());
5924cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
593094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Internalize the globals again after inlining
5944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalOptimizerPass());
5954cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
596094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead functions.
5974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalDCEPass());
5984cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
599094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // If we didn't decide to inline a function, check to see if we can
600094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // transform it to pass arguments by value instead of by reference.
6014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createArgumentPromotionPass());
6024cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
603094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // The IPO passes may leave cruft around.  Clean up after them.
6044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createInstructionCombiningPass());
6054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createJumpThreadingPass());
6064cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
607094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Break up allocas
6084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createScalarReplAggregatesPass());
6094cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
610094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Run a few AA driven optimizations here and now, to cleanup the code.
6114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createFunctionAttrsPass());  // Add nocapture.
6124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
6134cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
614094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Hoist loop invariants.
6154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createLICMPass());
6164cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
617094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove redundancies.
6184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGVNPass());
6194cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
620094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Remove dead memcpys.
6214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createMemCpyOptPass());
6224cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
623094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Nuke dead stores.
6244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createDeadStoreEliminationPass());
6254cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
626094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Cleanup and simplify the code after the scalar optimizations.
6274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createInstructionCombiningPass());
6284cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
6294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createJumpThreadingPass());
6304cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
631094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Delete basic blocks, which optimization passes may have killed.
6324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createCFGSimplificationPass());
6334cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
634094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea    // Now that we have optimized the program, discard unreachable functions.
6354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalDCEPass());
636fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang
6374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } else {
6384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
6394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createGlobalOptimizerPass());
6404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    LTOPasses.add(llvm::createConstantMergePass());
641094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
6424cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
6434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  LTOPasses.run(*mModule);
644da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
6454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#if ANDROID_ENGINEERING_BUILD
6464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (0 != gDebugDumpDirectory) {
6474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    std::string errs;
6484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    std::string Filename(gDebugDumpDirectory);
6494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    Filename += "/post-lto-module.ll";
6504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    llvm::raw_fd_ostream FS(Filename.c_str(), errs);
6514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mModule->print(FS, 0);
6524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    FS.close();
653094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea  }
6544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#endif
655094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea
6564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return 0;
657da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
658da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
659da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
6604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesvoid *Compiler::getSymbolAddress(char const *name) {
6614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return rsloaderGetSymbolAddress(mRSExecutable, name);
662da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien}
663da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
6644a68b1cb89df9507584a51c3444aff99347afb74Stephen HinesCompiler::~Compiler() {
6654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  rsloaderDisposeExec(mRSExecutable);
666fef9a1b0b772034b4f0894d1e2b29d1115617be0Zonr Chang
6674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // llvm::llvm_shutdown();
6681f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
6691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
67090cd3d1ec93c46389c00cd41375608632dd4ceb5Shih-wei Liao
6714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}  // namespace bcc
672