1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
//===--- RDFRegisters.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
#define LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
#include "llvm/ADT/BitVector.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <set>
#include <unordered_map>
#include <vector>
namespace llvm {
namespace rdf {
typedef uint32_t RegisterId;
// Template class for a map translating uint32_t into arbitrary types.
// The map will act like an indexed set: upon insertion of a new object,
// it will automatically assign a new index to it. Index of 0 is treated
// as invalid and is never allocated.
template <typename T, unsigned N = 32>
struct IndexedSet {
IndexedSet() : Map() { Map.reserve(N); }
T get(uint32_t Idx) const {
// Index Idx corresponds to Map[Idx-1].
assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
return Map[Idx-1];
}
uint32_t insert(T Val) {
// Linear search.
auto F = llvm::find(Map, Val);
if (F != Map.end())
return F - Map.begin() + 1;
Map.push_back(Val);
return Map.size(); // Return actual_index + 1.
}
uint32_t find(T Val) const {
auto F = llvm::find(Map, Val);
assert(F != Map.end());
return F - Map.begin() + 1;
}
private:
std::vector<T> Map;
};
struct RegisterRef {
RegisterId Reg = 0;
LaneBitmask Mask = LaneBitmask::getNone();
RegisterRef() = default;
explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
: Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
operator bool() const {
return Reg != 0 && Mask.any();
}
bool operator== (const RegisterRef &RR) const {
return Reg == RR.Reg && Mask == RR.Mask;
}
bool operator!= (const RegisterRef &RR) const {
return !operator==(RR);
}
bool operator< (const RegisterRef &RR) const {
return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
}
};
struct PhysicalRegisterInfo {
PhysicalRegisterInfo(const TargetRegisterInfo &tri,
const MachineFunction &mf);
static bool isRegMaskId(RegisterId R) {
return TargetRegisterInfo::isStackSlot(R);
}
RegisterId getRegMaskId(const uint32_t *RM) const {
return TargetRegisterInfo::index2StackSlot(RegMasks.find(RM));
}
const uint32_t *getRegMaskBits(RegisterId R) const {
return RegMasks.get(TargetRegisterInfo::stackSlot2Index(R));
}
RegisterRef normalize(RegisterRef RR) const;
bool alias(RegisterRef RA, RegisterRef RB) const {
if (!isRegMaskId(RA.Reg))
return !isRegMaskId(RB.Reg) ? aliasRR(RA, RB) : aliasRM(RA, RB);
return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
}
std::set<RegisterId> getAliasSet(RegisterId Reg) const;
const TargetRegisterInfo &getTRI() const { return TRI; }
private:
struct RegInfo {
unsigned MaxSuper = 0;
const TargetRegisterClass *RegClass = nullptr;
};
const TargetRegisterInfo &TRI;
std::vector<RegInfo> RegInfos;
IndexedSet<const uint32_t*> RegMasks;
bool aliasRR(RegisterRef RA, RegisterRef RB) const;
bool aliasRM(RegisterRef RR, RegisterRef RM) const;
bool aliasMM(RegisterRef RM, RegisterRef RN) const;
};
struct RegisterAggr {
RegisterAggr(const PhysicalRegisterInfo &pri)
: ExpAliasUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
RegisterAggr(const RegisterAggr &RG) = default;
bool empty() const { return Masks.empty(); }
bool hasAliasOf(RegisterRef RR) const;
bool hasCoverOf(RegisterRef RR) const;
static bool isCoverOf(RegisterRef RA, RegisterRef RB,
const PhysicalRegisterInfo &PRI) {
return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
}
RegisterAggr &insert(RegisterRef RR);
RegisterAggr &insert(const RegisterAggr &RG);
RegisterAggr &clear(RegisterRef RR);
RegisterAggr &clear(const RegisterAggr &RG);
RegisterRef clearIn(RegisterRef RR) const;
void print(raw_ostream &OS) const;
private:
typedef std::unordered_map<RegisterId, LaneBitmask> MapType;
public:
typedef MapType::const_iterator iterator;
iterator begin() const { return Masks.begin(); }
iterator end() const { return Masks.end(); }
private:
MapType Masks;
BitVector ExpAliasUnits; // Register units for explicit aliases.
bool CheckUnits = false;
const PhysicalRegisterInfo &PRI;
};
// Optionally print the lane mask, if it is not ~0.
struct PrintLaneMaskOpt {
PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
LaneBitmask Mask;
};
raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
} // namespace rdf
} // namespace llvm
#endif
|