remove unions from LLVM IR. They are severely buggy and not

being actively maintained, improved, or extended.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-08-28 04:09:24 +00:00
parent 5f88af5376
commit 61c70e98ac
33 changed files with 35 additions and 822 deletions

View File

@ -1367,21 +1367,6 @@ type to the type table.
</p>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"><a name="TYPE_CODE_UNION">TYPE_CODE_UNION Record</a>
</div>
<div class="doc_text">
<p><tt>[UNION, ...eltty...]</tt></p>
<p>The <tt>UNION</tt> record (code 17) adds a <tt>union</tt> type to
the type table. The <i>eltty</i> operand fields are zero or more type
indices representing the element types of the union.
</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="CONSTANTS_BLOCK">CONSTANTS_BLOCK Contents</a>
</div>

View File

@ -26,7 +26,6 @@
<li><a href="#lead0">Why don't GEP x,0,0,1 and GEP x,1 alias? </a></li>
<li><a href="#trail0">Why do GEP x,1,0,0 and GEP x,1 alias? </a></li>
<li><a href="#vectors">Can GEP index into vector elements?</a>
<li><a href="#unions">Can GEP index into unions?</a>
<li><a href="#addrspace">What effect do address spaces have on GEPs?</a>
<li><a href="#int">How is GEP different from ptrtoint, arithmetic, and inttoptr?</a></li>
<li><a href="#be">I'm writing a backend for a target which needs custom lowering for GEP. How do I do this?</a>
@ -369,16 +368,6 @@ idx3 = (char*) &amp;MyVar + 8
<!-- *********************************************************************** -->
<div class="doc_subsection">
<a name="unions"><b>Can GEP index into unions?</b></a>
</div>
<div class="doc_text">
<p>Unknown.</p>
</div>
<!-- *********************************************************************** -->
<div class="doc_subsection">
<a name="addrspace"><b>What effect do address spaces have on GEPs?</b></a>
</div>

View File

@ -74,7 +74,6 @@
<li><a href="#t_array">Array Type</a></li>
<li><a href="#t_struct">Structure Type</a></li>
<li><a href="#t_pstruct">Packed Structure Type</a></li>
<li><a href="#t_union">Union Type</a></li>
<li><a href="#t_vector">Vector Type</a></li>
</ol>
</li>
@ -1475,7 +1474,6 @@ Classifications</a> </div>
<a href="#t_pointer">pointer</a>,
<a href="#t_vector">vector</a>,
<a href="#t_struct">structure</a>,
<a href="#t_union">union</a>,
<a href="#t_array">array</a>,
<a href="#t_label">label</a>,
<a href="#t_metadata">metadata</a>.
@ -1495,7 +1493,6 @@ Classifications</a> </div>
<a href="#t_pointer">pointer</a>,
<a href="#t_struct">structure</a>,
<a href="#t_pstruct">packed structure</a>,
<a href="#t_union">union</a>,
<a href="#t_vector">vector</a>,
<a href="#t_opaque">opaque</a>.
</td>
@ -1643,8 +1640,8 @@ Classifications</a> </div>
<p>Aggregate Types are a subset of derived types that can contain multiple
member types. <a href="#t_array">Arrays</a>,
<a href="#t_struct">structs</a>, <a href="#t_vector">vectors</a> and
<a href="#t_union">unions</a> are aggregate types.</p>
<a href="#t_struct">structs</a>, and <a href="#t_vector">vectors</a> are
aggregate types.</p>
</div>
@ -1714,9 +1711,7 @@ Classifications</a> </div>
<h5>Overview:</h5>
<p>The function type can be thought of as a function signature. It consists of
a return type and a list of formal parameter types. The return type of a
function type is a scalar type, a void type, a struct type, or a union
type. If the return type is a struct type then all struct elements must be
of first class types, and the struct must have at least one element.</p>
function type is a first class type or a void type.</p>
<h5>Syntax:</h5>
<pre>
@ -1837,53 +1832,6 @@ Classifications</a> </div>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <a name="t_union">Union Type</a> </div>
<div class="doc_text">
<h5>Overview:</h5>
<p>A union type describes an object with size and alignment suitable for
an object of any one of a given set of types (also known as an "untagged"
union). It is similar in concept and usage to a
<a href="#t_struct">struct</a>, except that all members of the union
have an offset of zero. The elements of a union may be any type that has a
size. Unions must have at least one member - empty unions are not allowed.
</p>
<p>The size of the union as a whole will be the size of its largest member,
and the alignment requirements of the union as a whole will be the largest
alignment requirement of any member.</p>
<p>Union members are accessed using '<tt><a href="#i_load">load</a></tt> and
'<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
Since all members are at offset zero, the getelementptr instruction does
not affect the address, only the type of the resulting pointer.</p>
<h5>Syntax:</h5>
<pre>
union { &lt;type list&gt; }
</pre>
<h5>Examples:</h5>
<table class="layout">
<tr class="layout">
<td class="left"><tt>union { i32, i32*, float }</tt></td>
<td class="left">A union of three types: an <tt>i32</tt>, a pointer to
an <tt>i32</tt>, and a <tt>float</tt>.</td>
</tr><tr class="layout">
<td class="left">
<tt>union {&nbsp;float,&nbsp;i32&nbsp;(i32)&nbsp;*&nbsp;}</tt></td>
<td class="left">A union, where the first element is a <tt>float</tt> and the
second element is a <a href="#t_pointer">pointer</a> to a
<a href="#t_function">function</a> that takes an <tt>i32</tt>, returning
an <tt>i32</tt>.</td>
</tr>
</table>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <a name="t_pointer">Pointer Type</a> </div>
@ -2125,14 +2073,6 @@ Classifications</a> </div>
the number and types of elements must match those specified by the
type.</dd>
<dt><b>Union constants</b></dt>
<dd>Union constants are represented with notation similar to a structure with
a single element - that is, a single typed element surrounded
by braces (<tt>{}</tt>)). For example: "<tt>{ i32 4 }</tt>". The
<a href="#t_union">union type</a> can be initialized with a single-element
struct as long as the type of the struct element matches the type of
one of the union members.</dd>
<dt><b>Array constants</b></dt>
<dd>Array constants are represented with notation similar to array type
definitions (a comma separated list of elements, surrounded by square
@ -4153,7 +4093,7 @@ Instruction</a> </div>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>extractvalue</tt>' instruction is a value
of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
of <a href="#t_struct">struct</a> or
<a href="#t_array">array</a> type. The operands are constant indices to
specify which value to extract in a similar manner as indices in a
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.</p>
@ -4187,7 +4127,7 @@ Instruction</a> </div>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>insertvalue</tt>' instruction is a value
of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
of <a href="#t_struct">struct</a> or
<a href="#t_array">array</a> type. The second operand is a first-class
value to insert. The following operands are constant indices indicating
the position at which to insert the value in a similar manner as indices in a
@ -4420,12 +4360,12 @@ Instruction</a> </div>
indexes a value of the type pointed to (not necessarily the value directly
pointed to, since the first index can be non-zero), etc. The first type
indexed into must be a pointer value, subsequent types can be arrays,
vectors, structs and unions. Note that subsequent types being indexed into
vectors, and structs. Note that subsequent types being indexed into
can never be pointers, since that would require loading the pointer before
continuing calculation.</p>
<p>The type of each index argument depends on the type it is indexing into.
When indexing into a (optionally packed) structure or union, only <tt>i32</tt>
When indexing into a (optionally packed) structure, only <tt>i32</tt>
integer <b>constants</b> are allowed. When indexing into an array, pointer
or vector, integers of any width are allowed, and they are not required to be
constant.</p>

View File

@ -67,9 +67,8 @@ Almost dead code.
include/llvm/Analysis/LiveValues.h => Dan
lib/Transforms/IPO/MergeFunctions.cpp => consider for 2.8.
llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8.
ABCD, GEPSplitterPass
GEPSplitterPass
MSIL backend?
lib/Transforms/Utils/SSI.cpp -> ABCD depends on it.
-->

View File

@ -204,8 +204,7 @@ typedef enum {
LLVMPointerTypeKind, /**< Pointers */
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
LLVMMetadataTypeKind, /**< Metadata */
LLVMUnionTypeKind /**< Unions */
LLVMMetadataTypeKind /**< Metadata */
} LLVMTypeKind;
typedef enum {
@ -395,13 +394,6 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
/* Operations on union types */
LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
unsigned ElementCount);
LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount);
unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy);
void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest);
/* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
@ -574,7 +566,6 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
LLVMBool Packed);
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val);
/* Constant expressions */
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);

