/* Internal interfaces between the LLVM backend components
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Chris Lattner  (sabre@nondot.org)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC 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 General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

//===----------------------------------------------------------------------===//
// This is a C++ header file that defines the internal interfaces shared among
// the llvm-*.cpp files.
//===----------------------------------------------------------------------===//

#ifndef LLVM_INTERNAL_H
#define LLVM_INTERNAL_H

// LLVM headers
#include "llvm/CallingConv.h"
#include "llvm/Intrinsics.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/raw_os_ostream.h"

// System headers
#include <vector>
#include <cassert>
#include <string>

namespace llvm {
  class Module;
  class GlobalVariable;
  class Function;
  class GlobalValue;
  class BasicBlock;
  class Instruction;
  class AllocaInst;
  class BranchInst;
  class Value;
  class Constant;
  class ConstantInt;
  class Type;
  class FunctionType;
  class TargetMachine;
  class TargetData;
  class DebugInfo;
  template<typename> class AssertingVH;
  template<typename> class TrackingVH;
}
using namespace llvm;

typedef IRBuilder<true, TargetFolder> LLVMBuilder;

// Global state.

/// TheModule - This is the current global module that we are compiling into.
///
extern llvm::Module *TheModule;

/// TheDebugInfo - This object is responsible for gather all debug information.
/// If it's value is NULL then no debug information should be gathered.
extern llvm::DebugInfo *TheDebugInfo;

/// TheTarget - The current target being compiled for.
///
extern llvm::TargetMachine *TheTarget;

/// TheFolder - The constant folder to use.
extern TargetFolder *TheFolder;

/// getTargetData - Return the current TargetData object from TheTarget.
const TargetData &getTargetData();

/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
extern SmallSetVector<Constant *,32> AttributeUsedGlobals;

extern Constant* ConvertMetadataStringToGV(const char* str);

/// AddAnnotateAttrsToGlobal - Adds decls that have a
/// annotate attribute to a vector to be emitted later.
extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, union tree_node* decl);

// Mapping between GCC declarations and LLVM values.  The GCC declaration must
// satisfy HAS_RTL_P.

/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
extern Value *make_decl_llvm(union tree_node *);
#define DECL_LLVM(NODE) make_decl_llvm(NODE)

/// SET_DECL_LLVM - Set the DECL_LLVM for NODE to LLVM.
extern Value *set_decl_llvm(union tree_node *, Value *);
#define SET_DECL_LLVM(NODE, LLVM) set_decl_llvm(NODE, LLVM)

/// DECL_LLVM_IF_SET - The DECL_LLVM for NODE, if it is set, or NULL, if it is
/// not set.
extern Value *get_decl_llvm(union tree_node *);
#define DECL_LLVM_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_llvm(NODE) : NULL)

/// DECL_LLVM_SET_P - Returns nonzero if the DECL_LLVM for NODE has already
/// been set.
#define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)

/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
/// global will be output, and returns a declaration for it.
Value *make_definition_llvm(union tree_node *decl);
#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)

// Mapping between GCC declarations and non-negative integers.  The GCC
// declaration must not satisfy HAS_RTL_P.

/// set_decl_index - Associate a non-negative number with the given GCC
/// declaration.
int set_decl_index(union tree_node *, int);

/// get_decl_index - Get the non-negative number associated with the given GCC
/// declaration.  Returns a negative value if no such association has been made.
int get_decl_index(union tree_node *);

void changeLLVMConstant(Constant *Old, Constant *New);
void register_ctor_dtor(Function *, int, bool);
void readLLVMTypesStringTable();
void writeLLVMTypesStringTable();
void readLLVMValues();
void writeLLVMValues();
void clearTargetBuiltinCache();
const char* extractRegisterName(union tree_node*);
void handleVisibility(union tree_node* decl, GlobalValue *GV);
Twine getLLVMAssemblerName(union tree_node *);

struct StructTypeConversionInfo;

/// Return true if and only if field no. N from struct type T is a padding
/// element added to match llvm struct type size and gcc struct type size.
bool isPaddingElement(union tree_node*, unsigned N);

/// TypeConverter - Implement the converter from GCC types to LLVM types.
///
class TypeConverter {
  /// ConvertingStruct - If we are converting a RECORD or UNION to an LLVM type
  /// we set this flag to true.
  bool ConvertingStruct;

  /// PointersToReresolve - When ConvertingStruct is true, we handling of
  /// POINTER_TYPE and REFERENCE_TYPE is changed to return
  /// opaque*'s instead of recursively calling ConvertType.  When this happens,
  /// we add the POINTER_TYPE to this list.
  ///
  std::vector<tree_node*> PointersToReresolve;
public:
  TypeConverter() : ConvertingStruct(false) {}

  /// ConvertType - Returns the LLVM type to use for memory that holds a value
  /// of the given GCC type (GetRegType should be used for values in registers).
  const Type *ConvertType(tree_node *type);

  /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
  /// has any data that overlaps with structure padding in the specified LLVM
  /// type.
  static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);


  /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
  /// tree to an LLVM type.  This does the same thing that ConvertType does, but
  /// it also returns the function's LLVM calling convention and attributes.
  const FunctionType *ConvertFunctionType(tree_node *type,
                                          tree_node *decl,
                                          tree_node *static_chain,
                                          CallingConv::ID &CallingConv,
                                          AttrListPtr &PAL);

  /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
  /// return the LLVM type corresponding to the function.  This is useful for
  /// turning "T foo(...)" functions into "T foo(void)" functions.
  const FunctionType *ConvertArgListToFnType(tree_node *type,
                                             tree_node *arglist,
                                             tree_node *static_chain,
                                             CallingConv::ID &CallingConv,
                                             AttrListPtr &PAL);

private:
  const Type *ConvertRECORD(tree_node *type);
  bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info);
  void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info);
  void SelectUnionMember(tree_node *type, StructTypeConversionInfo &Info);
};

extern TypeConverter *TheTypeConverter;

/// ConvertType - Returns the LLVM type to use for memory that holds a value
/// of the given GCC type (GetRegType should be used for values in registers).
inline const Type *ConvertType(tree_node *type) {
  return TheTypeConverter->ConvertType(type);
}

/// GetFieldIndex - Return the index of the field in the given LLVM type that
/// corresponds to the GCC field declaration 'decl'.  This means that the LLVM
/// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
/// that its first bit is within the byte the LLVM field starts at).  Returns
/// INT_MAX if there is no such LLVM field.
int GetFieldIndex(union tree_node *decl, const Type *Ty);

/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
///
uint64_t getINTEGER_CSTVal(tree_node *exp);

/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
/// If Unsigned is false, returns whether it fits in a int64_t.  If Unsigned is
/// true, returns whether the value is non-negative and fits in a uint64_t.
/// Always returns false for overflowed constants or if t is NULL.
bool isInt64(tree_node *t, bool Unsigned);

/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer.  If
/// Unsigned is false, the value must fit in a int64_t.  If Unsigned is true,
/// the value must be non-negative and fit in a uint64_t.  Must not be used on
/// overflowed constants.  These conditions can be checked by calling isInt64.
uint64_t getInt64(tree_node *t, bool Unsigned);

/// isPassedByInvisibleReference - Return true if the specified type should be
/// passed by 'invisible reference'. In other words, instead of passing the
/// thing by value, pass the address of a temporary.
bool isPassedByInvisibleReference(tree_node *type);

/// isSequentialCompatible - Return true if the specified gcc array or pointer
/// type and the corresponding LLVM SequentialType lay out their components
/// identically in memory, so doing a GEP accesses the right memory location.
/// We assume that objects without a known size do not.
inline bool isSequentialCompatible(tree_node *type) {
  assert((TREE_CODE(type) == ARRAY_TYPE ||
          TREE_CODE(type) == POINTER_TYPE ||
          TREE_CODE(type) == REFERENCE_TYPE) && "not a sequential type!");
  // This relies on gcc types with constant size mapping to LLVM types with the
  // same size.  It is possible for the component type not to have a size:
  // struct foo;  extern foo bar[];
  return isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
}

/// OffsetIsLLVMCompatible - Return true if the given field is offset from the
/// start of the record by a constant amount which is not humongously big.
inline bool OffsetIsLLVMCompatible(tree_node *field_decl) {
  return isInt64(DECL_FIELD_OFFSET(field_decl), true);
}

/// ArrayLengthOf - Returns the length of the given gcc array type, or ~0ULL if
/// the array has variable or unknown length.
inline uint64_t ArrayLengthOf(tree_node *type) {
  assert(TREE_CODE(type) == ARRAY_TYPE && "Only for array types!");
  // If the element type has variable size and the array type has variable
  // length, but by some miracle the product gives a constant size, then we
  // also return ~0ULL here.  I can live with this, and I bet you can too!
  if (!isInt64(TYPE_SIZE(type), true) ||
      !isInt64(TYPE_SIZE(TREE_TYPE(type)), true))
    return ~0ULL;
  // May return zero for arrays that gcc considers to have non-zero length, but
  // only if the array type has zero size (this can happen if the element type
  // has zero size), in which case the discrepancy doesn't matter.
  //
  // If the user increased the alignment of the element type, then the size of
  // the array type is rounded up by that alignment, but the size of the element
  // is not.  Since gcc requires the user alignment to be strictly smaller than
  // the element size, this does not impact the length computation.
  return integer_zerop(TYPE_SIZE(type)) ?  0 : getInt64(TYPE_SIZE(type), true) /
    getInt64(TYPE_SIZE(TREE_TYPE(type)), true);
}

/// isBitfield - Returns whether to treat the specified field as a bitfield.
bool isBitfield(tree_node *field_decl);

/// getFieldOffsetInBits - Return the bit offset of a FIELD_DECL in a structure.
inline uint64_t getFieldOffsetInBits(tree_node *field) {
  assert(OffsetIsLLVMCompatible(field) && "Offset is not constant!");
  uint64_t Result = getInt64(DECL_FIELD_BIT_OFFSET(field), true);
  Result += getInt64(DECL_FIELD_OFFSET(field), true) * BITS_PER_UNIT;
  return Result;
}

/// getDeclaredType - Get the declared type for the specified field, and
/// not the shrunk-to-fit type that GCC gives us in TREE_TYPE.
tree_node *getDeclaredType(tree_node *field_decl);

/// ValidateRegisterVariable - Check that a static "asm" variable is
/// well-formed.  If not, emit error messages and return true.  If so, return
/// false.
bool ValidateRegisterVariable(tree_node *decl);

/// MemRef - This struct holds the information needed for a memory access:
/// a pointer to the memory, its alignment and whether the access is volatile.
class MemRef {
public:
  Value *Ptr;
  bool Volatile;
private:
  unsigned char LogAlign;
public:
  explicit MemRef() : Ptr(0), Volatile(false), LogAlign(0) {}
  explicit MemRef(Value *P, uint32_t A, bool V) : Ptr(P), Volatile(V) {
    // Forbid alignment 0 along with non-power-of-2 alignment values.
    assert(isPowerOf2_32(A) && "Alignment not a power of 2!");
    LogAlign = Log2_32(A);
  }

  uint32_t getAlignment() const {
    return 1U << LogAlign;
  }
};

/// LValue - This struct represents an lvalue in the program.  In particular,
/// the Ptr member indicates the memory that the lvalue lives in.  Alignment
/// is the alignment of the memory (in bytes).If this is a bitfield reference,
/// BitStart indicates the first bit in the memory that is part of the field
/// and BitSize indicates the extent.
///
/// "LValue" is intended to be a light-weight object passed around by-value.
class LValue : public MemRef {
public:
  unsigned char BitStart;
  unsigned char BitSize;
public:
  explicit LValue() : BitStart(255), BitSize(255) {}
  explicit LValue(MemRef &M) : MemRef(M), BitStart(255), BitSize(255) {}
  LValue(Value *P, uint32_t A, bool V = false) :
      MemRef(P, A, V), BitStart(255), BitSize(255) {}
  LValue(Value *P, uint32_t A, unsigned BSt, unsigned BSi, bool V = false) :
      MemRef(P, A, V), BitStart(BSt), BitSize(BSi) {
    assert(BitStart == BSt && BitSize == BSi &&
           "Bit values larger than 256?");
  }

  bool isBitfield() const { return BitStart != 255; }
};

/// PhiRecord - This struct holds the LLVM PHI node associated with a GCC phi.
struct PhiRecord {
  gimple gcc_phi;
  PHINode *PHI;
};

/// TreeToLLVM - An instance of this class is created and used to convert the
/// body of each function to LLVM.
///
class TreeToLLVM {
  // State that is initialized when the function starts.
  const TargetData &TD;
  tree_node *FnDecl;
  Function *Fn;
  BasicBlock *ReturnBB;
  unsigned ReturnOffset;

  // State that changes as the function is emitted.

  /// Builder - Instruction creator, the location to insert into is always the
  /// same as &Fn->back().
  LLVMBuilder Builder;

  // AllocaInsertionPoint - Place to insert alloca instructions.  Lazily created
  // and managed by CreateTemporary.
  Instruction *AllocaInsertionPoint;

  // SSAInsertionPoint - Place to insert reads corresponding to SSA default
  // definitions.
  Instruction *SSAInsertionPoint;

  /// BasicBlocks - Map from GCC to LLVM basic blocks.
  DenseMap<basic_block, BasicBlock*> BasicBlocks;

  /// LocalDecls - Map from local declarations to their associated LLVM values.
  DenseMap<tree_node *, AssertingVH<Value> > LocalDecls;

  /// PendingPhis - Phi nodes which have not yet been populated with operands.
  SmallVector<PhiRecord, 16> PendingPhis;

  // SSANames - Map from GCC ssa names to the defining LLVM value.
  DenseMap<tree_node *, TrackingVH<Value> > SSANames;

public:

  //===---------------------- Local Declarations --------------------------===//

  /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
  /// function.  However DECL_LOCAL can be used with declarations local to the
  /// current function as well as with global declarations.
  Value *make_decl_local(union tree_node *);
  #define DECL_LOCAL(NODE) make_decl_local(NODE)

  /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
  /// body of a variable or function will be output.  However DEFINITION_LOCAL
  /// can be used with declarations local to the current function as well as
  /// with global declarations.
  Value *make_definition_local(union tree_node *);
  #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)

  /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM.
  Value *set_decl_local(union tree_node *, Value *);
  #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)

  /// DECL_LOCAL_IF_SET - The DECL_LOCAL for NODE, if it is set, or NULL, if it
  /// is not set.
  Value *get_decl_local(union tree_node *);
  #define DECL_LOCAL_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_local(NODE) : NULL)

  /// DECL_LOCAL_SET_P - Returns nonzero if the DECL_LOCAL for NODE has already
  /// been set.
  #define DECL_LOCAL_SET_P(NODE) (DECL_LOCAL_IF_SET(NODE) != NULL)


private:

  //===---------------------- Exception Handling --------------------------===//

  /// NormalInvokes - Mapping from landing pad number to the set of invoke
  /// instructions that unwind to that landing pad.
  SmallVector<SmallVector<InvokeInst *, 8>, 16> NormalInvokes;

  /// ExceptionPtrs - Mapping from EH region index to the local holding the
  /// exception pointer for that region.
  SmallVector<AllocaInst *, 16> ExceptionPtrs;

  /// ExceptionFilters - Mapping from EH region index to the local holding the
  /// filter value for that region.
  SmallVector<AllocaInst *, 16> ExceptionFilters;

  /// FailureBlocks - Mapping from the index of a must-not-throw EH region to
  /// the block containing the failure code for the region (the code that is
  /// run if an exception is thrown in this region).
  SmallVector<BasicBlock *, 16> FailureBlocks;

  /// RewindBB - Block containing code that continues unwinding an exception.
  BasicBlock *RewindBB;

  /// RewindTmp - Local holding the exception to continue unwinding.
  AllocaInst *RewindTmp;

public:
  TreeToLLVM(tree_node *fndecl);
  ~TreeToLLVM();

  /// getFUNCTION_DECL - Return the FUNCTION_DECL node for the current function
  /// being compiled.
  tree_node *getFUNCTION_DECL() const { return FnDecl; }

  /// EmitFunction - Convert 'fndecl' to LLVM code.
  Function *EmitFunction();

  /// EmitBasicBlock - Convert the given basic block.
  void EmitBasicBlock(basic_block bb);

  /// EmitLV - Convert the specified l-value tree node to LLVM code, returning
  /// the address of the result.
  LValue EmitLV(tree_node *exp);

  void TODO(tree_node *exp = 0);

  /// CastToAnyType - Cast the specified value to the specified type regardless
  /// of the types involved. This is an inferred cast.
  Value *CastToAnyType (Value *V, bool VSigned, const Type* Ty, bool TySigned);

  /// CastToUIntType - Cast the specified value to the specified type assuming
  /// that V's type and Ty are integral types. This arbitrates between BitCast,
  /// Trunc and ZExt.
  Value *CastToUIntType(Value *V, const Type* Ty);

  /// CastToSIntType - Cast the specified value to the specified type assuming
  /// that V's type and Ty are integral types. This arbitrates between BitCast,
  /// Trunc and SExt.
  Value *CastToSIntType(Value *V, const Type* Ty);

  /// CastToFPType - Cast the specified value to the specified type assuming
  /// that V's type and Ty are floating point types. This arbitrates between
  /// BitCast, FPTrunc and FPExt.
  Value *CastToFPType(Value *V, const Type* Ty);

  /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type.  Does
  /// not support complex numbers.  The type is used to set overflow flags.
  Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);

  /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
  /// Does not support complex numbers.  The type is used to set overflow flags.
  Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);

  /// CreateAnyNeg - Negate an LLVM scalar value with the given GCC type.  Does
  /// not support complex numbers.  The type is used to set overflow flags.
  Value *CreateAnyNeg(Value *V, tree_node *type);

  /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
  /// Does not support complex numbers.
  Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);

  /// CreateTemporary - Create a new alloca instruction of the specified type,
  /// inserting it into the entry block and returning it.  The resulting
  /// instruction's type is a pointer to the specified type.
  AllocaInst *CreateTemporary(const Type *Ty);

  /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
  MemRef CreateTempLoc(const Type *Ty);

  /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
  /// GCC type specified by GCCType to know which elements to copy.
  void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);

  /// EmitAggregate - Store the specified tree node into the location given by
  /// DestLoc.
  void EmitAggregate(tree_node *exp, const MemRef &DestLoc);

private: // Helper functions.

  /// StartFunctionBody - Start the emission of 'fndecl', outputing all
  /// declarations for parameters and setting things up.
  void StartFunctionBody();

  /// FinishFunctionBody - Once the body of the function has been emitted, this
  /// cleans up and returns the result function.
  Function *FinishFunctionBody();

  /// PopulatePhiNodes - Populate generated phi nodes with their operands.
  void PopulatePhiNodes();

  /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
  BasicBlock *getBasicBlock(basic_block bb);

  /// getLabelDeclBlock - Lazily get and create a basic block for the specified
  /// label.
  BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);

  /// DefineSSAName - Use the given value as the definition of the given SSA
  /// name.  Returns the provided value as a convenience.
  Value *DefineSSAName(tree_node *reg, Value *Val);

  /// BeginBlock - Add the specified basic block to the end of the function.  If
  /// the previous block falls through into it, add an explicit branch.
  void BeginBlock(BasicBlock *BB);

  /// EmitAggregateZero - Zero the elements of DestLoc.
  void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);

  /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
  /// llvm.memset call with the specified operands.  Returns DestPtr bitcast
  /// to i8*.
  Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
  Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
  Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);

  /// EmitLandingPads - Emit EH landing pads.
  void EmitLandingPads();

  /// EmitFailureBlocks - Emit the blocks containing failure code executed when
  /// an exception is thrown in a must-not-throw region.
  void EmitFailureBlocks();

  /// EmitRewindBlock - Emit the block containing code to continue unwinding an
  /// exception.
  void EmitRewindBlock();

  /// EmitDebugInfo - Return true if debug info is to be emitted for current
  /// function.
  bool EmitDebugInfo();

private: // Helpers for exception handling.

  /// getLandingPad - Return the landing pad for the given exception handling
  /// region, creating it if necessary.
  BasicBlock *getLandingPad(unsigned RegionNo);

  /// getExceptionPtr - Return the local holding the exception pointer for the
  /// given exception handling region, creating it if necessary.
  AllocaInst *getExceptionPtr(unsigned RegionNo);

  /// getExceptionFilter - Return the local holding the filter value for the
  /// given exception handling region, creating it if necessary.
  AllocaInst *getExceptionFilter(unsigned RegionNo);

  /// getFailureBlock - Return the basic block containing the failure code for
  /// the given exception handling region, creating it if necessary.
  BasicBlock *getFailureBlock(unsigned RegionNo);

private:
  void EmitAutomaticVariableDecl(tree_node *decl);

  /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
  void EmitAnnotateIntrinsic(Value *V, tree_node *decl);

  /// EmitTypeGcroot - Emits call to make type a gcroot
  void EmitTypeGcroot(Value *V, tree_node *decl);

private:

  //===------------------ Render* - Convert GIMPLE to LLVM ----------------===//

  void RenderGIMPLE_ASM(gimple stmt);
  void RenderGIMPLE_ASSIGN(gimple stmt);
  void RenderGIMPLE_CALL(gimple stmt);
  void RenderGIMPLE_COND(gimple stmt);
  void RenderGIMPLE_EH_DISPATCH(gimple stmt);
  void RenderGIMPLE_GOTO(gimple stmt);
  void RenderGIMPLE_RESX(gimple stmt);
  void RenderGIMPLE_RETURN(gimple stmt);
  void RenderGIMPLE_SWITCH(gimple stmt);

  // Render helpers.

  /// EmitAssignRHS - Convert the RHS of a scalar GIMPLE_ASSIGN to LLVM.
  Value *EmitAssignRHS(gimple stmt);

  /// EmitAssignSingleRHS - Helper for EmitAssignRHS.  Handles those RHS that
  /// are not register expressions.
  Value *EmitAssignSingleRHS(tree_node *rhs);

  /// OutputCallRHS - Convert the RHS of a GIMPLE_CALL.
  Value *OutputCallRHS(gimple stmt, const MemRef *DestLoc);

  /// WriteScalarToLHS - Store RHS, a non-aggregate value, into the given LHS.
  void WriteScalarToLHS(tree_node *lhs, Value *Scalar);

private:

  //===---------- EmitReg* - Convert register expression to LLVM ----------===//

  /// GetRegType - Returns the LLVM type to use for registers that hold a value
  /// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
  /// determine the LLVM type to return.
  const Type *GetRegType(tree_node *type);

  /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
  /// defines the GCC middle-end type system.  For scalar GCC types inner_type
  /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
  /// true then the corresponding LLVM inner and outer types (see GetRegType)
  /// are equal except possibly if they are both pointer types (casts to 'void*'
  /// are considered useless for example) or types derived from pointer types
  /// (vector types with pointer element type are the only possibility here).
  /// This method converts LLVM values of the inner type to the outer type.
  Value *UselesslyTypeConvert(Value *V, const Type *Ty) {
    return Builder.CreateBitCast(V, Ty);
  }

  /// EmitRegister - Convert the specified gimple register or local constant of
  /// register type to an LLVM value.  Only creates code in the entry block.
  Value *EmitRegister(tree_node *reg);

  /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
  /// Only creates code in the entry block.
  Value *EmitReg_SSA_NAME(tree_node *reg);

  // Unary expressions.
  Value *EmitReg_ABS_EXPR(tree_node *op);
  Value *EmitReg_BIT_NOT_EXPR(tree_node *op);
  Value *EmitReg_CONJ_EXPR(tree_node *op);
  Value *EmitReg_CONVERT_EXPR(tree_node *type, tree_node *op);
  Value *EmitReg_NEGATE_EXPR(tree_node *op);
  Value *EmitReg_PAREN_EXPR(tree_node *exp);
  Value *EmitReg_TRUTH_NOT_EXPR(tree_node *type, tree_node *op);

  // Comparisons.

  /// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
  /// The result is an i1 boolean.
  Value *EmitCompare(tree_node *lhs, tree_node *rhs, tree_code code);

  // Binary expressions.
  Value *EmitReg_MinMaxExpr(tree_node *type, tree_node *op0, tree_node* op1,
                            unsigned UIPred, unsigned SIPred, unsigned Opc,
                            bool isMax);
  Value *EmitReg_RotateOp(tree_node *type, tree_node *op0, tree_node *op1,
                          unsigned Opc1, unsigned Opc2);
  Value *EmitReg_ShiftOp(tree_node *op0, tree_node* op1, unsigned Opc);
  Value *EmitReg_TruthOp(tree_node *type, tree_node *op0, tree_node *op1,
                         unsigned Opc);
  Value *EmitReg_BIT_AND_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_BIT_IOR_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_BIT_XOR_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_CEIL_DIV_EXPR(tree_node *type, tree_node *op0, tree_node *op1);
  Value *EmitReg_COMPLEX_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_FLOOR_DIV_EXPR(tree_node *type, tree_node *op0,
                                tree_node *op1);
  Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
                                tree_node *op1);
  Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
                                   tree_node *op1);
  Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
  Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
                                tree_node *op1);
  Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
  Value *EmitReg_TRUNC_MOD_EXPR(tree_node *op0, tree_node *op1);

  Value *EmitLoadOfLValue(tree_node *exp);
  Value *EmitOBJ_TYPE_REF(tree_node *exp);
  Value *EmitADDR_EXPR(tree_node *exp);
  Value *EmitCallOf(Value *Callee, gimple stmt, const MemRef *DestLoc,
                    const AttrListPtr &PAL);
  Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);

  // Inline Assembly and Register Variables.
  Value *EmitReadOfRegisterVariable(tree_node *vardecl);
  void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);

  // Helpers for Builtin Function Expansion.
  void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
  Value *BuildVector(const std::vector<Value*> &Elts);
  Value *BuildVector(Value *Elt, ...);
  Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
  Value *BuildBinaryAtomicBuiltin(gimple stmt, Intrinsic::ID id);
  Value *BuildCmpAndSwapAtomicBuiltin(gimple stmt, tree_node *type,
                                      bool isBool);

  // Builtin Function Expansion.
  bool EmitBuiltinCall(gimple stmt, tree_node *fndecl,
                       const MemRef *DestLoc, Value *&Result);
  bool EmitFrontendExpandedBuiltinCall(gimple stmt, tree_node *fndecl,
                                       const MemRef *DestLoc, Value *&Result);
  bool EmitBuiltinUnaryOp(Value *InVal, Value *&Result, Intrinsic::ID Id);
  Value *EmitBuiltinSQRT(gimple stmt);
  Value *EmitBuiltinPOWI(gimple stmt);
  Value *EmitBuiltinPOW(gimple stmt);

  bool EmitBuiltinConstantP(gimple stmt, Value *&Result);
  bool EmitBuiltinAlloca(gimple stmt, Value *&Result);
  bool EmitBuiltinExpect(gimple stmt, Value *&Result);
  bool EmitBuiltinExtendPointer(gimple stmt, Value *&Result);
  bool EmitBuiltinVAStart(gimple stmt);
  bool EmitBuiltinVAEnd(gimple stmt);
  bool EmitBuiltinVACopy(gimple stmt);
  bool EmitBuiltinMemCopy(gimple stmt, Value *&Result,
                          bool isMemMove, bool SizeCheck);
  bool EmitBuiltinMemSet(gimple stmt, Value *&Result, bool SizeCheck);
  bool EmitBuiltinBZero(gimple stmt, Value *&Result);
  bool EmitBuiltinPrefetch(gimple stmt);
  bool EmitBuiltinReturnAddr(gimple stmt, Value *&Result, bool isFrame);
  bool EmitBuiltinExtractReturnAddr(gimple stmt, Value *&Result);
  bool EmitBuiltinFrobReturnAddr(gimple stmt, Value *&Result);
  bool EmitBuiltinStackSave(gimple stmt, Value *&Result);
  bool EmitBuiltinStackRestore(gimple stmt);
  bool EmitBuiltinEHPointer(gimple stmt, Value *&Result);
  bool EmitBuiltinDwarfCFA(gimple stmt, Value *&Result);
  bool EmitBuiltinDwarfSPColumn(gimple stmt, Value *&Result);
  bool EmitBuiltinEHReturnDataRegno(gimple stmt, Value *&Result);
  bool EmitBuiltinEHReturn(gimple stmt, Value *&Result);
  bool EmitBuiltinInitDwarfRegSizes(gimple stmt, Value *&Result);
  bool EmitBuiltinUnwindInit(gimple stmt, Value *&Result);
  bool EmitBuiltinAdjustTrampoline(gimple stmt, Value *&Result);
  bool EmitBuiltinInitTrampoline(gimple stmt, Value *&Result);

  // Complex Math Expressions.
  Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
  void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
                    tree_node *elt_type);

  // L-Value Expressions.
  LValue EmitLV_ARRAY_REF(tree_node *exp);
  LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
  LValue EmitLV_COMPONENT_REF(tree_node *exp);
  LValue EmitLV_DECL(tree_node *exp);
  LValue EmitLV_INDIRECT_REF(tree_node *exp);
  LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
  LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
  LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
  LValue EmitLV_SSA_NAME(tree_node *exp);

  // Constant Expressions.
  Value *EmitINTEGER_CST(tree_node *exp);
  Value *EmitREAL_CST(tree_node *exp);
  Value *EmitCONSTRUCTOR(tree_node *exp, const MemRef *DestLoc);


  // Emit helpers.

  /// EmitMinInvariant - The given value is constant in this function.  Return
  /// the corresponding LLVM value. Only creates code in the entry block.
  Value *EmitMinInvariant(tree_node *reg);

  /// EmitInvariantAddress - The given address is constant in this function.
  /// Return the corresponding LLVM value. Only creates code in the entry block.
  Value *EmitInvariantAddress(tree_node *addr);

  /// EmitRegisterConstant - Convert the given global constant of register type
  /// to an LLVM constant.  Creates no code, only constants.
  Constant *EmitRegisterConstant(tree_node *reg);

  /// Mem2Reg - Convert a value of in-memory type (that given by ConvertType)
  /// to in-register type (that given by GetRegType).
  Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
  Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);

  /// Reg2Mem - Convert a value of in-register type (that given by GetRegType)
  /// to in-memory type (that given by ConvertType).
  Value *Reg2Mem(Value *V, tree_node *type, LLVMBuilder &Builder);

  /// EmitMemory - Convert the specified gimple register or local constant of
  /// register type to an LLVM value with in-memory type (given by ConvertType).
  Value *EmitMemory(tree_node *reg) {
    return Reg2Mem(EmitRegister(reg), TREE_TYPE(reg), Builder);
  }

  /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
  /// the memory location pointed to by Loc.  Takes care of adjusting for any
  /// differences between in-memory and in-register types (the returned value
  /// is of in-register type, as returned by GetRegType).
  Value *LoadRegisterFromMemory(MemRef Loc, tree_node *type,
                                LLVMBuilder &Builder);

  /// StoreRegisterToMemory - Stores the given value to the memory pointed to by
  /// Loc.  Takes care of adjusting for any differences between the value's type
  /// (which is the in-register type given by GetRegType) and the in-memory type.
  void StoreRegisterToMemory(Value *V, MemRef Loc, tree_node *type,
                             LLVMBuilder &Builder);

private:
  // Optional target defined builtin intrinsic expanding function.
  bool TargetIntrinsicLower(gimple stmt,
                            tree_node *fndecl,
                            const MemRef *DestLoc,
                            Value *&Result,
                            const Type *ResultType,
                            std::vector<Value*> &Ops);

public:
  // Helper for taking the address of a label.
  Constant *EmitLV_LABEL_DECL(tree_node *exp);
};

/// TreeConstantToLLVM - An instance of this class is created and used to
/// convert tree constant values to LLVM.  This is primarily for things like
/// global variable initializers.
///
class TreeConstantToLLVM {
public:
  // Constant Expressions
  static Constant *Convert(tree_node *exp);
  static Constant *ConvertINTEGER_CST(tree_node *exp);
  static Constant *ConvertREAL_CST(tree_node *exp);
  static Constant *ConvertVECTOR_CST(tree_node *exp);
  static Constant *ConvertSTRING_CST(tree_node *exp);
  static Constant *ConvertCOMPLEX_CST(tree_node *exp);
  static Constant *ConvertNOP_EXPR(tree_node *exp);
  static Constant *ConvertCONVERT_EXPR(tree_node *exp);
  static Constant *ConvertBinOp_CST(tree_node *exp);
  static Constant *ConvertCONSTRUCTOR(tree_node *exp);
  static Constant *ConvertArrayCONSTRUCTOR(tree_node *exp);
  static Constant *ConvertRecordCONSTRUCTOR(tree_node *exp);
  static Constant *ConvertUnionCONSTRUCTOR(tree_node *exp);
  static Constant *ConvertPOINTER_PLUS_EXPR(tree_node *exp);

  // Constant Expression l-values.
  static Constant *EmitLV(tree_node *exp);
  static Constant *EmitLV_Decl(tree_node *exp);
  static Constant *EmitLV_LABEL_DECL(tree_node *exp);
  static Constant *EmitLV_COMPLEX_CST(tree_node *exp);
  static Constant *EmitLV_STRING_CST(tree_node *exp);
  static Constant *EmitLV_COMPONENT_REF(tree_node *exp);
  static Constant *EmitLV_ARRAY_REF(tree_node *exp);

};

#endif /* LLVM_INTERNAL_H */
