adding cases of 'cast' instructions in optimizations
This commit is contained in:
72
opt.cpp
72
opt.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user