View File

@ -94,8 +94,7 @@ namespace bitc {
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
TYPE_CODE_METADATA = 16, // METADATA
TYPE_CODE_UNION = 17 // UNION: [eltty x N]
TYPE_CODE_METADATA = 16 // METADATA
};
// The type symbol table only has one code (TST_ENTRY_CODE).

View File

@ -33,7 +33,6 @@ namespace llvm {
class ArrayType;
class IntegerType;
class StructType;
class UnionType;
class PointerType;
class VectorType;
@ -459,49 +458,6 @@ struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> {
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
//===----------------------------------------------------------------------===//
// ConstantUnion - Constant Union Declarations
//
class ConstantUnion : public Constant {
friend struct ConstantCreator<ConstantUnion, UnionType, Constant*>;
ConstantUnion(const ConstantUnion &); // DO NOT IMPLEMENT
protected:
ConstantUnion(const UnionType *T, Constant* Val);
public:
// ConstantUnion accessors
static Constant *get(const UnionType *T, Constant* V);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
/// getType() specialization - Reduce amount of casting...
///
inline const UnionType *getType() const {
return reinterpret_cast<const UnionType*>(Value::getType());
}
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero structs are always
/// created as ConstantAggregateZero objects.
virtual bool isNullValue() const {
return false;
}
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const ConstantUnion *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantUnionVal;
}
};
template <>
struct OperandTraits<ConstantUnion> : public FixedNumOperandTraits<1> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantUnion, Constant)
//===----------------------------------------------------------------------===//
/// ConstantVector - Constant Vector Declarations

View File

@ -27,7 +27,6 @@ template<class ValType, class TypeClass> class TypeMap;
class FunctionValType;
class ArrayValType;
class StructValType;
class UnionValType;
class PointerValType;
class VectorValType;
class IntegerValType;
@ -226,8 +225,7 @@ public:
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID ||
T->getTypeID() == UnionTyID;
T->getTypeID() == VectorTyID;
}
};
@ -298,64 +296,6 @@ public:
bool isPacked() const { return (0 != getSubclassData()) ? true : false; }
};
/// UnionType - Class to represent union types. A union type is similar to
/// a structure, except that all member fields begin at offset 0.
///
class UnionType : public CompositeType {
friend class TypeMap<UnionValType, UnionType>;
UnionType(const UnionType &); // Do not implement
const UnionType &operator=(const UnionType &); // Do not implement
UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes);
public:
/// UnionType::get - This static method is the primary way to create a
/// UnionType.
static UnionType *get(const Type* const* Types, unsigned NumTypes);
/// UnionType::get - This static method is a convenience method for
/// creating union types by specifying the elements as arguments.
static UnionType *get(const Type *type, ...) END_WITH_NULL;
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(const Type *ElemTy);
/// Given an element type, return the member index of that type, or -1
/// if there is no such member type.
int getElementTypeIndex(const Type *ElemTy) const;
// Iterator access to the elements
typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; }
element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
// Random access to the elements
unsigned getNumElements() const { return NumContainedTys; }
const Type *getElementType(unsigned N) const {
assert(N < NumContainedTys && "Element number out of range!");
return ContainedTys[N];
}
/// getTypeAtIndex - Given an index value into the type, return the type of
/// the element. For a union type, this must be a constant value...
///
virtual const Type *getTypeAtIndex(const Value *V) const;
virtual const Type *getTypeAtIndex(unsigned Idx) const;
virtual bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned Idx) const;
// Implement the AbstractTypeUser interface.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const UnionType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == UnionTyID;
}
};
/// SequentialType - This is the superclass of the array, pointer and vector
/// type classes. All of these represent "arrays" in memory. The array type
/// represents a specifically sized array, pointer types are unsized/unknown

