32#define DEBUG_TYPE "hbr"
39 bool SbAE = (S < AE) || (S == AE &&
A.TiedEnd);
40 bool ASbE = (AS < E) || (AS == E &&
TiedEnd);
41 if ((AS < S && SbAE) || (S < AS && ASbE))
48 if (start() <=
A.start()) {
60 assert(end() ==
A.start() || overlaps(
A));
76 for (
const auto &R : RL)
88 iterator Iter = begin();
90 while (Iter != end()-1) {
91 iterator Next = std::next(Iter);
94 bool Merge = MergeAdjacent && (Iter->end() == Next->start());
95 if (
Merge || Iter->overlaps(*Next)) {
105void HexagonBlockRanges::RangeList::addsub(
const IndexRange &
A,
109 if (!
A.overlaps(
B)) {
115 IndexType AS =
A.start(), AE =
A.end();
116 IndexType BS =
B.start(), BE =
B.end();
128 add(AS, BS,
A.Fixed,
false);
134 add(BS, AE,
A.Fixed,
false);
136 add(BE, AE,
A.Fixed,
false);
145 for (iterator Next,
I = begin();
I != end();
I = Next) {
162 if (In.isDebugInstr())
165 Map.insert(std::make_pair(
Idx, &In));
172 auto F = Map.find(
Idx);
173 return (
F != Map.end()) ?
F->second :
nullptr;
178 for (
const auto &
I : Map)
208 for (
auto &
I : Map) {
209 if (
I.second != OldMI)
211 if (NewMI !=
nullptr)
221 TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()),
222 Reserved(TRI.getReservedRegs(mf)) {
225 if (RC->isAllocatable())
227 for (
unsigned R : *RC)
238 for (
auto I :
B.liveins()) {
240 if (
I.LaneMask.all() || (
I.LaneMask.any() && !S.isValid())) {
241 Tmp.insert({
I.PhysReg, 0});
244 for (; S.isValid(); ++S) {
245 unsigned SI = S.getSubRegIndex();
246 if ((
I.LaneMask &
TRI.getSubRegIndexLaneMask(SI)).any())
247 Tmp.insert({S.getSubReg(), 0});
252 if (!Reserved[
R.Reg])
255 if (!Reserved[S.Reg])
271 if (R.Reg.isPhysical()) {
272 if (
TRI.subregs(R.Reg).empty())
273 SRs.insert({R.Reg, 0});
277 assert(R.Reg.isVirtual());
278 auto &RC = *
MRI.getRegClass(R.Reg);
279 unsigned PReg = *RC.begin();
282 SRs.insert({R.Reg, 0});
283 for (;
I.isValid(); ++
I)
284 SRs.insert({R.Reg, I.getSubRegIndex()});
289void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
290 RegToRangeMap &LiveMap) {
291 std::map<RegisterRef,IndexType> LastDef, LastUse;
296 for (
auto R : getLiveIns(
B,
MRI, TRI))
297 LiveOnEntry.insert(R);
299 for (
auto R : LiveOnEntry)
302 auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) ->
void {
303 auto LD = LastDef[R], LU = LastUse[R];
308 LiveMap[R].add(LD, LU,
false,
false);
315 if (In.isDebugInstr())
317 IndexType
Index = IndexMap.getIndex(&In);
319 for (
auto &
Op : In.operands()) {
320 if (!
Op.isReg() || !
Op.isUse() ||
Op.isUndef())
322 RegisterRef R = {
Op.getReg(),
Op.getSubReg() };
323 if (
R.Reg.isPhysical() && Reserved[
R.Reg])
325 bool IsKill =
Op.isKill();
335 for (
auto &
Op :
In.operands()) {
336 if (!
Op.isReg() || !
Op.isDef() ||
Op.isUndef())
338 RegisterRef
R = {
Op.getReg(),
Op.getSubReg() };
340 if (S.Reg.isPhysical() && Reserved[S.Reg])
349 for (
auto &
Op :
In.operands()) {
353 for (
unsigned PR = 1,
N =
TRI.getNumRegs(); PR !=
N; ++PR) {
357 if (!
TRI.subregs(PR).empty())
361 if (BM[PR/32] & (1u << (PR%32)))
363 RegisterRef
R = { PR, 0 };
370 for (RegisterRef R : Defs)
374 for (RegisterRef S : Defs) {
376 assert(!S.Reg.isPhysical() ||
TRI.subregs(S.Reg).empty());
382 for (RegisterRef S : Clobbers) {
384 assert(!S.Reg.isPhysical() ||
TRI.subregs(S.Reg).empty());
388 LastDef[S] = LastUse[S] =
Index;
395 for (
auto *SB :
B.successors())
396 for (
auto R : getLiveIns(*SB,
MRI, TRI))
397 LiveOnExit.insert(R);
399 for (
auto R : LiveOnExit)
404 for (
auto &
I : LastUse)
406 Left.insert(
I.first);
407 for (
auto &
I : LastDef)
409 Left.insert(
I.first);
414 for (
auto &
P : LiveMap)
421 LLVM_DEBUG(
dbgs() << __func__ <<
": index map\n" << IndexMap <<
'\n');
422 computeInitialLiveRanges(IndexMap, LiveMap);
432 auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (
RegisterRef R) ->
void {
433 auto F = LiveMap.find(R);
434 if (
F == LiveMap.end() ||
F->second.empty()) {
440 RangeList::iterator
A = RL.begin(), Z = RL.end()-1;
457 DeadMap[R].add(DS, DE,
false,
false);
471 unsigned NumRegs =
TRI.getNumRegs();
473 for (
unsigned R = 1; R < NumRegs; ++R) {
475 if (Reserved[S.Reg] || Visited[S.Reg])
478 Visited[S.Reg] =
true;
481 for (
auto &
P : LiveMap)
482 if (
P.first.Reg.isVirtual())
483 addDeadRanges(
P.first);
504 OS <<
'[' <<
IR.start() <<
':' <<
IR.end() << (
IR.TiedEnd ?
'}' :
']');
512 for (
const auto &R : RL)
519 for (
auto &In : M.Block) {
521 OS <<
Idx << (
Idx == M.Last ?
". " :
" ") << In;
528 for (
const auto &
I :
P.Map) {
530 OS <<
printReg(
I.first.Reg, &
P.TRI,
I.first.Sub) <<
" -> " << RL <<
"\n";
unsigned const MachineRegisterInfo * MRI
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Legalize the Machine IR a function s Machine IR
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an Operation in the Expression.
void merge(const IndexRange &A)
bool overlaps(const IndexRange &A) const
bool contains(const IndexRange &A) const
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
MachineBasicBlock & getBlock() const
IndexType getNextIndex(IndexType Idx) const
IndexType getPrevIndex(IndexType Idx) const
IndexType getIndex(MachineInstr *MI) const
InstrIndexMap(MachineBasicBlock &B)
MachineInstr * getInstr(IndexType Idx) const
void subtract(const IndexRange &Range)
void include(const RangeList &RL)
void unionize(bool MergeAdjacent=false)
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
iterator_range< regclass_iterator > regclasses() const
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap)
std::set< RegisterRef > RegisterSet
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap)
HexagonBlockRanges(MachineFunction &MF)
std::map< RegisterRef, RangeList > RegToRangeMap