//===-- LLVM Code Emitter Interface -----------------------------*- C++ -*-===//
//
//                      High Level Virtual Machine (HLVM)
//
// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
//
// This software is free software; you can redistribute it and/or modify it 
// under the terms of the GNU Lesser General Public License as published by 
// the Free Software Foundation; either version 2.1 of the License, or (at 
// your option) any later version.
//
// This software is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
// more details.
//
// You should have received a copy of the GNU Lesser General Public License 
// along with this library in the file named LICENSE.txt; if not, write to the 
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
// MA 02110-1301 USA
//
//===----------------------------------------------------------------------===//
/// @file hlvm/CodeGen/LLVMEmitter.h
/// @author Reid Spencer <rspencer@reidspencer.com> (original author)
/// @date 2006/07/09
/// @since 0.2.0
/// @brief Declares the interface for emitting LLVM code
//===----------------------------------------------------------------------===//

#ifndef HLVM_CODEGEN_LLVMEMITTER_H
#define HLVM_CODEGEN_LLVMEMITTER_H

// Include the LLVM classes that we use
#include <llvm/Module.h>
#include <llvm/PassManager.h>
#include <llvm/BasicBlock.h>
#include <llvm/Function.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Instructions.h>
#include <llvm/DerivedTypes.h>
#include <llvm/TypeSymbolTable.h>
#include <llvm/Constants.h>
#include <llvm/CallingConv.h>
#include "llvm/Support/DataTypes.h"
#include <vector>

namespace hlvm {

/// A simple list of LLVM Modules
typedef std::vector<llvm::Module*> ModuleList;

/// A List of LLVM Branch Instructions. These are used to record unconditional
/// branches that need to be fixed up later with LLVMEmitter::ResolveBranches.
typedef std::vector<llvm::BranchInst*> BranchList;

/// A list of LLVM Blocks, presumably used in a push/pop stack fashion.
typedef std::vector<llvm::BasicBlock*> BlockStack;

/// A list of LLVM Values, used for argument lists
typedef std::vector<llvm::Value*> ArgList;

/// A list of LLVM types, used for function types
typedef std::vector<const llvm::Type*> TypeList;

/// This class provides utility functions for emitting LLVM code. It has no
/// concept of how to translate HLVM into LLVM, that logic is in LLVMGenerator
/// class. This class just keeps track of things in the LLVM world and provides
/// a group of methods to take care of the details of emitting LLVM code. The
/// main purpose for this class is simply to unclutter LLVMGenerator.
class LLVMEmitter 
{
  /// @name Constructors
  /// @{
  protected:
    LLVMEmitter();

  /// @}
  /// @name Function Emission
  /// @{
  public:

    // Start a new modules
    llvm::Module* StartModule(const std::string& ID);

    // Finish the started module
    llvm::Module* FinishModule();

    /// Start a new function. This sets up the context of the emitter to start
    /// generating code for function \p F.
    void StartFunction(llvm::Function* F);

    /// Finish the function previously started. This must be called after a call
    /// to StartFunction. Mostly this just checks that the generated function is
    /// sane.
    void FinishFunction();

    /// Add a type to the module
    void AddType(const llvm::Type* Ty, const std::string& name)
    {
      TheModule->addTypeName(name, Ty);
    }

    /// Add a Function to the module
    llvm::Function* NewFunction(
      const llvm::FunctionType* Ty, 
      llvm::GlobalValue::LinkageTypes LT,
      const std::string& name) 
    { 
      return new llvm::Function(Ty, LT, name, TheModule); 
    }

    /// Add a global variable to the module
    llvm::GlobalVariable* NewGVar(
      const llvm::Type* Ty, 
      llvm::GlobalValue::LinkageTypes LT,
      llvm::Constant* init, 
      const std::string& name)
    {
      return new llvm::GlobalVariable(Ty, false, LT, init, name, TheModule);
    }
    /// Add a global constant to the module
    llvm::GlobalVariable* NewGConst(
      const llvm::Type* Ty, 
      llvm::Constant* init, 
      const std::string& name)
    {
      return new llvm::GlobalVariable(Ty, true,
         llvm::GlobalValue::InternalLinkage, init, name, TheModule);
    }

