/* 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();

/// flag_default_initialize_globals - Whether global variables with no explicit
/// initial value should be zero initialized.
extern bool flag_default_initialize_globals;

/// flag_odr - Whether the language being compiled obeys the One Definition Rule
/// (i.e. if the same function is defined in multiple compilation units, all the
/// definitions are equivalent).
extern bool flag_odr;

/// flag_vararg_requires_arguments - Do not consider functions with no arguments
/// to take a variable number of arguments (...).  If set then a function like
/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
extern bool flag_vararg_requires_arguments;

/// 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;
}

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