LLVM: lib/CodeGen/InterferenceCache.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

21#include

22#include

23#include

24

25using namespace llvm;

26

27#define DEBUG_TYPE "regalloc"

28

29

30const InterferenceCache::BlockInterference

31 InterferenceCache::Cursor::NoInterference;

32

33

34

35

36

37

38

39

40

42 if (PhysRegEntriesCount == TRI->getNumRegs()) return;

43 free(PhysRegEntries);

44 PhysRegEntriesCount = TRI->getNumRegs();

45 PhysRegEntries = static_cast<unsigned char*>(

46 safe_calloc(PhysRegEntriesCount, sizeof(unsigned char)));

47}

48

54 MF = mf;

55 LIUArray = liuarray;

56 TRI = tri;

58 for (Entry &E : Entries)

59 E.clear(mf, indexes, lis);

60}

61

62InterferenceCache::Entry *InterferenceCache::get(MCRegister PhysReg) {

63 unsigned char E = PhysRegEntries[PhysReg.id()];

64 if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) {

65 if (!Entries[E].valid(LIUArray, TRI))

66 Entries[E].revalidate(LIUArray, TRI);

67 return &Entries[E];

68 }

69

70 E = RoundRobin;

72 RoundRobin = 0;

73 for (unsigned i = 0; i != CacheEntries; ++i) {

74

75 if (Entries[E].hasRefs()) {

77 E = 0;

78 continue;

79 }

80 Entries[E].reset(PhysReg, LIUArray, TRI, MF);

81 PhysRegEntries[PhysReg.id()] = E;

82 return &Entries[E];

83 }

85}

86

87

88void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray,

90

91 ++Tag;

92

93 PrevPos = SlotIndex();

94 unsigned i = 0;

95 for (MCRegUnit Unit : TRI->regunits(PhysReg))

96 RegUnits[i++].VirtTag = LIUArray[static_cast<unsigned>(Unit)].getTag();

97}

98

99void InterferenceCache::Entry::reset(MCRegister physReg,

100 LiveIntervalUnion *LIUArray,

101 const TargetRegisterInfo *TRI,

102 const MachineFunction *MF) {

103 assert(!hasRefs() && "Cannot reset cache entry with references");

104

106 PhysReg = physReg;

107 Blocks.resize(MF->getNumBlockIDs());

108

109

110 PrevPos = SlotIndex();

111 RegUnits.clear();

112 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

113 RegUnits.push_back(LIUArray[static_cast<unsigned>(Unit)]);

114 RegUnits.back().Fixed = &LIS->getRegUnit(Unit);

115 }

116}

117

118bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray,

119 const TargetRegisterInfo *TRI) {

120 unsigned i = 0, e = RegUnits.size();

121 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

122 if (i == e)

123 return false;

124 if (LIUArray[static_cast<unsigned>(Unit)].changedSince(RegUnits[i].VirtTag))

125 return false;

126 ++i;

127 }

128 return i == e;

129}

130

131void InterferenceCache::Entry::update(unsigned MBBNum) {

132 SlotIndex Start, Stop;

133 std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);

134

135

136 if (PrevPos != Start) {

137 if (!PrevPos.isValid() || Start < PrevPos) {

138 for (RegUnitInfo &RUI : RegUnits) {

139 RUI.VirtI.find(Start);

140 RUI.FixedI = RUI.Fixed->find(Start);

141 }

142 } else {

143 for (RegUnitInfo &RUI : RegUnits) {

144 RUI.VirtI.advanceTo(Start);

145 if (RUI.FixedI != RUI.Fixed->end())

146 RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start);

147 }

148 }

150 }

151

153 MF->getBlockNumbered(MBBNum)->getIterator();

154 BlockInterference *BI = &Blocks[MBBNum];

157 while (true) {

158 BI->Tag = Tag;

159 BI->First = BI->Last = SlotIndex();

160

161

162 for (RegUnitInfo &RUI : RegUnits) {

164 if (I.valid())

165 continue;

166 SlotIndex StartI = I.start();

167 if (StartI >= Stop)

168 continue;

169 if (!BI->First.isValid() || StartI < BI->First)

170 BI->First = StartI;

171 }

172

173

174 for (RegUnitInfo &RUI : RegUnits) {

177 if (I == E)

178 continue;

179 SlotIndex StartI = I->start;

180 if (StartI >= Stop)

181 continue;

182 if (!BI->First.isValid() || StartI < BI->First)

183 BI->First = StartI;

184 }

185

186

187 RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum);

188 RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum);

189 SlotIndex Limit = BI->First.isValid() ? BI->First : Stop;

190 for (unsigned i = 0, e = RegMaskSlots.size();

191 i != e && RegMaskSlots[i] < Limit; ++i)

193

194 BI->First = RegMaskSlots[i];

195 break;

196 }

197

198 PrevPos = Stop;

199 if (BI->First.isValid())

200 break;

201

202

203 if (++MFI == MF->end())

204 return;

205 MBBNum = MFI->getNumber();

206 BI = &Blocks[MBBNum];

207 if (BI->Tag == Tag)

208 return;

209 std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);

210 }

211

212

213 for (RegUnitInfo &RUI : RegUnits) {

215 if (I.valid() || I.start() >= Stop)

216 continue;

217 I.advanceTo(Stop);

218 bool Backup = I.valid() || I.start() >= Stop;

219 if (Backup)

220 --I;

221 SlotIndex StopI = I.stop();

222 if (!BI->Last.isValid() || StopI > BI->Last)

223 BI->Last = StopI;

224 if (Backup)

225 ++I;

226 }

227

228

229 for (RegUnitInfo &RUI : RegUnits) {

232 if (I == LR->end() || I->start >= Stop)

233 continue;

235 bool Backup = I == LR->end() || I->start >= Stop;

236 if (Backup)

237 --I;

238 SlotIndex StopI = I->end;

239 if (!BI->Last.isValid() || StopI > BI->Last)

240 BI->Last = StopI;

241 if (Backup)

242 ++I;

243 }

244

245

246 SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start;

247 for (unsigned i = RegMaskSlots.size();

248 i && RegMaskSlots[i-1].getDeadSlot() > Limit; --i)

250

251

252 BI->Last = RegMaskSlots[i-1].getDeadSlot();

253 break;

254 }

255}

static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static cl::opt< unsigned > CacheEntries("cdsort-cache-entries", cl::ReallyHidden, cl::desc("The size of the cache"))

Register const TargetRegisterInfo * TRI

SI Optimize VGPR LiveRange

size_t size() const

size - Get the array size.

void init(MachineFunction *mf, LiveIntervalUnion *liuarray, SlotIndexes *indexes, LiveIntervals *lis, const TargetRegisterInfo *tri)

init - Prepare cache for a new function.

Definition InterferenceCache.cpp:49

void reinitPhysRegEntries()

Definition InterferenceCache.cpp:41

Union of live intervals that are strong candidates for coalescing into a single register (either phys...

LiveSegments::iterator SegmentIter

Segments::iterator iterator

Segments::const_iterator const_iterator

iterator advanceTo(iterator I, SlotIndex Pos)

advanceTo - Advance the specified iterator to point to the Segment containing the specified position,...

Wrapper class representing physical registers. Should be passed by value.

constexpr unsigned id() const

BasicBlockListType::const_iterator const_iterator

static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)

clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.

bool isValid() const

Returns true if this is a valid index.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_calloc(size_t Count, size_t Sz)

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

ArrayRef(const T &OneElt) -> ArrayRef< T >