View File

@ -82,11 +82,10 @@ public:
IntegerTyID, ///< 8: Arbitrary bit width integers
FunctionTyID, ///< 9: Functions
StructTyID, ///< 10: Structures
UnionTyID, ///< 11: Unions
ArrayTyID, ///< 12: Arrays
PointerTyID, ///< 13: Pointers
OpaqueTyID, ///< 14: Opaque: type with unknown structure
VectorTyID, ///< 15: SIMD 'packed' format, or other vector type
ArrayTyID, ///< 11: Arrays
PointerTyID, ///< 12: Pointers
OpaqueTyID, ///< 13: Opaque: type with unknown structure
VectorTyID, ///< 14: SIMD 'packed' format, or other vector type
NumTypeIDs, // Must remain as last defined ID
LastPrimitiveTyID = MetadataTyID,
@ -243,10 +242,6 @@ public:
///
bool isStructTy() const { return ID == StructTyID; }
/// isUnionTy - True if this is an instance of UnionType.
///
bool isUnionTy() const { return ID == UnionTyID; }
/// isArrayTy - True if this is an instance of ArrayType.
///
bool isArrayTy() const { return ID == ArrayTyID; }
@ -306,7 +301,7 @@ public:
/// does not include vector types.
///
inline bool isAggregateType() const {
return ID == StructTyID || ID == ArrayTyID || ID == UnionTyID;
return ID == StructTyID || ID == ArrayTyID;
}
/// isSized - Return true if it makes sense to take the size of this type. To
@ -319,8 +314,7 @@ public:
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID &&
ID != UnionTyID)
if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID)
return false;
// If it is something that can have a size and it's concrete, it definitely
// has a size, otherwise we have to try harder to decide.

View File

@ -215,7 +215,6 @@ public:
ConstantFPVal, // This is an instance of ConstantFP
ConstantArrayVal, // This is an instance of ConstantArray
ConstantStructVal, // This is an instance of ConstantStruct
ConstantUnionVal, // This is an instance of ConstantUnion
ConstantVectorVal, // This is an instance of ConstantVector
ConstantPointerNullVal, // This is an instance of ConstantPointerNull
MDNodeVal, // This is an instance of MDNode

View File

@ -573,7 +573,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(type);
KEYWORD(opaque);
KEYWORD(union);
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);

View File

@ -1359,11 +1359,6 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
if (ParseStructType(Result, false))
return true;
break;
case lltok::kw_union:
// TypeRec ::= 'union' '{' ... '}'
if (ParseUnionType(Result))
return true;
break;
case lltok::lsquare:
// TypeRec ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
@ -1673,38 +1668,6 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
return false;
}
/// ParseUnionType
/// TypeRec
/// ::= 'union' '{' TypeRec (',' TypeRec)* '}'
bool LLParser::ParseUnionType(PATypeHolder &Result) {
assert(Lex.getKind() == lltok::kw_union);
Lex.Lex(); // Consume the 'union'
if (ParseToken(lltok::lbrace, "'{' expected after 'union'")) return true;
SmallVector<PATypeHolder, 8> ParamsList;
do {
LocTy EltTyLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
ParamsList.push_back(Result);
if (Result->isVoidTy())
return Error(EltTyLoc, "union element can not have void type");
if (!UnionType::isValidElementType(Result))
return Error(EltTyLoc, "invalid element type for union");
} while (EatIfPresent(lltok::comma)) ;
if (ParseToken(lltok::rbrace, "expected '}' at end of union"))
return true;
SmallVector<const Type*, 8> ParamsListTy;
for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
ParamsListTy.push_back(ParamsList[i].get());
Result = HandleUpRefs(UnionType::get(&ParamsListTy[0], ParamsListTy.size()));
return false;
}
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
/// token has already been consumed.
/// TypeRec
@ -2656,16 +2619,8 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = Constant::getNullValue(Ty);
return false;
case ValID::t_Constant:
if (ID.ConstantVal->getType() != Ty) {
// Allow a constant struct with a single member to be converted
// to a union, if the union has a member which is the same type
// as the struct member.
if (const UnionType* utype = dyn_cast<UnionType>(Ty)) {
return ParseUnionValue(utype, ID, V);
}
if (ID.ConstantVal->getType() != Ty)
return Error(ID.Loc, "constant expression type mismatch");
}
V = ID.ConstantVal;
return false;
@ -2696,22 +2651,6 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
return false;
}
bool LLParser::ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V) {
if (const StructType* stype = dyn_cast<StructType>(ID.ConstantVal->getType())) {
if (stype->getNumContainedTypes() != 1)
return Error(ID.Loc, "constant expression type mismatch");
int index = utype->getElementTypeIndex(stype->getContainedType(0));
if (index < 0)
return Error(ID.Loc, "initializer type is not a member of the union");
V = ConstantUnion::get(
utype, cast<Constant>(ID.ConstantVal->getOperand(0)));
return false;
}
return Error(ID.Loc, "constant expression type mismatch");
}
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs

View File