    /// Create a new AllocaInst in the entry block with the given name and type.
    /// The Type must have a fixed/constant size.
    llvm::AllocaInst* NewAutoVar(const llvm::Type* Ty, const std::string& name)
    {
      return new llvm::AllocaInst(Ty, 0, name, EntryInsertionPoint);
    }

    /// Add the specified basic block to the end of the function.  If
    /// the previous block falls through into it, add an explicit branch.  Also,
    /// manage fixups for EH info.
    void EmitBlock(llvm::BasicBlock *BB);
    
    /// Create a new LLVM block with the given \p name and push it onto the
    /// block stack.
    llvm::BasicBlock* pushBlock(const std::string& name);

    /// Pop a block off the block stack and return it.
    llvm::BasicBlock* popBlock();

    /// Replace the top of the block stack with a new block with the given
    /// \p name
    llvm::BasicBlock* newBlock(const std::string& name);

  /// @}
  /// @name Simple Helper Functions
  /// @{
  public: 
    /// Get the current module we're building
    llvm::Module* getModule() const { return TheModule; }

    /// Get the current function we're building
    llvm::Function* getFunction() const { return TheFunction; }

    /// Get the current block we are filling
    llvm::BasicBlock* getBlock() const { return TheBlock; }

    /// Get the name of the current block we're inserting into
    std::string getBlockName() const { 
      return TheBlock->getName(); 
    }
    // Get the terminating instruction of the current block
    llvm::Instruction* getBlockTerminator() const { 
      return TheBlock->getTerminator();
    }
    // Get the return type of the current function
    const llvm::Type* getReturnType() const {
      return TheFunction->getReturnType();
    }

    /// Return the total number of elements in the Type, examining recursively,
    /// any nested aggregate types.
    unsigned getNumElements(const llvm::Type *Ty);

    /// Return a constant expression for indexing into the first element of
    /// a constant global variable.
    llvm::Constant* getFirstElement(llvm::GlobalVariable* GV);

    /// If V is a PointerType then load its value unless the referent type is
    /// not first class type
    llvm::Value* Pointer2Value(llvm::Value* V) const;

    /// Convert the value V into a Boolean value.
    llvm::Value* ConvertToBoolean(llvm::Value* V) const;

    /// Run through the \p list and set the first operand of each branch
    /// instruction found there to the \p exit block. This presumes that the
    /// branch instruction is unconditional.
    void ResolveBreaks(llvm::BasicBlock* exit);
    void ResolveContinues(llvm::BasicBlock* entry);

    /// Return true if a cast from V to Ty does not change any bits.
    static bool IsNoopCast(llvm::Value *V, const llvm::Type *Ty);

    /// Cast the \p V  to \p Ty if it is not already that type.
    llvm::Value *CastToType(llvm::Value *V, bool isSigned, 
                            const llvm::Type *Ty, bool isSigned,
                            const std::string& newName);

    static void TwoZeroIndices(ArgList& indices) {
      indices.clear();
      indices.push_back(llvm::ConstantInt::getNullValue(llvm::Type::Int32Ty));
      indices.push_back(llvm::ConstantInt::getNullValue(llvm::Type::Int32Ty));
    }

    /// Convert a non-first-class type into a first-class type by constructing
    /// a pointer to the original type.
    const llvm::Type* getFirstClassType(const llvm::Type* Ty) {
      if (!Ty->isFirstClassType())
        return llvm::PointerType::get(Ty);
      return Ty;
    }

    /// Get an LLVM FunctionType for the corresponding arguments. This handles
    /// the details of converting non-first-class arguments and results into
    /// the appropriate pointers to those types and making the first function
    /// argument a pointer to the result storage, if necessary.
    llvm::FunctionType* getFunctionType(
      const std::string& name,       ///< The name to give the function type
      const llvm::Type* resultTy,    ///< The type of the function's result
      const TypeList& args,          ///< The list of the function's arguments
      bool varargs                   ///< Whether its a varargs function or not
    );

    llvm::Type* getTextType();
    llvm::Type* getStreamType();
    llvm::Type* getBufferType();
    llvm::FunctionType* getProgramType();

