Move getIndexExpressionsFromGEP() to ScopHelper. NFC.

This function is used by both ScopInfo and ScopBuilder. A common
location for this function is required when ScopInfo and ScopBuilder are
separated into separate files in the next commit.

llvm-svn: 273981
This commit is contained in:
Michael Kruse 2016-06-28 01:37:13 +00:00
parent 728356d10a
commit 6ff419c2ec
3 changed files with 68 additions and 61 deletions

View File

@ -19,6 +19,8 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueHandle.h"
#include <tuple>
#include <vector>
namespace llvm {
class LoopInfo;
@ -29,6 +31,7 @@ class Region;
class Pass;
class DominatorTree;
class RegionInfo;
class GetElementPtrInst;
} // namespace llvm
namespace polly {
@ -414,5 +417,21 @@ bool canSynthesize(const llvm::Value *V, const Scop &S,
/// Non-instructions do not use operands at a specific point such that in this
/// case this function returns nullptr.
llvm::BasicBlock *getUseBlock(llvm::Use &U);
/// @brief Derive the individual index expressions from a GEP instruction.
///
/// This function optimistically assumes the GEP references into a fixed size
/// array. If this is actually true, this function returns a list of array
/// subscript expressions as SCEV as well as a list of integers describing
/// the size of the individual array dimensions. Both lists have either equal
/// length or the size list is one element shorter in case there is no known
/// size available for the outermost array dimension.
///
/// @param GEP The GetElementPtr instruction to analyze.
///
/// @return A tuple with the subscript expressions and the dimension sizes.
std::tuple<std::vector<const llvm::SCEV *>, std::vector<int>>
getIndexExpressionsFromGEP(llvm::GetElementPtrInst *GEP,
llvm::ScalarEvolution &SE);
} // namespace polly
#endif

View File

@ -491,67 +491,6 @@ static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
}
}
/// @brief Derive the individual index expressions from a GEP instruction
///
/// This function optimistically assumes the GEP references into a fixed size
/// array. If this is actually true, this function returns a list of array
/// subscript expressions as SCEV as well as a list of integers describing
/// the size of the individual array dimensions. Both lists have either equal
/// length of the size list is one element shorter in case there is no known
/// size available for the outermost array dimension.
///
/// @param GEP The GetElementPtr instruction to analyze.
///
/// @return A tuple with the subscript expressions and the dimension sizes.
static std::tuple<std::vector<const SCEV *>, std::vector<int>>
getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
std::vector<const SCEV *> Subscripts;
std::vector<int> Sizes;
Type *Ty = GEP->getPointerOperandType();
bool DroppedFirstDim = false;
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
if (i == 1) {
if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
Ty = PtrTy->getElementType();
} else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
Ty = ArrayTy->getElementType();
} else {
Subscripts.clear();
Sizes.clear();
break;
}
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
if (Const->getValue()->isZero()) {
DroppedFirstDim = true;
continue;
}
Subscripts.push_back(Expr);
continue;
}
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
if (!ArrayTy) {
Subscripts.clear();
Sizes.clear();
break;
}
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
Sizes.push_back(ArrayTy->getNumElements());
Ty = ArrayTy->getElementType();
}
return std::make_tuple(Subscripts, Sizes);
}
MemoryAccess::~MemoryAccess() {
isl_id_free(Id);
isl_set_free(InvalidDomain);

View File

@ -490,3 +490,52 @@ llvm::BasicBlock *polly::getUseBlock(llvm::Use &U) {
return UI->getParent();
}
std::tuple<std::vector<const SCEV *>, std::vector<int>>
polly::getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
std::vector<const SCEV *> Subscripts;
std::vector<int> Sizes;
Type *Ty = GEP->getPointerOperandType();
bool DroppedFirstDim = false;
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
if (i == 1) {
if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
Ty = PtrTy->getElementType();
} else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
Ty = ArrayTy->getElementType();
} else {
Subscripts.clear();
Sizes.clear();
break;
}
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
if (Const->getValue()->isZero()) {
DroppedFirstDim = true;
continue;
}
Subscripts.push_back(Expr);
continue;
}
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
if (!ArrayTy) {
Subscripts.clear();
Sizes.clear();
break;
}
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
Sizes.push_back(ArrayTy->getNumElements());
Ty = ArrayTy->getElementType();
}
return std::make_tuple(Subscripts, Sizes);
}