[LLVMdev] How to make Polly ignore some non-affine memory accesses
Tobias Grosser
tobias at grosser.es
Sat Nov 19 08:38:34 PST 2011
On 11/18/2011 01:34 PM, Marcello Maggioni wrote:
> Ok , this is what I believe is the final patch that adds the
> non-affine accept functionality to Polly, this should have no issues.
>
> I added three tests, two in ScopInfo (two simple tests, one expected
> fail and one success based on the same source) and one in CodeGen that
> verifies that the code is generated.
>
> The patch is attached.
The patch includes only one test case. I also have some tiny last
comments inline. Otherwise the patch looks good.
> +++ test/ScopInfo/simple_nonaffine_loop_exfail.ll (revision 0)
> @@ -0,0 +1,42 @@
> +; RUN: opt %loadPolly %defaultOpts -polly-scops -analyze %s |
> FileCheck %s
> +; XFAIL: *
Why is this one still XFAIL?
> Index: lib/Analysis/ScopInfo.cpp
> ===================================================================
> --- lib/Analysis/ScopInfo.cpp (revision 144978)
> +++ lib/Analysis/ScopInfo.cpp (working copy)
> @@ -311,29 +311,38 @@
> Type = Access.isRead() ? Read : Write;
> statement = Statement;
>
> - isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset());
> BaseAddr = Access.getBase();
>
> - setBaseName();
> + if (Access.isAffine()) {
>
> - // Devide the access function by the size of the elements in the array.
> - //
> - // A stride one array access in C expressed as A[i] is expressed in LLVM-IR
> - // as something like A[i * elementsize]. This hides the fact that two
> - // subsequent values of 'i' index two values that are stored next to each
> - // other in memory. By this devision we make this characteristic obvious
> - // again.
> - isl_int v;
> - isl_int_init(v);
> - isl_int_set_si(v, Access.getElemSizeInBytes());
> - Affine = isl_pw_aff_scale_down(Affine, v);
> - isl_int_clear(v);
> + isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset());
>
> - AccessRelation = isl_map_from_pw_aff(Affine);
> - AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_in,
> - Statement->getBaseName());
> - AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
> - getBaseName().c_str());
> + setBaseName();
> +
> + // Devide the access function by the size of the elements in the array.
> + //
> + // A stride one array access in C expressed as A[i] is expressed in LLVM-IR
> + // as something like A[i * elementsize]. This hides the fact that two
> + // subsequent values of 'i' index two values that are stored next to each
> + // other in memory. By this devision we make this characteristic obvious
> + // again.
> + isl_int v;
> + isl_int_init(v);
> + isl_int_set_si(v, Access.getElemSizeInBytes());
> + Affine = isl_pw_aff_scale_down(Affine, v);
> + isl_int_clear(v);
> +
> + AccessRelation = isl_map_from_pw_aff(Affine);
> + AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_in,
> + Statement->getBaseName());
> + AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
> + getBaseName().c_str());
> + }
> + else
> + {
Use '} else {' here.
> Index: lib/Analysis/ScopDetection.cpp
> ===================================================================
> --- lib/Analysis/ScopDetection.cpp (revision 144978)
> +++ lib/Analysis/ScopDetection.cpp (working copy)
> @@ -79,6 +79,11 @@
> cl::desc("Ignore possible aliasing of the array bases"),
> cl::Hidden, cl::init(false));
>
> +static cl::opt<bool>
> +AllowNonAffine("polly-allow-nonaffine",
> + cl::desc("Allow non affine access functions for arrays"),
> + cl::Hidden, cl::init(false));
> +
> //===----------------------------------------------------------------------===//
> // Statistics.
>
> @@ -236,7 +241,9 @@
> BasePointer = dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
>
> if (!BasePointer)
> + {
> INVALID(AffFunc, "No base pointer");
> + }
This change is unneeded and unrelated.
>
> BaseValue = BasePointer->getValue();
>
> @@ -245,8 +252,9 @@
>
> AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
>
> - if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue))
> + if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue)&& !AllowNonAffine)
> INVALID(AffFunc, "Bad memory address "<< *AccessFunction);
> +
>
> // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
> // created by IndependentBlocks Pass.
> Index: lib/Analysis/TempScopInfo.cpp
> ===================================================================
> --- lib/Analysis/TempScopInfo.cpp (revision 144978)
> +++ lib/Analysis/TempScopInfo.cpp (working copy)
> @@ -98,12 +98,20 @@
> dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
>
> assert(BasePointer&& "Could not find base pointer");
> + AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
> +
> + if (isAffineExpr(&R, AccessFunction, *SE, BasePointer->getValue())) {
>
> - AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
> - Functions.push_back(std::make_pair(IRAccess(Type,
> + Functions.push_back(std::make_pair(IRAccess(Type,
> BasePointer->getValue(),
> - AccessFunction, Size),
> + AccessFunction, Size, true),
> &Inst));
> + } else {
> + Functions.push_back(std::make_pair(IRAccess(Type,
> + BasePointer->getValue(),
> + AccessFunction, Size, false),
> +&Inst));
> + }
You may want to simplify this to:
AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
bool IsAffine = isAffineExpr(&R, AccessFunction, *SE,
BasePointer->getValue()));
Functions.push_back(std::make_pair(IRAccess(Type,
BasePointer->getValue(),
AccessFunction, Size,
IsAffine);
Cheers and thanks for you work
Tobi
More information about the llvm-dev
mailing list