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:
Matt Pharr
2012-01-04 12:29:45 -08:00
parent 23b85cd88d
commit 4151778f5e
4 changed files with 62 additions and 11 deletions

11
ctx.cpp
View File

@@ -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

View File

@@ -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());
}

View File

@@ -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
View File

@@ -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;