Simplify a bunch of code by using CollectionType to collect struct

codepaths in with array/vector codepaths. (Issue #37).
This commit is contained in:
Matt Pharr
2011-06-29 07:59:43 +01:00
parent 214fb3197a
commit 6b153566f3
2 changed files with 51 additions and 88 deletions

27
ctx.cpp
View File

@@ -1516,29 +1516,18 @@ FunctionEmitContext::maskedStore(llvm::Value *rvalue, llvm::Value *lvalue,
assert(llvm::isa<const llvm::PointerType>(lvalue->getType()));
const StructType *structType = dynamic_cast<const StructType *>(rvalueType);
if (structType != NULL) {
// Assigning a structure
for (int i = 0; i < structType->GetElementCount(); ++i) {
const CollectionType *collectionType =
dynamic_cast<const CollectionType *>(rvalueType);
if (collectionType != NULL) {
// Assigning a structure / array / vector. Handle each element
// individually with what turns into a recursive call to
// makedStore()
for (int i = 0; i < collectionType->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->GetElementType(i));
}
return;
}
const SequentialType *sequentialType =
dynamic_cast<const SequentialType *>(rvalueType);
if (sequentialType != NULL) {
// Assigning arrays and vectors. Handle each element individually
// with what turns into a recursive call to makedStore()
for (int i = 0; i < sequentialType->GetElementCount(); ++i) {
llvm::Value *eltLValue = GetElementPtrInst(lvalue, 0, i, "lval_i_ptr");
llvm::Value *eltValue = ExtractInst(rvalue, i, "array_i_val");
StoreInst(eltValue, eltLValue, storeMask,
sequentialType->GetElementType());
collectionType->GetElementType(i));
}
return;
}

View File

@@ -2489,19 +2489,25 @@ ExprList::TypeCheck() {
llvm::Constant *
ExprList::GetConstant(const Type *type) const {
const StructType *structType = dynamic_cast<const StructType *>(type);
const SequentialType *sequentialType =
dynamic_cast<const SequentialType *>(type);
const CollectionType *collectionType =
dynamic_cast<const CollectionType *>(type);
if (collectionType == NULL)
return NULL;
if (structType != NULL) {
// We can potentially return an llvm::ConstantStruct if we have the
// 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->GetElementCount()) {
Error(pos, "Initializer list for struct \"%s\" must have %d "
"elements (has %d).", structType->GetString().c_str(),
(int)exprs.size(), structType->GetElementCount());
std::string name = NULL;
if (dynamic_cast<const StructType *>(type) != NULL)
name = "struct";
else if (dynamic_cast<const ArrayType *>(type) != NULL)
name = "array";
else if (dynamic_cast<const VectorType *>(type) != NULL)
name = "vector";
else
FATAL("Unexpected CollectionType in ExprList::GetConstant()");
if ((int)exprs.size() != collectionType->GetElementCount()) {
Error(pos, "Initializer list for %s \"%s\" must have %d elements "
"(has %d).", name.c_str(), collectionType->GetString().c_str(),
collectionType->GetElementCount(), (int)exprs.size());
return NULL;
}
@@ -2509,51 +2515,31 @@ 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->GetElementType(i);
const Type *elementType = collectionType->GetElementType(i);
llvm::Constant *c = exprs[i]->GetConstant(elementType);
if (c == NULL)
// If this list element couldn't convert to the right
// constant type for the corresponding struct member, then
// give up
// If this list element couldn't convert to the right constant
// type for the corresponding collection member, then give up.
return NULL;
cv.push_back(c);
}
if (dynamic_cast<const StructType *>(type) != NULL) {
#if defined(LLVM_2_8) || defined(LLVM_2_9)
return llvm::ConstantStruct::get(*g->ctx, cv, false);
#else
const llvm::StructType *llvmStructType =
llvm::dyn_cast<const llvm::StructType>(structType->LLVMType(g->ctx));
llvm::dyn_cast<const llvm::StructType>(collectionType->LLVMType(g->ctx));
assert(llvmStructType != NULL);
return llvm::ConstantStruct::get(llvmStructType, cv);
#endif
}
else if (sequentialType) {
// Similarly, if we have an array or vector type, we may be able to
// return the corresponding llvm constant value.
if ((int)exprs.size() != sequentialType->GetElementCount()) {
bool isArray = (dynamic_cast<const ArrayType *>(type) != NULL);
Error(pos, "Initializer list for %s \"%s\" must have %d elements (has %d).",
isArray ? "array" : "vector", sequentialType->GetString().c_str(),
(int)exprs.size(), sequentialType->GetElementCount());
return NULL;
}
std::vector<llvm::Constant *> cv;
for (unsigned int i = 0; i < exprs.size(); ++i) {
if (exprs[i] == NULL)
return NULL;
const Type *elementType = sequentialType->GetElementType();
llvm::Constant *c = exprs[i]->GetConstant(elementType);
if (c == NULL)
return NULL;
cv.push_back(c);
}
else {
const llvm::Type *lt = type->LLVMType(g->ctx);
const llvm::ArrayType *lat = llvm::dyn_cast<const llvm::ArrayType>(lt);
// FIXME: should the assert below validly fail for uniform vectors
// now?
// now? Need a test case to reproduce it and then to be sure we
// have the right fix; leave the assert until we can hit it...
assert(lat != NULL);
return llvm::ConstantArray::get(lat, cv);
}
@@ -3900,25 +3886,13 @@ lUniformValueToVarying(FunctionEmitContext *ctx, llvm::Value *value,
const llvm::Type *llvmType = type->GetAsVaryingType()->LLVMType(g->ctx);
llvm::Value *retValue = llvm::UndefValue::get(llvmType);
// for structs, just recursively make their elements varying (if
// needed) and populate the return struct
const StructType *structType = dynamic_cast<const StructType *>(type);
if (structType != NULL) {
for (int i = 0; i < structType->GetElementCount(); ++i) {
llvm::Value *v = ctx->ExtractInst(value, i, "struct_element");
v = lUniformValueToVarying(ctx, v, structType->GetElementType(i));
retValue = ctx->InsertInst(retValue, v, i, "set_struct_element");
}
return retValue;
}
// And similarly do the elements of arrays and vectors individually
const SequentialType *sequentialType =
dynamic_cast<const SequentialType *>(type);
if (sequentialType != NULL) {
for (int i = 0; i < sequentialType->GetElementCount(); ++i) {
// for structs/arrays/vectors, just recursively make their elements
// varying (if needed) and populate the return value.
const CollectionType *collectionType = dynamic_cast<const StructType *>(type);
if (collectionType != NULL) {
for (int i = 0; i < collectionType->GetElementCount(); ++i) {
llvm::Value *v = ctx->ExtractInst(value, i, "get_element");
v = lUniformValueToVarying(ctx, v, sequentialType->GetElementType());
v = lUniformValueToVarying(ctx, v, collectionType->GetElementType(i));
retValue = ctx->InsertInst(retValue, v, i, "set_element");
}
return retValue;