[LLVMdev] How to make Polly ignore some non-affine memory accesses
Marcello Maggioni
hayarms at gmail.com
Sun Nov 20 03:01:07 PST 2011
2011/11/19 Tobias Grosser <tobias at grosser.es>:
> 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?
I wanted to add a test case that in case of a "missing the flag" at
command line confirmed the functionality was actually disabled (and
this is the reason of the XFAIL test).
Originally you said I had to add a minimal test case to the patch,
should I add some more tests now with more complex scops?
>> 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.
Ouch!
>
>> 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
>
Ok, I'll simplify these parts, thanks.
Marcello
More information about the llvm-dev
mailing list