@ -32,7 +32,6 @@ namespace llvm {
class GlobalValue;
class MDString;
class MDNode;
class UnionType;
/// ValID - Represents a reference of a definition of some sort with no type.
/// There are several cases where we have to parse the value but where the
@ -229,7 +228,6 @@ namespace llvm {
}
bool ParseTypeRec(PATypeHolder &H);
bool ParseStructType(PATypeHolder &H, bool Packed);
bool ParseUnionType(PATypeHolder &H);
bool ParseArrayVectorType(PATypeHolder &H, bool isVector);
bool ParseFunctionType(PATypeHolder &Result);
PATypeHolder HandleUpRefs(const Type *Ty);
@ -298,7 +296,6 @@ namespace llvm {
return ParseTypeAndBasicBlock(BB, Loc, PFS);
}
bool ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V);
struct ParamInfo {
LocTy Loc;

View File

@ -98,7 +98,6 @@ namespace lltok {
kw_type,
kw_opaque,
kw_union,
kw_eq, kw_ne, kw_slt, kw_sgt, kw_sle, kw_sge, kw_ult, kw_ugt, kw_ule,
kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno,

View File

@ -297,8 +297,6 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
} else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
NewC = ConstantStruct::get(Context, &NewOps[0], NewOps.size(),
UserCS->getType()->isPacked());
} else if (ConstantUnion *UserCU = dyn_cast<ConstantUnion>(UserC)) {
NewC = ConstantUnion::get(UserCU->getType(), NewOps[0]);
} else if (isa<ConstantVector>(UserC)) {
NewC = ConstantVector::get(&NewOps[0], NewOps.size());
} else {
@ -591,13 +589,6 @@ bool BitcodeReader::ParseTypeTable() {
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
case bitc::TYPE_CODE_UNION: { // UNION: [eltty x N]
SmallVector<const Type*, 8> EltTys;
for (unsigned i = 0, e = Record.size(); i != e; ++i)
EltTys.push_back(getTypeByID(Record[i], true));
ResultTy = UnionType::get(&EltTys[0], EltTys.size());
break;
}
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
@ -1014,11 +1005,6 @@ bool BitcodeReader::ParseConstants() {
Elts.push_back(ValueList.getConstantFwdRef(Record[i],
STy->getElementType(i)));
V = ConstantStruct::get(STy, Elts);
} else if (const UnionType *UnTy = dyn_cast<UnionType>(CurTy)) {
uint64_t Index = Record[0];
Constant *Val = ValueList.getConstantFwdRef(Record[1],
UnTy->getElementType(Index));
V = ConstantUnion::get(UnTy, Val);
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
const Type *EltTy = ATy->getElementType();
for (unsigned i = 0; i != Size; ++i)

View File

@ -181,14 +181,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Log2_32_Ceil(VE.getTypes().size()+1)));
unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_UNION.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_UNION));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
Log2_32_Ceil(VE.getTypes().size()+1)));
unsigned UnionAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
@ -258,17 +250,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
AbbrevToUse = StructAbbrev;
break;
}
case Type::UnionTyID: {
const UnionType *UT = cast<UnionType>(T);
// UNION: [eltty x N]
Code = bitc::TYPE_CODE_UNION;
// Output all of the element types.
for (UnionType::element_iterator I = UT->element_begin(),
E = UT->element_end(); I != E; ++I)
TypeVals.push_back(VE.getTypeID(*I));
AbbrevToUse = UnionAbbrev;
break;
}
case Type::ArrayTyID: {
const ArrayType *AT = cast<ArrayType>(T);
// ARRAY: [numelts, eltty]
@ -811,20 +792,6 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(C->getOperand(i)));
AbbrevToUse = AggregateAbbrev;
} else if (isa<ConstantUnion>(C)) {
Code = bitc::CST_CODE_AGGREGATE;
// Unions only have one entry but we must send type along with it.
const Type *EntryKind = C->getOperand(0)->getType();
const UnionType *UnTy = cast<UnionType>(C->getType());
int UnionIndex = UnTy->getElementTypeIndex(EntryKind);
assert(UnionIndex != -1 && "Constant union contains invalid entry");
Record.push_back(UnionIndex);
Record.push_back(VE.getValueID(C->getOperand(0)));
AbbrevToUse = AggregateAbbrev;
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
switch (CE->getOpcode()) {
default:

View File

@ -1433,21 +1433,6 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
"Layout of constant struct may be incorrect!");
}
static void EmitGlobalConstantUnion(const ConstantUnion *CU,
unsigned AddrSpace, AsmPrinter &AP) {
const TargetData *TD = AP.TM.getTargetData();
unsigned Size = TD->getTypeAllocSize(CU->getType());
const Constant *Contents = CU->getOperand(0);
unsigned FilledSize = TD->getTypeAllocSize(Contents->getType());
// Print the actually filled part
EmitGlobalConstantImpl(Contents, AddrSpace, AP);
// And pad with enough zeroes
AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace);
}
static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
AsmPrinter &AP) {
// FP Constants are printed as integer constants to avoid losing
@ -1573,9 +1558,6 @@ static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
return;
}
if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV))
return EmitGlobalConstantUnion(CVU, AddrSpace, AP);
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
return EmitGlobalConstantVector(V, AddrSpace, AP);

View File

