[polly] r177777 - codegen: properly instantiate SCEVs to the place where they are used
Tobias Grosser
grosser at fim.uni-passau.de
Fri Mar 22 16:42:53 PDT 2013
Author: grosser
Date: Fri Mar 22 18:42:53 2013
New Revision: 177777
URL: http://llvm.org/viewvc/llvm-project?rev=177777&view=rev
Log:
codegen: properly instantiate SCEVs to the place where they are used
Given the following code
for (i = 0; i < 10; i++) {
;
}
S: A[i] = 0
When code generating S using scev based code generation, we need to retrieve
the scev of 'i' at the location of 'S'. If we do not do this the scev that
we obtain will be expressed as {0,+,1}_for and will reference loop iterators
that do not surround 'S' and that we consequently do not know how to code
generate. What we really want is the scev to be instantiated to the value of 'i'
after the loop. This value is {10} and it can be code generated without
troubles.
Modified:
polly/trunk/include/polly/CodeGen/BlockGenerators.h
polly/trunk/lib/CodeGen/BlockGenerators.cpp
polly/trunk/test/Isl/CodeGen/20130221.ll
Modified: polly/trunk/include/polly/CodeGen/BlockGenerators.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/BlockGenerators.h?rev=177777&r1=177776&r2=177777&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/BlockGenerators.h (original)
+++ polly/trunk/include/polly/CodeGen/BlockGenerators.h Fri Mar 22 18:42:53 2013
@@ -96,27 +96,43 @@ protected:
/// variable to their new values
/// (for values recalculated in the new ScoP, but not
/// within this basic block).
+ /// @param L The loop that surrounded the instruction that referenced
+ /// this value in the original code. This loop is used to
+ /// evaluate the scalar evolution at the right scope.
///
/// @returns o The old value, if it is still valid.
/// o The new value, if available.
/// o NULL, if no value is found.
Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap,
- LoopToScevMapT <S);
+ LoopToScevMapT <S, Loop *L);
void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
ValueMapT &GlobalMap, LoopToScevMapT <S);
+ /// @brief Get the innermost loop that surrounds an instruction.
+ ///
+ /// @param Inst The instruction for which we get the loop.
+ /// @return The innermost loop that surrounds the instruction.
+ Loop *getLoopForInst(const Instruction *Inst);
+
/// @brief Get the memory access offset to be added to the base address
+ ///
+ /// @param L The loop that surrounded the instruction that referenced this
+ /// memory subscript in the original code.
std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Value *BaseAddress, ValueMapT &BBMap,
ValueMapT &GlobalMap,
- LoopToScevMapT <S);
+ LoopToScevMapT <S, Loop *L);
/// @brief Get the new operand address according to the changed access in
/// JSCOP file.
+ ///
+ /// @param L The loop that surrounded the instruction that used this operand
+ /// in the original code.
Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
Value *BaseAddress, ValueMapT &BBMap,
- ValueMapT &GlobalMap, LoopToScevMapT <S);
+ ValueMapT &GlobalMap, LoopToScevMapT <S,
+ Loop *L);
/// @brief Generate the operand address
Value *generateLocationAccessed(const Instruction *Inst,
@@ -225,7 +241,7 @@ private:
int getVectorWidth();
Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
- VectorValueMapT &ScalarMaps);
+ VectorValueMapT &ScalarMaps, Loop *L);
Type *getVectorPtrTy(const Value *V, int Width);
Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=177777&r1=177776&r2=177777&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Fri Mar 22 18:42:53 2013
@@ -170,7 +170,8 @@ BlockGenerator::BlockGenerator(IRBuilder
}
Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
- ValueMapT &GlobalMap, LoopToScevMapT <S) {
+ ValueMapT &GlobalMap, LoopToScevMapT <S,
+ Loop *L) {
// We assume constants never change.
// This avoids map lookups for many calls to this function.
if (isa<Constant>(Old))
@@ -191,7 +192,7 @@ Value *BlockGenerator::getNewValue(const
}
if (SCEVCodegen && SE.isSCEVable(Old->getType()))
- if (const SCEV *Scev = SE.getSCEV(const_cast<Value *>(Old)))
+ if (const SCEV *Scev = SE.getSCEVAtScope(const_cast<Value *>(Old), L)) {
if (!isa<SCEVCouldNotCompute>(Scev)) {
const SCEV *NewScev = apply(Scev, LTS, SE);
ValueToValueMap VTV;
@@ -205,6 +206,7 @@ Value *BlockGenerator::getNewValue(const
BBMap[Old] = Expanded;
return Expanded;
}
+ }
if (const Instruction *Inst = dyn_cast<Instruction>(Old)) {
(void) Inst;
@@ -226,7 +228,8 @@ void BlockGenerator::copyInstScalar(cons
OE = Inst->op_end();
OI != OE; ++OI) {
Value *OldOperand = *OI;
- Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap, LTS);
+ Value *NewOperand =
+ getNewValue(OldOperand, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
if (!NewOperand) {
assert(!isa<StoreInst>(NewInst) &&
@@ -247,7 +250,7 @@ void BlockGenerator::copyInstScalar(cons
std::vector<Value *> BlockGenerator::getMemoryAccessIndex(
__isl_keep isl_map *AccessRelation, Value *BaseAddress, ValueMapT &BBMap,
- ValueMapT &GlobalMap, LoopToScevMapT <S) {
+ ValueMapT &GlobalMap, LoopToScevMapT <S, Loop *L) {
assert((isl_map_dim(AccessRelation, isl_dim_out) == 1) &&
"Only single dimensional access functions supported");
@@ -255,7 +258,7 @@ std::vector<Value *> BlockGenerator::get
std::vector<Value *> IVS;
for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
- Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap, LTS);
+ Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap, LTS, L);
IVS.push_back(NewIV);
}
@@ -275,9 +278,9 @@ std::vector<Value *> BlockGenerator::get
Value *BlockGenerator::getNewAccessOperand(
__isl_keep isl_map *NewAccessRelation, Value *BaseAddress, ValueMapT &BBMap,
- ValueMapT &GlobalMap, LoopToScevMapT <S) {
+ ValueMapT &GlobalMap, LoopToScevMapT <S, Loop *L) {
std::vector<Value *> IndexArray = getMemoryAccessIndex(
- NewAccessRelation, BaseAddress, BBMap, GlobalMap, LTS);
+ NewAccessRelation, BaseAddress, BBMap, GlobalMap, LTS, L);
Value *NewOperand =
Builder.CreateGEP(BaseAddress, IndexArray, "p_newarrayidx_");
return NewOperand;
@@ -296,11 +299,12 @@ Value *BlockGenerator::generateLocationA
Value *NewPointer;
if (!NewAccessRelation) {
- NewPointer = getNewValue(Pointer, BBMap, GlobalMap, LTS);
+ NewPointer =
+ getNewValue(Pointer, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
} else {
Value *BaseAddress = const_cast<Value *>(Access.getBaseAddr());
NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, BBMap,
- GlobalMap, LTS);
+ GlobalMap, LTS, getLoopForInst(Inst));
}
isl_map_free(CurrentAccessRelation);
@@ -308,6 +312,11 @@ Value *BlockGenerator::generateLocationA
return NewPointer;
}
+Loop *
+BlockGenerator::getLoopForInst(const llvm::Instruction *Inst) {
+ return P->getAnalysis<LoopInfo>().getLoopFor(Inst->getParent());
+}
+
Value *
BlockGenerator::generateScalarLoad(const LoadInst *Load, ValueMapT &BBMap,
ValueMapT &GlobalMap, LoopToScevMapT <S) {
@@ -326,8 +335,8 @@ BlockGenerator::generateScalarStore(cons
const Value *Pointer = Store->getPointerOperand();
Value *NewPointer =
generateLocationAccessed(Store, Pointer, BBMap, GlobalMap, LTS);
- Value *ValueOperand =
- getNewValue(Store->getValueOperand(), BBMap, GlobalMap, LTS);
+ Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap,
+ LTS, getLoopForInst(Store));
return Builder.CreateStore(ValueOperand, NewPointer);
}
@@ -382,7 +391,8 @@ VectorBlockGenerator::VectorBlockGenerat
}
Value *VectorBlockGenerator::getVectorValue(
- const Value *Old, ValueMapT &VectorMap, VectorValueMapT &ScalarMaps) {
+ const Value *Old, ValueMapT &VectorMap, VectorValueMapT &ScalarMaps,
+ Loop *L) {
if (VectorMap.count(Old))
return VectorMap[Old];
@@ -393,7 +403,7 @@ Value *VectorBlockGenerator::getVectorVa
for (int Lane = 0; Lane < Width; Lane++)
Vector = Builder.CreateInsertElement(
Vector,
- getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane], VLTS[Lane]),
+ getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane], VLTS[Lane], L),
Builder.getInt32(Lane));
VectorMap[Old] = Vector;
@@ -415,7 +425,8 @@ Value *VectorBlockGenerator::generateStr
ValueMapT &BBMap) {
const Value *Pointer = Load->getPointerOperand();
Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
- Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0]);
+ Value *NewPointer =
+ getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0], getLoopForInst(Load));
Value *VectorPtr =
Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr");
LoadInst *VecLoad =
@@ -430,7 +441,8 @@ Value *VectorBlockGenerator::generateStr
ValueMapT &BBMap) {
const Value *Pointer = Load->getPointerOperand();
Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
- Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0]);
+ Value *NewPointer =
+ getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0], getLoopForInst(Load));
Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
Load->getName() + "_p_vec_p");
LoadInst *ScalarLoad =
@@ -457,8 +469,8 @@ Value *VectorBlockGenerator::generateUnk
Value *Vector = UndefValue::get(VectorType);
for (int i = 0; i < VectorWidth; i++) {
- Value *NewPointer =
- getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
+ Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i],
+ VLTS[i], getLoopForInst(Load));
Value *ScalarLoad =
Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_");
Vector = Builder.CreateInsertElement(
@@ -495,8 +507,8 @@ void VectorBlockGenerator::copyUnaryInst
ValueMapT &VectorMap,
VectorValueMapT &ScalarMaps) {
int VectorWidth = getVectorWidth();
- Value *NewOperand =
- getVectorValue(Inst->getOperand(0), VectorMap, ScalarMaps);
+ Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap, ScalarMaps,
+ getLoopForInst(Inst));
assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
@@ -508,12 +520,13 @@ void VectorBlockGenerator::copyUnaryInst
void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
ValueMapT &VectorMap,
VectorValueMapT &ScalarMaps) {
+ Loop *L = getLoopForInst(Inst);
Value *OpZero = Inst->getOperand(0);
Value *OpOne = Inst->getOperand(1);
Value *NewOpZero, *NewOpOne;
- NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
- NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
+ NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps, L);
+ NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps, L);
Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero, NewOpOne,
Inst->getName() + "p_vec");
@@ -527,13 +540,13 @@ void VectorBlockGenerator::copyStore(
MemoryAccess &Access = Statement.getAccessFor(Store);
const Value *Pointer = Store->getPointerOperand();
- Value *Vector =
- getVectorValue(Store->getValueOperand(), VectorMap, ScalarMaps);
+ Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
+ ScalarMaps, getLoopForInst(Store));
if (Access.isStrideOne(isl_map_copy(Schedule))) {
Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
- Value *NewPointer =
- getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0], VLTS[0]);
+ Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0],
+ VLTS[0], getLoopForInst(Store));
Value *VectorPtr =
Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr");
@@ -544,8 +557,8 @@ void VectorBlockGenerator::copyStore(
} else {
for (unsigned i = 0; i < ScalarMaps.size(); i++) {
Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i));
- Value *NewPointer =
- getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
+ Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i],
+ VLTS[i], getLoopForInst(Store));
Builder.CreateStore(Scalar, NewPointer);
}
}
Modified: polly/trunk/test/Isl/CodeGen/20130221.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/20130221.ll?rev=177777&r1=177776&r2=177777&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/20130221.ll (original)
+++ polly/trunk/test/Isl/CodeGen/20130221.ll Fri Mar 22 18:42:53 2013
@@ -1,5 +1,4 @@
-; RUN: opt %loadPolly -polly-codegen-isl %s -polly-codegen-scev
-; XFAIL: *
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
More information about the llvm-commits
mailing list