Modify SizeOf() and StructOffset() to not compute value based on target for generic targets.
Specifically, we want to be able to late-bind on whether the mask is i32s or i1s, so if there's any chance of ambiguity, we emit code that does the "GEP from a NULL base pointer" trick to compute the value later in compilation.
This commit is contained in:
11
ctx.cpp
11
ctx.cpp
@@ -1468,7 +1468,7 @@ FunctionEmitContext::applyVaryingGEP(llvm::Value *basePtr, llvm::Value *index,
|
||||
// Find the scale factor for the index (i.e. the size of the object
|
||||
// that the pointer(s) point(s) to.
|
||||
const Type *scaleType = ptrType->GetBaseType();
|
||||
llvm::Value *scale = g->target.SizeOf(scaleType->LLVMType(g->ctx));
|
||||
llvm::Value *scale = g->target.SizeOf(scaleType->LLVMType(g->ctx), bblock);
|
||||
|
||||
bool indexIsVarying =
|
||||
llvm::isa<LLVM_TYPE_CONST llvm::VectorType>(index->getType());
|
||||
@@ -1651,7 +1651,8 @@ FunctionEmitContext::AddElementOffset(llvm::Value *basePtr, int elementNum,
|
||||
if (st != NULL)
|
||||
// If the pointer is to a structure, Target::StructOffset() gives
|
||||
// us the offset in bytes to the given element of the structure
|
||||
offset = g->target.StructOffset(st->LLVMType(g->ctx), elementNum);
|
||||
offset = g->target.StructOffset(st->LLVMType(g->ctx), elementNum,
|
||||
bblock);
|
||||
else {
|
||||
// Otherwise we should have a vector or array here and the offset
|
||||
// is given by the element number times the size of the element
|
||||
@@ -1660,7 +1661,7 @@ FunctionEmitContext::AddElementOffset(llvm::Value *basePtr, int elementNum,
|
||||
dynamic_cast<const SequentialType *>(ptrType->GetBaseType());
|
||||
Assert(st != NULL);
|
||||
llvm::Value *size =
|
||||
g->target.SizeOf(st->GetElementType()->LLVMType(g->ctx));
|
||||
g->target.SizeOf(st->GetElementType()->LLVMType(g->ctx), bblock);
|
||||
llvm::Value *scale = (g->target.is32Bit || g->opt.force32BitAddressing) ?
|
||||
LLVMInt32(elementNum) : LLVMInt64(elementNum);
|
||||
offset = BinaryOperator(llvm::Instruction::Mul, size, scale);
|
||||
@@ -2479,7 +2480,7 @@ FunctionEmitContext::LaunchInst(llvm::Value *callee,
|
||||
|
||||
llvm::Function *falloc = m->module->getFunction("ISPCAlloc");
|
||||
Assert(falloc != NULL);
|
||||
llvm::Value *structSize = g->target.SizeOf(argStructType);
|
||||
llvm::Value *structSize = g->target.SizeOf(argStructType, bblock);
|
||||
if (structSize->getType() != LLVMTypes::Int64Type)
|
||||
// ISPCAlloc expects the size as an uint64_t, but on 32-bit
|
||||
// targets, SizeOf returns a 32-bit value
|
||||
@@ -2575,7 +2576,7 @@ FunctionEmitContext::addVaryingOffsetsIfNeeded(llvm::Value *ptr,
|
||||
// Find the size of a uniform element of the varying type
|
||||
LLVM_TYPE_CONST llvm::Type *llvmBaseUniformType =
|
||||
baseType->GetAsUniformType()->LLVMType(g->ctx);
|
||||
llvm::Value *unifSize = g->target.SizeOf(llvmBaseUniformType);
|
||||
llvm::Value *unifSize = g->target.SizeOf(llvmBaseUniformType, bblock);
|
||||
unifSize = SmearUniform(unifSize);
|
||||
|
||||
// Compute offset = <0, 1, .. > * unifSize
|
||||
|
||||
5
expr.cpp
5
expr.cpp
@@ -1106,7 +1106,8 @@ lEmitBinaryArith(BinaryExpr::Op op, llvm::Value *value0, llvm::Value *value1,
|
||||
// points to in order to return the difference in elements.
|
||||
LLVM_TYPE_CONST llvm::Type *llvmElementType =
|
||||
ptrType->GetBaseType()->LLVMType(g->ctx);
|
||||
llvm::Value *size = g->target.SizeOf(llvmElementType);
|
||||
llvm::Value *size = g->target.SizeOf(llvmElementType,
|
||||
ctx->GetCurrentBasicBlock());
|
||||
if (ptrType->IsVaryingType())
|
||||
size = ctx->SmearUniform(size);
|
||||
|
||||
@@ -5875,7 +5876,7 @@ SizeOfExpr::GetValue(FunctionEmitContext *ctx) const {
|
||||
if (llvmType == NULL)
|
||||
return NULL;
|
||||
|
||||
return g->target.SizeOf(llvmType);
|
||||
return g->target.SizeOf(llvmType, ctx->GetCurrentBasicBlock());
|
||||
}
|
||||
|
||||
|
||||
|
||||
51
ispc.cpp
51
ispc.cpp
@@ -50,6 +50,7 @@
|
||||
#include <llvm/Analysis/DIBuilder.h>
|
||||
#include <llvm/Analysis/DebugInfo.h>
|
||||
#include <llvm/Support/Dwarf.h>
|
||||
#include <llvm/Instructions.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm/Target/TargetOptions.h>
|
||||
#include <llvm/Target/TargetData.h>
|
||||
@@ -358,7 +359,30 @@ Target::GetISAString() const {
|
||||
|
||||
|
||||
llvm::Value *
|
||||
Target::SizeOf(LLVM_TYPE_CONST llvm::Type *type) {
|
||||
Target::SizeOf(LLVM_TYPE_CONST llvm::Type *type,
|
||||
llvm::BasicBlock *insertAtEnd) {
|
||||
if (isa == Target::GENERIC && type->isPrimitiveType() == false) {
|
||||
llvm::Value *index[1] = { LLVMInt32(1) };
|
||||
LLVM_TYPE_CONST llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||
#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn)
|
||||
llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
|
||||
insertAtEnd);
|
||||
#else
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, &index[0], &index[1],
|
||||
"sizeof_gep", insertAtEnd);
|
||||
#endif
|
||||
if (is32Bit || g->opt.force32BitAddressing)
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
"sizeof_int", insertAtEnd);
|
||||
else
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
"sizeof_int", insertAtEnd);
|
||||
}
|
||||
|
||||
const llvm::TargetData *td = GetTargetMachine()->getTargetData();
|
||||
Assert(td != NULL);
|
||||
uint64_t byteSize = td->getTypeSizeInBits(type) / 8;
|
||||
@@ -370,7 +394,30 @@ Target::SizeOf(LLVM_TYPE_CONST llvm::Type *type) {
|
||||
|
||||
|
||||
llvm::Value *
|
||||
Target::StructOffset(LLVM_TYPE_CONST llvm::Type *type, int element) {
|
||||
Target::StructOffset(LLVM_TYPE_CONST llvm::Type *type, int element,
|
||||
llvm::BasicBlock *insertAtEnd) {
|
||||
if (isa == Target::GENERIC && type->isPrimitiveType() == false) {
|
||||
llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
|
||||
LLVM_TYPE_CONST llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||
#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn)
|
||||
llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
|
||||
insertAtEnd);
|
||||
#else
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, &indices[0], &indices[2],
|
||||
"offset_gep", insertAtEnd);
|
||||
#endif
|
||||
if (is32Bit || g->opt.force32BitAddressing)
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
"offset_int", insertAtEnd);
|
||||
else
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
"offset_int", insertAtEnd);
|
||||
}
|
||||
|
||||
const llvm::TargetData *td = GetTargetMachine()->getTargetData();
|
||||
Assert(td != NULL);
|
||||
LLVM_TYPE_CONST llvm::StructType *structType =
|
||||
|
||||
6
ispc.h
6
ispc.h
@@ -177,12 +177,14 @@ struct Target {
|
||||
const char *GetISAString() const;
|
||||
|
||||
/** Returns the size of the given type */
|
||||
llvm::Value *SizeOf(LLVM_TYPE_CONST llvm::Type *type);
|
||||
llvm::Value *SizeOf(LLVM_TYPE_CONST llvm::Type *type,
|
||||
llvm::BasicBlock *insertAtEnd);
|
||||
|
||||
/** Given a structure type and an element number in the structure,
|
||||
returns a value corresponding to the number of bytes from the start
|
||||
of the structure where the element is located. */
|
||||
llvm::Value *StructOffset(LLVM_TYPE_CONST llvm::Type *type,
|
||||
int element);
|
||||
int element, llvm::BasicBlock *insertAtEnd);
|
||||
|
||||
/** llvm Target object representing this target. */
|
||||
const llvm::Target *target;
|
||||
|
||||
Reference in New Issue
Block a user