@ -2804,11 +2804,6 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
}
Ty = StTy->getElementType(Field);
} else if (const UnionType *UnTy = dyn_cast<UnionType>(Ty)) {
unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
// Offset canonically 0 for unions, but type changes
Ty = UnTy->getElementType(Field);
} else {
Ty = cast<SequentialType>(Ty)->getElementType();

View File

@ -454,15 +454,6 @@ uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
case Type::StructTyID:
// Get the layout annotation... which is lazily created on demand.
return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
case Type::UnionTyID: {
const UnionType *UnTy = cast<UnionType>(Ty);
uint64_t Size = 0;
for (UnionType::element_iterator i = UnTy->element_begin(),
e = UnTy->element_end(); i != e; ++i) {
Size = std::max(Size, getTypeSizeInBits(*i));
}
return Size;
}
case Type::IntegerTyID:
return cast<IntegerType>(Ty)->getBitWidth();
case Type::VoidTyID:
@ -519,17 +510,6 @@ unsigned TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const {
unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
return std::max(Align, Layout->getAlignment());
}
case Type::UnionTyID: {
const UnionType *UnTy = cast<UnionType>(Ty);
unsigned Align = 1;
// Unions need the maximum alignment of all their entries
for (UnionType::element_iterator i = UnTy->element_begin(),
e = UnTy->element_end(); i != e; ++i) {
Align = std::max(Align, getAlignment(*i, abi_or_pref));
}
return Align;
}
case Type::IntegerTyID:
case Type::VoidTyID:
AlignType = INTEGER_ALIGN;
@ -614,11 +594,6 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
// Update Ty to refer to current element
Ty = STy->getElementType(FieldNo);
} else if (const UnionType *UnTy = dyn_cast<UnionType>(*TI)) {
unsigned FieldNo = cast<ConstantInt>(Indices[CurIDX])->getZExtValue();
// Offset into union is canonically 0, but type changes
Ty = UnTy->getElementType(FieldNo);
} else {
// Update Ty to refer to current element
Ty = cast<SequentialType>(Ty)->getElementType();

View File

@ -220,20 +220,6 @@ bool FunctionComparator::isEquivalentType(const Type *Ty1,
return true;
}
case Type::UnionTyID: {
const UnionType *UTy1 = cast<UnionType>(Ty1);
const UnionType *UTy2 = cast<UnionType>(Ty2);
if (UTy1->getNumElements() != UTy2->getNumElements())
return false;
for (unsigned i = 0, e = UTy1->getNumElements(); i != e; ++i) {
if (!isEquivalentType(UTy1->getElementType(i), UTy2->getElementType(i)))
return false;
}
return true;
}
case Type::FunctionTyID: {
const FunctionType *FTy1 = cast<FunctionType>(Ty1);
const FunctionType *FTy2 = cast<FunctionType>(Ty2);

View File

@ -238,21 +238,6 @@ void TypePrinting::CalcTypeName(const Type *Ty,
OS << '>';
break;
}
case Type::UnionTyID: {
const UnionType *UTy = cast<UnionType>(Ty);
OS << "union {";
for (StructType::element_iterator I = UTy->element_begin(),
E = UTy->element_end(); I != E; ++I) {
OS << ' ';
CalcTypeName(*I, TypeStack, OS);
if (llvm::next(I) == UTy->element_end())
OS << ' ';
else
OS << ',';
}
OS << '}';
break;
}
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
CalcTypeName(PTy->getElementType(), TypeStack, OS);
@ -1042,16 +1027,6 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
if (const ConstantUnion *CU = dyn_cast<ConstantUnion>(CV)) {
Out << "{ ";
TypePrinter.print(CU->getOperand(0)->getType(), Out);
Out << ' ';
WriteAsOperandInternal(Out, CU->getOperand(0), &TypePrinter, Machine,
Context);
Out << " }";
return;
}
if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
const Type *ETy = CP->getType()->getElementType();
assert(CP->getNumOperands() > 0 &&

View File

@ -357,22 +357,6 @@ static Constant *getFoldedSizeOf(const Type *Ty, const Type *DestTy,
}
}
if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
unsigned NumElems = UTy->getNumElements();
// Check for a union with all members having the same size.
Constant *MemberSize =
getFoldedSizeOf(UTy->getElementType(0), DestTy, true);
bool AllSame = true;
for (unsigned i = 1; i != NumElems; ++i)
if (MemberSize !=
getFoldedSizeOf(UTy->getElementType(i), DestTy, true)) {
AllSame = false;
break;
}
if (AllSame)
return MemberSize;
}
// Pointer size doesn't depend on the pointee type, so canonicalize them
// to an arbitrary pointee.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
@ -438,24 +422,6 @@ static Constant *getFoldedAlignOf(const Type *Ty, const Type *DestTy,
return MemberAlign;
}
if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
// Union alignment is the maximum alignment of any member.
// Without target data, we can't compare much, but we can check to see
// if all the members have the same alignment.
unsigned NumElems = UTy->getNumElements();
// Check for a union with all members having the same alignment.
Constant *MemberAlign =
getFoldedAlignOf(UTy->getElementType(0), DestTy, true);
bool AllSame = true;
for (unsigned i = 1; i != NumElems; ++i)
if (MemberAlign != getFoldedAlignOf(UTy->getElementType(i), DestTy, true)) {
AllSame = false;
break;
}
if (AllSame)
return MemberAlign;
}
// Pointer alignment doesn't depend on the pointee type, so canonicalize them
// to an arbitrary pointee.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
@ -909,8 +875,6 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
unsigned numOps;
if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy))
numOps = AR->getNumElements();
else if (AggTy->isUnionTy())
numOps = 1;
else
numOps = cast<StructType>(AggTy)->getNumElements();
@ -927,10 +891,6 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
if (const StructType* ST = dyn_cast<StructType>(AggTy))
return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
if (const UnionType* UT = dyn_cast<UnionType>(AggTy)) {
assert(Ops.size() == 1 && "Union can only contain a single value!");
return ConstantUnion::get(UT, Ops[0]);
}
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}

View File

