Detect more gather/scatter cases that are actually base+offsets.

We now recognize patterns like (ptr + offset1 + offset2) as being
cases we can handle with the base_offsets variants of the gather/scatter
functions.  (This can come up with multidimensional array indexing,
for example.)

Issue #150.
This commit is contained in:
Matt Pharr
2012-01-08 14:06:12 -08:00
parent 0ed11a7832
commit be0c77d556

22
opt.cpp
View File

@@ -1063,7 +1063,8 @@ lGetConstantAddExprBaseOffset(llvm::Constant *op0, llvm::Constant *op1,
*offsets with an int vector of the per-lane offsets *offsets with an int vector of the per-lane offsets
*/ */
static llvm::Value * static llvm::Value *
lGetBasePtrAndOffsets(llvm::Value *ptrs, llvm::Value **offsets) { lGetBasePtrAndOffsets(llvm::Value *ptrs, llvm::Value **offsets,
llvm::Instruction *insertBefore) {
llvm::Value *base = lGetBasePointer(ptrs); llvm::Value *base = lGetBasePointer(ptrs);
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
@@ -1079,12 +1080,20 @@ lGetBasePtrAndOffsets(llvm::Value *ptrs, llvm::Value **offsets) {
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add) { if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add) {
// If we have a common pointer plus something, then we're also // If we have a common pointer plus something, then we're also
// good. // good.
if ((base = lGetBasePointer(bop->getOperand(0))) != NULL) { if ((base = lGetBasePtrAndOffsets(bop->getOperand(0),
*offsets = bop->getOperand(1); offsets, insertBefore)) != NULL) {
*offsets =
llvm::BinaryOperator::Create(llvm::Instruction::Add, *offsets,
bop->getOperand(1), "new_offsets",
insertBefore);
return base; return base;
} }
else if ((base = lGetBasePointer(bop->getOperand(1))) != NULL) { else if ((base = lGetBasePtrAndOffsets(bop->getOperand(1),
*offsets = bop->getOperand(0); offsets, insertBefore)) != NULL) {
*offsets =
llvm::BinaryOperator::Create(llvm::Instruction::Add, *offsets,
bop->getOperand(0), "new_offsets",
insertBefore);
return base; return base;
} }
} }
@@ -1316,7 +1325,8 @@ GatherScatterFlattenOpt::runOnBasicBlock(llvm::BasicBlock &bb) {
// lGetBasePtrAndOffsets). // lGetBasePtrAndOffsets).
llvm::Value *ptrs = callInst->getArgOperand(0); llvm::Value *ptrs = callInst->getArgOperand(0);
llvm::Value *offsetVector = NULL; llvm::Value *offsetVector = NULL;
llvm::Value *basePtr = lGetBasePtrAndOffsets(ptrs, &offsetVector); llvm::Value *basePtr = lGetBasePtrAndOffsets(ptrs, &offsetVector,
callInst);
if (basePtr == NULL || offsetVector == NULL) if (basePtr == NULL || offsetVector == NULL)
// It's actually a fully general gather/scatter with a varying // It's actually a fully general gather/scatter with a varying