  /// @}
  /// @name Simple Value getters
  /// @{
  public:
    llvm::Constant* getTrue() const  { return llvm::ConstantInt::getTrue(); }
    llvm::Constant* getFalse() const { return llvm::ConstantInt::getFalse(); }
    llvm::Constant* getZero() const { 
      return llvm::ConstantInt::getNullValue(llvm::Type::Int32Ty);
    }
    llvm::Constant* getFOne() const { 
      return llvm::ConstantFP::get(llvm::Type::FloatTy,1.0);
    }
    llvm::Constant* getDOne() const { 
      return llvm::ConstantFP::get(llvm::Type::DoubleTy,1.0);
    }
    llvm::Constant* getFPOne(const llvm::Type* Ty) const {
      return llvm::ConstantFP::get(Ty,1.0);
    }
    llvm::Constant* getOne(const llvm::Type* Ty) const {
      return llvm::ConstantInt::get(Ty,1);
    }
    llvm::Constant* getSVal(const llvm::Type* Ty, int64_t val) const {
      return llvm::ConstantInt::get(Ty,val);
    }
    llvm::Constant* getUVal(const llvm::Type* Ty, uint64_t val) const {
      return llvm::ConstantInt::get(Ty,val);
    }
    llvm::Constant* getNullValue(const llvm::Type* Ty) const { 
      return llvm::Constant::getNullValue(Ty);
    }
    llvm::Constant* getAllOnes(const llvm::Type* Ty) const {
      return llvm::ConstantInt::getAllOnesValue(Ty);
    }
  /// @}
  /// @name Simple emitters
  /// @{
  public:
    llvm::CmpInst* emitNE(llvm::Value* V1, llvm::Value* V2);
    llvm::CmpInst* emitEQ(llvm::Value* V1, llvm::Value* V2);
    llvm::CmpInst* emitLT(llvm::Value* V1, llvm::Value* V2, bool sign = false);
    llvm::CmpInst* emitGT(llvm::Value* V1, llvm::Value* V2, bool sign = false);
    llvm::CmpInst* emitLE(llvm::Value* V1, llvm::Value* V2, bool sign = false);
    llvm::CmpInst* emitGE(llvm::Value* V1, llvm::Value* V2, bool sign = false);