@ -59,7 +59,6 @@ Constant *Constant::getNullValue(const Type *Ty) {
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
case Type::UnionTyID:
case Type::ArrayTyID:
case Type::VectorTyID:
return ConstantAggregateZero::get(Ty);
@ -587,27 +586,6 @@ Constant* ConstantStruct::get(LLVMContext &Context,
return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
}
ConstantUnion::ConstantUnion(const UnionType *T, Constant* V)
: Constant(T, ConstantUnionVal,
OperandTraits<ConstantUnion>::op_end(this) - 1, 1) {
Use *OL = OperandList;
assert(T->getElementTypeIndex(V->getType()) >= 0 &&
"Initializer for union element isn't a member of union type!");
*OL = V;
}
// ConstantUnion accessors.
Constant* ConstantUnion::get(const UnionType* T, Constant* V) {
LLVMContextImpl* pImpl = T->getContext().pImpl;
// Create a ConstantAggregateZero value if all elements are zeros...
if (!V->isNullValue())
return pImpl->UnionConstants.getOrCreate(T, V);
return ConstantAggregateZero::get(T);
}
ConstantVector::ConstantVector(const VectorType *T,
const std::vector<Constant*> &V)
: Constant(T, ConstantVectorVal,
@ -946,8 +924,7 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
// Factory Function Implementation
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
assert((Ty->isStructTy() || Ty->isUnionTy()
|| Ty->isArrayTy() || Ty->isVectorTy()) &&
assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
"Cannot create an aggregate zero of non-aggregate type!");
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
@ -1032,13 +1009,6 @@ void ConstantStruct::destroyConstant() {
destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantUnion::destroyConstant() {
getRawType()->getContext().pImpl->UnionConstants.remove(this);
destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantVector::destroyConstant() {
@ -2117,55 +2087,6 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
destroyConstant();
}
void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
assert(U == OperandList && "Union constants can only have one use!");
assert(getNumOperands() == 1 && "Union constants can only have one use!");
assert(getOperand(0) == From && "ReplaceAllUsesWith broken!");
std::pair<LLVMContextImpl::UnionConstantsTy::MapKey, ConstantUnion*> Lookup;
Lookup.first.first = cast<UnionType>(getRawType());
Lookup.second = this;
Lookup.first.second = ToC;
LLVMContextImpl *pImpl = getRawType()->getContext().pImpl;
Constant *Replacement = 0;
if (ToC->isNullValue()) {
Replacement = ConstantAggregateZero::get(getRawType());
} else {
// Check to see if we have this union type already.
bool Exists;
LLVMContextImpl::UnionConstantsTy::MapTy::iterator I =
pImpl->UnionConstants.InsertOrGetItem(Lookup, Exists);
if (Exists) {
Replacement = I->second;
} else {
// Okay, the new shape doesn't exist in the system yet. Instead of
// creating a new constant union, inserting it, replaceallusesof'ing the
// old with the new, then deleting the old... just update the current one
// in place!
pImpl->UnionConstants.MoveConstantToNewSlot(this, I);
// Update to the new value.
setOperand(0, ToC);
return;
}
}
assert(Replacement != this && "I didn't contain From!");
// Everyone using this now uses the replacement.
uncheckedReplaceAllUsesWith(Replacement);
// Delete the old constant!
destroyConstant();
}
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");

View File

@ -511,14 +511,6 @@ struct ConstantKeyData<ConstantStruct> {
}
};
template<>
struct ConstantKeyData<ConstantUnion> {
typedef Constant* ValType;
static ValType getValType(ConstantUnion *CU) {
return cast<Constant>(CU->getOperand(0));
}
};
// ConstantPointerNull does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {

View File

@ -156,8 +156,6 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMFunctionTypeKind;
case Type::StructTyID:
return LLVMStructTypeKind;
case Type::UnionTyID:
return LLVMUnionTypeKind;
case Type::ArrayTyID:
return LLVMArrayTypeKind;
case Type::PointerTyID:
@ -316,34 +314,6 @@ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) {
return unwrap<StructType>(StructTy)->isPacked();
}
/*--.. Operations on union types ..........................................--*/
LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
unsigned ElementCount) {
SmallVector<const Type*, 8> Tys;
for (LLVMTypeRef *I = ElementTypes,
*E = ElementTypes + ElementCount; I != E; ++I)
Tys.push_back(unwrap(*I));
return wrap(UnionType::get(&Tys[0], Tys.size()));
}
LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount) {
return LLVMUnionTypeInContext(LLVMGetGlobalContext(), ElementTypes,
ElementCount);
}
unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy) {
return unwrap<UnionType>(UnionTy)->getNumElements();
}
void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest) {
UnionType *Ty = unwrap<UnionType>(UnionTy);
for (FunctionType::param_iterator I = Ty->element_begin(),
E = Ty->element_end(); I != E; ++I)
*Dest++ = wrap(*I);
}
/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) {
@ -628,10 +598,6 @@ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) {
return wrap(ConstantVector::get(
unwrap<Constant>(ScalarConstantVals, Size), Size));
}
LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val) {
return wrap(ConstantUnion::get(unwrap<UnionType>(Ty), unwrap<Constant>(Val)));
}
/*--.. Constant expressions ................................................--*/
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) {

View File

@ -57,14 +57,11 @@ LLVMContextImpl::~LLVMContextImpl() {
DropReferences());
std::for_each(StructConstants.map_begin(), StructConstants.map_end(),
DropReferences());
std::for_each(UnionConstants.map_begin(), UnionConstants.map_end(),
DropReferences());
std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(),
DropReferences());
ExprConstants.freeConstants();
ArrayConstants.freeConstants();
StructConstants.freeConstants();
UnionConstants.freeConstants();
VectorConstants.freeConstants();
AggZeroConstants.freeConstants();
NullPtrConstants.freeConstants();

View File

@ -144,10 +144,6 @@ public:
ConstantStruct, true /*largekey*/> StructConstantsTy;
StructConstantsTy StructConstants;
typedef ConstantUniqueMap<Constant*, UnionType, ConstantUnion>
UnionConstantsTy;
UnionConstantsTy UnionConstants;
typedef ConstantUniqueMap<std::vector<Constant*>, VectorType,
ConstantVector> VectorConstantsTy;
VectorConstantsTy VectorConstants;
@ -192,7 +188,6 @@ public:
TypeMap<PointerValType, PointerType> PointerTypes;
TypeMap<FunctionValType, FunctionType> FunctionTypes;
TypeMap<StructValType, StructType> StructTypes;
TypeMap<UnionValType, UnionType> UnionTypes;
TypeMap<IntegerValType, IntegerType> IntegerTypes;
// Opaque types are not structurally uniqued, so don't use TypeMap.

View File

