blob: a117ace6b6494a89eb7084de65f9c38f172b727e [file] [log] [blame]
//===--- ConstantConversion.cpp - Converting and working with constants ---===//
//
// Copyright (C) 2011 to 2013 Duncan Sands
//
// This file is part of DragonEgg.
//
// DragonEgg 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.
//
// DragonEgg 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
// DragonEgg; see the file COPYING. If not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
//
//===----------------------------------------------------------------------===//
// This is the code that converts GCC constants to LLVM.
//===----------------------------------------------------------------------===//
// Plugin headers
#include "dragonegg/Cache.h"
#include "dragonegg/ADT/IntervalList.h"
#include "dragonegg/ADT/Range.h"
#include "dragonegg/ConstantConversion.h"
#include "dragonegg/Internals.h"
#include "dragonegg/TypeConversion.h"
// LLVM headers
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Host.h"
// System headers
#include <gmp.h>
// GCC headers
#include "auto-host.h"
#ifndef ENABLE_BUILD_WITH_CXX
#include <cstring> // Otherwise included by system.h with C linkage.
extern "C" {
#endif
#include "config.h"
// Stop GCC declaring 'getopt' as it can clash with the system's declaration.
#undef HAVE_DECL_GETOPT
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#if (GCC_MINOR < 7)
#include "flags.h" // For POINTER_TYPE_OVERFLOW_UNDEFINED.
#endif
#include "tm_p.h" // For CONSTANT_ALIGNMENT.
#ifndef ENABLE_BUILD_WITH_CXX
} // extern "C"
#endif
// Trees header.
#include "dragonegg/Trees.h"
using namespace llvm;
static LLVMContext &Context = getGlobalContext();
// Forward declarations.
static Constant *ConvertInitializerImpl(tree, TargetFolder &);
static Constant *AddressOfImpl(tree, TargetFolder &);
//===----------------------------------------------------------------------===//
// ... InterpretAsType ...
//===----------------------------------------------------------------------===//
// TODO: Implement InterpretAsType more efficiently. Turning everything into
// bits is simple but can involve a lot of work when dealing with large arrays.
// For example:
// struct task_struct {
// char comm[16];
// };
// union task_union {
// struct task_struct task;
// unsigned long stack[2048*sizeof(long)/sizeof(long)];
// };
// union task_union init_task_union = { { comm: "swapper" } };
typedef Range<int> SignedRange;
/// BitSlice - A contiguous range of bits held in memory.
namespace {
class BitSlice {
SignedRange R;
Constant *Contents; // Null if and only if the range is empty.
bool contentsValid() const {
if (empty())
return !Contents;
return Contents && isa<IntegerType>(Contents->getType()) &&
getBitWidth() == Contents->getType()->getPrimitiveSizeInBits();
}
/// ExtendRange - Extend the slice to a wider range. All added bits are zero.
BitSlice ExtendRange(SignedRange r, TargetFolder &Folder) const;
/// ReduceRange - Reduce the slice to a smaller range discarding any bits that
/// do not belong to the new range.
BitSlice ReduceRange(SignedRange r, TargetFolder &Folder) const;
public:
/// BitSlice - Default constructor: empty bit range.
BitSlice() : R(), Contents(0) {}
/// BitSlice - Constructor for the given range of bits. The bits themselves
/// are supplied in 'contents' as a constant of integer type (if the range is
/// empty then 'contents' must be null). On little-endian machines the least
/// significant bit of 'contents' corresponds to the first bit of the range
/// (aka "First"), while on big-endian machines it corresponds to the last bit
/// of the range (aka "Last-1").
BitSlice(SignedRange r, Constant *contents) : R(r), Contents(contents) {
assert(contentsValid() && "Contents do not match range");
}
/// BitSlice - Constructor for the range of bits ['first', 'last').
BitSlice(int first, int last, Constant *contents)
: R(first, last), Contents(contents) {
assert(contentsValid() && "Contents do not match range");
}
/// empty - Return whether the bit range is empty.
bool empty() const { return R.empty(); }
/// getBitWidth - Return the number of bits in the range.
unsigned getBitWidth() const { return (unsigned) R.getWidth(); }
/// getRange - Return the range of bits in this slice.
SignedRange getRange() const { return R; }
/// Displace - Return the result of sliding all bits by the given offset.
BitSlice Displace(int Offset) const {
return BitSlice(R.Displace(Offset), Contents);
}
/// getBits - Return the bits in the given range. The supplied range need not
/// be contained in the range of the slice, but if not then the bits outside
/// the slice get an undefined value. The bits are returned as a constant of
/// integer type. On little-endian machine the least significant bit of the
/// returned value corresponds to the first bit of the range (aka "First"),
/// while on big-endian machines it corresponds to the last bit of the range
/// (aka "Last-1").
Constant *getBits(SignedRange r, TargetFolder &Folder) const;
/// Merge - Join the slice with another (which must be disjoint), forming the
/// convex hull of the ranges. The bits in the range of one of the slices are
/// those of that slice. Any other bits have an undefined value.
void Merge(const BitSlice &other, TargetFolder &Folder);
};
} // Unnamed namespace.
/// ExtendRange - Extend the slice to a wider range. All added bits are zero.
BitSlice BitSlice::ExtendRange(SignedRange r, TargetFolder &Folder) const {
assert(r.contains(R) && "Not an extension!");
// Quick exit if the range did not actually increase.
if (R == r)
return *this;
assert(!r.empty() && "Empty ranges did not evaluate as equal?");
Type *ExtTy = IntegerType::get(Context, (unsigned) r.getWidth());
// If the slice contains no bits then every bit of the extension is zero.
if (empty())
return BitSlice(r, Constant::getNullValue(ExtTy));
// Extend the contents to the new type.
Constant *C = Folder.CreateZExtOrBitCast(Contents, ExtTy);
// Position the old contents correctly inside the new contents.
unsigned deltaFirst = (unsigned)(R.getFirst() - r.getFirst());
unsigned deltaLast = (unsigned)(r.getLast() - R.getLast());
if (BYTES_BIG_ENDIAN && deltaLast) {
(void) deltaFirst; // Avoid unused variable warning.
Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast);
C = Folder.CreateShl(C, ShiftAmt);
} else if (!BYTES_BIG_ENDIAN && deltaFirst) {
(void) deltaLast; // Avoid unused variable warning.
Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst);
C = Folder.CreateShl(C, ShiftAmt);
}
return BitSlice(r, C);
}
/// getBits - Return the bits in the given range. The supplied range need not
/// be contained in the range of the slice, but if not then the bits outside
/// the slice get an undefined value. The bits are returned as a constant of
/// integer type. On little-endian machine the least significant bit of the
/// returned value corresponds to the first bit of the range (aka "First"),
/// while on big-endian machines it corresponds to the last bit of the range
/// (aka "Last-1").
Constant *BitSlice::getBits(SignedRange r, TargetFolder &Folder) const {
assert(!r.empty() && "Bit range is empty!");
// Quick exit if the desired range matches that of the slice.
if (R == r)
return Contents;
Type *RetTy = IntegerType::get(Context, (unsigned) r.getWidth());
// If the slice contains no bits then every returned bit is undefined.
if (empty())
return UndefValue::get(RetTy);
// Extend to the convex hull of the two ranges.
BitSlice Slice = ExtendRange(R.Join(r), Folder);
// Chop the slice down to the requested range.
Slice = Slice.ReduceRange(r, Folder);
// Now we can just return the bits contained in the slice.
return Slice.Contents;
}
/// Merge - Join the slice with another (which must be disjoint), forming the
/// convex hull of the ranges. The bits in the range of one of the slices are
/// those of that slice. Any other bits have an undefined value.
void BitSlice::Merge(const BitSlice &other, TargetFolder &Folder) {
// If the other slice is empty, the result is this slice.
if (other.empty())
return;
// If this slice is empty, the result is the other slice.
if (empty()) {
*this = other;
return;
}
assert(!R.intersects(other.getRange()) && "Slices overlap!");
// Extend each slice to the convex hull of the ranges.
SignedRange Hull = R.Join(other.getRange());
BitSlice ExtThis = ExtendRange(Hull, Folder);
BitSlice ExtOther = other.ExtendRange(Hull, Folder);
// Since the slices are disjoint and all added bits are zero they can be
// joined via a simple 'or'.
*this = BitSlice(Hull, Folder.CreateOr(ExtThis.Contents, ExtOther.Contents));
}
/// ReduceRange - Reduce the slice to a smaller range discarding any bits that
/// do not belong to the new range.
BitSlice BitSlice::ReduceRange(SignedRange r, TargetFolder &Folder) const {
assert(R.contains(r) && "Not a reduction!");
// Quick exit if the range did not actually decrease.
if (R == r)
return *this;
// The trivial case of reducing to an empty range.
if (r.empty())
return BitSlice();
assert(!R.empty() && "Empty ranges did not evaluate as equal?");
// Move the least-significant bit to the correct position.
Constant *C = Contents;
unsigned deltaFirst = (unsigned)(r.getFirst() - R.getFirst());
unsigned deltaLast = (unsigned)(R.getLast() - r.getLast());
if (BYTES_BIG_ENDIAN && deltaLast) {
(void) deltaFirst; // Avoid unused variable warning.
Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast);
C = Folder.CreateLShr(C, ShiftAmt);
} else if (!BYTES_BIG_ENDIAN && deltaFirst) {
(void) deltaLast; // Avoid unused variable warning.
Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst);
C = Folder.CreateLShr(C, ShiftAmt);
}
// Truncate to the new type.
Type *RedTy = IntegerType::get(Context, (unsigned) r.getWidth());
C = Folder.CreateTruncOrBitCast(C, RedTy);
return BitSlice(r, C);
}
/// ViewAsBits - View the given constant as a bunch of bits, i.e. as one big
/// integer. Only the bits in the given range are needed, so there is no need
/// to supply bits outside this range though it is harmless to do so. There is
/// also no need to supply undefined bits inside the range.
static BitSlice ViewAsBits(Constant *C, SignedRange R, TargetFolder &Folder) {
if (R.empty())
return BitSlice();
// Sanitize the range to make life easier in what follows.
Type *Ty = C->getType();
int StoreSize = getDataLayout().getTypeStoreSizeInBits(Ty);
R = R.Meet(SignedRange(0, StoreSize));
// Quick exit if it is clear that there are no bits in the range.
if (R.empty())
return BitSlice();
assert(StoreSize > 0 && "Empty range not eliminated?");
switch (Ty->getTypeID()) {
default:
llvm_unreachable("Unsupported type!");
case Type::PointerTyID: {
// Cast to an integer with the same number of bits and return that.
Type *IntTy = getDataLayout().getIntPtrType(Ty);
return BitSlice(0, StoreSize, Folder.CreatePtrToInt(C, IntTy));
}
case Type::DoubleTyID:
case Type::FloatTyID:
case Type::FP128TyID:
case Type::IntegerTyID:
case Type::PPC_FP128TyID:
case Type::X86_FP80TyID:
case Type::X86_MMXTyID: {
// Bitcast to an integer with the same number of bits and return that.
unsigned BitWidth = Ty->getPrimitiveSizeInBits();
IntegerType *IntTy = IntegerType::get(Context, BitWidth);
C = Folder.CreateBitCast(C, IntTy);
// Be careful about where the bits are placed in case this is a funky type
// like i1. If the width is a multiple of the address unit then there is
// nothing to worry about: the bits occupy the range [0, StoreSize). But
// if not then endianness matters: on big-endian machines there are padding
// bits at the start, while on little-endian machines they are at the end.
return BYTES_BIG_ENDIAN ? BitSlice(StoreSize - BitWidth, StoreSize, C)
: BitSlice(0, BitWidth, C);
}
case Type::ArrayTyID: {
ArrayType *ATy = cast<ArrayType>(Ty);
Type *EltTy = ATy->getElementType();
const unsigned Stride = getDataLayout().getTypeAllocSizeInBits(EltTy);
assert(Stride > 0 && "Store size smaller than alloc size?");
// Elements with indices in [FirstElt, LastElt) overlap the range.
unsigned FirstElt = R.getFirst() / Stride;
unsigned LastElt = (R.getLast() + Stride - 1) / Stride;
assert(LastElt <= ATy->getNumElements() && "Store size bigger than array?");
// Visit all elements that overlap the requested range, accumulating their
// bits in Bits.
BitSlice Bits;
SignedRange StrideRange(0, Stride);
for (unsigned i = FirstElt; i < LastElt; ++i) {
int EltOffsetInBits = i * Stride;
// Extract the element.
Constant *Elt = Folder.CreateExtractValue(C, i);
// View it as a bunch of bits.
SignedRange NeededBits = StrideRange.Meet(R.Displace(-EltOffsetInBits));
assert(!NeededBits.empty() && "Used element computation wrong!");
BitSlice EltBits = ViewAsBits(Elt, NeededBits, Folder);
// Add to the already known bits.
Bits.Merge(EltBits.Displace(EltOffsetInBits), Folder);
}
return Bits;
}
case Type::StructTyID: {
StructType *STy = cast<StructType>(Ty);
const StructLayout *SL = getDataLayout().getStructLayout(STy);
// Fields with indices in [FirstIdx, LastIdx) overlap the range.
unsigned FirstIdx = SL->getElementContainingOffset(R.getFirst() / 8);
unsigned LastIdx =
1 + SL->getElementContainingOffset((R.getLast() - 1) / 8);
// Visit all fields that overlap the requested range, accumulating their
// bits in Bits.
BitSlice Bits;
for (unsigned i = FirstIdx; i < LastIdx; ++i) {
int FieldOffsetInBits = SL->getElementOffset(i) * 8;
// Extract the field.
Constant *Field = Folder.CreateExtractValue(C, i);
// Only part of the field may be needed. Compute which bits they are.
Type *FieldTy = Field->getType();
unsigned FieldStoreSize = getDataLayout().getTypeStoreSizeInBits(FieldTy);
SignedRange NeededBits(0, FieldStoreSize);
NeededBits = NeededBits.Meet(R.Displace(-FieldOffsetInBits));
// View the needed part of the field as a bunch of bits.
if (!NeededBits.empty()) { // No field bits needed if only using padding.
BitSlice FieldBits = ViewAsBits(Field, NeededBits, Folder);
// Add to the already known bits.
Bits.Merge(FieldBits.Displace(FieldOffsetInBits), Folder);
}
}
return Bits;
}
case Type::VectorTyID: {
VectorType *VTy = cast<VectorType>(Ty);
Type *EltTy = VTy->getElementType();
const unsigned Stride = getDataLayout().getTypeAllocSizeInBits(EltTy);
assert(Stride > 0 && "Store size smaller than alloc size?");
// Elements with indices in [FirstElt, LastElt) overlap the range.
unsigned FirstElt = R.getFirst() / Stride;
unsigned LastElt = (R.getLast() + Stride - 1) / Stride;
assert(LastElt <= VTy->getNumElements() &&
"Store size bigger than vector?");
// Visit all elements that overlap the requested range, accumulating their
// bits in Bits.
BitSlice Bits;
SignedRange StrideRange(0, Stride);
for (unsigned i = FirstElt; i < LastElt; ++i) {
int EltOffsetInBits = i * Stride;
// Extract the element.
ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
Constant *Elt = Folder.CreateExtractElement(C, Idx);
// View it as a bunch of bits.
SignedRange NeededBits = StrideRange.Meet(R.Displace(-EltOffsetInBits));
assert(!NeededBits.empty() && "Used element computation wrong!");
BitSlice EltBits = ViewAsBits(Elt, NeededBits, Folder);
// Add to the already known bits.
Bits.Merge(EltBits.Displace(EltOffsetInBits), Folder);
}
return Bits;
}
}
}
/// InterpretAsType - Interpret the bits of the given constant (starting from
/// StartingBit) as representing a constant of type 'Ty'. This results in the
/// same constant as you would get by storing the bits of 'C' to memory (with
/// the first bit stored being 'StartingBit') and then loading out a (constant)
/// value of type 'Ty' from the stored to memory location.
static Constant *
InterpretAsType(Constant *C, Type *Ty, int StartingBit, TargetFolder &Folder) {
// Efficient handling for some common cases.
if (C->getType() == Ty)
return C;
if (isa<UndefValue>(C))
return UndefValue::get(Ty);
if (C->isNullValue())
return Constant::getNullValue(Ty);
// The general case.
switch (Ty->getTypeID()) {
default:
llvm_unreachable("Unsupported type!");
case Type::IntegerTyID: {
unsigned BitWidth = Ty->getPrimitiveSizeInBits();
unsigned StoreSize = getDataLayout().getTypeStoreSizeInBits(Ty);
// Convert the constant into a bunch of bits. Only the bits to be "loaded"
// out are needed, so rather than converting the entire constant this only
// converts enough to get all of the required bits.
BitSlice Bits = ViewAsBits(
C, SignedRange(StartingBit, StartingBit + StoreSize), Folder);
// Extract the bits used by the integer. If the integer width is a multiple
// of the address unit then the endianness of the target doesn't matter. If
// not then the padding bits come at the start on big-endian machines and at
// the end on little-endian machines.
Bits = Bits.Displace(-StartingBit);
return BYTES_BIG_ENDIAN
? Bits.getBits(SignedRange(StoreSize - BitWidth, StoreSize), Folder)
: Bits.getBits(SignedRange(0, BitWidth), Folder);
}
case Type::PointerTyID: {
// Interpret as an integer with the same number of bits then cast back to
// the original type.
Type *IntTy = getDataLayout().getIntPtrType(Ty);
C = InterpretAsType(C, IntTy, StartingBit, Folder);
return Folder.CreateIntToPtr(C, Ty);
}
case Type::DoubleTyID:
case Type::FloatTyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
case Type::X86_FP80TyID:
case Type::X86_MMXTyID: {
// Interpret as an integer with the same number of bits then cast back to
// the original type.
unsigned BitWidth = Ty->getPrimitiveSizeInBits();
IntegerType *IntTy = IntegerType::get(Context, BitWidth);
return Folder.CreateBitCast(InterpretAsType(C, IntTy, StartingBit, Folder),
Ty);
}
case Type::ArrayTyID: {
// Interpret each array element in turn.
ArrayType *ATy = cast<ArrayType>(Ty);
Type *EltTy = ATy->getElementType();
const unsigned Stride = getDataLayout().getTypeAllocSizeInBits(EltTy);
const unsigned NumElts = ATy->getNumElements();
std::vector<Constant *> Vals(NumElts);
for (unsigned i = 0; i != NumElts; ++i)
Vals[i] = InterpretAsType(C, EltTy, StartingBit + i * Stride, Folder);
return ConstantArray::get(ATy, Vals); // TODO: Use ArrayRef constructor.
}
case Type::StructTyID: {
// Interpret each struct field in turn.
StructType *STy = cast<StructType>(Ty);
const StructLayout *SL = getDataLayout().getStructLayout(STy);
unsigned NumElts = STy->getNumElements();
std::vector<Constant *> Vals(NumElts);
for (unsigned i = 0; i != NumElts; ++i)
Vals[i] =
InterpretAsType(C, STy->getElementType(i),
StartingBit + SL->getElementOffsetInBits(i), Folder);
return ConstantStruct::get(STy, Vals); // TODO: Use ArrayRef constructor.
}
case Type::VectorTyID: {
// Interpret each vector element in turn.
VectorType *VTy = cast<VectorType>(Ty);
Type *EltTy = VTy->getElementType();
const unsigned Stride = getDataLayout().getTypeAllocSizeInBits(EltTy);
const unsigned NumElts = VTy->getNumElements();
SmallVector<Constant *, 16> Vals(NumElts);
for (unsigned i = 0; i != NumElts; ++i)
Vals[i] = InterpretAsType(C, EltTy, StartingBit + i * Stride, Folder);
return ConstantVector::get(Vals);
}
}
}
//===----------------------------------------------------------------------===//
// ... ExtractRegisterFromConstant ...
//===----------------------------------------------------------------------===//
/// ExtractRegisterFromConstantImpl - Implementation of
/// ExtractRegisterFromConstant.
static Constant *ExtractRegisterFromConstantImpl(
Constant *C, tree type, int StartingByte, TargetFolder &Folder) {
// NOTE: Needs to be kept in sync with getRegType and RepresentAsMemory.
int StartingBit = StartingByte * BITS_PER_UNIT;
switch (TREE_CODE(type)) {
default:
debug_tree(type);
llvm_unreachable("Unknown register type!");
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case INTEGER_TYPE: {
// For integral types, extract an integer with size equal to the mode size,
// then truncate down to the precision. For example, when extracting a bool
// this probably first loads out an i8 or i32 which is then truncated to i1.
// This roundabout approach means we get the right result on both little and
// big endian machines.
unsigned Size = GET_MODE_BITSIZE(TYPE_MODE(type));
Type *MemTy = IntegerType::get(Context, Size);
C = InterpretAsType(C, MemTy, StartingBit, Folder);
return Folder.CreateTruncOrBitCast(C, getRegType(type));
}
case COMPLEX_TYPE: {
tree elt_type = main_type(type);
unsigned Stride = GET_MODE_BITSIZE(TYPE_MODE(elt_type));
Constant *Vals[2] = {
ExtractRegisterFromConstantImpl(C, elt_type, StartingBit, Folder),
ExtractRegisterFromConstantImpl(C, elt_type, StartingBit + Stride, Folder)
};
return ConstantStruct::getAnon(Vals);
}
#if (GCC_MINOR > 5)
case NULLPTR_TYPE:
#endif
case OFFSET_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
return InterpretAsType(C, getRegType(type), StartingBit, Folder);
case REAL_TYPE:
// NOTE: This might be wrong for floats with precision less than their alloc
// size on big-endian machines.
return InterpretAsType(C, getRegType(type), StartingBit, Folder);
case VECTOR_TYPE: {
tree elt_type = main_type(type);
unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
unsigned Stride = GET_MODE_BITSIZE(TYPE_MODE(elt_type));
SmallVector<Constant *, 16> Vals(NumElts);
for (unsigned i = 0; i != NumElts; ++i)
Vals[i] = ExtractRegisterFromConstantImpl(
C, elt_type, StartingBit + i * Stride, Folder);
return ConstantVector::get(Vals);
}
}
}
/// ExtractRegisterFromConstant - Extract a value of the given scalar GCC type
/// from a constant. The returned value is of in-register type, as returned by
/// getRegType, and is what you would get by storing the constant to memory and
/// using LoadRegisterFromMemory to load a register value back out starting from
/// byte StartingByte.
Constant *
ExtractRegisterFromConstant(Constant *C, tree type, int StartingByte) {
TargetFolder Folder(&getDataLayout());
return ExtractRegisterFromConstantImpl(C, type, StartingByte, Folder);
}
//===----------------------------------------------------------------------===//
// ... ConvertInitializer ...
//===----------------------------------------------------------------------===//
/// getAsRegister - Turn the given GCC scalar constant into an LLVM constant of
/// register type.
static Constant *getAsRegister(tree exp, TargetFolder &Folder) {
Constant *C = ConvertInitializerImpl(exp, Folder);
return ExtractRegisterFromConstantImpl(C, main_type(exp), 0, Folder);
}
/// RepresentAsMemory - Turn a constant of in-register type (corresponding
/// to the given GCC type) into an in-memory constant. The result has the
/// property that applying ExtractRegisterFromConstant to it gives you the
/// original in-register constant back again.
static Constant *
RepresentAsMemory(Constant *C, tree type, TargetFolder &Folder) {
// NOTE: Needs to be kept in sync with ExtractRegisterFromConstant.
assert(C->getType() == getRegType(type) && "Constant has wrong type!");
Constant *Result;
switch (TREE_CODE(type)) {
default:
debug_tree(type);
llvm_unreachable("Unknown register type!");
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case INTEGER_TYPE: {
// For integral types extend to an integer with size equal to the mode size.
// For example, when inserting a bool this probably extends it to an i8 or
// to an i32. This approach means we get the right result on both little
// and big endian machines.
unsigned Size = GET_MODE_BITSIZE(TYPE_MODE(type));
Type *MemTy = IntegerType::get(Context, Size);
bool isSigned = !TYPE_UNSIGNED(type);
Result = isSigned ? Folder.CreateSExtOrBitCast(C, MemTy)
: Folder.CreateZExtOrBitCast(C, MemTy);
break;
}
case COMPLEX_TYPE: {
tree elt_type = main_type(type);
Constant *Real = Folder.CreateExtractValue(C, 0);
Constant *Imag = Folder.CreateExtractValue(C, 1);
Real = RepresentAsMemory(Real, elt_type, Folder);
Imag = RepresentAsMemory(Imag, elt_type, Folder);
Constant *Vals[2] = { Real, Imag };
Result = ConstantStruct::getAnon(Vals);
break;
}
#if (GCC_MINOR > 5)
case NULLPTR_TYPE:
#endif
case OFFSET_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
Result = C;
break;
case REAL_TYPE:
// NOTE: This might be wrong for floats with precision less than their alloc
// size on big-endian machines.
// If the float precision is less than the alloc size then it will be padded
// out below.
Result = C;
break;
case VECTOR_TYPE: {
tree elt_type = main_type(type);
unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
std::vector<Constant *> Vals(NumElts);
for (unsigned i = 0; i != NumElts; ++i) {
ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
Vals[i] = Folder.CreateExtractElement(C, Idx);
Vals[i] = RepresentAsMemory(Vals[i], elt_type, Folder);
}
// The elements may have funky types, so forming a vector may not always be
// possible.
Result = ConstantStruct::getAnon(Vals);
break;
}
}
// Ensure that the result satisfies the guarantees given by ConvertInitializer
// by turning it into a type with the right size and an appropriate alignment.
Result = InterpretAsType(Result, ConvertType(type), 0, Folder);
assert(C == ExtractRegisterFromConstantImpl(Result, type, 0, Folder) &&
"Register inserted wrong!");
return Result;
}
/// ConvertInitializerWithCast - Convert the initial value for a global variable
/// to an equivalent LLVM constant then cast to the given type if both the type
/// and the initializer are scalar, or if the initializer's type only differs in
/// trivial ways from the given type. This is convenient for avoiding confusing
/// and pointless type changes in the IR, and for making explicit the implicit
/// scalar casts that GCC allows in "assignments" such as initializing a record
/// field.
static Constant *
ConvertInitializerWithCast(tree exp, tree type, TargetFolder &Folder) {
// Convert the initializer. Note that the type of the returned value may be
// pretty much anything.
Constant *C = ConvertInitializerImpl(exp, Folder);
// If casting to or from an aggregate then just return the initializer as is.
// If the types differ then this is probably something like a struct ending in
// a flexible array being initialized with a struct ending in an array of some
// definite size.
if (isa<AGGREGATE_TYPE>(type) || isa<AGGREGATE_TYPE>(TREE_TYPE(exp)))
return C;
// Scalar to scalar cast. This is where the implicit scalar casts that GCC
// permits are made explicit.
Type *DestTy = getRegType(type);
if (C->getType() == DestTy)
// No cast is needed if the type is already correct.
return C;
// Ensure that the initializer has a sensible type. Note that it would be
// wrong to just interpret the constant as being of type DestTy here since
// that would not perform a value extension (adding extra zeros or sign bits
// when casting to a larger integer type for example): any extra bits would
// wrongly get an undefined value instead.
C = ExtractRegisterFromConstantImpl(C, main_type(exp), 0, Folder);
// Cast to the desired type.
bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp));
bool DestIsSigned = !TYPE_UNSIGNED(type);
Instruction::CastOps opcode =
CastInst::getCastOpcode(C, SrcIsSigned, DestTy, DestIsSigned);
C = Folder.CreateCast(opcode, C, DestTy);
return RepresentAsMemory(C, type, Folder);
}
/// ConvertCST - Return the given simple constant as an array of bytes. For the
/// moment only INTEGER_CST, REAL_CST, COMPLEX_CST and VECTOR_CST are supported.
static Constant *ConvertCST(tree exp, TargetFolder &) {
const tree type = main_type(exp);
unsigned SizeInChars =
(TREE_INT_CST_LOW(TYPE_SIZE(type)) + CHAR_BIT - 1) / CHAR_BIT;
// Encode the constant in Buffer in target format.
SmallVector<uint8_t, 16> Buffer(SizeInChars);
unsigned CharsWritten = native_encode_expr(exp, &Buffer[0], SizeInChars);
assert(CharsWritten == SizeInChars && "Failed to fully encode expression!");
(void)
CharsWritten; // Avoid unused variable warning when assertions disabled.
// Turn it into an LLVM byte array.
return ConstantDataArray::get(Context, Buffer);
}
static Constant *ConvertSTRING_CST(tree exp, TargetFolder &) {
// TODO: Enhance GCC's native_encode_expr to handle arbitrary strings and not
// just those with a byte component type; then ConvertCST can handle strings.
ArrayType *StrTy = cast<ArrayType>(ConvertType(TREE_TYPE(exp)));
Type *ElTy = StrTy->getElementType();
unsigned Len = (unsigned) TREE_STRING_LENGTH(exp);
std::vector<Constant *> Elts;
if (ElTy->isIntegerTy(8)) {
const unsigned char *InStr =
(const unsigned char *)TREE_STRING_POINTER(exp);
for (unsigned i = 0; i != Len; ++i)
Elts.push_back(ConstantInt::get(Type::getInt8Ty(Context), InStr[i]));
} else if (ElTy->isIntegerTy(16)) {
assert((Len & 1) == 0 &&
"Length in bytes should be a multiple of element size");
const uint16_t *InStr = (const unsigned short *)TREE_STRING_POINTER(exp);
for (unsigned i = 0; i != Len / 2; ++i) {
// gcc has constructed the initializer elements in the target endianness,
// but we're going to treat them as ordinary shorts from here, with
// host endianness. Adjust if necessary.
if (llvm::sys::IsBigEndianHost == BYTES_BIG_ENDIAN)
Elts.push_back(ConstantInt::get(Type::getInt16Ty(Context), InStr[i]));
else
Elts.push_back(
ConstantInt::get(Type::getInt16Ty(Context), ByteSwap_16(InStr[i])));
}
} else if (ElTy->isIntegerTy(32)) {
assert((Len & 3) == 0 &&
"Length in bytes should be a multiple of element size");
const uint32_t *InStr = (const uint32_t *)TREE_STRING_POINTER(exp);
for (unsigned i = 0; i != Len / 4; ++i) {
// gcc has constructed the initializer elements in the target endianness,
// but we're going to treat them as ordinary ints from here, with
// host endianness. Adjust if necessary.
if (llvm::sys::IsBigEndianHost == BYTES_BIG_ENDIAN)
Elts.push_back(ConstantInt::get(Type::getInt32Ty(Context), InStr[i]));
else
Elts.push_back(
ConstantInt::get(Type::getInt32Ty(Context), ByteSwap_32(InStr[i])));
}
} else {
llvm_unreachable("Unknown character type!");
}
unsigned LenInElts =
Len / TREE_INT_CST_LOW(TYPE_SIZE_UNIT(main_type(main_type(exp))));
unsigned ConstantSize = StrTy->getNumElements();
if (LenInElts != ConstantSize) {
// If this is a variable sized array type, set the length to LenInElts.
if (ConstantSize == 0) {
tree Domain = TYPE_DOMAIN(main_type(exp));
if (!Domain || !TYPE_MAX_VALUE(Domain)) {
ConstantSize = LenInElts;
StrTy = ArrayType::get(ElTy, LenInElts);
}
}
if (ConstantSize < LenInElts) {
// Only some chars are being used, truncate the string: char X[2] = "foo";
Elts.resize(ConstantSize);
} else {
// Fill the end of the string with nulls.
Constant *C = Constant::getNullValue(ElTy);
for (; LenInElts != ConstantSize; ++LenInElts)
Elts.push_back(C);
}
}
return ConstantArray::get(StrTy, Elts);
}
static Constant *ConvertADDR_EXPR(tree exp, TargetFolder &Folder) {
return AddressOfImpl(TREE_OPERAND(exp, 0), Folder);
}
/// ConvertArrayCONSTRUCTOR - Convert a CONSTRUCTOR with array or vector type.
static Constant *ConvertArrayCONSTRUCTOR(tree exp, TargetFolder &Folder) {
const DataLayout &DL = getDataLayout();
tree init_type = main_type(exp);
Type *InitTy = ConvertType(init_type);
tree elt_type = main_type(init_type);
Type *EltTy = ConvertType(elt_type);
// Check that the element type has a known, constant size.
assert(isSizeCompatible(elt_type) && "Variable sized array element!");
uint64_t EltSize = DL.getTypeAllocSizeInBits(EltTy);
/// Elts - The initial values to use for the array elements. A null entry
/// means that the corresponding array element should be default initialized.
std::vector<Constant *> Elts;
// Resize to the number of array elements if known. This ensures that every
// element will be at least default initialized even if no initial value is
// given for it.
uint64_t TypeElts =
isa<ARRAY_TYPE>(init_type) ? ArrayLengthOf(init_type)
: TYPE_VECTOR_SUBPARTS(init_type);
if (TypeElts != NO_LENGTH)
Elts.resize(TypeElts);
// If GCC indices into the array need adjusting to make them zero indexed then
// record here the value to subtract off.
tree lower_bnd = NULL_TREE;
if (isa<ARRAY_TYPE>(init_type) && TYPE_DOMAIN(init_type) &&
!integer_zerop(TYPE_MIN_VALUE(TYPE_DOMAIN(init_type))))
lower_bnd = TYPE_MIN_VALUE(TYPE_DOMAIN(init_type));
unsigned NextIndex = 0;
unsigned HOST_WIDE_INT ix;
tree elt_index, elt_value;
FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(exp), ix, elt_index, elt_value) {
// Find and decode the constructor's value.
Constant *Val = ConvertInitializerWithCast(elt_value, elt_type, Folder);
uint64_t ValSize = DL.getTypeAllocSizeInBits(Val->getType());
assert(ValSize <= EltSize && "Element initial value too big!");
// If the initial value is smaller than the element size then pad it out.
if (ValSize < EltSize) {
unsigned PadBits = EltSize - ValSize;
assert(PadBits % BITS_PER_UNIT == 0 && "Non-unit type size?");
unsigned Units = PadBits / BITS_PER_UNIT;
Constant *PaddedElt[] = { Val,
getDefaultValue(GetUnitType(Context, Units)) };
Val = ConstantStruct::getAnon(PaddedElt);
}
// Get the index position of the element within the array. Note that this
// can be NULL_TREE, which means that it belongs in the next available slot.
tree index = elt_index;
// The first and last elements to fill in, inclusive.
unsigned FirstIndex, LastIndex;
if (!index) {
LastIndex = FirstIndex = NextIndex;
} else if (isa<RANGE_EXPR>(index)) {
tree first = TREE_OPERAND(index, 0);
tree last = TREE_OPERAND(index, 1);
// Subtract off the lower bound if any to ensure indices start from zero.
if (lower_bnd != NULL_TREE) {
first = fold_build2(MINUS_EXPR, main_type(first), first, lower_bnd);
last = fold_build2(MINUS_EXPR, main_type(last), last, lower_bnd);
}
assert(host_integerp(first, 1) && host_integerp(last, 1) &&
"Unknown range_expr!");
FirstIndex = tree_low_cst(first, 1);
LastIndex = tree_low_cst(last, 1);
} else {
// Subtract off the lower bound if any to ensure indices start from zero.
if (lower_bnd != NULL_TREE)
index = fold_build2(MINUS_EXPR, main_type(index), index, lower_bnd);
assert(host_integerp(index, 1));
FirstIndex = tree_low_cst(index, 1);
LastIndex = FirstIndex;
}
// Process all of the elements in the range.
if (LastIndex >= Elts.size())
Elts.resize(LastIndex + 1);
for (; FirstIndex <= LastIndex; ++FirstIndex)
Elts[FirstIndex] = Val;
NextIndex = FirstIndex;
}
unsigned NumElts = Elts.size();
// Zero length array.
if (!NumElts)
return getDefaultValue(InitTy);
// Default initialize any elements that had no initial value specified.
Constant *DefaultElt = getDefaultValue(EltTy);
for (unsigned i = 0; i != NumElts; ++i)
if (!Elts[i])
Elts[i] = DefaultElt;
// Check whether any of the elements have different types. If so we need to
// return a struct instead of an array. This can occur in cases where we have
// an array of unions, and the various unions had different parts initialized.
// While there, compute the maximum element alignment.
bool isHomogeneous = true;
Type *ActualEltTy = Elts[0]->getType();
unsigned MaxAlign = DL.getABITypeAlignment(ActualEltTy);
for (unsigned i = 1; i != NumElts; ++i)
if (Elts[i]->getType() != ActualEltTy) {
MaxAlign = std::max(DL.getABITypeAlignment(Elts[i]->getType()), MaxAlign);
isHomogeneous = false;
}
// We guarantee that initializers are always at least as big as the LLVM type
// for the initializer. If needed, append padding to ensure this.
uint64_t TypeSize = DL.getTypeAllocSizeInBits(InitTy);
if (NumElts * EltSize < TypeSize) {
unsigned PadBits = TypeSize - NumElts * EltSize;
assert(PadBits % BITS_PER_UNIT == 0 && "Non-unit type size?");
unsigned Units = PadBits / BITS_PER_UNIT;
Elts.push_back(getDefaultValue(GetUnitType(Context, Units)));
isHomogeneous = false;
}
// If any elements are more aligned than the GCC type then we need to return a
// packed struct. This can happen if the user forced a small alignment on the
// array type.
if (MaxAlign * 8 > TYPE_ALIGN(main_type(exp)))
return ConstantStruct::getAnon(Context, Elts, /*Packed*/ true);
// Return as a struct if the contents are not homogeneous.
if (!isHomogeneous) {
std::vector<Constant *> StructElts;
unsigned First = 0, E = Elts.size();
while (First < E) {
// Find the maximal value of Last s.t. all elements in the range
// [First, Last) have the same type.
Type *Ty = Elts[First]->getType();
unsigned Last = First + 1;
for (; Last != E; ++Last)
if (Elts[Last]->getType() != Ty)
break;
unsigned NumSameType = Last - First;
Constant *StructElt;
if (NumSameType == 1)
StructElt = Elts[First];
else
StructElt =
ConstantArray::get(ArrayType::get(Ty, NumSameType),
ArrayRef<Constant *>(&Elts[First], NumSameType));
StructElts.push_back(StructElt);
First = Last;
}
return ConstantStruct::getAnon(Context, StructElts);
}
// Make the IR more pleasant by returning as a vector if the GCC type was a
// vector. However this is only correct if the initial values had the same
// type as the vector element type, rather than some random other type.
if (isa<VECTOR_TYPE>(init_type) && ActualEltTy == EltTy)
return ConstantVector::get(Elts);
return ConstantArray::get(ArrayType::get(ActualEltTy, Elts.size()), Elts);
}
/// FieldContents - A constant restricted to a range of bits. Any part of the
/// constant outside of the range is discarded. The range may be bigger than
/// the constant in which case any extra bits have an undefined value.
namespace {
class FieldContents {
TargetFolder &Folder;
SignedRange R; // The range of bits occupied by the constant.
Constant *C; // The constant. May be null if the range is empty.
int Starts; // The first bit of the constant is positioned at this offset.
FieldContents(SignedRange r, Constant *c, int starts, TargetFolder &folder)
: Folder(folder), R(r), C(c), Starts(starts) {
assert((R.empty() || C) && "Need constant when range not empty!");
}
/// getAsBits - Return the bits in the range as an integer (or null if the
/// range is empty).
Constant *getAsBits() const {
if (R.empty())
return 0;
Type *IntTy = IntegerType::get(Context, R.getWidth());
return InterpretAsType(C, IntTy, R.getFirst() - Starts, Folder);
}
/// isSafeToReturnContentsDirectly - Return whether the current value for the
/// constant properly represents the bits in the range and so can be handed to
/// the user as is.
bool isSafeToReturnContentsDirectly(const DataLayout &DL) const {
// If there is no constant (allowed when the range is empty) then one needs
// to be created.
if (!C)
return false;
// If the first bit of the constant is not the first bit of the range then
// it needs to be displaced before being passed to the user.
if (!R.empty() && R.getFirst() != Starts)
return false;
Type *Ty = C->getType();
// Check that the type isn't something like i17. Avoiding types like this
// is not needed for correctness, but makes life easier for the optimizers.
if ((Ty->getPrimitiveSizeInBits() % BITS_PER_UNIT) != 0)
return false;
// If the constant is wider than the range then it needs to be truncated
// before being passed to the user.
unsigned AllocBits = DL.getTypeAllocSizeInBits(Ty);
return AllocBits <= (unsigned) R.getWidth();
}
public:
/// get - Fill the range [first, last) with the given constant.
static FieldContents
get(int first, int last, Constant *c, TargetFolder &folder) {
return FieldContents(SignedRange(first, last), c, first, folder);
}
// Copy assignment operator.
FieldContents &operator=(const FieldContents & other) {
R = other.R;
C = other.C;
Starts = other.Starts;
Folder = other.Folder;
return *this;
}
/// getRange - Return the range occupied by this field.
SignedRange getRange() const { return R; }
/// ChangeRangeTo - Change the range occupied by this field.
void ChangeRangeTo(SignedRange r) { R = r; }
/// JoinWith - Form the union of this field with another field (which must be
/// disjoint from this one). After this the range will be the convex hull of
/// the ranges of the two fields.
void JoinWith(const FieldContents &S);
/// extractContents - Return the contained bits as a constant which contains
/// every defined bit in the range, yet is guaranteed to have alloc size no
/// larger than the width of the range. Unlike the other methods for this
/// class, this one requires that the width of the range be a multiple of an
/// address unit, which usually means a multiple of 8.
Constant *extractContents(const DataLayout &DL) {
assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?");
/// If the current value for the constant can be used to represent the bits
/// in the range then just return it.
if (isSafeToReturnContentsDirectly(DL))
return C;
// If the range is empty then return a constant with zero size.
if (R.empty()) {
// Return an empty array. Remember the returned value as an optimization
// in case we are called again.
C = UndefValue::get(GetUnitType(Context, 0));
assert(isSafeToReturnContentsDirectly(DL) && "Unit over aligned?");
return C;
}
// If the type is something like i17 then round it up to a multiple of a
// byte. This is not needed for correctness, but helps the optimizers.
if ((C->getType()->getPrimitiveSizeInBits() % BITS_PER_UNIT) != 0) {
Type *Ty = C->getType();
assert(Ty->isIntegerTy() && "Non-integer type with non-byte size!");
unsigned BitWidth =
RoundUpToAlignment(Ty->getPrimitiveSizeInBits(), BITS_PER_UNIT);
Ty = IntegerType::get(Context, BitWidth);
C = TheFolder->CreateZExtOrBitCast(C, Ty);
if (isSafeToReturnContentsDirectly(DL))
return C;
}
// Turn the contents into a bunch of bytes. Remember the returned value as
// an optimization in case we are called again.
// TODO: If the contents only need to be truncated and have struct or array
// type then we could try to do the truncation by dropping or modifying the
// last elements of the constant, maybe yielding something less horrible.
unsigned Units = R.getWidth() / BITS_PER_UNIT;
C = InterpretAsType(C, GetUnitType(Context, Units), R.getFirst() - Starts,
Folder);
Starts = R.getFirst();
assert(isSafeToReturnContentsDirectly(DL) && "Unit over aligned?");
return C;
}
};
} // Unnamed namespace.
/// JoinWith - Form the union of this field with another field (which must be
/// disjoint from this one). After this the range will be the convex hull of
/// the ranges of the two fields.
void FieldContents::JoinWith(const FieldContents &S) {
if (S.R.empty())
return;
if (R.empty()) {
*this = S;
return;
}
// Consider the contents of the fields to be bunches of bits and paste them
// together. This can result in a nasty integer constant expression, but as
// we only get here for bitfields that's mostly harmless.
BitSlice Bits(R, getAsBits());
Bits.Merge(BitSlice(S.R, S.getAsBits()), Folder);
R = Bits.getRange();
C = Bits.getBits(R, Folder);
Starts = R.empty() ? 0 : R.getFirst();
}
static Constant *ConvertRecordCONSTRUCTOR(tree exp, TargetFolder &Folder) {
// FIXME: This new logic, especially the handling of bitfields, is untested
// and probably wrong on big-endian machines.
IntervalList<FieldContents, int, 8> Layout;
const DataLayout &DL = getDataLayout();
tree type = main_type(exp);
Type *Ty = ConvertType(type);
uint64_t TypeSize = DL.getTypeAllocSizeInBits(Ty);
// Ensure that fields without an initial value are default initialized by
// explicitly setting the starting value for all fields to be zero. If an
// initial value is supplied for a field then the value will overwrite and
// replace the zero starting value later.
if (flag_default_initialize_globals) {
// Record all interesting fields so they can easily be visited backwards.
SmallVector<tree, 16> Fields;
for (tree field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) {
if (!isa<FIELD_DECL>(field))
continue;
// Ignore fields with variable or unknown position since they cannot be
// default initialized.
if (!OffsetIsLLVMCompatible(field))
continue;
Fields.push_back(field);
}
// Process the fields in reverse order. This is for the benefit of union
// types for which the first field must be default initialized (iterating
// in forward order would default initialize the last field).
for (SmallVector<tree, 16>::reverse_iterator I = Fields.rbegin(),
E = Fields.rend();
I != E; ++I) {
tree field = *I;
uint64_t FirstBit = getFieldOffsetInBits(field);
assert(FirstBit <= TypeSize && "Field off end of type!");
// Determine the width of the field.
uint64_t BitWidth;
Type *FieldTy = ConvertType(TREE_TYPE(field));
if (isInt64(DECL_SIZE(field), true)) {
// The field has a size and it is a constant, so use it. Note that
// this size may be smaller than the type size. For example, if the
// next field starts inside alignment padding at the end of this one
// then DECL_SIZE will be the size with the padding used by the next
// field not included.
BitWidth = getInt64(DECL_SIZE(field), true);
} else {
// If the field has variable or unknown size then use the size of the
// LLVM type instead as it gives the minimum size the field may have.
if (!FieldTy->isSized())
// An incomplete type - this field cannot be default initialized.
continue;
BitWidth = DL.getTypeAllocSizeInBits(FieldTy);
if (FirstBit + BitWidth > TypeSize)
BitWidth = TypeSize - FirstBit;
}
uint64_t LastBit = FirstBit + BitWidth;
// Zero the bits occupied by the field. It is safe to use FieldTy here as
// it is guaranteed to cover all parts of the GCC type that can be default
// initialized. This makes for nicer IR than just using a bunch of bytes.
Constant *Zero = Constant::getNullValue(FieldTy);
Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Zero, Folder));
}
}
// For each field for which an initial value was specified, set the bits
// occupied by the field to that value.
unsigned HOST_WIDE_INT ix;
tree field, next_field, value;
next_field = TYPE_FIELDS(type);
FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(exp), ix, field, value) {
if (!field) {
// Move on to the next FIELD_DECL, skipping contained methods, types etc.
field = next_field;
while (1) {
assert(field && "Fell off end of record!");
if (isa<FIELD_DECL>(field))
break;
field = TREE_CHAIN(field);
}
}
next_field = TREE_CHAIN(field);
assert(isa<FIELD_DECL>(field) && "Initial value not for a field!");
assert(OffsetIsLLVMCompatible(field) && "Field position not known!");
// Turn the initial value for this field into an LLVM constant.
Constant *Init =
ConvertInitializerWithCast(value, main_type(field), Folder);
// Work out the range of bits occupied by the field.
uint64_t FirstBit = getFieldOffsetInBits(field);
assert(FirstBit <= TypeSize && "Field off end of type!");
// If a size was specified for the field then use it. Otherwise take the
// size from the initial value.
uint64_t BitWidth = isInt64(DECL_SIZE(field), true)
? getInt64(DECL_SIZE(field), true)
: DL.getTypeAllocSizeInBits(Init->getType());
uint64_t LastBit = FirstBit + BitWidth;
// Set the bits occupied by the field to the initial value.
Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Init, Folder));
}
// Force all fields to begin and end on a byte boundary. This automagically
// takes care of bitfields.
Layout.AlignBoundaries(BITS_PER_UNIT);
// Determine whether to return a packed struct. If returning an ordinary
// struct would result in an initializer that is more aligned than its GCC
// type then return a packed struct instead. If a field's alignment would
// make it start after its desired position then also use a packed struct.
bool Pack = false;
unsigned MaxAlign = TYPE_ALIGN(type);
for (unsigned i = 0, e = Layout.getNumIntervals(); i != e; ++i) {
FieldContents F = Layout.getInterval(i);
unsigned First = F.getRange().getFirst();
Constant *Val = F.extractContents(DL);
unsigned Alignment = DL.getABITypeAlignment(Val->getType()) * 8;
if (Alignment > MaxAlign || First % Alignment) {
Pack = true;
break;
}
}
// Create the elements that will make up the struct. As well as the fields
// themselves there may also be padding elements.
std::vector<Constant *> Elts;
Elts.reserve(Layout.getNumIntervals());
unsigned EndOfPrevious = 0; // Offset of first bit after previous element.
for (unsigned i = 0, e = Layout.getNumIntervals(); i != e; ++i) {
FieldContents F = Layout.getInterval(i);
unsigned First = F.getRange().getFirst();
Constant *Val = F.extractContents(DL);
assert(EndOfPrevious <= First && "Previous field too big!");
// If there is a gap then we may need to fill it with padding.
if (First > EndOfPrevious) {
// There is a gap between the end of the previous field and the start of
// this one. The alignment of the field contents may mean that it will
// start at the right offset anyway, but if not then insert padding.
bool NeedPadding = true;
if (!Pack) {
// If the field's alignment will take care of the gap then there is no
// need for padding.
unsigned Alignment = DL.getABITypeAlignment(Val->getType()) * 8;
if (First == (EndOfPrevious + Alignment - 1) / Alignment * Alignment)
NeedPadding = false;
}
if (NeedPadding) {
// Fill the gap with padding.
assert((First - EndOfPrevious) % BITS_PER_UNIT == 0 &&
"Non-unit field boundaries!");
unsigned Units = (First - EndOfPrevious) / BITS_PER_UNIT;
Elts.push_back(getDefaultValue(GetUnitType(Context, Units)));
}
}
// Append the field.
Elts.push_back(Val);
EndOfPrevious = First + DL.getTypeAllocSizeInBits(Val->getType());
}
// We guarantee that initializers are always at least as big as the LLVM type
// for the initializer. If needed, append padding to ensure this.
if (EndOfPrevious < TypeSize) {
assert((TypeSize - EndOfPrevious) % BITS_PER_UNIT == 0 &&
"Non-unit type size?");
unsigned Units = (TypeSize - EndOfPrevious) / BITS_PER_UNIT;
Elts.push_back(getDefaultValue(GetUnitType(Context, Units)));
}
// Okay, we're done. Return the computed elements as a constant with the type
// of exp if possible.
if (StructType *STy = dyn_cast<StructType>(Ty))
if (STy->isPacked() == Pack && STy->getNumElements() == Elts.size()) {
bool EltTypesMatch = true;
for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
Type *EltTy = Elts[i]->getType();
Type *FieldTy = STy->getElementType(i);
if (EltTy == FieldTy)
continue;
// When a recursive record type is converted, some of its pointer fields
// may be converted to the artifical type {}* to break the recursion. As
// type converting the field directly gives the proper pointer type, the
// result is a mismatch between the field and element types. Fix it up.
if (EltTy->isPointerTy() && FieldTy->isPointerTy()) {
Elts[i] = Folder.CreateBitCast(Elts[i], FieldTy);
continue;
}
// Too hard, just give up.
EltTypesMatch = false;
break;
}
if (EltTypesMatch)
return ConstantStruct::get(STy, Elts);
}
// Otherwise return the computed elements as an anonymous struct.
return ConstantStruct::getAnon(Context, Elts, Pack);
}
static Constant *ConvertCONSTRUCTOR(tree exp, TargetFolder &Folder) {
// If the constructor is empty then default initialize all of the components.
// It is safe to use the LLVM type here as it covers every part of the GCC
// type that can possibly be default initialized.
if (CONSTRUCTOR_NELTS(exp) == 0)
return getDefaultValue(ConvertType(TREE_TYPE(exp)));
switch (TREE_CODE(TREE_TYPE(exp))) {
default:
debug_tree(exp);
llvm_unreachable("Unknown constructor!");
case VECTOR_TYPE:
case ARRAY_TYPE:
return ConvertArrayCONSTRUCTOR(exp, Folder);
case QUAL_UNION_TYPE:
case RECORD_TYPE:
case UNION_TYPE:
return ConvertRecordCONSTRUCTOR(exp, Folder);
}
}
static Constant *ConvertMINUS_EXPR(tree exp, TargetFolder &Folder) {
Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
if (LHS->getType()->isPtrOrPtrVectorTy()) {
Type *PtrIntTy = getDataLayout().getIntPtrType(LHS->getType());
LHS = Folder.CreatePtrToInt(LHS, PtrIntTy);
RHS = Folder.CreatePtrToInt(RHS, PtrIntTy);
}
return RepresentAsMemory(Folder.CreateSub(LHS, RHS), main_type(exp), Folder);
}
static Constant *ConvertPLUS_EXPR(tree exp, TargetFolder &Folder) {
Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
return RepresentAsMemory(Folder.CreateAdd(LHS, RHS), main_type(exp), Folder);
}
static Constant *ConvertPOINTER_PLUS_EXPR(tree exp, TargetFolder &Folder) {
Constant *Ptr = getAsRegister(TREE_OPERAND(exp, 0), Folder); // Pointer
Constant *Idx = getAsRegister(TREE_OPERAND(exp, 1), Folder); // Offset (units)
// Convert the pointer into an i8* and add the offset to it.
Ptr = Folder.CreateBitCast(Ptr, GetUnitPointerType(Context));
Constant *Result = POINTER_TYPE_OVERFLOW_UNDEFINED
? Folder.CreateInBoundsGetElementPtr(Ptr, Idx)
: Folder.CreateGetElementPtr(Ptr, Idx);
// The result may be of a different pointer type.
Result = Folder.CreateBitCast(Result, getRegType(TREE_TYPE(exp)));
return RepresentAsMemory(Result, main_type(exp), Folder);
}
static Constant *ConvertVIEW_CONVERT_EXPR(tree exp, TargetFolder &Folder) {
// Does not change the bits, only the type they are considered to be.
return ConvertInitializerImpl(TREE_OPERAND(exp, 0), Folder);
}
/// ConvertInitializerImpl - Implementation of ConvertInitializer.
static Constant *ConvertInitializerImpl(tree exp, TargetFolder &Folder) {
assert(!isa<CONST_DECL>(exp) && !HAS_RTL_P(exp) &&
"Cache collision with decl_llvm!");
// If we already converted the initializer then return the cached copy.
if (Constant *C = cast_or_null<Constant>(getCachedValue(exp)))
return C;
Constant *Init;
switch (TREE_CODE(exp)) {
default:
debug_tree(exp);
llvm_unreachable("Unknown constant to convert!");
case COMPLEX_CST:
case INTEGER_CST:
case REAL_CST:
case VECTOR_CST:
Init = ConvertCST(exp, Folder);
break;
case STRING_CST:
Init = ConvertSTRING_CST(exp, Folder);
break;
case ADDR_EXPR:
Init = ConvertADDR_EXPR(exp, Folder);
break;
case CONSTRUCTOR:
Init = ConvertCONSTRUCTOR(exp, Folder);
break;
case CONVERT_EXPR:
case NOP_EXPR:
Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), main_type(exp),
Folder);
break;
case MINUS_EXPR:
Init = ConvertMINUS_EXPR(exp, Folder);
break;
case PLUS_EXPR:
Init = ConvertPLUS_EXPR(exp, Folder);
break;
case POINTER_PLUS_EXPR:
Init = ConvertPOINTER_PLUS_EXPR(exp, Folder);
break;
case VIEW_CONVERT_EXPR:
Init = ConvertVIEW_CONVERT_EXPR(exp, Folder);
break;
}
// Make the IR easier to read by returning a constant of the expected type if
// it is safe and efficient to do so.
if (!isa<AGGREGATE_TYPE>(TREE_TYPE(exp)))
Init = InterpretAsType(Init, ConvertType(TREE_TYPE(exp)), 0, Folder);
#ifndef NDEBUG
// Check that the guarantees we make about the returned value actually hold.
// The initializer should always be at least as big as the constructor's type,
// and except in the cases of incomplete types or types with variable size the
// sizes should be the same.
Type *Ty = ConvertType(TREE_TYPE(exp));
if (Ty->isSized()) {
uint64_t InitSize = getDataLayout().getTypeAllocSizeInBits(Init->getType());
uint64_t TypeSize = getDataLayout().getTypeAllocSizeInBits(Ty);
if (InitSize < TypeSize) {
debug_tree(exp);
llvm_unreachable("Constant too small for type!");
}
}
if (getDataLayout().getABITypeAlignment(Init->getType()) * 8 >
TYPE_ALIGN(main_type(exp))) {
debug_tree(exp);
llvm_unreachable("Constant over aligned!");
}
#endif
// Cache the result of converting the initializer since the same tree is often
// converted multiple times.
setCachedValue(exp, Init);
return Init;
}
/// ConvertInitializer - Convert the initial value for a global variable to an
/// equivalent LLVM constant. Also handles constant constructors. The type of
/// the returned value may be pretty much anything. All that is guaranteed is
/// that its alloc size is equal to the size of the initial value and that its
/// alignment is less than or equal to the initial value's GCC type alignment.
/// Note that the GCC type may have variable size or no size, in which case the
/// size is determined by the initial value. When this happens the size of the
/// initial value may exceed the alloc size of the LLVM memory type generated
/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
Constant *ConvertInitializer(tree exp) {
TargetFolder Folder(&getDataLayout());
return ConvertInitializerImpl(exp, Folder);
}
//===----------------------------------------------------------------------===//
// ... AddressOf ...
//===----------------------------------------------------------------------===//
/// AddressOfSimpleConstant - Return the address of a simple constant, such as a
/// number or constructor.
static Constant *AddressOfSimpleConstant(tree exp, TargetFolder &Folder) {
Constant *Init = ConvertInitializerImpl(exp, Folder);
// Cache the constants to avoid making obvious duplicates that have to be
// folded by the optimizer.
static DenseMap<Constant *, GlobalVariable *> CSTCache;
GlobalVariable *&Slot = CSTCache[Init];
if (Slot)
return Slot;
// Create a new global variable.
Slot = new GlobalVariable(*TheModule, Init->getType(), true,
GlobalVariable::PrivateLinkage, Init, ".cst");
unsigned align = TYPE_ALIGN(main_type(exp));
#ifdef CONSTANT_ALIGNMENT
align = CONSTANT_ALIGNMENT(exp, align);
#endif
Slot->setAlignment(align);
// Allow identical constants to be merged if the user allowed it.
// FIXME: maybe this flag should be set unconditionally, and instead the
// ConstantMerge pass should be disabled if flag_merge_constants is zero.
Slot->setUnnamedAddr(flag_merge_constants);
return Slot;
}
/// AddressOfARRAY_REF - Return the address of an array element or slice.
static Constant *AddressOfARRAY_REF(tree exp, TargetFolder &Folder) {
tree array = TREE_OPERAND(exp, 0);
tree index = TREE_OPERAND(exp, 1);
tree index_type = main_type(index);
assert(isa<ARRAY_TYPE>(TREE_TYPE(array)) && "Unknown ARRAY_REF!");
// Check for variable sized reference.
assert(isSizeCompatible(main_type(main_type(array))) &&
"Global with variable size?");
// Get the index into the array as an LLVM integer constant.
Constant *IndexVal = getAsRegister(index, Folder);
// Subtract off the lower bound, if any.
tree lower_bound = array_ref_low_bound(exp);
if (!integer_zerop(lower_bound)) {
// Get the lower bound as an LLVM integer constant.
Constant *LowerBoundVal = getAsRegister(lower_bound, Folder);
IndexVal = Folder.CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type),
hasNSW(index_type));
}
// Avoid any assumptions about how the array type is represented in LLVM by
// doing the GEP on a pointer to the first array element.
Constant *ArrayAddr = AddressOfImpl(array, Folder);
Type *EltTy = ConvertType(main_type(main_type(array)));
ArrayAddr = Folder.CreateBitCast(ArrayAddr, EltTy->getPointerTo());
return POINTER_TYPE_OVERFLOW_UNDEFINED
? Folder.CreateInBoundsGetElementPtr(ArrayAddr, IndexVal)
: Folder.CreateGetElementPtr(ArrayAddr, IndexVal);
}
/// AddressOfCOMPONENT_REF - Return the address of a field in a record.
static Constant *AddressOfCOMPONENT_REF(tree exp, TargetFolder &Folder) {
tree field_decl = TREE_OPERAND(exp, 1);
// Compute the field offset in units from the start of the record.
Constant *Offset;
if (TREE_OPERAND(exp, 2)) {
Offset = getAsRegister(TREE_OPERAND(exp, 2), Folder);
// At this point the offset is measured in units divided by (exactly)
// (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to units.
unsigned factor = DECL_OFFSET_ALIGN(field_decl) / BITS_PER_UNIT;
if (factor != 1)
Offset =
Folder.CreateMul(Offset, ConstantInt::get(Offset->getType(), factor));
} else {
assert(DECL_FIELD_OFFSET(field_decl) && "Field offset not available!");
Offset = getAsRegister(DECL_FIELD_OFFSET(field_decl), Folder);
}
// Here BitStart gives the offset of the field in bits from Offset.
uint64_t BitStart = getInt64(DECL_FIELD_BIT_OFFSET(field_decl), true);
// Incorporate as much of it as possible into the pointer computation.
uint64_t Units = BitStart / BITS_PER_UNIT;
if (Units > 0) {
Offset =
Folder.CreateAdd(Offset, ConstantInt::get(Offset->getType(), Units));
BitStart -= Units * BITS_PER_UNIT;
(void) BitStart;
}
assert(BitStart == 0 &&
"It's a bitfield reference or we didn't get to the field!");
Type *UnitPtrTy = GetUnitPointerType(Context);
Constant *StructAddr = AddressOfImpl(TREE_OPERAND(exp, 0), Folder);
Constant *FieldPtr = Folder.CreateBitCast(StructAddr, UnitPtrTy);
FieldPtr = Folder.CreateInBoundsGetElementPtr(FieldPtr, Offset);
return FieldPtr;
}
/// AddressOfCOMPOUND_LITERAL_EXPR - Return the address of a compound literal.
static Constant *
AddressOfCOMPOUND_LITERAL_EXPR(tree exp, TargetFolder &Folder) {
tree decl = DECL_EXPR_DECL(COMPOUND_LITERAL_EXPR_DECL_EXPR(exp));
return AddressOfImpl(decl, Folder);
}
/// AddressOfDecl - Return the address of a global.
static Constant *AddressOfDecl(tree exp, TargetFolder &) {
return cast<Constant>(DEFINITION_LLVM(exp));
}
/// AddressOfINDIRECT_REF - Return the address of a dereference.
static Constant *AddressOfINDIRECT_REF(tree exp, TargetFolder &Folder) {
// The address is just the dereferenced operand. Get it as an LLVM constant.
return getAsRegister(TREE_OPERAND(exp, 0), Folder);
}
/// AddressOfLABEL_DECL - Return the address of a label.
static Constant *AddressOfLABEL_DECL(tree exp, TargetFolder &) {
extern TreeToLLVM *TheTreeToLLVM;
assert(TheTreeToLLVM &&
"taking the address of a label while not compiling the function!");
// Figure out which function this is for, verify it's the one we're compiling.
if (DECL_CONTEXT(exp)) {
assert(isa<FUNCTION_DECL>(DECL_CONTEXT(exp)) &&
"Address of label in nested function?");
assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
"Taking the address of a label that isn't in the current fn!?");
}
return TheTreeToLLVM->AddressOfLABEL_DECL(exp);
}
#if (GCC_MINOR > 5)
/// AddressOfMEM_REF - Return the address of a memory reference.
static Constant *AddressOfMEM_REF(tree exp, TargetFolder &Folder) {
// The address is the first operand offset in bytes by the second.
Constant *Addr = getAsRegister(TREE_OPERAND(exp, 0), Folder);
if (integer_zerop(TREE_OPERAND(exp, 1)))
return Addr;
// Convert to a byte pointer and displace by the offset.
Addr = Folder.CreateBitCast(Addr, GetUnitPointerType(Context));
APInt Delta = getAPIntValue(TREE_OPERAND(exp, 1));
Constant *Offset = ConstantInt::get(Context, Delta);
// The address is always inside the referenced object, so "inbounds".
return Folder.CreateInBoundsGetElementPtr(Addr, Offset);
}
#endif
/// AddressOfImpl - Implementation of AddressOf.
static Constant *AddressOfImpl(tree exp, TargetFolder &Folder) {
Constant *Addr;
switch (TREE_CODE(exp)) {
default:
debug_tree(exp);
llvm_unreachable("Unknown constant to take the address of!");
case COMPLEX_CST:
case FIXED_CST:
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
case VECTOR_CST:
Addr = AddressOfSimpleConstant(exp, Folder);
break;
case ARRAY_RANGE_REF:
case ARRAY_REF:
Addr = AddressOfARRAY_REF(exp, Folder);
break;
case COMPONENT_REF:
Addr = AddressOfCOMPONENT_REF(exp, Folder);
break;
case COMPOUND_LITERAL_EXPR:
Addr = AddressOfCOMPOUND_LITERAL_EXPR(exp, Folder);
break;
case CONSTRUCTOR:
Addr = AddressOfSimpleConstant(exp, Folder);
break;
case CONST_DECL:
case FUNCTION_DECL:
case VAR_DECL:
Addr = AddressOfDecl(exp, Folder);
break;
case INDIRECT_REF:
#if (GCC_MINOR < 6)
case MISALIGNED_INDIRECT_REF:
#endif
Addr = AddressOfINDIRECT_REF(exp, Folder);
break;
case LABEL_DECL:
Addr = AddressOfLABEL_DECL(exp, Folder);
break;
#if (GCC_MINOR > 5)
case MEM_REF:
Addr = AddressOfMEM_REF(exp, Folder);
break;
#endif
}
// Ensure that the address has the expected type. It is simpler to do this
// once here rather than in every AddressOf helper.
Type *Ty;
if (isa<VOID_TYPE>(TREE_TYPE(exp)))
Ty = GetUnitPointerType(Context); // void* -> i8*.
else
Ty = ConvertType(TREE_TYPE(exp))->getPointerTo();
return Folder.CreateBitCast(Addr, Ty);
}
/// AddressOf - Given an expression with a constant address such as a constant,
/// a global variable or a label, returns the address. The type of the returned
/// is always a pointer type and, as long as 'exp' does not have void type, the
/// type of the pointee is the memory type that corresponds to the type of exp
/// (see ConvertType).
Constant *AddressOf(tree exp) {
TargetFolder Folder(&getDataLayout());
return AddressOfImpl(exp, Folder);
}