[LLVMdev] [polly] ISL vector code generation

Tobias Grosser tobias at grosser.es
Mon Dec 17 15:45:37 PST 2012


On 12/18/2012 12:18 AM, Sebastian Pop wrote:
> Hi,
>
> thanks to Tobias for doing most of the work to get the vector code generation
> working with ISL's code generation.  Attached are two patches to port the vector
> code generation part of the testsuite from Cloog/CodeGen to Isl/CodeGen.
>
> Tobi, do you want to commit these two patches separately, or you want me to
> combine them, as the second patch is needed to make the testsuite pass?

Hi Sebastian,

I think it would be best if we first commit the second patch, but 
without the isl code generation changes. This is mainly a refactoring 
that establishes a proper interface for the isStride... functions. The
set that we passed in until now was very CLooG specific. Now we have a
proper interface and only need to adapt the CLooG output slightly to 
match this interface. I added some comments inline regarding this patch.

The remaining parts can then be merged to a single patch that adds 
vectorization support.

The first patch looks good, but needs still the stride-stuff from the
second patch.

The second patch still needs some love. Mainly documentation
and some little stylistic changes. Here the comments:

>
>     int getVectorWidth();
>
> diff --git a/include/polly/ScopInfo.h b/include/polly/ScopInfo.h
> index a6cf997..0d9ba1e 100755
> --- a/include/polly/ScopInfo.h
> +++ b/include/polly/ScopInfo.h
> @@ -150,18 +150,18 @@ public:
>
>     /// @brief Get the stride of this memory access in the specified domain
>     ///        subset.
> -  isl_set *getStride(__isl_take const isl_set *domainSubset) const;
> +  isl_set *getStride(__isl_take const isl_map *SubSchedule) const;

I dislike the name SubSchedule. Maybe we can use PartialSchedule or just 
Schedule. Also, we should document what kind of map is expected. Meaning 
a map from the statement to a schedule where the innermost dimension of 
the schedule is the dimension for which we want to get the stride.

> diff --git a/lib/CodeGen/CodeGeneration.cpp b/lib/CodeGen/CodeGeneration.cpp
> index 737f3b2..ccfcd04 100644
> --- a/lib/CodeGen/CodeGeneration.cpp
> +++ b/lib/CodeGen/CodeGeneration.cpp
> @@ -422,7 +422,16 @@ void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
>       }
>     }
>
> -  VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
> +  isl_map *Schedule = Statement->getScattering();
> +  int ScheduledDimensions = isl_set_dim(Domain, isl_dim_set);
> +  int UnscheduledDimensions = isl_map_dim(Schedule, isl_dim_out)
> +                              - ScheduledDimensions;
> +
> +  Schedule = isl_map_project_out(Schedule, isl_dim_out, ScheduledDimensions,
> +                                 UnscheduledDimensions);
> +  VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Schedule, P);

Can we move this change into a separate function. This will allow us to 
document that this function takes the cloog specific domain and 
translates it into a map Statement -> PartialSchedule, where the partial 
schedule for all dimensions that have been code generated up to this point.

> +  isl_map_free(Schedule);
>   }
>
>   void ClastStmtCodeGen::codegen(const clast_block *b) {
> diff --git a/lib/CodeGen/IslCodeGeneration.cpp b/lib/CodeGen/IslCodeGeneration.cpp
> index 431b960..c83e4b7 100644
> --- a/lib/CodeGen/IslCodeGeneration.cpp
> +++ b/lib/CodeGen/IslCodeGeneration.cpp
> @@ -596,7 +596,7 @@ private:
>     void createIf(__isl_take isl_ast_node *If);
>     void createUserVector(__isl_take isl_ast_node *User,
>                           std::vector<Value*> &IVS, __isl_take isl_id *IteratorID,
> -                        isl_set *Domain);
> +                        __isl_take isl_union_map *Domain);

The name should be consistent in function definition and declaration.

>     void createUser(__isl_take isl_ast_node *User);
>     void createBlock(__isl_take isl_ast_node *Block);
>   };
> @@ -671,7 +671,7 @@ unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
>   void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
>                                         std::vector<Value*> &IVS,
>                                         __isl_take isl_id *IteratorID,
> -                                      __isl_keep isl_set *Domain) {
> +                                      __isl_take isl_union_map *SubSchedule) {

I am not sure if 'SubSchedule' is very descriptive. PartialSchedule 
maybe. Also, we may want to add somewhere a comment that this is the 
schedule reaching up to the depth of the current statement.

>     isl_id *Annotation = isl_ast_node_get_annotation(User);
>     assert(Annotation && "Vector user statement is not annotated");
>
> @@ -682,11 +682,17 @@ void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
>     ScopStmt *Stmt = (ScopStmt *) isl_id_get_user(Id);
>     VectorValueMapT VectorMap(IVS.size());
>
> +  SubSchedule = isl_union_map_intersect_domain(SubSchedule,
> +    isl_union_set_from_set(Stmt->getDomain()));

You can use a variable 'Domain' to get rid of this ugly line break. ;-)

> +  isl_map *Schedule = isl_map_from_union_map(SubSchedule);
> +
>     createSubstitutionsVector(isl_pw_multi_aff_copy(Info->PMA),
>                               isl_ast_build_copy(Info->Context),
>                               Stmt, VectorMap, IVS, IteratorID);
> -  VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, Domain, P);
> +  VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, Schedule, P);

After having addressed the comments, you can commit the patches. I will 
look at them again post-commit.

Cheers
Tobias







More information about the llvm-dev mailing list