@ -50,7 +50,7 @@ void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
/// Because of the way Type subclasses are allocated, this function is necessary
/// to use the correct kind of "delete" operator to deallocate the Type object.
/// Some type objects (FunctionTy, StructTy, UnionTy) allocate additional space
/// Some type objects (FunctionTy, StructTy) allocate additional space
/// after the space for their derived type to hold the contained types array of
/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are
/// allocated with the type object, decreasing allocations and eliminating the
@ -66,8 +66,7 @@ void Type::destroy() const {
// Structures and Functions allocate their contained types past the end of
// the type object itself. These need to be destroyed differently than the
// other types.
if (this->isFunctionTy() || this->isStructTy() ||
this->isUnionTy()) {
if (this->isFunctionTy() || this->isStructTy()) {
// First, make sure we destruct any PATypeHandles allocated by these
// subclasses. They must be manually destructed.
for (unsigned i = 0; i < NumContainedTys; ++i)
@ -77,10 +76,10 @@ void Type::destroy() const {
// to delete this as an array of char.
if (this->isFunctionTy())
static_cast<const FunctionType*>(this)->FunctionType::~FunctionType();
else if (this->isStructTy())
else {
assert(isStructTy());
static_cast<const StructType*>(this)->StructType::~StructType();
else
static_cast<const UnionType*>(this)->UnionType::~UnionType();
}
// Finally, remove the memory as an array deallocation of the chars it was
// constructed from.
@ -234,7 +233,7 @@ bool Type::isSizedDerivedType() const {
if (const VectorType *PTy = dyn_cast<VectorType>(this))
return PTy->getElementType()->isSized();
if (!this->isStructTy() && !this->isUnionTy())
if (!this->isStructTy())
return false;
// Okay, our struct is sized if all of the elements are...
@ -319,31 +318,6 @@ const Type *StructType::getTypeAtIndex(unsigned Idx) const {
}
bool UnionType::indexValid(const Value *V) const {
// Union indexes require 32-bit integer constants.
if (V->getType()->isIntegerTy(32))
if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
return indexValid(CU->getZExtValue());
return false;
}
bool UnionType::indexValid(unsigned V) const {
return V < NumContainedTys;
}
// getTypeAtIndex - Given an index value into the type, return the type of the
// element. For a structure type, this must be a constant value...
//
const Type *UnionType::getTypeAtIndex(const Value *V) const {
unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
return getTypeAtIndex(Idx);
}
const Type *UnionType::getTypeAtIndex(unsigned Idx) const {
assert(indexValid(Idx) && "Invalid structure index!");
return ContainedTys[Idx];
}
//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
@ -507,23 +481,6 @@ StructType::StructType(LLVMContext &C,
setAbstract(isAbstract);
}
UnionType::UnionType(LLVMContext &C,const Type* const* Types, unsigned NumTypes)
: CompositeType(C, UnionTyID) {
ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1);
NumContainedTys = NumTypes;
bool isAbstract = false;
for (unsigned i = 0; i < NumTypes; ++i) {
assert(Types[i] && "<null> type for union field!");
assert(isValidElementType(Types[i]) &&
"Invalid type for union element!");
new (&ContainedTys[i]) PATypeHandle(Types[i], this);
isAbstract |= Types[i]->isAbstract();
}
// Calculate whether or not this type is abstract
setAbstract(isAbstract);
}
ArrayType::ArrayType(const Type *ElType, uint64_t NumEl)
: SequentialType(ArrayTyID, ElType) {
NumElements = NumEl;
@ -711,15 +668,6 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
return true;
}
if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
const UnionType *UTy2 = cast<UnionType>(Ty2);
if (UTy->getNumElements() != UTy2->getNumElements()) return false;
for (unsigned i = 0, e = UTy2->getNumElements(); i != e; ++i)
if (!TypesEqual(UTy->getElementType(i), UTy2->getElementType(i), EqTypes))
return false;
return true;
}
if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
const ArrayType *ATy2 = cast<ArrayType>(Ty2);
return ATy->getNumElements() == ATy2->getNumElements() &&
@ -986,60 +934,6 @@ bool StructType::isValidElementType(const Type *ElemTy) {
}
//===----------------------------------------------------------------------===//
// Union Type Factory...
//
UnionType *UnionType::get(const Type* const* Types, unsigned NumTypes) {
assert(NumTypes > 0 && "union must have at least one member type!");
UnionValType UTV(Types, NumTypes);
UnionType *UT = 0;
LLVMContextImpl *pImpl = Types[0]->getContext().pImpl;
UT = pImpl->UnionTypes.get(UTV);
if (!UT) {
// Value not found. Derive a new type!
UT = (UnionType*) operator new(sizeof(UnionType) +
sizeof(PATypeHandle) * NumTypes);
new (UT) UnionType(Types[0]->getContext(), Types, NumTypes);
pImpl->UnionTypes.add(UTV, UT);
}
#ifdef DEBUG_MERGE_TYPES
DEBUG(dbgs() << "Derived new type: " << *UT << "\n");
#endif
return UT;
}
UnionType *UnionType::get(const Type *type, ...) {
va_list ap;
SmallVector<const llvm::Type*, 8> UnionFields;
va_start(ap, type);
while (type) {
UnionFields.push_back(type);
type = va_arg(ap, llvm::Type*);
}
unsigned NumTypes = UnionFields.size();
assert(NumTypes > 0 && "union must have at least one member type!");
return llvm::UnionType::get(&UnionFields[0], NumTypes);
}
bool UnionType::isValidElementType(const Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
!ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
}
int UnionType::getElementTypeIndex(const Type *ElemTy) const {
int index = 0;
for (UnionType::element_iterator I = element_begin(), E = element_end();
I != E; ++I, ++index) {
if (ElemTy == *I) return index;
}
return -1;
}
//===----------------------------------------------------------------------===//
// Pointer Type Factory...
//
@ -1287,21 +1181,6 @@ void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
pImpl->StructTypes.TypeBecameConcrete(this, AbsTy);
}
// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void UnionType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
LLVMContextImpl *pImpl = OldType->getContext().pImpl;
pImpl->UnionTypes.RefineAbstractType(this, OldType, NewType);
}
void UnionType::typeBecameConcrete(const DerivedType *AbsTy) {
LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
pImpl->UnionTypes.TypeBecameConcrete(this, AbsTy);
}
// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.

View File

@ -180,32 +180,6 @@ public:
}
};
// UnionValType - Define a class to hold the key that goes into the TypeMap
//
class UnionValType {
std::vector<const Type*> ElTypes;
public:
UnionValType(const Type* const* Types, unsigned NumTypes)
: ElTypes(&Types[0], &Types[NumTypes]) {}
static UnionValType get(const UnionType *UT) {
std::vector<const Type *> ElTypes;
ElTypes.reserve(UT->getNumElements());
for (unsigned i = 0, e = UT->getNumElements(); i != e; ++i)
ElTypes.push_back(UT->getElementType(i));
return UnionValType(&ElTypes[0], ElTypes.size());
}
static unsigned hashTypeStructure(const UnionType *UT) {
return UT->getNumElements();
}
inline bool operator<(const UnionValType &UTV) const {
return (ElTypes < UTV.ElTypes);
}
};
// FunctionValType - Define a class to hold the key that goes into the TypeMap
//
class FunctionValType {

View File

@ -1560,7 +1560,8 @@ void Verifier::VerifyType(const Type *Ty) {
"Function type with invalid parameter type", ElTy, FTy);
VerifyType(ElTy);
}
} break;
break;
}
case Type::StructTyID: {
const StructType *STy = cast<StructType>(Ty);
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
@ -1569,34 +1570,29 @@ void Verifier::VerifyType(const Type *Ty) {
"Structure type with invalid element type", ElTy, STy);
VerifyType(ElTy);
}
} break;
case Type::UnionTyID: {
const UnionType *UTy = cast<UnionType>(Ty);
for (unsigned i = 0, e = UTy->getNumElements(); i != e; ++i) {
const Type *ElTy = UTy->getElementType(i);
Assert2(UnionType::isValidElementType(ElTy),
"Union type with invalid element type", ElTy, UTy);
VerifyType(ElTy);
}
} break;
break;
}
case Type::ArrayTyID: {
const ArrayType *ATy = cast<ArrayType>(Ty);
Assert1(ArrayType::isValidElementType(ATy->getElementType()),
"Array type with invalid element type", ATy);
VerifyType(ATy->getElementType());
} break;
break;
}
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
Assert1(PointerType::isValidElementType(PTy->getElementType()),
"Pointer type with invalid element type", PTy);
VerifyType(PTy->getElementType());
} break;
break;
}
case Type::VectorTyID: {
const VectorType *VTy = cast<VectorType>(Ty);
Assert1(VectorType::isValidElementType(VTy->getElementType()),
"Vector type with invalid element type", VTy);
VerifyType(VTy->getElementType());
} break;
break;
}
default:
break;
}

