/*
 * 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.
 */

#ifndef BCC_COMPILER_H
#define BCC_COMPILER_H

namespace llvm {

class raw_ostream;
class PassManager;
class DataLayout;
class TargetMachine;

} // end namespace llvm

namespace bcc {

class CompilerConfig;
class OutputFile;
class Script;

//===----------------------------------------------------------------------===//
// Design of Compiler
//===----------------------------------------------------------------------===//
// 1. A compiler instance can be constructed provided an "initial config."
// 2. A compiler can later be re-configured using config().
// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e.,
//    mTarget) according to the configuration supplied. TargetMachine instance
//    is *shared* across the different calls to compile() before the next call
//    to config().
// 4. Once a compiler instance is created, you can use the compile() service
//    to compile the file over and over again. Each call uses TargetMachine
//    instance to construct the compilation passes.
class Compiler {
public:
  enum ErrorCode {
    kSuccess,

    kInvalidConfigNoTarget,
    kErrCreateTargetMachine,
    kErrSwitchTargetMachine,
    kErrNoTargetMachine,
    kErrDataLayoutNoMemory,
    kErrMaterialization,
    kErrInvalidOutputFileState,
    kErrPrepareOutput,
    kPrepareCodeGenPass,

    kErrHookBeforeAddLTOPasses,
    kErrHookAfterAddLTOPasses,
    kErrHookAfterExecuteLTOPasses,

    kErrHookBeforeAddCodeGenPasses,
    kErrHookAfterAddCodeGenPasses,
    kErrHookBeforeExecuteCodeGenPasses,
    kErrHookAfterExecuteCodeGenPasses,

    kErrInvalidSource
  };

  static const char *GetErrorString(enum ErrorCode pErrCode);

private:
  llvm::TargetMachine *mTarget;
  // LTO is enabled by default.
  bool mEnableLTO;

  enum ErrorCode runLTO(Script &pScript);
  enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult);

public:
  Compiler();
  Compiler(const CompilerConfig &pConfig);

  enum ErrorCode config(const CompilerConfig &pConfig);

  // Compile a script and output the result to a LLVM stream.
  //
  // @param IRStream If not NULL, the LLVM-IR that is fed to code generation
  //                 will be written to IRStream.
  enum ErrorCode compile(Script &pScript, llvm::raw_ostream &pResult,
                         llvm::raw_ostream *IRStream);

  // Compile a script and output the result to a file.
  enum ErrorCode compile(Script &pScript, OutputFile &pResult,
                         llvm::raw_ostream *IRStream = 0);

  const llvm::TargetMachine& getTargetMachine() const
  { return *mTarget; }

  void enableLTO(bool pEnable = true)
  { mEnableLTO = pEnable; }

  virtual ~Compiler();

protected:
  //===--------------------------------------------------------------------===//
  // Plugin callbacks for sub-class.
  //===--------------------------------------------------------------------===//
  // Called before adding first pass to code-generation passes.
  virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called after adding last pass to code-generation passes.
  virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called before executing code-generation passes.
  virtual bool beforeExecuteLTOPasses(Script &pScript,
                                          llvm::PassManager &pPM)
  { return true; }

  // Called after executing code-generation passes.
  virtual bool afterExecuteLTOPasses(Script &pScript)
  { return true; }

  // Called before adding first pass to code-generation passes.
  virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called after adding last pass to code-generation passes.
  virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called before executing code-generation passes.
  virtual bool beforeExecuteCodeGenPasses(Script &pScript,
                                          llvm::PassManager &pPM)
  { return true; }

  // Called after executing code-generation passes.
  virtual bool afterExecuteCodeGenPasses(Script &pScript)
  { return true; }
};

} // end namespace bcc

#endif // BCC_COMPILER_H
