Index: polly/trunk/include/polly/ScheduleOptimizer.h =================================================================== --- polly/trunk/include/polly/ScheduleOptimizer.h +++ polly/trunk/include/polly/ScheduleOptimizer.h @@ -87,8 +87,8 @@ /// to. /// @param OAI Target Transform Info and the SCoP dependencies. /// @returns The transformed schedule. - static __isl_give isl_schedule * - optimizeSchedule(__isl_take isl_schedule *Schedule, + static isl::schedule + optimizeSchedule(isl::schedule Schedule, const polly::OptimizerAdditionalInfoTy *OAI = nullptr); /// Apply schedule tree transformations. @@ -103,8 +103,8 @@ /// @param Node The schedule object post-transformations will be applied to. /// @param OAI Target Transform Info and the SCoP dependencies. /// @returns The transformed schedule. - static __isl_give isl_schedule_node * - optimizeScheduleNode(__isl_take isl_schedule_node *Node, + static isl::schedule_node + optimizeScheduleNode(isl::schedule_node Node, const polly::OptimizerAdditionalInfoTy *OAI = nullptr); /// Decide if the @p NewSchedule is profitable for @p S. @@ -113,8 +113,7 @@ /// @param NewSchedule The new schedule we computed. /// /// @return True, if we believe @p NewSchedule is an improvement for @p S. - static bool isProfitableSchedule(polly::Scop &S, - __isl_keep isl_schedule *NewSchedule); + static bool isProfitableSchedule(polly::Scop &S, isl::schedule NewSchedule); /// Isolate a set of partial tile prefixes. /// @@ -138,9 +137,10 @@ /// tiling. /// @param DefaultTileSize A default tile size that is used for dimensions /// that are not covered by the TileSizes vector. - static __isl_give isl_schedule_node * - tileNode(__isl_take isl_schedule_node *Node, const char *Identifier, - llvm::ArrayRef TileSizes, int DefaultTileSize); + static isl::schedule_node tileNode(isl::schedule_node Node, + const char *Identifier, + llvm::ArrayRef TileSizes, + int DefaultTileSize); /// Tile a schedule node and unroll point loops. /// @@ -148,9 +148,9 @@ /// @param TileSizes A vector of tile sizes that should be used for /// tiling. /// @param DefaultTileSize A default tile size that is used for dimensions - static __isl_give isl_schedule_node * - applyRegisterTiling(__isl_take isl_schedule_node *Node, - llvm::ArrayRef TileSizes, int DefaultTileSize); + static isl::schedule_node applyRegisterTiling(isl::schedule_node Node, + llvm::ArrayRef TileSizes, + int DefaultTileSize); /// Apply the BLIS matmul optimization pattern. /// @@ -197,8 +197,8 @@ /// @param TTI Target Transform Info. /// @param MMI Parameters of the matrix multiplication operands. /// @returns The transformed schedule. - static __isl_give isl_schedule_node * - optimizeMatMulPattern(__isl_take isl_schedule_node *Node, + static isl::schedule_node + optimizeMatMulPattern(isl::schedule_node Node, const llvm::TargetTransformInfo *TTI, polly::MatMulInfoTy &MMI); @@ -208,7 +208,7 @@ /// permutable. /// /// @param Node The node to check. - static bool isTileableBandNode(__isl_keep isl_schedule_node *Node); + static bool isTileableBandNode(isl::schedule_node Node); /// Pre-vectorizes one scheduling dimension of a schedule band. /// @@ -241,9 +241,9 @@ /// DimToVectorize can be divided by VectorWidth. The default VectorWidth is /// currently constant and not yet target specific. This function does not /// reason about parallelism. - static __isl_give isl_schedule_node * - prevectSchedBand(__isl_take isl_schedule_node *Node, unsigned DimToVectorize, - int VectorWidth); + static isl::schedule_node prevectSchedBand(isl::schedule_node Node, + unsigned DimToVectorize, + int VectorWidth); /// Apply additional optimizations on the bands in the schedule tree. /// @@ -276,7 +276,7 @@ /// @param Node The schedule node to (possibly) optimize. /// @param User A pointer to forward some use information /// (currently unused). - static isl_schedule_node *standardBandOpts(__isl_take isl_schedule_node *Node, + static isl::schedule_node standardBandOpts(isl::schedule_node Node, void *User); /// Check if this node contains a partial schedule that could @@ -299,7 +299,7 @@ /// @param Node The node to check. /// @param D The SCoP dependencies. /// @param MMI Parameters of the matrix multiplication operands. - static bool isMatrMultPattern(__isl_keep isl_schedule_node *Node, + static bool isMatrMultPattern(isl::schedule_node Node, const polly::Dependences *D, polly::MatMulInfoTy &MMI); @@ -313,8 +313,8 @@ /// @param Node The schedule node to be modified. /// @param MacroKernelParams Parameters of the macro kernel /// to be used as tile sizes. - static __isl_give isl_schedule_node * - createMacroKernel(__isl_take isl_schedule_node *Node, + static isl::schedule_node + createMacroKernel(isl::schedule_node Node, MacroKernelParamsTy MacroKernelParams); /// Create the BLIS macro-kernel. @@ -328,8 +328,8 @@ /// @param MicroKernelParams Parameters of the micro kernel /// to be used as tile sizes. /// @see MicroKernelParamsTy - static __isl_give isl_schedule_node * - createMicroKernel(__isl_take isl_schedule_node *Node, + static isl::schedule_node + createMicroKernel(isl::schedule_node Node, MicroKernelParamsTy MicroKernelParams); }; Index: polly/trunk/lib/Transform/ScheduleOptimizer.cpp =================================================================== --- polly/trunk/lib/Transform/ScheduleOptimizer.cpp +++ polly/trunk/lib/Transform/ScheduleOptimizer.cpp @@ -351,81 +351,74 @@ return Node; } -__isl_give isl_schedule_node * -ScheduleTreeOptimizer::prevectSchedBand(__isl_take isl_schedule_node *Node, - unsigned DimToVectorize, - int VectorWidth) { - assert(isl_schedule_node_get_type(Node) == isl_schedule_node_band); - - auto Space = isl_schedule_node_band_get_space(Node); - auto ScheduleDimensions = isl_space_dim(Space, isl_dim_set); - isl_space_free(Space); +isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand( + isl::schedule_node Node, unsigned DimToVectorize, int VectorWidth) { + assert(isl_schedule_node_get_type(Node.get()) == isl_schedule_node_band); + + auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get())); + auto ScheduleDimensions = Space.dim(isl::dim::set); assert(DimToVectorize < ScheduleDimensions); if (DimToVectorize > 0) { - Node = isl_schedule_node_band_split(Node, DimToVectorize); - Node = isl_schedule_node_child(Node, 0); + Node = isl::manage( + isl_schedule_node_band_split(Node.release(), DimToVectorize)); + Node = Node.child(0); } if (DimToVectorize < ScheduleDimensions - 1) - Node = isl_schedule_node_band_split(Node, 1); - Space = isl_schedule_node_band_get_space(Node); - auto Sizes = isl_multi_val_zero(Space); - auto Ctx = isl_schedule_node_get_ctx(Node); - Sizes = - isl_multi_val_set_val(Sizes, 0, isl_val_int_from_si(Ctx, VectorWidth)); - Node = isl_schedule_node_band_tile(Node, Sizes); - Node = isolateFullPartialTiles(give(Node), VectorWidth).release(); - Node = isl_schedule_node_child(Node, 0); + Node = isl::manage(isl_schedule_node_band_split(Node.release(), 1)); + Space = isl::manage(isl_schedule_node_band_get_space(Node.get())); + auto Sizes = isl::multi_val::zero(Space); + Sizes = Sizes.set_val(0, isl::val(Node.get_ctx(), VectorWidth)); + Node = + isl::manage(isl_schedule_node_band_tile(Node.release(), Sizes.release())); + Node = isolateFullPartialTiles(Node, VectorWidth); + Node = Node.child(0); // Make sure the "trivially vectorizable loop" is not unrolled. Otherwise, // we will have troubles to match it in the backend. - Node = isl_schedule_node_band_set_ast_build_options( - Node, isl_union_set_read_from_str(Ctx, "{ unroll[x]: 1 = 0 }")); - Node = isl_schedule_node_band_sink(Node); - Node = isl_schedule_node_child(Node, 0); - if (isl_schedule_node_get_type(Node) == isl_schedule_node_leaf) - Node = isl_schedule_node_parent(Node); - isl_id *LoopMarker = isl_id_alloc(Ctx, "SIMD", nullptr); - Node = isl_schedule_node_insert_mark(Node, LoopMarker); - return Node; -} - -__isl_give isl_schedule_node * -ScheduleTreeOptimizer::tileNode(__isl_take isl_schedule_node *Node, - const char *Identifier, ArrayRef TileSizes, - int DefaultTileSize) { - auto Ctx = isl_schedule_node_get_ctx(Node); - auto Space = isl_schedule_node_band_get_space(Node); - auto Dims = isl_space_dim(Space, isl_dim_set); - auto Sizes = isl_multi_val_zero(Space); + Node = Node.band_set_ast_build_options( + isl::union_set(Node.get_ctx(), "{ unroll[x]: 1 = 0 }")); + Node = isl::manage(isl_schedule_node_band_sink(Node.release())); + Node = Node.child(0); + if (isl_schedule_node_get_type(Node.get()) == isl_schedule_node_leaf) + Node = Node.parent(); + auto LoopMarker = isl::id::alloc(Node.get_ctx(), "SIMD", nullptr); + return Node.insert_mark(LoopMarker); +} + +isl::schedule_node ScheduleTreeOptimizer::tileNode(isl::schedule_node Node, + const char *Identifier, + ArrayRef TileSizes, + int DefaultTileSize) { + auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get())); + auto Dims = Space.dim(isl::dim::set); + auto Sizes = isl::multi_val::zero(Space); std::string IdentifierString(Identifier); for (unsigned i = 0; i < Dims; i++) { auto tileSize = i < TileSizes.size() ? TileSizes[i] : DefaultTileSize; - Sizes = isl_multi_val_set_val(Sizes, i, isl_val_int_from_si(Ctx, tileSize)); + Sizes = Sizes.set_val(i, isl::val(Node.get_ctx(), tileSize)); } auto TileLoopMarkerStr = IdentifierString + " - Tiles"; - isl_id *TileLoopMarker = - isl_id_alloc(Ctx, TileLoopMarkerStr.c_str(), nullptr); - Node = isl_schedule_node_insert_mark(Node, TileLoopMarker); - Node = isl_schedule_node_child(Node, 0); - Node = isl_schedule_node_band_tile(Node, Sizes); - Node = isl_schedule_node_child(Node, 0); + auto TileLoopMarker = + isl::id::alloc(Node.get_ctx(), TileLoopMarkerStr.c_str(), nullptr); + Node = Node.insert_mark(TileLoopMarker); + Node = Node.child(0); + Node = + isl::manage(isl_schedule_node_band_tile(Node.release(), Sizes.release())); + Node = Node.child(0); auto PointLoopMarkerStr = IdentifierString + " - Points"; - isl_id *PointLoopMarker = - isl_id_alloc(Ctx, PointLoopMarkerStr.c_str(), nullptr); - Node = isl_schedule_node_insert_mark(Node, PointLoopMarker); - Node = isl_schedule_node_child(Node, 0); - return Node; + auto PointLoopMarker = + isl::id::alloc(Node.get_ctx(), PointLoopMarkerStr.c_str(), nullptr); + Node = Node.insert_mark(PointLoopMarker); + return Node.child(0); } -__isl_give isl_schedule_node * -ScheduleTreeOptimizer::applyRegisterTiling(__isl_take isl_schedule_node *Node, +isl::schedule_node +ScheduleTreeOptimizer::applyRegisterTiling(isl::schedule_node Node, llvm::ArrayRef TileSizes, int DefaultTileSize) { - auto *Ctx = isl_schedule_node_get_ctx(Node); Node = tileNode(Node, "Register tiling", TileSizes, DefaultTileSize); - Node = isl_schedule_node_band_set_ast_build_options( - Node, isl_union_set_read_from_str(Ctx, "{unroll[x]}")); - return Node; + auto Ctx = Node.get_ctx(); + return Node.band_set_ast_build_options(isl::union_set(Ctx, "{unroll[x]}")); } namespace { @@ -456,31 +449,27 @@ } } // namespace -bool ScheduleTreeOptimizer::isTileableBandNode( - __isl_keep isl_schedule_node *Node) { - if (isl_schedule_node_get_type(Node) != isl_schedule_node_band) +bool ScheduleTreeOptimizer::isTileableBandNode(isl::schedule_node Node) { + if (isl_schedule_node_get_type(Node.get()) != isl_schedule_node_band) return false; - if (isl_schedule_node_n_children(Node) != 1) + if (isl_schedule_node_n_children(Node.get()) != 1) return false; - if (!isl_schedule_node_band_get_permutable(Node)) + if (!isl_schedule_node_band_get_permutable(Node.get())) return false; - auto Space = isl_schedule_node_band_get_space(Node); - auto Dims = isl_space_dim(Space, isl_dim_set); - isl_space_free(Space); + auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get())); + auto Dims = Space.dim(isl::dim::set); if (Dims <= 1) return false; - auto ManagedNode = isl::manage(isl_schedule_node_copy(Node)); - return isSimpleInnermostBand(ManagedNode); + return isSimpleInnermostBand(Node); } -__isl_give isl_schedule_node * -ScheduleTreeOptimizer::standardBandOpts(__isl_take isl_schedule_node *Node, - void *User) { +__isl_give isl::schedule_node +ScheduleTreeOptimizer::standardBandOpts(isl::schedule_node Node, void *User) { if (FirstLevelTiling) Node = tileNode(Node, "1st level tiling", FirstLevelTileSizes, FirstLevelDefaultTileSize); @@ -496,12 +485,11 @@ if (PollyVectorizerChoice == VECTORIZER_NONE) return Node; - auto Space = isl_schedule_node_band_get_space(Node); - auto Dims = isl_space_dim(Space, isl_dim_set); - isl_space_free(Space); + auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get())); + auto Dims = Space.dim(isl::dim::set); for (int i = Dims - 1; i >= 0; i--) - if (isl_schedule_node_band_member_get_coincident(Node, i)) { + if (Node.band_member_get_coincident(i)) { Node = prevectSchedBand(Node, i, PrevectorWidth); break; } @@ -521,27 +509,20 @@ /// @return The position of the dimension in case the isl /// constraint satisfies the requirements, a negative /// value, otherwise. -static int getMatMulConstraintDim(__isl_keep isl_constraint *Constraint, - enum isl_dim_type DimType) { +static int getMatMulConstraintDim(isl::constraint Constraint, + isl::dim DimType) { int DimPos = -1; - auto *LocalSpace = isl_constraint_get_local_space(Constraint); - int LocalSpaceDimNum = isl_local_space_dim(LocalSpace, DimType); + auto LocalSpace = Constraint.get_local_space(); + int LocalSpaceDimNum = LocalSpace.dim(DimType); for (int i = 0; i < LocalSpaceDimNum; i++) { - auto *Val = isl_constraint_get_coefficient_val(Constraint, DimType, i); - if (isl_val_is_zero(Val)) { - isl_val_free(Val); + auto Val = Constraint.get_coefficient_val(DimType, i); + if (Val.is_zero()) continue; - } - if (DimPos >= 0 || (DimType == isl_dim_out && !isl_val_is_one(Val)) || - (DimType == isl_dim_in && !isl_val_is_negone(Val))) { - isl_val_free(Val); - isl_local_space_free(LocalSpace); + if (DimPos >= 0 || (DimType == isl::dim::out && !Val.is_one()) || + (DimType == isl::dim::in && !Val.is_negone())) return -1; - } DimPos = i; - isl_val_free(Val); } - isl_local_space_free(LocalSpace); return DimPos; } @@ -557,63 +538,20 @@ /// @param DimOutPos The output dimension of the isl constraint. /// @return isl_stat_ok in case the isl constraint satisfies /// the requirements, isl_stat_error otherwise. -static isl_stat isMatMulOperandConstraint(__isl_keep isl_constraint *Constraint, +static isl_stat isMatMulOperandConstraint(isl::constraint Constraint, int &DimInPos, int &DimOutPos) { - auto *Val = isl_constraint_get_constant_val(Constraint); - if (!isl_constraint_is_equality(Constraint) || !isl_val_is_zero(Val)) { - isl_val_free(Val); + auto Val = Constraint.get_constant_val(); + if (!isl_constraint_is_equality(Constraint.get()) || !Val.is_zero()) return isl_stat_error; - } - isl_val_free(Val); - DimInPos = getMatMulConstraintDim(Constraint, isl_dim_in); + DimInPos = getMatMulConstraintDim(Constraint, isl::dim::in); if (DimInPos < 0) return isl_stat_error; - DimOutPos = getMatMulConstraintDim(Constraint, isl_dim_out); + DimOutPos = getMatMulConstraintDim(Constraint, isl::dim::out); if (DimOutPos < 0) return isl_stat_error; return isl_stat_ok; } -/// Check that the access relation corresponds to a non-constant operand -/// of the matrix multiplication. -/// -/// Access relations that correspond to non-constant operands of the matrix -/// multiplication depend only on two input dimensions and have two output -/// dimensions. The function checks that the isl basic map @p bmap satisfies -/// the requirements. The two input dimensions can be specified via @p user -/// array. -/// -/// @param bmap The isl basic map to be checked. -/// @param user The input dimensions of @p bmap. -/// @return isl_stat_ok in case isl basic map satisfies the requirements, -/// isl_stat_error otherwise. -static isl_stat isMatMulOperandBasicMap(__isl_take isl_basic_map *bmap, - void *user) { - auto *Constraints = isl_basic_map_get_constraint_list(bmap); - isl_basic_map_free(bmap); - if (isl_constraint_list_n_constraint(Constraints) != 2) { - isl_constraint_list_free(Constraints); - return isl_stat_error; - } - int InPosPair[] = {-1, -1}; - auto DimInPos = user ? static_cast(user) : InPosPair; - for (int i = 0; i < 2; i++) { - auto *Constraint = isl_constraint_list_get_constraint(Constraints, i); - int InPos, OutPos; - if (isMatMulOperandConstraint(Constraint, InPos, OutPos) == - isl_stat_error || - OutPos > 1 || (DimInPos[OutPos] >= 0 && DimInPos[OutPos] != InPos)) { - isl_constraint_free(Constraint); - isl_constraint_list_free(Constraints); - return isl_stat_error; - } - DimInPos[OutPos] = InPos; - isl_constraint_free(Constraint); - } - isl_constraint_list_free(Constraints); - return isl_stat_ok; -} - /// Permute the two dimensions of the isl map. /// /// Permute @p DstPos and @p SrcPos dimensions of the isl map @p Map that @@ -624,30 +562,28 @@ /// @param DstPos The first dimension. /// @param SrcPos The second dimension. /// @return The modified map. -__isl_give isl_map *permuteDimensions(__isl_take isl_map *Map, - enum isl_dim_type DimType, - unsigned DstPos, unsigned SrcPos) { - assert(DstPos < isl_map_dim(Map, DimType) && - SrcPos < isl_map_dim(Map, DimType)); +isl::map permuteDimensions(isl::map Map, isl::dim DimType, unsigned DstPos, + unsigned SrcPos) { + assert(DstPos < Map.dim(DimType) && SrcPos < Map.dim(DimType)); if (DstPos == SrcPos) return Map; - isl_id *DimId = nullptr; - if (isl_map_has_tuple_id(Map, DimType)) - DimId = isl_map_get_tuple_id(Map, DimType); - auto FreeDim = DimType == isl_dim_in ? isl_dim_out : isl_dim_in; - isl_id *FreeDimId = nullptr; - if (isl_map_has_tuple_id(Map, FreeDim)) - FreeDimId = isl_map_get_tuple_id(Map, FreeDim); + isl::id DimId; + if (Map.has_tuple_id(DimType)) + DimId = Map.get_tuple_id(DimType); + auto FreeDim = DimType == isl::dim::in ? isl::dim::out : isl::dim::in; + isl::id FreeDimId; + if (Map.has_tuple_id(FreeDim)) + FreeDimId = Map.get_tuple_id(FreeDim); auto MaxDim = std::max(DstPos, SrcPos); auto MinDim = std::min(DstPos, SrcPos); - Map = isl_map_move_dims(Map, FreeDim, 0, DimType, MaxDim, 1); - Map = isl_map_move_dims(Map, FreeDim, 0, DimType, MinDim, 1); - Map = isl_map_move_dims(Map, DimType, MinDim, FreeDim, 1, 1); - Map = isl_map_move_dims(Map, DimType, MaxDim, FreeDim, 0, 1); + Map = Map.move_dims(FreeDim, 0, DimType, MaxDim, 1); + Map = Map.move_dims(FreeDim, 0, DimType, MinDim, 1); + Map = Map.move_dims(DimType, MinDim, FreeDim, 1, 1); + Map = Map.move_dims(DimType, MaxDim, FreeDim, 0, 1); if (DimId) - Map = isl_map_set_tuple_id(Map, DimType, DimId); + Map = Map.set_tuple_id(DimType, DimId); if (FreeDimId) - Map = isl_map_set_tuple_id(Map, FreeDim, FreeDimId); + Map = Map.set_tuple_id(FreeDim, FreeDimId); return Map; } @@ -663,12 +599,26 @@ /// second output dimension. /// @return True in case @p AccMap has the expected form and false, /// otherwise. -static bool isMatMulOperandAcc(__isl_keep isl_map *AccMap, int &FirstPos, - int &SecondPos) { +static bool isMatMulOperandAcc(isl::map AccMap, int &FirstPos, int &SecondPos) { int DimInPos[] = {FirstPos, SecondPos}; - if (isl_map_foreach_basic_map(AccMap, isMatMulOperandBasicMap, - static_cast(DimInPos)) != isl_stat_ok || - DimInPos[0] < 0 || DimInPos[1] < 0) + auto Lambda = [=, &DimInPos](isl::basic_map BasicMap) -> isl::stat { + auto Constraints = BasicMap.get_constraint_list(); + if (isl_constraint_list_n_constraint(Constraints.get()) != 2) + return isl::stat::error; + for (int i = 0; i < 2; i++) { + auto Constraint = + isl::manage(isl_constraint_list_get_constraint(Constraints.get(), i)); + int InPos, OutPos; + if (isMatMulOperandConstraint(Constraint, InPos, OutPos) == + isl_stat_error || + OutPos > 1 || (DimInPos[OutPos] >= 0 && DimInPos[OutPos] != InPos)) + return isl::stat::error; + DimInPos[OutPos] = InPos; + } + return isl::stat::ok; + }; + if (AccMap.foreach_basic_map(Lambda) != isl::stat::ok || DimInPos[0] < 0 || + DimInPos[1] < 0) return false; FirstPos = DimInPos[0]; SecondPos = DimInPos[1]; @@ -690,26 +640,22 @@ MatMulInfoTy &MMI) { if (!MemAccess->isLatestArrayKind() || !MemAccess->isRead()) return false; - isl_map *AccMap = MemAccess->getLatestAccessRelation().release(); + auto AccMap = MemAccess->getLatestAccessRelation(); if (isMatMulOperandAcc(AccMap, MMI.i, MMI.j) && !MMI.ReadFromC && - isl_map_n_basic_map(AccMap) == 1) { + isl_map_n_basic_map(AccMap.get()) == 1) { MMI.ReadFromC = MemAccess; - isl_map_free(AccMap); return true; } if (isMatMulOperandAcc(AccMap, MMI.i, MMI.k) && !MMI.A && - isl_map_n_basic_map(AccMap) == 1) { + isl_map_n_basic_map(AccMap.get()) == 1) { MMI.A = MemAccess; - isl_map_free(AccMap); return true; } if (isMatMulOperandAcc(AccMap, MMI.k, MMI.j) && !MMI.B && - isl_map_n_basic_map(AccMap) == 1) { + isl_map_n_basic_map(AccMap.get()) == 1) { MMI.B = MemAccess; - isl_map_free(AccMap); return true; } - isl_map_free(AccMap); return false; } @@ -726,37 +672,28 @@ /// @return True in case the corresponding SCoP statement /// represents matrix multiplication and false, /// otherwise. -static bool containsOnlyMatrMultAcc(__isl_keep isl_map *PartialSchedule, +static bool containsOnlyMatrMultAcc(isl::map PartialSchedule, MatMulInfoTy &MMI) { - auto *InputDimId = isl_map_get_tuple_id(PartialSchedule, isl_dim_in); - auto *Stmt = static_cast(isl_id_get_user(InputDimId)); - isl_id_free(InputDimId); - unsigned OutDimNum = isl_map_dim(PartialSchedule, isl_dim_out); + auto InputDimId = PartialSchedule.get_tuple_id(isl::dim::in); + auto *Stmt = static_cast(InputDimId.get_user()); + unsigned OutDimNum = PartialSchedule.dim(isl::dim::out); assert(OutDimNum > 2 && "In case of the matrix multiplication the loop nest " "and, consequently, the corresponding scheduling " "functions have at least three dimensions."); - auto *MapI = permuteDimensions(isl_map_copy(PartialSchedule), isl_dim_out, - MMI.i, OutDimNum - 1); - auto *MapJ = permuteDimensions(isl_map_copy(PartialSchedule), isl_dim_out, - MMI.j, OutDimNum - 1); - auto *MapK = permuteDimensions(isl_map_copy(PartialSchedule), isl_dim_out, - MMI.k, OutDimNum - 1); + auto MapI = + permuteDimensions(PartialSchedule, isl::dim::out, MMI.i, OutDimNum - 1); + auto MapJ = + permuteDimensions(PartialSchedule, isl::dim::out, MMI.j, OutDimNum - 1); + auto MapK = + permuteDimensions(PartialSchedule, isl::dim::out, MMI.k, OutDimNum - 1); for (auto *MemA = Stmt->begin(); MemA != Stmt->end() - 1; MemA++) { auto *MemAccessPtr = *MemA; if (MemAccessPtr->isLatestArrayKind() && MemAccessPtr != MMI.WriteToC && !isMatMulNonScalarReadAccess(MemAccessPtr, MMI) && - !(MemAccessPtr->isStrideZero(isl::manage(isl_map_copy(MapI))) && - MemAccessPtr->isStrideZero(isl::manage(isl_map_copy(MapJ))) && - MemAccessPtr->isStrideZero(isl::manage(isl_map_copy(MapK))))) { - isl_map_free(MapI); - isl_map_free(MapJ); - isl_map_free(MapK); + !(MemAccessPtr->isStrideZero(MapI)) && + MemAccessPtr->isStrideZero(MapJ) && MemAccessPtr->isStrideZero(MapK)) return false; - } } - isl_map_free(MapI); - isl_map_free(MapJ); - isl_map_free(MapK); return true; } @@ -774,30 +711,22 @@ /// acceptable value. /// @return True in case dependencies correspond to the matrix multiplication /// and false, otherwise. -static bool containsOnlyMatMulDep(__isl_keep isl_map *Schedule, - const Dependences *D, int &Pos) { - auto *Dep = D->getDependences(Dependences::TYPE_RAW); - auto *Red = D->getDependences(Dependences::TYPE_RED); +static bool containsOnlyMatMulDep(isl::map Schedule, const Dependences *D, + int &Pos) { + auto Dep = isl::manage(D->getDependences(Dependences::TYPE_RAW)); + auto Red = isl::manage(D->getDependences(Dependences::TYPE_RED)); if (Red) - Dep = isl_union_map_union(Dep, Red); - auto *DomainSpace = isl_space_domain(isl_map_get_space(Schedule)); - auto *Space = isl_space_map_from_domain_and_range(isl_space_copy(DomainSpace), - DomainSpace); - auto *Deltas = isl_map_deltas(isl_union_map_extract_map(Dep, Space)); - isl_union_map_free(Dep); - int DeltasDimNum = isl_set_dim(Deltas, isl_dim_set); + Dep = Dep.unite(Red); + auto DomainSpace = Schedule.get_space().domain(); + auto Space = DomainSpace.map_from_domain_and_range(DomainSpace); + auto Deltas = Dep.extract_map(Space).deltas(); + int DeltasDimNum = Deltas.dim(isl::dim::set); for (int i = 0; i < DeltasDimNum; i++) { - auto *Val = isl_set_plain_get_val_if_fixed(Deltas, isl_dim_set, i); - Pos = Pos < 0 && isl_val_is_one(Val) ? i : Pos; - if (isl_val_is_nan(Val) || - !(isl_val_is_zero(Val) || (i == Pos && isl_val_is_one(Val)))) { - isl_val_free(Val); - isl_set_free(Deltas); + auto Val = Deltas.plain_get_val_if_fixed(isl::dim::set, i); + Pos = Pos < 0 && Val.is_one() ? i : Pos; + if (Val.is_nan() || !(Val.is_zero() || (i == Pos && Val.is_one()))) return false; - } - isl_val_free(Val); } - isl_set_free(Deltas); if (DeltasDimNum == 0 || Pos < 0) return false; return true; @@ -826,11 +755,10 @@ /// to check. /// @D The SCoP dependencies. /// @MMI Parameters of the matrix multiplication operands. -static bool containsMatrMult(__isl_keep isl_map *PartialSchedule, - const Dependences *D, MatMulInfoTy &MMI) { - auto *InputDimsId = isl_map_get_tuple_id(PartialSchedule, isl_dim_in); - auto *Stmt = static_cast(isl_id_get_user(InputDimsId)); - isl_id_free(InputDimsId); +static bool containsMatrMult(isl::map PartialSchedule, const Dependences *D, + MatMulInfoTy &MMI) { + auto InputDimsId = PartialSchedule.get_tuple_id(isl::dim::in); + auto *Stmt = static_cast(InputDimsId.get_user()); if (Stmt->size() <= 1) return false; for (auto *MemA = Stmt->end() - 1; MemA != Stmt->begin(); MemA--) { @@ -839,13 +767,10 @@ continue; if (!MemAccessPtr->isWrite()) return false; - auto *AccMap = MemAccessPtr->getLatestAccessRelation().release(); - if (isl_map_n_basic_map(AccMap) != 1 || - !isMatMulOperandAcc(AccMap, MMI.i, MMI.j)) { - isl_map_free(AccMap); + auto AccMap = MemAccessPtr->getLatestAccessRelation(); + if (isl_map_n_basic_map(AccMap.get()) != 1 || + !isMatMulOperandAcc(AccMap, MMI.i, MMI.j)) return false; - } - isl_map_free(AccMap); MMI.WriteToC = MemAccessPtr; break; } @@ -868,49 +793,48 @@ /// @param Node The band node to be modified. /// @param FirstDim The first dimension to be permuted. /// @param SecondDim The second dimension to be permuted. -static __isl_give isl_schedule_node * -permuteBandNodeDimensions(__isl_take isl_schedule_node *Node, unsigned FirstDim, - unsigned SecondDim) { - assert(isl_schedule_node_get_type(Node) == isl_schedule_node_band && - isl_schedule_node_band_n_member(Node) > std::max(FirstDim, SecondDim)); - auto PartialSchedule = isl_schedule_node_band_get_partial_schedule(Node); - auto PartialScheduleFirstDim = - isl_multi_union_pw_aff_get_union_pw_aff(PartialSchedule, FirstDim); - auto PartialScheduleSecondDim = - isl_multi_union_pw_aff_get_union_pw_aff(PartialSchedule, SecondDim); - PartialSchedule = isl_multi_union_pw_aff_set_union_pw_aff( - PartialSchedule, SecondDim, PartialScheduleFirstDim); - PartialSchedule = isl_multi_union_pw_aff_set_union_pw_aff( - PartialSchedule, FirstDim, PartialScheduleSecondDim); - Node = isl_schedule_node_delete(Node); - Node = isl_schedule_node_insert_partial_schedule(Node, PartialSchedule); - return Node; -} - -__isl_give isl_schedule_node *ScheduleTreeOptimizer::createMicroKernel( - __isl_take isl_schedule_node *Node, MicroKernelParamsTy MicroKernelParams) { - applyRegisterTiling(Node, {MicroKernelParams.Mr, MicroKernelParams.Nr}, 1); - Node = isl_schedule_node_parent(isl_schedule_node_parent(Node)); - Node = permuteBandNodeDimensions(Node, 0, 1); - return isl_schedule_node_child(isl_schedule_node_child(Node, 0), 0); +static isl::schedule_node permuteBandNodeDimensions(isl::schedule_node Node, + unsigned FirstDim, + unsigned SecondDim) { + assert(isl_schedule_node_get_type(Node.get()) == isl_schedule_node_band && + isl_schedule_node_band_n_member(Node.get()) > + std::max(FirstDim, SecondDim)); + auto PartialSchedule = + isl::manage(isl_schedule_node_band_get_partial_schedule(Node.get())); + auto PartialScheduleFirstDim = PartialSchedule.get_union_pw_aff(FirstDim); + auto PartialScheduleSecondDim = PartialSchedule.get_union_pw_aff(SecondDim); + PartialSchedule = + PartialSchedule.set_union_pw_aff(SecondDim, PartialScheduleFirstDim); + PartialSchedule = + PartialSchedule.set_union_pw_aff(FirstDim, PartialScheduleSecondDim); + Node = isl::manage(isl_schedule_node_delete(Node.release())); + return Node.insert_partial_schedule(PartialSchedule); +} + +isl::schedule_node ScheduleTreeOptimizer::createMicroKernel( + isl::schedule_node Node, MicroKernelParamsTy MicroKernelParams) { + Node = applyRegisterTiling(Node, {MicroKernelParams.Mr, MicroKernelParams.Nr}, + 1); + Node = Node.parent().parent(); + return permuteBandNodeDimensions(Node, 0, 1).child(0).child(0); } -__isl_give isl_schedule_node *ScheduleTreeOptimizer::createMacroKernel( - __isl_take isl_schedule_node *Node, MacroKernelParamsTy MacroKernelParams) { - assert(isl_schedule_node_get_type(Node) == isl_schedule_node_band); +isl::schedule_node ScheduleTreeOptimizer::createMacroKernel( + isl::schedule_node Node, MacroKernelParamsTy MacroKernelParams) { + assert(isl_schedule_node_get_type(Node.get()) == isl_schedule_node_band); if (MacroKernelParams.Mc == 1 && MacroKernelParams.Nc == 1 && MacroKernelParams.Kc == 1) return Node; - int DimOutNum = isl_schedule_node_band_n_member(Node); + int DimOutNum = isl_schedule_node_band_n_member(Node.get()); std::vector TileSizes(DimOutNum, 1); TileSizes[DimOutNum - 3] = MacroKernelParams.Mc; TileSizes[DimOutNum - 2] = MacroKernelParams.Nc; TileSizes[DimOutNum - 1] = MacroKernelParams.Kc; Node = tileNode(Node, "1st level tiling", TileSizes, 1); - Node = isl_schedule_node_parent(isl_schedule_node_parent(Node)); + Node = Node.parent().parent(); Node = permuteBandNodeDimensions(Node, DimOutNum - 2, DimOutNum - 1); Node = permuteBandNodeDimensions(Node, DimOutNum - 3, DimOutNum - 1); - return isl_schedule_node_child(isl_schedule_node_child(Node, 0), 0); + return Node.child(0).child(0); } /// Get the size of the widest type of the matrix multiplication operands @@ -1059,23 +983,21 @@ /// @param FirstDim, SecondDim The input dimensions that are used to define /// the specified access relation. /// @return The specified access relation. -__isl_give isl_map *getMatMulAccRel(__isl_take isl_map *MapOldIndVar, - unsigned FirstDim, unsigned SecondDim) { - auto *Ctx = isl_map_get_ctx(MapOldIndVar); - auto *AccessRelSpace = isl_space_alloc(Ctx, 0, 9, 3); - auto *AccessRel = isl_map_universe(AccessRelSpace); - AccessRel = isl_map_equate(AccessRel, isl_dim_in, FirstDim, isl_dim_out, 0); - AccessRel = isl_map_equate(AccessRel, isl_dim_in, 5, isl_dim_out, 1); - AccessRel = isl_map_equate(AccessRel, isl_dim_in, SecondDim, isl_dim_out, 2); - return isl_map_apply_range(MapOldIndVar, AccessRel); +isl::map getMatMulAccRel(isl::map MapOldIndVar, unsigned FirstDim, + unsigned SecondDim) { + auto AccessRelSpace = isl::space(MapOldIndVar.get_ctx(), 0, 9, 3); + auto AccessRel = isl::map::universe(AccessRelSpace); + AccessRel = AccessRel.equate(isl::dim::in, FirstDim, isl::dim::out, 0); + AccessRel = AccessRel.equate(isl::dim::in, 5, isl::dim::out, 1); + AccessRel = AccessRel.equate(isl::dim::in, SecondDim, isl::dim::out, 2); + return MapOldIndVar.apply_range(AccessRel); } -__isl_give isl_schedule_node * -createExtensionNode(__isl_take isl_schedule_node *Node, - __isl_take isl_map *ExtensionMap) { - auto *Extension = isl_union_map_from_map(ExtensionMap); - auto *NewNode = isl_schedule_node_from_extension(Extension); - return isl_schedule_node_graft_before(Node, NewNode); +isl::schedule_node createExtensionNode(isl::schedule_node Node, + isl::map ExtensionMap) { + auto Extension = isl::union_map(ExtensionMap); + auto NewNode = isl::schedule_node::from_extension(Extension); + return Node.graft_before(NewNode); } /// Apply the packing transformation. @@ -1110,76 +1032,74 @@ /// to be taken into account. /// @param MMI Parameters of the matrix multiplication operands. /// @return The optimized schedule node. -static __isl_give isl_schedule_node *optimizeDataLayoutMatrMulPattern( - __isl_take isl_schedule_node *Node, __isl_take isl_map *MapOldIndVar, - MicroKernelParamsTy MicroParams, MacroKernelParamsTy MacroParams, - MatMulInfoTy &MMI) { - auto InputDimsId = isl_map_get_tuple_id(MapOldIndVar, isl_dim_in); - auto *Stmt = static_cast(isl_id_get_user(InputDimsId)); - isl_id_free(InputDimsId); +static isl::schedule_node +optimizeDataLayoutMatrMulPattern(isl::schedule_node Node, isl::map MapOldIndVar, + MicroKernelParamsTy MicroParams, + MacroKernelParamsTy MacroParams, + MatMulInfoTy &MMI) { + auto InputDimsId = MapOldIndVar.get_tuple_id(isl::dim::in); + auto *Stmt = static_cast(InputDimsId.get_user()); // Create a copy statement that corresponds to the memory access to the // matrix B, the second operand of the matrix multiplication. - Node = isl_schedule_node_parent(isl_schedule_node_parent(Node)); - Node = isl_schedule_node_parent(isl_schedule_node_parent(Node)); - Node = isl_schedule_node_parent(Node); - Node = isl_schedule_node_child(isl_schedule_node_band_split(Node, 2), 0); - auto *AccRel = getMatMulAccRel(isl_map_copy(MapOldIndVar), 3, 7); + Node = Node.parent().parent().parent().parent().parent(); + Node = isl::manage(isl_schedule_node_band_split(Node.release(), 2)).child(0); + auto AccRel = getMatMulAccRel(isl::manage(MapOldIndVar.copy()), 3, 7); unsigned FirstDimSize = MacroParams.Nc / MicroParams.Nr; unsigned SecondDimSize = MacroParams.Kc; unsigned ThirdDimSize = MicroParams.Nr; auto *SAI = Stmt->getParent()->createScopArrayInfo( MMI.B->getElementType(), "Packed_B", {FirstDimSize, SecondDimSize, ThirdDimSize}); - AccRel = - isl_map_set_tuple_id(AccRel, isl_dim_out, SAI->getBasePtrId().release()); - auto *OldAcc = MMI.B->getLatestAccessRelation().release(); - MMI.B->setNewAccessRelation(AccRel); - auto *ExtMap = - isl_map_project_out(isl_map_copy(MapOldIndVar), isl_dim_out, 2, - isl_map_dim(MapOldIndVar, isl_dim_out) - 2); - ExtMap = isl_map_reverse(ExtMap); - ExtMap = isl_map_fix_si(ExtMap, isl_dim_out, MMI.i, 0); - auto *Domain = Stmt->getDomain(); + AccRel = AccRel.set_tuple_id(isl::dim::out, SAI->getBasePtrId()); + auto OldAcc = MMI.B->getLatestAccessRelation(); + MMI.B->setNewAccessRelation(AccRel.release()); + auto ExtMap = MapOldIndVar.project_out(isl::dim::out, 2, + MapOldIndVar.dim(isl::dim::out) - 2); + ExtMap = ExtMap.reverse(); + ExtMap = ExtMap.fix_si(isl::dim::out, MMI.i, 0); + auto Domain = isl::manage(Stmt->getDomain()); // Restrict the domains of the copy statements to only execute when also its // originating statement is executed. - auto *DomainId = isl_set_get_tuple_id(Domain); + auto DomainId = Domain.get_tuple_id(); auto *NewStmt = Stmt->getParent()->addScopStmt( - OldAcc, MMI.B->getLatestAccessRelation().release(), isl_set_copy(Domain)); - ExtMap = isl_map_set_tuple_id(ExtMap, isl_dim_out, isl_id_copy(DomainId)); - ExtMap = isl_map_intersect_range(ExtMap, isl_set_copy(Domain)); - ExtMap = isl_map_set_tuple_id(ExtMap, isl_dim_out, NewStmt->getDomainId()); + OldAcc.release(), MMI.B->getLatestAccessRelation().release(), + Domain.copy()); + ExtMap = ExtMap.set_tuple_id(isl::dim::out, isl::manage(DomainId.copy())); + ExtMap = ExtMap.intersect_range(isl::manage(Domain.copy())); + ExtMap = + ExtMap.set_tuple_id(isl::dim::out, isl::manage(NewStmt->getDomainId())); Node = createExtensionNode(Node, ExtMap); // Create a copy statement that corresponds to the memory access // to the matrix A, the first operand of the matrix multiplication. - Node = isl_schedule_node_child(Node, 0); - AccRel = getMatMulAccRel(isl_map_copy(MapOldIndVar), 4, 6); + Node = Node.child(0); + AccRel = getMatMulAccRel(isl::manage(MapOldIndVar.copy()), 4, 6); FirstDimSize = MacroParams.Mc / MicroParams.Mr; ThirdDimSize = MicroParams.Mr; SAI = Stmt->getParent()->createScopArrayInfo( MMI.A->getElementType(), "Packed_A", {FirstDimSize, SecondDimSize, ThirdDimSize}); - AccRel = - isl_map_set_tuple_id(AccRel, isl_dim_out, SAI->getBasePtrId().release()); - OldAcc = MMI.A->getLatestAccessRelation().release(); - MMI.A->setNewAccessRelation(AccRel); - ExtMap = isl_map_project_out(MapOldIndVar, isl_dim_out, 3, - isl_map_dim(MapOldIndVar, isl_dim_out) - 3); - ExtMap = isl_map_reverse(ExtMap); - ExtMap = isl_map_fix_si(ExtMap, isl_dim_out, MMI.j, 0); + AccRel = AccRel.set_tuple_id(isl::dim::out, SAI->getBasePtrId()); + OldAcc = MMI.A->getLatestAccessRelation(); + MMI.A->setNewAccessRelation(AccRel.release()); + ExtMap = MapOldIndVar.project_out(isl::dim::out, 3, + MapOldIndVar.dim(isl::dim::out) - 3); + ExtMap = ExtMap.reverse(); + ExtMap = ExtMap.fix_si(isl::dim::out, MMI.j, 0); NewStmt = Stmt->getParent()->addScopStmt( - OldAcc, MMI.A->getLatestAccessRelation().release(), isl_set_copy(Domain)); + OldAcc.release(), MMI.A->getLatestAccessRelation().release(), + Domain.copy()); // Restrict the domains of the copy statements to only execute when also its // originating statement is executed. - ExtMap = isl_map_set_tuple_id(ExtMap, isl_dim_out, DomainId); - ExtMap = isl_map_intersect_range(ExtMap, Domain); - ExtMap = isl_map_set_tuple_id(ExtMap, isl_dim_out, NewStmt->getDomainId()); + ExtMap = ExtMap.set_tuple_id(isl::dim::out, DomainId); + ExtMap = ExtMap.intersect_range(Domain); + ExtMap = + ExtMap.set_tuple_id(isl::dim::out, isl::manage(NewStmt->getDomainId())); Node = createExtensionNode(Node, ExtMap); - Node = isl_schedule_node_child(isl_schedule_node_child(Node, 0), 0); - return isl_schedule_node_child(isl_schedule_node_child(Node, 0), 0); + return Node.child(0).child(0).child(0).child(0); } /// Get a relation mapping induction variables produced by schedule @@ -1194,18 +1114,16 @@ /// @see ScheduleTreeOptimizer::createMicroKernel /// @see ScheduleTreeOptimizer::createMacroKernel /// @see getMacroKernelParams -__isl_give isl_map * -getInductionVariablesSubstitution(__isl_take isl_schedule_node *Node, +isl::map +getInductionVariablesSubstitution(isl::schedule_node Node, MicroKernelParamsTy MicroKernelParams, MacroKernelParamsTy MacroKernelParams) { - auto *Child = isl_schedule_node_get_child(Node, 0); - auto *UnMapOldIndVar = isl_schedule_node_get_prefix_schedule_union_map(Child); - isl_schedule_node_free(Child); - auto *MapOldIndVar = isl_map_from_union_map(UnMapOldIndVar); - if (isl_map_dim(MapOldIndVar, isl_dim_out) > 9) - MapOldIndVar = - isl_map_project_out(MapOldIndVar, isl_dim_out, 0, - isl_map_dim(MapOldIndVar, isl_dim_out) - 9); + auto Child = Node.child(0); + auto UnMapOldIndVar = Child.get_prefix_schedule_union_map(); + auto MapOldIndVar = isl::map::from_union_map(UnMapOldIndVar); + if (MapOldIndVar.dim(isl::dim::out) > 9) + return MapOldIndVar.project_out(isl::dim::out, 0, + MapOldIndVar.dim(isl::dim::out) - 9); return MapOldIndVar; } @@ -1254,14 +1172,14 @@ /// @param Node The child of the mark node to be inserted. /// @param BasePtr The pointer to be marked. /// @return The modified isl_schedule_node. -static isl_schedule_node *markInterIterationAliasFree(isl_schedule_node *Node, +static isl::schedule_node markInterIterationAliasFree(isl::schedule_node Node, llvm::Value *BasePtr) { if (!BasePtr) return Node; - auto *Ctx = isl_schedule_node_get_ctx(Node); - auto *Id = isl_id_alloc(Ctx, "Inter iteration alias-free", BasePtr); - return isl_schedule_node_child(isl_schedule_node_insert_mark(Node, Id), 0); + auto Id = + isl::id::alloc(Node.get_ctx(), "Inter iteration alias-free", BasePtr); + return Node.insert_mark(Id).child(0); } /// Restore the initial ordering of dimensions of the band node @@ -1278,35 +1196,33 @@ if (isl_schedule_node_get_type(Node.child(0).keep()) != isl_schedule_node_leaf) return Node; - auto Domain = isl::manage(isl_schedule_node_get_universe_domain(Node.keep())); + auto Domain = Node.get_universe_domain(); assert(isl_union_set_n_set(Domain.keep()) == 1); - if (isl_schedule_node_get_schedule_depth(Node.keep()) != 0 || + if (Node.get_schedule_depth() != 0 || (isl::set(isl::manage(Domain.copy())).dim(isl::dim::set) != isl_schedule_node_band_n_member(Node.keep()))) return Node; Node = isl::manage(isl_schedule_node_delete(Node.take())); - auto PartialSchedulePwAff = - isl::manage(isl_union_set_identity_union_pw_multi_aff(Domain.take())); + auto PartialSchedulePwAff = Domain.identity_union_pw_multi_aff(); auto PartialScheduleMultiPwAff = isl::multi_union_pw_aff(PartialSchedulePwAff); - PartialScheduleMultiPwAff = isl::manage(isl_multi_union_pw_aff_reset_tuple_id( - PartialScheduleMultiPwAff.take(), isl_dim_set)); - return isl::manage(isl_schedule_node_insert_partial_schedule( - Node.take(), PartialScheduleMultiPwAff.take())); + PartialScheduleMultiPwAff = + PartialScheduleMultiPwAff.reset_tuple_id(isl::dim::set); + return Node.insert_partial_schedule(PartialScheduleMultiPwAff); } } // namespace -__isl_give isl_schedule_node *ScheduleTreeOptimizer::optimizeMatMulPattern( - __isl_take isl_schedule_node *Node, const llvm::TargetTransformInfo *TTI, +isl::schedule_node ScheduleTreeOptimizer::optimizeMatMulPattern( + isl::schedule_node Node, const llvm::TargetTransformInfo *TTI, MatMulInfoTy &MMI) { assert(TTI && "The target transform info should be provided."); Node = markInterIterationAliasFree( Node, MMI.WriteToC->getLatestScopArrayInfo()->getBasePtr()); - int DimOutNum = isl_schedule_node_band_n_member(Node); + int DimOutNum = isl_schedule_node_band_n_member(Node.get()); assert(DimOutNum > 2 && "In case of the matrix multiplication the loop nest " "and, consequently, the corresponding scheduling " "functions have at least three dimensions."); - Node = getBandNodeWithOriginDimOrder(isl::manage(Node)).take(); + Node = getBandNodeWithOriginDimOrder(Node); Node = permuteBandNodeDimensions(Node, MMI.i, DimOutNum - 3); int NewJ = MMI.j == DimOutNum - 3 ? MMI.i : MMI.j; int NewK = MMI.k == DimOutNum - 3 ? MMI.i : MMI.k; @@ -1320,78 +1236,72 @@ if (MacroKernelParams.Mc == 1 || MacroKernelParams.Nc == 1 || MacroKernelParams.Kc == 1) return Node; - auto *MapOldIndVar = getInductionVariablesSubstitution( - Node, MicroKernelParams, MacroKernelParams); + auto MapOldIndVar = getInductionVariablesSubstitution(Node, MicroKernelParams, + MacroKernelParams); if (!MapOldIndVar) return Node; - Node = - isolateAndUnrollMatMulInnerLoops(give(Node), MicroKernelParams).release(); + Node = isolateAndUnrollMatMulInnerLoops(Node, MicroKernelParams); return optimizeDataLayoutMatrMulPattern(Node, MapOldIndVar, MicroKernelParams, MacroKernelParams, MMI); } -bool ScheduleTreeOptimizer::isMatrMultPattern( - __isl_keep isl_schedule_node *Node, const Dependences *D, - MatMulInfoTy &MMI) { - auto *PartialSchedule = - isl_schedule_node_band_get_partial_schedule_union_map(Node); - Node = isl_schedule_node_child(Node, 0); - auto LeafType = isl_schedule_node_get_type(Node); - Node = isl_schedule_node_parent(Node); +bool ScheduleTreeOptimizer::isMatrMultPattern(isl::schedule_node Node, + const Dependences *D, + MatMulInfoTy &MMI) { + auto PartialSchedule = isl::manage( + isl_schedule_node_band_get_partial_schedule_union_map(Node.get())); + Node = Node.child(0); + auto LeafType = isl_schedule_node_get_type(Node.get()); + Node = Node.parent(); if (LeafType != isl_schedule_node_leaf || - isl_schedule_node_band_n_member(Node) < 3 || - isl_schedule_node_get_schedule_depth(Node) != 0 || - isl_union_map_n_map(PartialSchedule) != 1) { - isl_union_map_free(PartialSchedule); + isl_schedule_node_band_n_member(Node.get()) < 3 || + Node.get_schedule_depth() != 0 || + isl_union_map_n_map(PartialSchedule.get()) != 1) return false; - } - auto *NewPartialSchedule = isl_map_from_union_map(PartialSchedule); - if (containsMatrMult(NewPartialSchedule, D, MMI)) { - isl_map_free(NewPartialSchedule); + auto NewPartialSchedule = isl::map::from_union_map(PartialSchedule); + if (containsMatrMult(NewPartialSchedule, D, MMI)) return true; - } - isl_map_free(NewPartialSchedule); return false; } __isl_give isl_schedule_node * ScheduleTreeOptimizer::optimizeBand(__isl_take isl_schedule_node *Node, void *User) { - if (!isTileableBandNode(Node)) + if (!isTileableBandNode(isl::manage(isl_schedule_node_copy(Node)))) return Node; const OptimizerAdditionalInfoTy *OAI = static_cast(User); MatMulInfoTy MMI; - if (PMBasedOpts && User && isMatrMultPattern(Node, OAI->D, MMI)) { + if (PMBasedOpts && User && + isMatrMultPattern(isl::manage(isl_schedule_node_copy(Node)), OAI->D, + MMI)) { DEBUG(dbgs() << "The matrix multiplication pattern was detected\n"); - return optimizeMatMulPattern(Node, OAI->TTI, MMI); + return optimizeMatMulPattern(isl::manage(Node), OAI->TTI, MMI).release(); } - return standardBandOpts(Node, User); + return standardBandOpts(isl::manage(Node), User).release(); } -__isl_give isl_schedule * -ScheduleTreeOptimizer::optimizeSchedule(__isl_take isl_schedule *Schedule, +isl::schedule +ScheduleTreeOptimizer::optimizeSchedule(isl::schedule Schedule, const OptimizerAdditionalInfoTy *OAI) { - isl_schedule_node *Root = isl_schedule_get_root(Schedule); + auto Root = Schedule.get_root(); Root = optimizeScheduleNode(Root, OAI); - isl_schedule_free(Schedule); - auto S = isl_schedule_node_get_schedule(Root); - isl_schedule_node_free(Root); - return S; + return Root.get_schedule(); } -__isl_give isl_schedule_node *ScheduleTreeOptimizer::optimizeScheduleNode( - __isl_take isl_schedule_node *Node, const OptimizerAdditionalInfoTy *OAI) { - Node = isl_schedule_node_map_descendant_bottom_up( - Node, optimizeBand, const_cast(static_cast(OAI))); +isl::schedule_node ScheduleTreeOptimizer::optimizeScheduleNode( + isl::schedule_node Node, const OptimizerAdditionalInfoTy *OAI) { + Node = isl::manage(isl_schedule_node_map_descendant_bottom_up( + Node.release(), optimizeBand, + const_cast(static_cast(OAI)))); return Node; } -bool ScheduleTreeOptimizer::isProfitableSchedule( - Scop &S, __isl_keep isl_schedule *NewSchedule) { +bool ScheduleTreeOptimizer::isProfitableSchedule(Scop &S, + isl::schedule NewSchedule) { // To understand if the schedule has been optimized we check if the schedule // has changed at all. // TODO: We can improve this by tracking if any necessarily beneficial @@ -1401,15 +1311,13 @@ // optimizations, by comparing (yet to be defined) performance metrics // before/after the scheduling optimizer // (e.g., #stride-one accesses) - if (S.containsExtensionNode(NewSchedule)) + if (S.containsExtensionNode(NewSchedule.get())) return true; - auto *NewScheduleMap = isl_schedule_get_map(NewSchedule); - isl_union_map *OldSchedule = S.getSchedule(); + auto NewScheduleMap = NewSchedule.get_map(); + auto OldSchedule = isl::manage(S.getSchedule()); assert(OldSchedule && "Only IslScheduleOptimizer can insert extension nodes " "that make Scop::getSchedule() return nullptr."); - bool changed = !isl_union_map_is_equal(OldSchedule, NewScheduleMap); - isl_union_map_free(OldSchedule); - isl_union_map_free(NewScheduleMap); + bool changed = !OldSchedule.is_equal(NewScheduleMap); return changed; } @@ -1564,8 +1472,7 @@ SC = SC.set_proximity(Proximity); SC = SC.set_validity(Validity); SC = SC.set_coincidence(Validity); - isl_schedule *Schedule; - Schedule = SC.compute_schedule().release(); + auto Schedule = SC.compute_schedule(); isl_options_set_on_error(Ctx, OnErrorStatus); // In cases the scheduler is not able to optimize the code, we just do not @@ -1576,7 +1483,7 @@ DEBUG({ auto *P = isl_printer_to_str(Ctx); P = isl_printer_set_yaml_style(P, ISL_YAML_STYLE_BLOCK); - P = isl_printer_print_schedule(P, Schedule); + P = isl_printer_print_schedule(P, Schedule.get()); auto *str = isl_printer_get_str(P); dbgs() << "NewScheduleTree: \n" << str << "\n"; free(str); @@ -1586,15 +1493,12 @@ Function &F = S.getFunction(); auto *TTI = &getAnalysis().getTTI(F); const OptimizerAdditionalInfoTy OAI = {TTI, const_cast(&D)}; - isl_schedule *NewSchedule = - ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI); + auto NewSchedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI); - if (!ScheduleTreeOptimizer::isProfitableSchedule(S, NewSchedule)) { - isl_schedule_free(NewSchedule); + if (!ScheduleTreeOptimizer::isProfitableSchedule(S, NewSchedule)) return false; - } - S.setScheduleTree(NewSchedule); + S.setScheduleTree(NewSchedule.release()); S.markAsOptimized(); if (OptimizedScops)