    llvm::LoadInst* emitLoad(llvm::Value* V, const std::string& name) const {
      return new llvm::LoadInst(V, name, TheBlock);
    }
    llvm::StoreInst* emitStore(llvm::Value* from, llvm::Value* to) const {
      return new llvm::StoreInst(from, to, TheBlock);
    }
    llvm::BinaryOperator* emitNeg(llvm::Value* V) const {
      return llvm::BinaryOperator::createNeg(V,"neg",TheBlock);
    }
    llvm::BinaryOperator* emitCmpl(llvm::Value* V) const {
      return llvm::BinaryOperator::create(llvm::Instruction::Xor,
        V, getAllOnes(V->getType()), "cmpl", TheBlock);
    }
    llvm::Constant* emitSizeOf(llvm::Value* V1) {
      return llvm::ConstantExpr::getSizeOf(V1->getType());
    }
    llvm::Constant* emitSizeof(llvm::Type* Ty) {
      return llvm::ConstantExpr::getSizeOf(Ty);
    }
    llvm::BinaryOperator* emitAdd(llvm::Value* V1, llvm::Value* V2) {
      return llvm::BinaryOperator::createAdd(V1, V2, "add", TheBlock);
    }
    llvm::BinaryOperator* emitSub(llvm::Value* V1, llvm::Value* V2) {
      return llvm::BinaryOperator::createSub(V1, V2, "sub", TheBlock);
    }
    llvm::BinaryOperator* emitMul(llvm::Value* V1, llvm::Value* V2) {
      return llvm::BinaryOperator::createMul(V1, V2, "mul", TheBlock);
    }
    llvm::BinaryOperator* emitSDiv(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createSDiv(V1, V2, "div", TheBlock);
    }
    llvm::BinaryOperator* emitUDiv(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createUDiv(V1, V2, "div", TheBlock);
    }
    llvm::BinaryOperator* emitSRem(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createSRem(V1, V2, "mod", TheBlock);
    }
    llvm::BinaryOperator* emitURem(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createURem(V1, V2, "mod", TheBlock);
    }
    llvm::BinaryOperator* emitBAnd(llvm::Value*V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createAnd(V1, V2, "band", TheBlock);
    }
    llvm::BinaryOperator* emitBOr(llvm::Value*V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createOr(V1, V2, "bor", TheBlock);
    }
    llvm::BinaryOperator* emitBXor(llvm::Value*V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::createXor(V1, V2, "bxor", TheBlock);
    }
    llvm::BinaryOperator* emitBNor(llvm::Value* V1, llvm::Value* V2) const {
      llvm::BinaryOperator* bor = 
        llvm::BinaryOperator::createOr(V1, V2, "bnor", TheBlock);
      return llvm::BinaryOperator::createNot(bor,"bnor",TheBlock);
    }
    llvm::BinaryOperator* emitNot(llvm::Value* V1) const {
      return llvm::BinaryOperator::createNot(
        ConvertToBoolean(V1),"not",TheBlock);
    }
    llvm::BinaryOperator* emitAnd(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::create(llvm::Instruction::And, 
        ConvertToBoolean(V1), ConvertToBoolean(V2), "and", TheBlock);
    }
    llvm::BinaryOperator* emitOr(llvm::Value* V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::create(llvm::Instruction::Or, 
        ConvertToBoolean(V1), ConvertToBoolean(V2), "or", TheBlock);
    }
    llvm::BinaryOperator* emitXor(llvm::Value*V1, llvm::Value* V2) const {
      return llvm::BinaryOperator::create(llvm::Instruction::Xor, 
        ConvertToBoolean(V1), ConvertToBoolean(V2), "xor", TheBlock);
    }
    llvm::BinaryOperator* emitNor(llvm::Value* V1, llvm::Value* V2) const {
      llvm::BinaryOperator* op = llvm::BinaryOperator::create(
        llvm::Instruction::Or, ConvertToBoolean(V1), ConvertToBoolean(V2), 
        "nor", TheBlock);
      return llvm::BinaryOperator::createNot(op,"nor",TheBlock);
    }
    llvm::SelectInst* emitSelect(llvm::Value* V1, llvm::Value* V2, 
      llvm::Value* V3, const std::string& name) {
      return new llvm::SelectInst(V1,V2,V3,name,TheBlock);
    }
    llvm::BranchInst* emitBranch(llvm::BasicBlock* blk) {
      return new llvm::BranchInst(blk,TheBlock);
    }
    llvm::BranchInst* emitBreak() {
      llvm::BranchInst* brnch = new llvm::BranchInst(TheBlock,TheBlock);
      breaks.push_back(brnch);
      return brnch;
    }
    llvm::BranchInst* emitContinue() {
      llvm::BranchInst* brnch = new llvm::BranchInst(TheBlock,TheBlock);
      continues.push_back(brnch);
      return brnch;
    }

    llvm::ReturnInst* emitReturn(llvm::Value* V);

    llvm::CallInst* emitCall(llvm::Function* F, const ArgList& args); 

    llvm::GetElementPtrInst* emitGEP(llvm::Value* V, const ArgList& indices) {
      return new llvm::GetElementPtrInst(V, &indices[0], indices.size(), "",
                                         TheBlock);
    }

    llvm::GetElementPtrInst* emitGEP(llvm::Value* V, llvm::Value* index) {
      llvm::Value* indices[2];
      indices[0] = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
      indices[1] = index;
      return new llvm::GetElementPtrInst(V, indices, 2, "",TheBlock);
    }

    /// This method implements an assignment of a src value to a pointer to a
    /// destination value. It handles all cases from a simple store instruction
    /// for first class types, to construction of temporary global variables 
    /// for assignment of constant aggregates to variables.
    void emitAssign(llvm::Value* dest, llvm::Value* src);

    /// Copy one aggregate to another. This method will use individual load and
    /// store instructions for small aggregates or the llvm.memcpy intrinsic for
    /// larger ones.
    void emitAggregateCopy(
      llvm::Value *DestPtr,  ///< Pointer to destination aggregate
      llvm::Value *SrcPtr    ///< Pointer to source aggregate
    );

    /// Emit an llvm.memcpy.i64 intrinsic
    void emitMemCpy(
      llvm::Value *dest,  ///< A Pointer type value to receive the data
      llvm::Value *src,   ///< A Pointer type value that is the data source
      llvm::Value *size   ///< A ULong Type value to specify # of bytes to copy
    );

