Merge pull request #746 from ifilippov/master

Adding cases of 'cast' instructions in optimizations
This commit is contained in:
Dmitry Babokin
2014-02-21 12:25:58 +03:00
2 changed files with 50 additions and 24 deletions

72
opt.cpp
View File

@@ -1220,12 +1220,24 @@ char ImproveMemoryOpsPass::ID = 0;
*/ */
static llvm::Value * static llvm::Value *
lCheckForActualPointer(llvm::Value *v) { lCheckForActualPointer(llvm::Value *v) {
if (v == NULL) if (v == NULL) {
return NULL; return NULL;
else if (llvm::isa<llvm::PointerType>(v->getType())) }
else if (llvm::isa<llvm::PointerType>(v->getType())) {
return v; return v;
else if (llvm::isa<llvm::PtrToIntInst>(v)) }
else if (llvm::isa<llvm::PtrToIntInst>(v)) {
return v; return v;
}
else if (llvm::CastInst *ci = llvm::dyn_cast<llvm::CastInst>(v)) {
llvm::Value *t = lCheckForActualPointer(ci->getOperand(0));
if (t == NULL) {
return NULL;
}
else {
return v;
}
}
else { else {
llvm::ConstantExpr *uce = llvm::ConstantExpr *uce =
llvm::dyn_cast<llvm::ConstantExpr>(v); llvm::dyn_cast<llvm::ConstantExpr>(v);
@@ -1243,7 +1255,7 @@ lCheckForActualPointer(llvm::Value *v) {
pointer value; otherwise it returns NULL. pointer value; otherwise it returns NULL.
*/ */
static llvm::Value * static llvm::Value *
lGetBasePointer(llvm::Value *v) { lGetBasePointer(llvm::Value *v, llvm::Instruction *insertBefore) {
if (llvm::isa<llvm::InsertElementInst>(v) || if (llvm::isa<llvm::InsertElementInst>(v) ||
llvm::isa<llvm::ShuffleVectorInst>(v)) { llvm::isa<llvm::ShuffleVectorInst>(v)) {
llvm::Value *element = LLVMFlattenInsertChain llvm::Value *element = LLVMFlattenInsertChain
@@ -1267,6 +1279,20 @@ lGetBasePointer(llvm::Value *v) {
else if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) { else if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
return lCheckForActualPointer(cdv->getSplatValue()); return lCheckForActualPointer(cdv->getSplatValue());
} }
// It is a little bit tricky to use operations with pointers, casted to int with another bit size
// but sometimes it is useful, so we handle this case here.
else if (llvm::CastInst *ci = llvm::dyn_cast<llvm::CastInst>(v)) {
llvm::Value *t = lGetBasePointer(ci->getOperand(0), insertBefore);
if (t == NULL) {
return NULL;
}
else {
return llvm::CastInst::Create(ci->getOpcode(),
t, ci->getType()->getScalarType(),
LLVMGetName(t, "_cast"),
insertBefore);
}
}
return NULL; return NULL;
} }
@@ -1320,7 +1346,7 @@ lGetBasePtrAndOffsets(llvm::Value *ptrs, llvm::Value **offsets,
LLVMDumpValue(ptrs); LLVMDumpValue(ptrs);
} }
llvm::Value *base = lGetBasePointer(ptrs); llvm::Value *base = lGetBasePointer(ptrs, insertBefore);
if (base != NULL) { if (base != NULL) {
// We have a straight up varying pointer with no indexing that's // We have a straight up varying pointer with no indexing that's
// actually all the same value. // actually all the same value.
@@ -1456,30 +1482,30 @@ lExtractConstantOffset(llvm::Value *vec, llvm::Value **constOffset,
return; return;
} }
llvm::SExtInst *sext = llvm::dyn_cast<llvm::SExtInst>(vec); llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(vec);
if (sext != NULL) { if (cast != NULL) {
// Check the sext target. // Check the cast target.
llvm::Value *co, *vo; llvm::Value *co, *vo;
lExtractConstantOffset(sext->getOperand(0), &co, &vo, insertBefore); lExtractConstantOffset(cast->getOperand(0), &co, &vo, insertBefore);
// make new sext instructions for the two parts // make new cast instructions for the two parts
if (co == NULL) if (co == NULL)
*constOffset = NULL; *constOffset = NULL;
else else
*constOffset = new llvm::SExtInst(co, sext->getType(), *constOffset = llvm::CastInst::Create(cast->getOpcode(),
LLVMGetName(co, "_sext"), co, cast->getType(),
LLVMGetName(co, "_cast"),
insertBefore); insertBefore);
if (vo == NULL) if (vo == NULL)
*variableOffset = NULL; *variableOffset = NULL;
else else
*variableOffset = new llvm::SExtInst(vo, sext->getType(), *variableOffset = llvm::CastInst::Create(cast->getOpcode(),
LLVMGetName(vo, "_sext"), vo, cast->getType(),
LLVMGetName(vo, "_cast"),
insertBefore); insertBefore);
return; return;
} }
// FIXME? handle bitcasts / type casts here
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(vec); llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(vec);
if (bop != NULL) { if (bop != NULL) {
llvm::Value *op0 = bop->getOperand(0); llvm::Value *op0 = bop->getOperand(0);
@@ -1671,17 +1697,17 @@ lExtract248Scale(llvm::Value *splatOperand, int splatValue,
*/ */
static llvm::Value * static llvm::Value *
lExtractOffsetVector248Scale(llvm::Value **vec) { lExtractOffsetVector248Scale(llvm::Value **vec) {
llvm::SExtInst *sext = llvm::dyn_cast<llvm::SExtInst>(*vec); llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(*vec);
if (sext != NULL) { if (cast != NULL) {
llvm::Value *sextOp = sext->getOperand(0); llvm::Value *castOp = cast->getOperand(0);
// Check the sext target. // Check the cast target.
llvm::Value *scale = lExtractOffsetVector248Scale(&sextOp); llvm::Value *scale = lExtractOffsetVector248Scale(&castOp);
if (scale == NULL) if (scale == NULL)
return NULL; return NULL;
// make a new sext instruction so that we end up with the right // make a new cast instruction so that we end up with the right
// type // type
*vec = new llvm::SExtInst(sextOp, sext->getType(), "offset_sext", sext); *vec = llvm::CastInst::Create(cast->getOpcode(), castOp, cast->getType(), "offset_cast", cast);
return scale; return scale;
} }

View File

@@ -5,7 +5,7 @@ export uniform int width() { return programCount; }
export void f_f(uniform float RET[], uniform float aFOO[]) { export void f_f(uniform float RET[], uniform float aFOO[]) {
uniform int a = 1; uniform int a = 1;
uniform int * uniform b = &a; uniform int * uniform b = &a;
int64 pi = (int64)b; uintptr_t pi = (uintptr_t)b;
RET[programIndex] = *((uniform int * varying)pi); RET[programIndex] = *((uniform int * varying)pi);
} }