1 //===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // InterferenceCache remembers per-block interference in LiveIntervalUnions.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "regalloc"
15 #include "InterferenceCache.h"
16 #include "llvm/Target/TargetRegisterInfo.h"
20 void InterferenceCache::init(MachineFunction
*mf
,
21 LiveIntervalUnion
*liuarray
,
23 const TargetRegisterInfo
*tri
) {
27 PhysRegEntries
.assign(TRI
->getNumRegs(), 0);
28 for (unsigned i
= 0; i
!= CacheEntries
; ++i
)
29 Entries
[i
].clear(indexes
);
32 InterferenceCache::Entry
*InterferenceCache::get(unsigned PhysReg
) {
33 unsigned E
= PhysRegEntries
[PhysReg
];
34 if (E
< CacheEntries
&& Entries
[E
].getPhysReg() == PhysReg
) {
35 if (!Entries
[E
].valid(LIUArray
, TRI
))
36 Entries
[E
].revalidate();
39 // No valid entry exists, pick the next round-robin entry.
41 if (++RoundRobin
== CacheEntries
)
43 Entries
[E
].reset(PhysReg
, LIUArray
, TRI
, MF
);
44 PhysRegEntries
[PhysReg
] = E
;
48 /// revalidate - LIU contents have changed, update tags.
49 void InterferenceCache::Entry::revalidate() {
50 // Invalidate all block entries.
52 // Invalidate all iterators.
53 PrevPos
= SlotIndex();
54 for (unsigned i
= 0, e
= Aliases
.size(); i
!= e
; ++i
)
55 Aliases
[i
].second
= Aliases
[i
].first
->getTag();
58 void InterferenceCache::Entry::reset(unsigned physReg
,
59 LiveIntervalUnion
*LIUArray
,
60 const TargetRegisterInfo
*TRI
,
61 const MachineFunction
*MF
) {
62 // LIU's changed, invalidate cache.
65 Blocks
.resize(MF
->getNumBlockIDs());
67 for (const unsigned *AS
= TRI
->getOverlaps(PhysReg
); *AS
; ++AS
) {
68 LiveIntervalUnion
*LIU
= LIUArray
+ *AS
;
69 Aliases
.push_back(std::make_pair(LIU
, LIU
->getTag()));
73 PrevPos
= SlotIndex();
74 unsigned e
= Aliases
.size();
76 for (unsigned i
= 0; i
!= e
; ++i
)
77 Iters
[i
].setMap(Aliases
[i
].first
->getMap());
80 bool InterferenceCache::Entry::valid(LiveIntervalUnion
*LIUArray
,
81 const TargetRegisterInfo
*TRI
) {
82 unsigned i
= 0, e
= Aliases
.size();
83 for (const unsigned *AS
= TRI
->getOverlaps(PhysReg
); *AS
; ++AS
, ++i
) {
84 LiveIntervalUnion
*LIU
= LIUArray
+ *AS
;
85 if (i
== e
|| Aliases
[i
].first
!= LIU
)
87 if (LIU
->changedSince(Aliases
[i
].second
))
93 void InterferenceCache::Entry::update(unsigned MBBNum
) {
94 BlockInterference
*BI
= &Blocks
[MBBNum
];
96 BI
->First
= BI
->Last
= SlotIndex();
98 SlotIndex Start
, Stop
;
99 tie(Start
, Stop
) = Indexes
->getMBBRange(MBBNum
);
101 // Use advanceTo only when possible.
102 if (PrevPos
!= Start
) {
103 if (!PrevPos
.isValid() || Start
< PrevPos
)
104 for (unsigned i
= 0, e
= Iters
.size(); i
!= e
; ++i
)
105 Iters
[i
].find(Start
);
107 for (unsigned i
= 0, e
= Iters
.size(); i
!= e
; ++i
)
108 Iters
[i
].advanceTo(Start
);
112 // Check for first interference.
113 for (unsigned i
= 0, e
= Iters
.size(); i
!= e
; ++i
) {
117 SlotIndex StartI
= I
.start();
120 if (!BI
->First
.isValid() || StartI
< BI
->First
)
124 // No interference in block.
125 if (!BI
->First
.isValid())
128 // Check for last interference.
129 for (unsigned i
= 0, e
= Iters
.size(); i
!= e
; ++i
) {
131 if (!I
.valid() || I
.start() >= Stop
)
134 bool Backup
= !I
.valid() || I
.start() >= Stop
;
137 SlotIndex StopI
= I
.stop();
138 if (!BI
->Last
.isValid() || StopI
> BI
->Last
)