    /// Emit an llvm.memmove.i64 intrinsic
    void emitMemMove(
      llvm::Value *dest,  ///< A Pointer type value to receive the data
      llvm::Value *src,   ///< A Pointer type value that is the data source
      llvm::Value *size   ///< A ULong Type value to specify # of bytes to move
    );

    /// Emit an llvm.memset.i64 intrinsic
    void emitMemSet(
      llvm::Value *dest,  ///< A Pointer type value to receive the data
      llvm::Value *val,   ///< An integer type that specifies the byte to set
      llvm::Value *size   ///< A ULong Type value to specif # of bytes to set
    );

  /// @}
  /// @name Emitters for Stream Operations
  /// @{
  public:
    llvm::CallInst* emitOpen(llvm::Value* strm);
    llvm::CallInst* emitClose(llvm::Value* strm);
    llvm::CallInst* emitRead(llvm::Value* strm,llvm::Value* V2,llvm::Value* V3);
    llvm::CallInst* emitWrite(llvm::Value* strm,llvm::Value*V2);

  /// @}
  /// @name Emitters for Math functions
  /// @{
  public:
    llvm::CallInst* emitIsPInf(llvm::Value* V);
    llvm::CallInst* emitIsNInf(llvm::Value* V);
    llvm::CallInst* emitIsNan(llvm::Value* V);
    llvm::CallInst* emitTrunc(llvm::Value* V);
    llvm::CallInst* emitRound(llvm::Value* V);
    llvm::CallInst* emitFloor(llvm::Value* V);
    llvm::CallInst* emitCeiling(llvm::Value* V);
    llvm::CallInst* emitLogE(llvm::Value* V);
    llvm::CallInst* emitLog2(llvm::Value* V);
    llvm::CallInst* emitLog10(llvm::Value* V);
    llvm::CallInst* emitSquareRoot(llvm::Value* V);
    llvm::CallInst* emitCubeRoot(llvm::Value* V);
    llvm::CallInst* emitFactorial(llvm::Value* V);
    llvm::CallInst* emitPower(llvm::Value* V1,llvm::Value*V2);
    llvm::CallInst* emitRoot(llvm::Value* V1,llvm::Value*V2);
    llvm::CallInst* emitGCD(llvm::Value* V1,llvm::Value*V2);
    llvm::CallInst* emitLCM(llvm::Value* V1,llvm::Value*V2);

  /// @}
  /// @name Other miscellaneous functions
  /// @{
  public:

    /// Return the unique ID of the specified basic
    /// block for uses that take the address of it.
    llvm::Constant *getIndirectGotoBlockNumber(llvm::BasicBlock *BB);
    
    /// Get (and potentially lazily create) the indirect
    /// goto block.
    llvm::BasicBlock *getIndirectGotoBlock();
    
    /// Zero the elements of DestPtr.
    void EmitAggregateZero(llvm::Value *DestPtr);
                           
    /// Emit an unconditional branch to the specified basic block, running 
    /// cleanups if the branch exits scopes.  The argument specify
    /// how to handle these cleanups.
    void EmitBranchInternal(llvm::BasicBlock *Dest, bool IsExceptionEdge);

    /// Add the specified unconditional branch to the fixup list for the 
    /// outermost exception scope, merging it if there is already a fixup that 
    /// works.
    void AddBranchFixup(llvm::BranchInst *BI, bool isExceptionEdge);

  /// @}
  /// @name Data Members
  /// @{
  protected:
    BlockStack blocks;              ///< The stack of nested blocks 
    BranchList breaks;              ///< The list of breaks to fix up later
    BranchList continues;           ///< The list of continues to fix up later
    llvm::Module *TheModule;        ///< The module that we are compiling into.
    llvm::Function * TheFunction;   ///< The function we're constructing
    llvm::BasicBlock* TheEntryBlock;///< The function's entry block
    llvm::BasicBlock* TheExitBlock; ///< The function's exit (return) block
    llvm::Instruction* EntryInsertionPoint; ///< Insertion point for entry stuff
    llvm::BasicBlock* TheBlock;     ///< The current block we're building
  /// @}
};

extern LLVMEmitter* new_LLVMEmitter();

} // end hlvm namespace

#endif
