Simplify a bunch of code by using CollectionType to collect struct
codepaths in with array/vector codepaths. (Issue #37).
This commit is contained in:
27
ctx.cpp
27
ctx.cpp
@@ -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;
|
||||
}
|
||||
|
||||
90
expr.cpp
90
expr.cpp
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user