View File

@ -1,3 +0,0 @@
; RUN: llvm-as %s -o /dev/null
%X = type union { i32, i32* }

View File

@ -1,14 +0,0 @@
; RUN: llvm-as < %s | llvm-dis > %t1.ll
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
; RUN: diff %t1.ll %t2.ll
%union.anon = type union { i8, i32, float }
@union1 = constant union { i32, i8 } { i32 4 }
@union2 = constant union { i32, i8 } insertvalue(union { i32, i8 } undef, i32 4, 0)
@union3 = common global %union.anon zeroinitializer, align 8
define void @"Unions" () {
ret void
}

View File

@ -71,8 +71,6 @@
; PLAIN: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
; PLAIN: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; PLAIN: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
; OPT: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
; OPT: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: @c = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
@ -82,8 +80,6 @@
; OPT: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
; OPT: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
; OPT: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
; TO: @a = constant i64 18480
; TO: @b = constant i64 8
; TO: @c = constant i64 16
@ -93,8 +89,6 @@
; TO: @g = constant i64 8
; TO: @h = constant i64 8
; TO: @i = constant i64 8
; TO: @j = constant i64 8
; TO: @k = constant i64 8
@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64)
@ -105,8 +99,6 @@
@g = constant i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64)
@h = constant i64 ptrtoint (double** getelementptr (double** null, i64 1) to i64)
@i = constant i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64)
@j = constant i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64)
@k = constant i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64)
; The target-dependent folder should cast GEP indices to integer-sized pointers.
@ -275,14 +267,6 @@ define i1* @hoo1() nounwind {
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fj() nounwind {
; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fk() nounwind {
; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; OPT: define i64 @fa() nounwind {
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
; OPT: }
@ -310,12 +294,6 @@ define i1* @hoo1() nounwind {
; OPT: define i64 @fi() nounwind {
; OPT: ret i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
; OPT: }
; OPT: define i64 @fj() nounwind {
; OPT: ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: }
; OPT: define i64 @fk() nounwind {
; OPT: ret i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
; OPT: }
; TO: define i64 @fa() nounwind {
; TO: ret i64 18480
; TO: }
@ -343,12 +321,6 @@ define i1* @hoo1() nounwind {
; TO: define i64 @fi() nounwind {
; TO: ret i64 8
; TO: }
; TO: define i64 @fj() nounwind {
; TO: ret i64 8
; TO: }
; TO: define i64 @fk() nounwind {
; TO: ret i64 8
; TO: }
; SCEV: Classifying expressions for: @fa
; SCEV: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
; SCEV: --> (2310 * sizeof(double))
@ -376,12 +348,6 @@ define i1* @hoo1() nounwind {
; SCEV: Classifying expressions for: @fi
; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
; SCEV: --> alignof(i1*)
; SCEV: Classifying expressions for: @fj
; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
; SCEV: --> alignof(double)
; SCEV: Classifying expressions for: @fk
; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
; SCEV: --> sizeof(double)
define i64 @fa() nounwind {
%t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64
@ -419,14 +385,6 @@ define i64 @fi() nounwind {
%t = bitcast i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64) to i64
ret i64 %t
}
define i64 @fj() nounwind {
%t = bitcast i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64) to i64
ret i64 %t
}
define i64 @fk() nounwind {
%t = bitcast i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64) to i64
ret i64 %t
}
; PLAIN: define i64* @fM() nounwind {
; PLAIN: %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*