Initial plumbing to add CollectionType base-class as common ancestor

to StructTypes, ArrayTypes, and VectorTypes.  Issue #37.
This commit is contained in:
Matt Pharr
2011-06-29 07:41:35 +01:00
parent b4068efcfb
commit 214fb3197a
6 changed files with 83 additions and 52 deletions

12
ctx.cpp
View File

@@ -1359,10 +1359,10 @@ FunctionEmitContext::gather(llvm::Value *lvalue, const Type *type,
// If we're gathering structures, do an element-wise gather
// recursively.
llvm::Value *retValue = llvm::UndefValue::get(retType);
for (int i = 0; i < st->NumElements(); ++i) {
for (int i = 0; i < st->GetElementCount(); ++i) {
llvm::Value *eltPtrs = GetElementPtrInst(lvalue, 0, i);
// This in turn will be another gather
llvm::Value *eltValues = LoadInst(eltPtrs, st->GetMemberType(i),
llvm::Value *eltValues = LoadInst(eltPtrs, st->GetElementType(i),
name);
retValue = InsertInst(retValue, eltValues, i, "set_value");
}
@@ -1519,12 +1519,12 @@ FunctionEmitContext::maskedStore(llvm::Value *rvalue, llvm::Value *lvalue,
const StructType *structType = dynamic_cast<const StructType *>(rvalueType);
if (structType != NULL) {
// Assigning a structure
for (int i = 0; i < structType->NumElements(); ++i) {
for (int i = 0; i < structType->GetElementCount(); ++i) {
llvm::Value *eltValue = ExtractInst(rvalue, i, "rvalue_member");
llvm::Value *eltLValue = GetElementPtrInst(lvalue, 0, i,
"struct_lvalue_ptr");
StoreInst(eltValue, eltLValue, storeMask,
structType->GetMemberType(i));
structType->GetElementType(i));
}
return;
}
@@ -1598,10 +1598,10 @@ FunctionEmitContext::scatter(llvm::Value *rvalue, llvm::Value *lvalue,
const StructType *structType = dynamic_cast<const StructType *>(rvalueType);
if (structType) {
// Scatter the struct elements individually
for (int i = 0; i < structType->NumElements(); ++i) {
for (int i = 0; i < structType->GetElementCount(); ++i) {
llvm::Value *lv = GetElementPtrInst(lvalue, 0, i);
llvm::Value *rv = ExtractInst(rvalue, i);
scatter(rv, lv, storeMask, structType->GetMemberType(i));
scatter(rv, lv, storeMask, structType->GetElementType(i));
}
return;
}

View File

@@ -1526,7 +1526,7 @@ AssignExpr::GetValue(FunctionEmitContext *ctx) const {
if (st != NULL) {
bool anyUniform = false;
for (int i = 0; i < st->NumElements(); ++i) {
if (st->GetMemberType(i)->IsUniformType())
if (st->GetElementType(i)->IsUniformType())
anyUniform = true;
}
@@ -2498,10 +2498,10 @@ ExprList::GetConstant(const Type *type) const {
// same number of elements in the ExprList as the struct has
// members (and the various elements line up with the shape of the
// corresponding struct elements).
if ((int)exprs.size() != structType->NumElements()) {
if ((int)exprs.size() != structType->GetElementCount()) {
Error(pos, "Initializer list for struct \"%s\" must have %d "
"elements (has %d).", structType->GetString().c_str(),
(int)exprs.size(), structType->NumElements());
(int)exprs.size(), structType->GetElementCount());
return NULL;
}
@@ -2509,7 +2509,7 @@ ExprList::GetConstant(const Type *type) const {
for (unsigned int i = 0; i < exprs.size(); ++i) {
if (exprs[i] == NULL)
return NULL;
const Type *elementType = structType->GetMemberType(i);
const Type *elementType = structType->GetElementType(i);
llvm::Constant *c = exprs[i]->GetConstant(elementType);
if (c == NULL)
// If this list element couldn't convert to the right
@@ -2832,7 +2832,7 @@ MemberExpr::GetType() const {
// Otherwise it's a struct, and the result type is the element
// type, possibly promoted to varying if the struct type / lvalue
// is varying.
const Type *elementType = structType->GetMemberType(identifier);
const Type *elementType = structType->GetElementType(identifier);
if (!elementType)
Error(identifierPos, "Element name \"%s\" not present in struct type \"%s\".%s",
identifier.c_str(), structType->GetString().c_str(),
@@ -2912,7 +2912,7 @@ MemberExpr::getElementNumber() const {
}
}
else {
elementNumber = structType->GetMemberNumber(identifier);
elementNumber = structType->GetElementNumber(identifier);
if (elementNumber == -1)
Error(identifierPos, "Element name \"%s\" not present in struct type \"%s\".%s",
identifier.c_str(), structType->GetString().c_str(),
@@ -3004,7 +3004,7 @@ MemberExpr::getCandidateNearMatches() const {
return "";
std::vector<std::string> elementNames;
for (int i = 0; i < structType->NumElements(); ++i)
for (int i = 0; i < structType->GetElementCount(); ++i)
elementNames.push_back(structType->GetElementName(i));
std::vector<std::string> alternates = MatchStrings(identifier, elementNames);
if (!alternates.size())
@@ -3904,9 +3904,9 @@ lUniformValueToVarying(FunctionEmitContext *ctx, llvm::Value *value,
// needed) and populate the return struct
const StructType *structType = dynamic_cast<const StructType *>(type);
if (structType != NULL) {
for (int i = 0; i < structType->NumElements(); ++i) {
for (int i = 0; i < structType->GetElementCount(); ++i) {
llvm::Value *v = ctx->ExtractInst(value, i, "struct_element");
v = lUniformValueToVarying(ctx, v, structType->GetMemberType(i));
v = lUniformValueToVarying(ctx, v, structType->GetElementType(i));
retValue = ctx->InsertInst(retValue, v, i, "set_struct_element");
}
return retValue;

View File

@@ -248,8 +248,8 @@ lRecursiveCheckVarying(const Type *t) {
const StructType *st = dynamic_cast<const StructType *>(t);
if (st) {
for (int i = 0; i < st->NumElements(); ++i)
if (lRecursiveCheckVarying(st->GetMemberType(i)))
for (int i = 0; i < st->GetElementCount(); ++i)
if (lRecursiveCheckVarying(st->GetElementType(i)))
return true;
}
return false;
@@ -1041,8 +1041,8 @@ Module::writeObjectFileOrAssembly(OutputType outputType, const char *outFileName
static void
lRecursiveAddStructs(const StructType *structType,
std::vector<const StructType *> &structParamTypes) {
for (int i = 0; i < structType->NumElements(); ++i) {
const Type *elementBaseType = structType->GetMemberType(i)->GetBaseType();
for (int i = 0; i < structType->GetElementCount(); ++i) {
const Type *elementBaseType = structType->GetElementType(i)->GetBaseType();
const StructType *elementStructType =
dynamic_cast<const StructType *>(elementBaseType);
if (elementStructType != NULL) {
@@ -1112,9 +1112,9 @@ lEmitStructDecls(std::vector<const StructType *> &structTypes, FILE *file) {
StructDAGNode *node = new StructDAGNode;
structToNode[st] = node;
for (int j = 0; j < st->NumElements(); ++j) {
for (int j = 0; j < st->GetElementCount(); ++j) {
const StructType *elementStructType =
dynamic_cast<const StructType *>(st->GetMemberType(j));
dynamic_cast<const StructType *>(st->GetElementType(j));
// If this element is a struct type and we haven't already
// processed it for the current struct type, then upate th
// dependencies and record that this element type has other
@@ -1144,8 +1144,8 @@ lEmitStructDecls(std::vector<const StructType *> &structTypes, FILE *file) {
for (unsigned int i = 0; i < sortedTypes.size(); ++i) {
const StructType *st = sortedTypes[i];
fprintf(file, "struct %s {\n", st->GetStructName().c_str());
for (int j = 0; j < st->NumElements(); ++j) {
const Type *type = st->GetMemberType(j)->GetAsNonConstType();
for (int j = 0; j < st->GetElementCount(); ++j) {
const Type *type = st->GetElementType(j)->GetAsNonConstType();
std::string d = type->GetCDeclaration(st->GetElementName(j));
fprintf(file, " %s;\n", d.c_str());
}
@@ -1210,8 +1210,8 @@ lGetVectorsFromStructs(const std::vector<const StructType *> &structParamTypes,
std::vector<const VectorType *> *vectorParamTypes) {
for (unsigned int i = 0; i < structParamTypes.size(); ++i) {
const StructType *structType = structParamTypes[i];
for (int j = 0; j < structType->NumElements(); ++j) {
const Type *elementType = structType->GetMemberType(j);
for (int j = 0; j < structType->GetElementCount(); ++j) {
const Type *elementType = structType->GetElementType(j);
const ArrayType *at = dynamic_cast<const ArrayType *>(elementType);
if (at)

View File

@@ -233,16 +233,16 @@ lInitSymbol(llvm::Value *lvalue, const char *symName, const Type *type,
// The { ... } case; make sure we have the same number of
// expressions in the ExprList as we have struct members
int nInits = exprList->exprs.size();
if (nInits != st->NumElements())
if (nInits != st->GetElementCount())
Error(initExpr->pos,
"Initializer for struct \"%s\" requires %d values; %d provided.",
symName, st->NumElements(), nInits);
symName, st->GetElementCount(), nInits);
else {
// Initialize each struct member with the corresponding
// value from the ExprList
for (int i = 0; i < nInits; ++i) {
llvm::Value *ep = ctx->GetElementPtrInst(lvalue, 0, i, "structelement");
lInitSymbol(ep, symName, st->GetMemberType(i), exprList->exprs[i],
lInitSymbol(ep, symName, st->GetElementType(i), exprList->exprs[i],
ctx, pos);
}
}
@@ -251,9 +251,9 @@ lInitSymbol(llvm::Value *lvalue, const char *symName, const Type *type,
initExpr->GetType()->IsBoolType()) {
// Otherwise initialize all of the struct elements in turn with
// the initExpr.
for (int i = 0; i < st->NumElements(); ++i) {
for (int i = 0; i < st->GetElementCount(); ++i) {
llvm::Value *ep = ctx->GetElementPtrInst(lvalue, 0, i, "structelement");
lInitSymbol(ep, symName, st->GetMemberType(i), initExpr, ctx, pos);
lInitSymbol(ep, symName, st->GetElementType(i), initExpr, ctx, pos);
}
}
else {

View File

@@ -410,6 +410,14 @@ AtomicType::GetDIType(llvm::DIDescriptor scope) const {
}
///////////////////////////////////////////////////////////////////////////
// SequentialType
const Type *SequentialType::GetElementType(int index) const {
return GetElementType();
}
///////////////////////////////////////////////////////////////////////////
// ArrayType
@@ -1035,8 +1043,8 @@ StructType::GetSOAType(int width) const {
std::vector<const Type *> et;
// The SOA version of a structure is just a structure that holds SOAed
// versions of its elements
for (int i = 0; i < NumElements(); ++i) {
const Type *t = GetMemberType(i);
for (int i = 0; i < GetElementCount(); ++i) {
const Type *t = GetElementType(i);
et.push_back(t->GetSOAType(width));
}
return new StructType(name, et, elementNames, elementPositions,
@@ -1125,8 +1133,8 @@ StructType::GetCDeclaration(const std::string &n) const {
const llvm::Type *
StructType::LLVMType(llvm::LLVMContext *ctx) const {
std::vector<const llvm::Type *> llvmTypes;
for (int i = 0; i < NumElements(); ++i) {
const Type *type = GetMemberType(i);
for (int i = 0; i < GetElementCount(); ++i) {
const Type *type = GetElementType(i);
llvmTypes.push_back(type->LLVMType(ctx));
}
return llvm::StructType::get(*ctx, llvmTypes);
@@ -1146,7 +1154,7 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
// alignment and size, using that to figure out its offset w.r.t. the
// start of the structure.
for (unsigned int i = 0; i < elementTypes.size(); ++i) {
llvm::DIType eltType = GetMemberType(i)->GetDIType(scope);
llvm::DIType eltType = GetElementType(i)->GetDIType(scope);
uint64_t eltAlign = eltType.getAlignInBits();
uint64_t eltSize = eltType.getSizeInBits();
@@ -1197,7 +1205,7 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
const Type *
StructType::GetMemberType(int i) const {
StructType::GetElementType(int i) const {
assert(i < (int)elementTypes.size());
// If the struct is uniform qualified, then each member comes out with
// the same type as in the original source file. If it's varying, then
@@ -1209,7 +1217,7 @@ StructType::GetMemberType(int i) const {
const Type *
StructType::GetMemberType(const std::string &n) const {
StructType::GetElementType(const std::string &n) const {
for (unsigned int i = 0; i < elementNames.size(); ++i)
if (elementNames[i] == n) {
const Type *ret = isUniform ? elementTypes[i] :
@@ -1221,7 +1229,7 @@ StructType::GetMemberType(const std::string &n) const {
int
StructType::GetMemberNumber(const std::string &n) const {
StructType::GetElementNumber(const std::string &n) const {
for (unsigned int i = 0; i < elementNames.size(); ++i)
if (elementNames[i] == n)
return i;
@@ -1775,10 +1783,10 @@ Type::Equal(const Type *a, const Type *b) {
const StructType *sta = dynamic_cast<const StructType *>(a);
const StructType *stb = dynamic_cast<const StructType *>(b);
if (sta && stb) {
if (sta->NumElements() != stb->NumElements())
if (sta->GetElementCount() != stb->GetElementCount())
return false;
for (int i = 0; i < sta->NumElements(); ++i)
if (!Equal(sta->GetMemberType(i), stb->GetMemberType(i)))
for (int i = 0; i < sta->GetElementCount(); ++i)
if (!Equal(sta->GetElementType(i), stb->GetElementType(i)))
return false;
return true;
}

45
type.h
View File

@@ -243,19 +243,42 @@ private:
};
/** @brief Abstract base class for tpyes that represent sequences
/** @brief Abstract base class for types that represent collections of
other types.
This is a common base class that StructTypes, ArrayTypes, and
VectorTypes all inherit from.
*/
class CollectionType : public Type {
public:
/** Returns the total number of elements in the collection. */
virtual int GetElementCount() const = 0;
/** Returns the type of the element given by index. (The value of
index must be between 0 and GetElementCount()-1.
*/
virtual const Type *GetElementType(int index) const = 0;
};
/** @brief Abstract base class for types that represent sequences
SequentialType is an abstract base class that adds interface routines
for types that represent linear sequences of other types (i.e., arrays
and vectors).
*/
class SequentialType : public Type {
class SequentialType : public CollectionType {
public:
/** Returns the total number of elements in the sequence. */
virtual int GetElementCount() const = 0;
/** Returns the Type of the elements that the sequence stores. */
/** Returns the Type of the elements that the sequence stores; for
SequentialTypes, all elements have the same type . */
virtual const Type *GetElementType() const = 0;
/** SequentialType provides an implementation of this CollectionType
method, just passing the query on to the GetElementType(void)
implementation, since all of the elements of a SequentialType have
the same type.
*/
const Type *GetElementType(int index) const;
};
@@ -439,7 +462,7 @@ private:
/** @brief Representation of a structure holding a number of members.
*/
class StructType : public Type {
class StructType : public CollectionType {
public:
StructType(const std::string &name, const std::vector<const Type *> &elts,
const std::vector<std::string> &eltNames,
@@ -469,21 +492,21 @@ public:
/** Returns the type of the structure element with the given name (if any).
Returns NULL if there is no such named element. */
const Type *GetMemberType(const std::string &name) const;
const Type *GetElementType(const std::string &name) const;
/** Returns the type of the i'th structure element. The value of \c i must
be between 0 and NumElements()-1. */
const Type *GetMemberType(int i) const;
const Type *GetElementType(int i) const;
/** Returns which structure element number (starting from zero) that
has the given name. If there is no such element, return -1. */
int GetMemberNumber(const std::string &name) const;
int GetElementNumber(const std::string &name) const;
/** Returns the name of the i'th element of the structure. */
const std::string GetElementName(int i) const { return elementNames[i]; }
/** Returns the total number of elements in the structure. */
int NumElements() const { return int(elementTypes.size()); }
int GetElementCount() const { return int(elementTypes.size()); }
/** Returns the name of the structure type. (e.g. struct Foo -> "Foo".) */
const std::string &GetStructName() const { return name; }