[polly] r309934 - [PPCGCodeGeneration] Construct `isl_multi_pw_aff` of PPCGArray.bounds even when polly-ignore-parameter-bounds is turned on.
Siddharth Bhat via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 3 05:09:33 PDT 2017
Author: bollu
Date: Thu Aug 3 05:09:33 2017
New Revision: 309934
URL: http://llvm.org/viewvc/llvm-project?rev=309934&view=rev
Log:
[PPCGCodeGeneration] Construct `isl_multi_pw_aff` of PPCGArray.bounds even when polly-ignore-parameter-bounds is turned on.
When we have `-polly-ignore-parameter-bounds`, `Scop::Context` does not contain
all the paramters present in the program.
The construction of the `isl_multi_pw_aff` requires all the indivisual `pw_aff`
to have the same parameter dimensions. To achieve this, we used to realign
every `pw_aff` with `Scop::Context`. However, in conjunction with
`-polly-ignore-parameter-bounds`, this is now incorrect, since `Scop::Context`
does not contain all parameters.
We set this up correctly by creating a space that has all the parameters
used by all the `isl_pw_aff`. Then, we realign all `isl_pw_aff` to this space.
Added:
polly/trunk/test/GPGPU/bounds-construction-with-ignore-param-bounds.ll
Modified:
polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
Modified: polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp?rev=309934&r1=309933&r2=309934&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp Thu Aug 3 05:09:33 2017
@@ -2349,6 +2349,56 @@ std::string GPUNodeBuilder::finalizeKern
return Assembly;
}
+/// Construct an `isl_pw_aff_list` from a vector of `isl_pw_aff`
+/// @param PwAffs The list of piecewise affine functions to create an
+/// `isl_pw_aff_list` from. We expect an rvalue ref because
+/// all the isl_pw_aff are used up by this function.
+///
+/// @returns The `isl_pw_aff_list`.
+__isl_give isl_pw_aff_list *
+createPwAffList(isl_ctx *Context,
+ const std::vector<__isl_take isl_pw_aff *> &&PwAffs) {
+ isl_pw_aff_list *List = isl_pw_aff_list_alloc(Context, PwAffs.size());
+
+ for (unsigned i = 0; i < PwAffs.size(); i++) {
+ List = isl_pw_aff_list_insert(List, i, PwAffs[i]);
+ }
+ return List;
+}
+
+/// Align all the `PwAffs` such that they have the same parameter dimensions.
+///
+/// We loop over all `pw_aff` and align all of their spaces together to
+/// create a common space for all the `pw_aff`. This common space is the
+/// `AlignSpace`. We then align all the `pw_aff` to this space. We start
+/// with the given `SeedSpace`.
+/// @param PwAffs The list of piecewise affine functions we want to align.
+/// This is an rvalue reference because the entire vector is
+/// used up by the end of the operation.
+/// @param SeedSpace The space to start the alignment process with.
+/// @returns A std::pair, whose first element is the aligned space,
+/// whose second element is the vector of aligned piecewise
+/// affines.
+static std::pair<__isl_give isl_space *, std::vector<__isl_give isl_pw_aff *>>
+alignPwAffs(const std::vector<__isl_take isl_pw_aff *> &&PwAffs,
+ __isl_take isl_space *SeedSpace) {
+ assert(SeedSpace && "Invalid seed space given.");
+
+ isl_space *AlignSpace = SeedSpace;
+ for (isl_pw_aff *PwAff : PwAffs) {
+ isl_space *PwAffSpace = isl_pw_aff_get_domain_space(PwAff);
+ AlignSpace = isl_space_align_params(AlignSpace, PwAffSpace);
+ }
+ std::vector<isl_pw_aff *> AdjustedPwAffs;
+
+ for (unsigned i = 0; i < PwAffs.size(); i++) {
+ isl_pw_aff *Adjusted = PwAffs[i];
+ assert(Adjusted && "Invalid pw_aff given.");
+ Adjusted = isl_pw_aff_align_params(Adjusted, isl_space_copy(AlignSpace));
+ AdjustedPwAffs.push_back(Adjusted);
+ }
+ return std::make_pair(AlignSpace, AdjustedPwAffs);
+}
namespace {
class PPCGCodeGeneration : public ScopPass {
@@ -2732,12 +2782,7 @@ public:
/// @param PPCGArray The array to compute bounds for.
/// @param Array The polly array from which to take the information.
void setArrayBounds(gpu_array_info &PPCGArray, ScopArrayInfo *Array) {
- isl_pw_aff_list *BoundsList =
- isl_pw_aff_list_alloc(S->getIslCtx(), PPCGArray.n_index);
- std::vector<isl::pw_aff> PwAffs;
-
- isl_space *AlignSpace = S->getParamSpace();
- AlignSpace = isl_space_add_dims(AlignSpace, isl_dim_set, 1);
+ std::vector<isl_pw_aff *> Bounds;
if (PPCGArray.n_index > 0) {
if (isl_set_is_empty(PPCGArray.extent)) {
@@ -2746,9 +2791,7 @@ public:
isl_space_params(isl_set_get_space(Dom)));
isl_set_free(Dom);
isl_pw_aff *Zero = isl_pw_aff_from_aff(isl_aff_zero_on_domain(LS));
- Zero = isl_pw_aff_align_params(Zero, isl_space_copy(AlignSpace));
- PwAffs.push_back(isl::manage(isl_pw_aff_copy(Zero)));
- BoundsList = isl_pw_aff_list_insert(BoundsList, 0, Zero);
+ Bounds.push_back(Zero);
} else {
isl_set *Dom = isl_set_copy(PPCGArray.extent);
Dom = isl_set_project_out(Dom, isl_dim_set, 1, PPCGArray.n_index - 1);
@@ -2761,9 +2804,7 @@ public:
One = isl_aff_add_constant_si(One, 1);
Bound = isl_pw_aff_add(Bound, isl_pw_aff_alloc(Dom, One));
Bound = isl_pw_aff_gist(Bound, S->getContext());
- Bound = isl_pw_aff_align_params(Bound, isl_space_copy(AlignSpace));
- PwAffs.push_back(isl::manage(isl_pw_aff_copy(Bound)));
- BoundsList = isl_pw_aff_list_insert(BoundsList, 0, Bound);
+ Bounds.push_back(Bound);
}
}
@@ -2772,13 +2813,31 @@ public:
auto LS = isl_pw_aff_get_domain_space(Bound);
auto Aff = isl_multi_aff_zero(LS);
Bound = isl_pw_aff_pullback_multi_aff(Bound, Aff);
- Bound = isl_pw_aff_align_params(Bound, isl_space_copy(AlignSpace));
- PwAffs.push_back(isl::manage(isl_pw_aff_copy(Bound)));
- BoundsList = isl_pw_aff_list_insert(BoundsList, i, Bound);
+ Bounds.push_back(Bound);
}
- isl_space_free(AlignSpace);
+ /// To construct a `isl_multi_pw_aff`, we need all the indivisual `pw_aff`
+ /// to have the same parameter dimensions. So, we need to align them to an
+ /// appropriate space.
+ /// Scop::Context is _not_ an appropriate space, because when we have
+ /// `-polly-ignore-parameter-bounds` enabled, the Scop::Context does not
+ /// contain all parameter dimensions.
+ /// So, use the helper `alignPwAffs` to align all the `isl_pw_aff` together.
+ isl_space *SeedAlignSpace = S->getParamSpace();
+ SeedAlignSpace = isl_space_add_dims(SeedAlignSpace, isl_dim_set, 1);
+
+ isl_space *AlignSpace = nullptr;
+ std::vector<isl_pw_aff *> AlignedBounds;
+ std::tie(AlignSpace, AlignedBounds) =
+ alignPwAffs(std::move(Bounds), SeedAlignSpace);
+
+ assert(AlignSpace && "alignPwAffs did not initialise AlignSpace");
+
+ isl_pw_aff_list *BoundsList =
+ createPwAffList(S->getIslCtx(), std::move(AlignedBounds));
+
isl_space *BoundsSpace = isl_set_get_space(PPCGArray.extent);
+ BoundsSpace = isl_space_align_params(BoundsSpace, AlignSpace);
assert(BoundsSpace && "Unable to access space of array.");
assert(BoundsList && "Unable to access list of bounds.");
Added: polly/trunk/test/GPGPU/bounds-construction-with-ignore-param-bounds.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/GPGPU/bounds-construction-with-ignore-param-bounds.ll?rev=309934&view=auto
==============================================================================
--- polly/trunk/test/GPGPU/bounds-construction-with-ignore-param-bounds.ll (added)
+++ polly/trunk/test/GPGPU/bounds-construction-with-ignore-param-bounds.ll Thu Aug 3 05:09:33 2017
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -S -polly-codegen-ppcg \
+; RUN: -polly-ignore-parameter-bounds \
+; RUN: -polly-invariant-load-hoisting < %s| FileCheck %s -check-prefix=HOST-IR
+
+; When we have `-polly-ignore-parameter-bounds`, `Scop::Context` does not contain
+; all the parameters present in the program.
+;
+; The construction of the `isl_multi_pw_aff` requires all the indivisual `pw_aff`
+; to have the same parameter dimensions. To achieve this, we used to realign
+; every `pw_aff` with `Scop::Context`. However, in conjunction with
+; `-polly-ignore-parameter-bounds`, this is now incorrect, since `Scop::Context`
+; does not contain all parameters.
+;
+; We check that Polly does the right thing in this case and sets up the parameter
+; dimensions correctly.
+
+
+; Check that kernel launch is generated in host IR.
+; the declare would not be generated unless a call to a kernel exists.
+; HOST-IR: declare void @polly_launchKernel(i8*, i32, i32, i32, i32, i32, i8*)
+; ModuleID = 'test/GPGPU/bounds-construction-with-ignore-param-bounds.ll'
+
+; C pseudocode
+; ------------
+; void f(int *arr, long niters, long stride) {
+; for(int i = 0; i < niters; i++) {
+; arr[i * stride] = 1;
+; }
+; }
+
+target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @f(i32 *%arr, i64 %niters, i64 %stride) unnamed_addr #1 {
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+ %idx = mul nuw nsw i64 %indvar, %stride
+ %slot = getelementptr i32, i32* %arr, i64 %idx
+ store i32 1, i32* %slot, align 4
+ %indvar.next = add nuw nsw i64 %indvar, 1
+ %check = icmp sgt i64 %indvar.next, %niters
+ br i1 %check, label %exit, label %loop
+
+exit: ; preds = %loop
+ ret void
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind uwtable }
More information about the llvm-commits
mailing list