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()));
|
assert(llvm::isa<const llvm::PointerType>(lvalue->getType()));
|
||||||
|
|
||||||
const StructType *structType = dynamic_cast<const StructType *>(rvalueType);
|
const CollectionType *collectionType =
|
||||||
if (structType != NULL) {
|
dynamic_cast<const CollectionType *>(rvalueType);
|
||||||
// Assigning a structure
|
if (collectionType != NULL) {
|
||||||
for (int i = 0; i < structType->GetElementCount(); ++i) {
|
// 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 *eltValue = ExtractInst(rvalue, i, "rvalue_member");
|
||||||
llvm::Value *eltLValue = GetElementPtrInst(lvalue, 0, i,
|
llvm::Value *eltLValue = GetElementPtrInst(lvalue, 0, i,
|
||||||
"struct_lvalue_ptr");
|
"struct_lvalue_ptr");
|
||||||
StoreInst(eltValue, eltLValue, storeMask,
|
StoreInst(eltValue, eltLValue, storeMask,
|
||||||
structType->GetElementType(i));
|
collectionType->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());
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
112
expr.cpp
112
expr.cpp
@@ -2489,71 +2489,57 @@ ExprList::TypeCheck() {
|
|||||||
|
|
||||||
llvm::Constant *
|
llvm::Constant *
|
||||||
ExprList::GetConstant(const Type *type) const {
|
ExprList::GetConstant(const Type *type) const {
|
||||||
const StructType *structType = dynamic_cast<const StructType *>(type);
|
const CollectionType *collectionType =
|
||||||
const SequentialType *sequentialType =
|
dynamic_cast<const CollectionType *>(type);
|
||||||
dynamic_cast<const SequentialType *>(type);
|
if (collectionType == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (structType != NULL) {
|
std::string name = NULL;
|
||||||
// We can potentially return an llvm::ConstantStruct if we have the
|
if (dynamic_cast<const StructType *>(type) != NULL)
|
||||||
// same number of elements in the ExprList as the struct has
|
name = "struct";
|
||||||
// members (and the various elements line up with the shape of the
|
else if (dynamic_cast<const ArrayType *>(type) != NULL)
|
||||||
// corresponding struct elements).
|
name = "array";
|
||||||
if ((int)exprs.size() != structType->GetElementCount()) {
|
else if (dynamic_cast<const VectorType *>(type) != NULL)
|
||||||
Error(pos, "Initializer list for struct \"%s\" must have %d "
|
name = "vector";
|
||||||
"elements (has %d).", structType->GetString().c_str(),
|
else
|
||||||
(int)exprs.size(), structType->GetElementCount());
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<llvm::Constant *> cv;
|
||||||
|
for (unsigned int i = 0; i < exprs.size(); ++i) {
|
||||||
|
if (exprs[i] == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
const Type *elementType = collectionType->GetElementType(i);
|
||||||
|
llvm::Constant *c = exprs[i]->GetConstant(elementType);
|
||||||
std::vector<llvm::Constant *> cv;
|
if (c == NULL)
|
||||||
for (unsigned int i = 0; i < exprs.size(); ++i) {
|
// If this list element couldn't convert to the right constant
|
||||||
if (exprs[i] == NULL)
|
// type for the corresponding collection member, then give up.
|
||||||
return NULL;
|
return NULL;
|
||||||
const Type *elementType = structType->GetElementType(i);
|
cv.push_back(c);
|
||||||
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
|
|
||||||
return NULL;
|
|
||||||
cv.push_back(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (dynamic_cast<const StructType *>(type) != NULL) {
|
||||||
#if defined(LLVM_2_8) || defined(LLVM_2_9)
|
#if defined(LLVM_2_8) || defined(LLVM_2_9)
|
||||||
return llvm::ConstantStruct::get(*g->ctx, cv, false);
|
return llvm::ConstantStruct::get(*g->ctx, cv, false);
|
||||||
#else
|
#else
|
||||||
const llvm::StructType *llvmStructType =
|
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);
|
assert(llvmStructType != NULL);
|
||||||
return llvm::ConstantStruct::get(llvmStructType, cv);
|
return llvm::ConstantStruct::get(llvmStructType, cv);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (sequentialType) {
|
else {
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm::Type *lt = type->LLVMType(g->ctx);
|
const llvm::Type *lt = type->LLVMType(g->ctx);
|
||||||
const llvm::ArrayType *lat = llvm::dyn_cast<const llvm::ArrayType>(lt);
|
const llvm::ArrayType *lat = llvm::dyn_cast<const llvm::ArrayType>(lt);
|
||||||
// FIXME: should the assert below validly fail for uniform vectors
|
// 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);
|
assert(lat != NULL);
|
||||||
return llvm::ConstantArray::get(lat, cv);
|
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);
|
const llvm::Type *llvmType = type->GetAsVaryingType()->LLVMType(g->ctx);
|
||||||
llvm::Value *retValue = llvm::UndefValue::get(llvmType);
|
llvm::Value *retValue = llvm::UndefValue::get(llvmType);
|
||||||
|
|
||||||
// for structs, just recursively make their elements varying (if
|
// for structs/arrays/vectors, just recursively make their elements
|
||||||
// needed) and populate the return struct
|
// varying (if needed) and populate the return value.
|
||||||
const StructType *structType = dynamic_cast<const StructType *>(type);
|
const CollectionType *collectionType = dynamic_cast<const StructType *>(type);
|
||||||
if (structType != NULL) {
|
if (collectionType != NULL) {
|
||||||
for (int i = 0; i < structType->GetElementCount(); ++i) {
|
for (int i = 0; i < collectionType->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) {
|
|
||||||
llvm::Value *v = ctx->ExtractInst(value, i, "get_element");
|
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");
|
retValue = ctx->InsertInst(retValue, v, i, "set_element");
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
|
|||||||
Reference in New Issue
Block a user