1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[VPlan] Add VPBlockUtils::blocksOnly helper.

This patch adds a blocksOnly helpers which take an iterator range
over VPBlockBase * or const VPBlockBase * and returns an interator
range that only include BlockTy blocks. The accesses are casted to
BlockTy.

Reviewed By: a.elovikov

Differential Revision: https://reviews.llvm.org/D101093
This commit is contained in:
Florian Hahn 2021-04-25 17:11:41 +01:00
parent cc0eecb859
commit 55f97d3d98
2 changed files with 59 additions and 0 deletions

View File

@ -2201,6 +2201,20 @@ public:
}
return Count;
}
/// Return an iterator range over \p Iter which only includes \p BlockTy
/// blocks. The accesses are casted to \p BlockTy.
template <typename BlockTy, typename T> static auto blocksOnly(T Iter) {
// We need to first create an iterator range over VPBlockBase & instead of
// VPBlockBase * for filter_range to work properly.
auto Mapped = map_range(
Iter, [](VPBlockBase *Block) -> VPBlockBase & { return *Block; });
auto Filter = make_filter_range(
Mapped, [](VPBlockBase &Block) { return isa<BlockTy>(&Block); });
return map_range(Filter, [](VPBlockBase &Block) -> BlockTy * {
return cast<BlockTy>(&Block);
});
}
};
class VPInterleavedAccessInfo {

View File

@ -405,6 +405,25 @@ TEST(VPBasicBlockTest, TraversingIteratorTest) {
EXPECT_EQ(R2BB2, FromIterator[6]);
EXPECT_EQ(R1BB3, FromIterator[7]);
// const VPBasicBlocks only.
FromIterator.clear();
copy(VPBlockUtils::blocksOnly<const VPBasicBlock>(depth_first(Start)),
std::back_inserter(FromIterator));
EXPECT_EQ(6u, FromIterator.size());
EXPECT_EQ(R1BB1, FromIterator[0]);
EXPECT_EQ(R1BB2, FromIterator[1]);
EXPECT_EQ(R1BB4, FromIterator[2]);
EXPECT_EQ(R2BB1, FromIterator[3]);
EXPECT_EQ(R2BB2, FromIterator[4]);
EXPECT_EQ(R1BB3, FromIterator[5]);
// VPRegionBlocks only.
SmallVector<VPRegionBlock *> FromIteratorVPRegion(
VPBlockUtils::blocksOnly<VPRegionBlock>(depth_first(Start)));
EXPECT_EQ(2u, FromIteratorVPRegion.size());
EXPECT_EQ(R1, FromIteratorVPRegion[0]);
EXPECT_EQ(R2, FromIteratorVPRegion[1]);
// Post-order.
FromIterator.clear();
copy(post_order(Start), std::back_inserter(FromIterator));
@ -599,6 +618,14 @@ TEST(VPBasicBlockTest, TraversingIteratorTest) {
EXPECT_EQ(R3BB1, FromIterator[5]);
EXPECT_EQ(VPBB2, FromIterator[6]);
SmallVector<VPBlockBase *> FromIteratorVPBB;
copy(VPBlockUtils::blocksOnly<VPBasicBlock>(depth_first(Start)),
std::back_inserter(FromIteratorVPBB));
EXPECT_EQ(VPBB1, FromIteratorVPBB[0]);
EXPECT_EQ(R2BB1, FromIteratorVPBB[1]);
EXPECT_EQ(R3BB1, FromIteratorVPBB[2]);
EXPECT_EQ(VPBB2, FromIteratorVPBB[3]);
// Post-order.
FromIterator.clear();
copy(post_order(Start), std::back_inserter(FromIterator));
@ -611,6 +638,24 @@ TEST(VPBasicBlockTest, TraversingIteratorTest) {
EXPECT_EQ(R1, FromIterator[5]);
EXPECT_EQ(VPBB1, FromIterator[6]);
// Post-order, const VPRegionBlocks only.
SmallVector<const VPRegionBlock *> FromIteratorVPRegion(
VPBlockUtils::blocksOnly<const VPRegionBlock>(post_order(Start)));
EXPECT_EQ(3u, FromIteratorVPRegion.size());
EXPECT_EQ(R3, FromIteratorVPRegion[0]);
EXPECT_EQ(R2, FromIteratorVPRegion[1]);
EXPECT_EQ(R1, FromIteratorVPRegion[2]);
// Post-order, VPBasicBlocks only.
FromIterator.clear();
copy(VPBlockUtils::blocksOnly<VPBasicBlock>(post_order(Start)),
std::back_inserter(FromIterator));
EXPECT_EQ(FromIterator.size(), 4u);
EXPECT_EQ(VPBB2, FromIterator[0]);
EXPECT_EQ(R3BB1, FromIterator[1]);
EXPECT_EQ(R2BB1, FromIterator[2]);
EXPECT_EQ(VPBB1, FromIterator[3]);
// Use Plan to properly clean up created blocks.
VPlan Plan;
Plan.setEntry(VPBB1);