Changeset View
Changeset View
Standalone View
Standalone View
llvm/include/llvm/Analysis/VectorUtils.h
Show First 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | |||||
/// A[i+2] = c; // Member of index 2 | /// A[i+2] = c; // Member of index 2 | ||||
/// A[i+3] = d; // Member of index 3 | /// A[i+3] = d; // Member of index 3 | ||||
/// } | /// } | ||||
/// | /// | ||||
/// Note: the interleaved load group could have gaps (missing members), but | /// Note: the interleaved load group could have gaps (missing members), but | ||||
/// the interleaved store group doesn't allow gaps. | /// the interleaved store group doesn't allow gaps. | ||||
template <typename InstTy> class InterleaveGroup { | template <typename InstTy> class InterleaveGroup { | ||||
public: | public: | ||||
InterleaveGroup(unsigned Factor, bool Reverse, unsigned Align) | InterleaveGroup(uint32_t Factor, bool Reverse, uint32_t Align) | ||||
: Factor(Factor), Reverse(Reverse), Align(Align), InsertPos(nullptr) {} | : Factor(Factor), Reverse(Reverse), Align(Align), InsertPos(nullptr) {} | ||||
InterleaveGroup(InstTy *Instr, int Stride, unsigned Align) | InterleaveGroup(InstTy *Instr, int32_t Stride, uint32_t Align) | ||||
: Align(Align), InsertPos(Instr) { | : Align(Align), InsertPos(Instr) { | ||||
assert(Align && "The alignment should be non-zero"); | assert(Align && "The alignment should be non-zero"); | ||||
Factor = std::abs(Stride); | Factor = std::abs(Stride); | ||||
assert(Factor > 1 && "Invalid interleave factor"); | assert(Factor > 1 && "Invalid interleave factor"); | ||||
Reverse = Stride < 0; | Reverse = Stride < 0; | ||||
Members[0] = Instr; | Members[0] = Instr; | ||||
} | } | ||||
bool isReverse() const { return Reverse; } | bool isReverse() const { return Reverse; } | ||||
unsigned getFactor() const { return Factor; } | uint32_t getFactor() const { return Factor; } | ||||
unsigned getAlignment() const { return Align; } | uint32_t getAlignment() const { return Align; } | ||||
unsigned getNumMembers() const { return Members.size(); } | uint32_t getNumMembers() const { return Members.size(); } | ||||
/// Try to insert a new member \p Instr with index \p Index and | /// Try to insert a new member \p Instr with index \p Index and | ||||
/// alignment \p NewAlign. The index is related to the leader and it could be | /// alignment \p NewAlign. The index is related to the leader and it could be | ||||
/// negative if it is the new leader. | /// negative if it is the new leader. | ||||
/// | /// | ||||
/// \returns false if the instruction doesn't belong to the group. | /// \returns false if the instruction doesn't belong to the group. | ||||
bool insertMember(InstTy *Instr, int Index, unsigned NewAlign) { | bool insertMember(InstTy *Instr, int32_t Index, uint32_t NewAlign) { | ||||
assert(NewAlign && "The new member's alignment should be non-zero"); | assert(NewAlign && "The new member's alignment should be non-zero"); | ||||
int Key = Index + SmallestKey; | int32_t Key = Index + SmallestKey; | ||||
// Skip if there is already a member with the same index. | // Skip if there is already a member with the same index. | ||||
if (Members.find(Key) != Members.end()) | if (Members.find(Key) != Members.end()) | ||||
return false; | return false; | ||||
if (Key > LargestKey) { | if (Key > LargestKey) { | ||||
// The largest index is always less than the interleave factor. | // The largest index is always less than the interleave factor. | ||||
if (Index >= static_cast<int>(Factor)) | if (Index >= static_cast<int>(Factor)) | ||||
Show All 12 Lines | bool insertMember(InstTy *Instr, int32_t Index, uint32_t NewAlign) { | ||||
Align = std::min(Align, NewAlign); | Align = std::min(Align, NewAlign); | ||||
Members[Key] = Instr; | Members[Key] = Instr; | ||||
return true; | return true; | ||||
} | } | ||||
/// Get the member with the given index \p Index | /// Get the member with the given index \p Index | ||||
/// | /// | ||||
/// \returns nullptr if contains no such member. | /// \returns nullptr if contains no such member. | ||||
InstTy *getMember(unsigned Index) const { | InstTy *getMember(uint32_t Index) const { | ||||
int Key = SmallestKey + Index; | int32_t Key = SmallestKey + Index; | ||||
auto Member = Members.find(Key); | auto Member = Members.find(Key); | ||||
if (Member == Members.end()) | if (Member == Members.end()) | ||||
return nullptr; | return nullptr; | ||||
return Member->second; | return Member->second; | ||||
} | } | ||||
/// Get the index for the given member. Unlike the key in the member | /// Get the index for the given member. Unlike the key in the member | ||||
/// map, the index starts from 0. | /// map, the index starts from 0. | ||||
unsigned getIndex(const InstTy *Instr) const { | uint32_t getIndex(const InstTy *Instr) const { | ||||
for (auto I : Members) { | for (auto I : Members) { | ||||
if (I.second == Instr) | if (I.second == Instr) | ||||
return I.first - SmallestKey; | return I.first - SmallestKey; | ||||
} | } | ||||
llvm_unreachable("InterleaveGroup contains no such member"); | llvm_unreachable("InterleaveGroup contains no such member"); | ||||
} | } | ||||
Show All 21 Lines | assert(!getMember(0)->mayWriteToMemory() && | ||||
"Group should have been invalidated"); | "Group should have been invalidated"); | ||||
assert(!isReverse() && "Group should have been invalidated"); | assert(!isReverse() && "Group should have been invalidated"); | ||||
// This is a group of loads, with gaps, and without a last-member | // This is a group of loads, with gaps, and without a last-member | ||||
return true; | return true; | ||||
} | } | ||||
private: | private: | ||||
unsigned Factor; // Interleave Factor. | uint32_t Factor; // Interleave Factor. | ||||
bool Reverse; | bool Reverse; | ||||
unsigned Align; | uint32_t Align; | ||||
DenseMap<int, InstTy *> Members; | DenseMap<int32_t, InstTy *> Members; | ||||
int SmallestKey = 0; | int32_t SmallestKey = 0; | ||||
int LargestKey = 0; | int32_t LargestKey = 0; | ||||
// To avoid breaking dependences, vectorized instructions of an interleave | // To avoid breaking dependences, vectorized instructions of an interleave | ||||
// group should be inserted at either the first load or the last store in | // group should be inserted at either the first load or the last store in | ||||
// program order. | // program order. | ||||
// | // | ||||
// E.g. %even = load i32 // Insert Position | // E.g. %even = load i32 // Insert Position | ||||
// %add = add i32 %even // Use of %even | // %add = add i32 %even // Use of %even | ||||
// %odd = load i32 | // %odd = load i32 | ||||
▲ Show 20 Lines • Show All 231 Lines • Show Last 20 Lines |