Revert "Make libbcc public."

This reverts commit 80232dd16c0affb2afae01cde6c94abf23ac1ba8.
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
new file mode 100644
index 0000000..2348d56
--- /dev/null
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Compiler.h"
+
+#include <llvm/Analysis/Passes.h>
+#include <llvm/CodeGen/RegAllocRegistry.h>
+#include <llvm/Module.h>
+#include <llvm/PassManager.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Transforms/IPO.h>
+#include <llvm/Transforms/Scalar.h>
+
+#include "CompilerConfig.h"
+#include "DebugHelper.h"
+#include "OutputFile.h"
+#include "Script.h"
+#include "Source.h"
+
+using namespace bcc;
+
+const char *Compiler::GetErrorString(enum ErrorCode pErrCode) {
+  static const char *ErrorString[] = {
+    /* kSuccess */
+    "Successfully compiled.",
+    /* kInvalidConfigNoTarget */
+    "Invalid compiler config supplied (getTarget() returns NULL.) "
+    "(missing call to CompilerConfig::initialize()?)",
+    /* kErrCreateTargetMachine */
+    "Failed to create llvm::TargetMachine.",
+    /* kErrSwitchTargetMachine */
+    "Failed to switch llvm::TargetMachine.",
+    /* kErrNoTargetMachine */
+    "Failed to compile the script since there's no available TargetMachine."
+    " (missing call to Compiler::config()?)",
+    /* kErrTargetDataNoMemory */
+    "Out of memory when create TargetData during compilation.",
+    /* kErrMaterialization */
+    "Failed to materialize the module.",
+    /* kErrInvalidOutputFileState */
+    "Supplied output file was invalid (in the error state.)",
+    /* kErrPrepareOutput */
+    "Failed to prepare file for output.",
+    /* kPrepareCodeGenPass */
+    "Failed to construct pass list for code-generation.",
+
+    /* kErrHookBeforeAddLTOPasses */
+    "Error occurred during beforeAddLTOPasses() in subclass.",
+    /* kErrHookAfterAddLTOPasses */
+    "Error occurred during afterAddLTOPasses() in subclass.",
+    /* kErrHookBeforeExecuteLTOPasses */
+    "Error occurred during beforeExecuteLTOPasses() in subclass.",
+    /* kErrHookAfterExecuteLTOPasses */
+    "Error occurred during afterExecuteLTOPasses() in subclass.",
+
+    /* kErrHookBeforeAddCodeGenPasses */
+    "Error occurred during beforeAddCodeGenPasses() in subclass.",
+    /* kErrHookAfterAddCodeGenPasses */
+    "Error occurred during afterAddCodeGenPasses() in subclass.",
+    /* kErrHookBeforeExecuteCodeGenPasses */
+    "Error occurred during beforeExecuteCodeGenPasses() in subclass.",
+    /* kErrHookAfterExecuteCodeGenPasses */
+    "Error occurred during afterExecuteCodeGenPasses() in subclass.",
+
+    /* kMaxErrorCode */
+    "(Unknown error code)"
+  };
+
+  if (pErrCode > kMaxErrorCode) {
+    pErrCode = kMaxErrorCode;
+  }
+
+  return ErrorString[ static_cast<size_t>(pErrCode) ];
+}
+
+//===----------------------------------------------------------------------===//
+// Instance Methods
+//===----------------------------------------------------------------------===//
+Compiler::Compiler() : mTarget(NULL), mEnableLTO(true) {
+  return;
+}
+
+Compiler::Compiler(const CompilerConfig &pConfig) : mTarget(NULL),
+                                                    mEnableLTO(true) {
+  const std::string &triple = pConfig.getTriple();
+
+  enum ErrorCode err = config(pConfig);
+  if (err != kSuccess) {
+    ALOGE("%s (%s, features: %s)", GetErrorString(err),
+          triple.c_str(), pConfig.getFeatureString().c_str());
+    return;
+  }
+
+  return;
+}
+
+enum Compiler::ErrorCode Compiler::config(const CompilerConfig &pConfig) {
+  if (pConfig.getTarget() == NULL) {
+    return kInvalidConfigNoTarget;
+  }
+
+  llvm::TargetMachine *new_target =
+      (pConfig.getTarget())->createTargetMachine(pConfig.getTriple(),
+                                                 pConfig.getCPU(),
+                                                 pConfig.getFeatureString(),
+                                                 pConfig.getTargetOptions(),
+                                                 pConfig.getRelocationModel(),
+                                                 pConfig.getCodeModel(),
+                                                 pConfig.getOptimizationLevel());
+
+  if (new_target == NULL) {
+    return ((mTarget != NULL) ? kErrSwitchTargetMachine :
+                                kErrCreateTargetMachine);
+  }
+
+  // Replace the old TargetMachine.
+  delete mTarget;
+  mTarget = new_target;
+
+  // Adjust register allocation policy according to the optimization level.
+  //  createFastRegisterAllocator: fast but bad quality
+  //  createLinearScanRegisterAllocator: not so fast but good quality
+  if ((pConfig.getOptimizationLevel() == llvm::CodeGenOpt::None)) {
+    llvm::RegisterRegAlloc::setDefault(llvm::createFastRegisterAllocator);
+  } else {
+    llvm::RegisterRegAlloc::setDefault(llvm::createGreedyRegisterAllocator);
+  }
+
+  // Relax all machine instructions.
+  mTarget->setMCRelaxAll(true);
+
+  return kSuccess;
+}
+
+Compiler::~Compiler() {
+  delete mTarget;
+}
+
+enum Compiler::ErrorCode Compiler::runLTO(Script &pScript) {
+  llvm::TargetData *target_data = NULL;
+
+  // Pass manager for link-time optimization
+  llvm::PassManager lto_passes;
+
+  // Prepare TargetData target data from Module
+  target_data = new (std::nothrow) llvm::TargetData(*mTarget->getTargetData());
+  if (target_data == NULL) {
+    return kErrTargetDataNoMemory;
+  }
+
+  // Add TargetData to the pass manager.
+  lto_passes.add(target_data);
+
+  // Invokde "beforeAddLTOPasses" before adding the first pass.
+  if (!beforeAddLTOPasses(pScript, lto_passes)) {
+    return kErrHookBeforeAddLTOPasses;
+  }
+
+  // We now create passes list performing LTO. These are copied from
+  // (including comments) llvm::PassManagerBuilder::populateLTOPassManager().
+  // Only a subset of these LTO passes are enabled in optimization level 0 as
+  // they interfere with interactive debugging.
+  //
+  // FIXME: Figure out which passes (if any) makes sense for levels 1 and 2.
+  //if ( != llvm::CodeGenOpt::None) {
+  if (mTarget->getOptLevel() == llvm::CodeGenOpt::None) {
+    lto_passes.add(llvm::createGlobalOptimizerPass());
+    lto_passes.add(llvm::createConstantMergePass());
+  } else {
+    // Propagate constants at call sites into the functions they call. This
+    // opens opportunities for globalopt (and inlining) by substituting
+    // function pointers passed as arguments to direct uses of functions.
+    lto_passes.add(llvm::createIPSCCPPass());
+
+    // Now that we internalized some globals, see if we can hack on them!
+    lto_passes.add(llvm::createGlobalOptimizerPass());
+
+    // Linking modules together can lead to duplicated global constants, only
+    // keep one copy of each constant...
+    lto_passes.add(llvm::createConstantMergePass());
+
+    // Remove unused arguments from functions...
+    lto_passes.add(llvm::createDeadArgEliminationPass());
+
+    // Reduce the code after globalopt and ipsccp. Both can open up
+    // significant simplification opportunities, and both can propagate
+    // functions through function pointers. When this happens, we often have
+    // to resolve varargs calls, etc, so let instcombine do this.
+    lto_passes.add(llvm::createInstructionCombiningPass());
+
+    // Inline small functions
+    lto_passes.add(llvm::createFunctionInliningPass());
+
+    // Remove dead EH info.
+    lto_passes.add(llvm::createPruneEHPass());
+
+    // Internalize the globals again after inlining
+    lto_passes.add(llvm::createGlobalOptimizerPass());
+
+    // Remove dead functions.
+    lto_passes.add(llvm::createGlobalDCEPass());
+
+    // If we didn't decide to inline a function, check to see if we can
+    // transform it to pass arguments by value instead of by reference.
+    lto_passes.add(llvm::createArgumentPromotionPass());
+
+    // The IPO passes may leave cruft around.  Clean up after them.
+    lto_passes.add(llvm::createInstructionCombiningPass());
+    lto_passes.add(llvm::createJumpThreadingPass());
+
+    // Break up allocas
+    lto_passes.add(llvm::createScalarReplAggregatesPass());
+
+    // Run a few AA driven optimizations here and now, to cleanup the code.
+    lto_passes.add(llvm::createFunctionAttrsPass());  // Add nocapture.
+    lto_passes.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
+
+    // Hoist loop invariants.
+    lto_passes.add(llvm::createLICMPass());
+
+    // Remove redundancies.
+    lto_passes.add(llvm::createGVNPass());
+
+    // Remove dead memcpys.
+    lto_passes.add(llvm::createMemCpyOptPass());
+
+    // Nuke dead stores.
+    lto_passes.add(llvm::createDeadStoreEliminationPass());
+
+    // Cleanup and simplify the code after the scalar optimizations.
+    lto_passes.add(llvm::createInstructionCombiningPass());
+
+    lto_passes.add(llvm::createJumpThreadingPass());
+
+    // Delete basic blocks, which optimization passes may have killed.
+    lto_passes.add(llvm::createCFGSimplificationPass());
+
+    // Now that we have optimized the program, discard unreachable functions.
+    lto_passes.add(llvm::createGlobalDCEPass());
+  }
+
+  // Invokde "afterAddLTOPasses" after pass manager finished its
+  // construction.
+  if (!afterAddLTOPasses(pScript, lto_passes)) {
+    return kErrHookAfterAddLTOPasses;
+  }
+
+  // Invokde "beforeExecuteLTOPasses" before executing the passes.
+  if (!beforeExecuteLTOPasses(pScript, lto_passes)) {
+    return kErrHookBeforeExecuteLTOPasses;
+  }
+
+  lto_passes.run(pScript.getSource().getModule());
+
+  // Invokde "afterExecuteLTOPasses" before returning.
+  if (!afterExecuteLTOPasses(pScript)) {
+    return kErrHookAfterExecuteLTOPasses;
+  }
+
+  return kSuccess;
+}
+
+enum Compiler::ErrorCode Compiler::runCodeGen(Script &pScript,
+                                              llvm::raw_ostream &pResult) {
+  llvm::TargetData *target_data;
+  llvm::MCContext *mc_context = NULL;
+
+  // Create pass manager for MC code generation.
+  llvm::PassManager codegen_passes;
+
+  // Prepare TargetData target data from Module
+  target_data = new (std::nothrow) llvm::TargetData(*mTarget->getTargetData());
+  if (target_data == NULL) {
+    return kErrTargetDataNoMemory;
+  }
+
+  // Add TargetData to the pass manager.
+  codegen_passes.add(target_data);
+
+  // Invokde "beforeAddCodeGenPasses" before adding the first pass.
+  if (!beforeAddCodeGenPasses(pScript, codegen_passes)) {
+    return kErrHookBeforeAddCodeGenPasses;
+  }
+
+  // Add passes to the pass manager to emit machine code through MC layer.
+  if (mTarget->addPassesToEmitMC(codegen_passes, mc_context, pResult,
+                                 /* DisableVerify */false)) {
+    return kPrepareCodeGenPass;
+  }
+
+  // Invokde "afterAddCodeGenPasses" after pass manager finished its
+  // construction.
+  if (!afterAddCodeGenPasses(pScript, codegen_passes)) {
+    return kErrHookAfterAddCodeGenPasses;
+  }
+
+  // Invokde "beforeExecuteCodeGenPasses" before executing the passes.
+  if (!beforeExecuteCodeGenPasses(pScript, codegen_passes)) {
+    return kErrHookBeforeExecuteCodeGenPasses;
+  }
+
+  // Execute the pass.
+  codegen_passes.run(pScript.getSource().getModule());
+
+  // Invokde "afterExecuteCodeGenPasses" before returning.
+  if (!afterExecuteCodeGenPasses(pScript)) {
+    return kErrHookAfterExecuteCodeGenPasses;
+  }
+
+  return kSuccess;
+}
+
+enum Compiler::ErrorCode Compiler::compile(Script &pScript,
+                                           llvm::raw_ostream &pResult) {
+  llvm::Module &module = pScript.getSource().getModule();
+  enum ErrorCode err;
+
+  if (mTarget == NULL) {
+    return kErrNoTargetMachine;
+  }
+
+  // Materialize the bitcode module.
+  if (module.getMaterializer() != NULL) {
+    std::string error;
+    // A module with non-null materializer means that it is a lazy-load module.
+    // Materialize it now via invoking MaterializeAllPermanently(). This
+    // function returns false when the materialization is successful.
+    if (module.MaterializeAllPermanently(&error)) {
+      ALOGE("Failed to materialize the module `%s'! (%s)",
+            module.getModuleIdentifier().c_str(), error.c_str());
+      return kErrMaterialization;
+    }
+  }
+
+  if (mEnableLTO && ((err = runLTO(pScript)) != kSuccess)) {
+    return err;
+  }
+
+  if ((err = runCodeGen(pScript, pResult)) != kSuccess) {
+    return err;
+  }
+
+  return kSuccess;
+}
+
+enum Compiler::ErrorCode Compiler::compile(Script &pScript,
+                                           OutputFile &pResult) {
+  // Check the state of the specified output file.
+  if (pResult.hasError()) {
+    return kErrInvalidOutputFileState;
+  }
+
+  // Open the output file decorated in llvm::raw_ostream.
+  llvm::raw_ostream *out = pResult.dup();
+  if (out == NULL) {
+    return kErrPrepareOutput;
+  }
+
+  // Delegate the request.
+  enum Compiler::ErrorCode err = compile(pScript, *out);
+
+  // Close the output before return.
+  delete out;
+
+  return err;
+}