31#define DEBUG_TYPE "hbr"
38 bool SbAE = (S < AE) || (S == AE &&
A.TiedEnd);
39 bool ASbE = (AS < E) || (AS == E &&
TiedEnd);
40 if ((AS < S && SbAE) || (S < AS && ASbE))
47 if (start() <=
A.start()) {
59 assert(end() ==
A.start() || overlaps(
A));
75 for (
const auto &R : RL)
87 iterator Iter = begin();
89 while (Iter != end()-1) {
90 iterator Next = std::next(Iter);
93 bool Merge = MergeAdjacent && (Iter->end() == Next->start());
94 if (
Merge || Iter->overlaps(*Next)) {
104void HexagonBlockRanges::RangeList::addsub(
const IndexRange &
A,
108 if (!
A.overlaps(
B)) {
114 IndexType AS =
A.start(), AE =
A.end();
115 IndexType BS =
B.start(), BE =
B.end();
127 add(AS, BS,
A.Fixed,
false);
133 add(BS, AE,
A.Fixed,
false);
135 add(BE, AE,
A.Fixed,
false);
144 for (iterator Next,
I = begin();
I != end();
I = Next) {
161 if (In.isDebugInstr())
164 Map.insert(std::make_pair(
Idx, &In));
171 auto F = Map.find(
Idx);
172 return (
F != Map.end()) ?
F->second :
nullptr;
177 for (
const auto &
I : Map)
207 for (
auto &
I : Map) {
208 if (
I.second != OldMI)
210 if (NewMI !=
nullptr)
220 TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()),
221 Reserved(TRI.getReservedRegs(mf)) {
224 if (RC->isAllocatable())
226 for (
unsigned R : *RC)
237 for (
auto I :
B.liveins()) {
239 if (
I.LaneMask.all() || (
I.LaneMask.any() && !S.isValid())) {
240 Tmp.insert({
I.PhysReg, 0});
243 for (; S.isValid(); ++S) {
244 unsigned SI = S.getSubRegIndex();
245 if ((
I.LaneMask &
TRI.getSubRegIndexLaneMask(SI)).any())
246 Tmp.insert({S.getSubReg(), 0});
251 if (!Reserved[
R.Reg])
254 if (!Reserved[S.Reg])
270 if (R.Reg.isPhysical()) {
271 if (
TRI.subregs(R.Reg).empty())
272 SRs.insert({R.Reg, 0});
276 assert(R.Reg.isVirtual());
277 auto &RC = *
MRI.getRegClass(R.Reg);
278 unsigned PReg = *RC.begin();
281 SRs.insert({R.Reg, 0});
282 for (;
I.isValid(); ++
I)
283 SRs.insert({R.Reg, I.getSubRegIndex()});
288void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
289 RegToRangeMap &LiveMap) {
290 std::map<RegisterRef,IndexType> LastDef, LastUse;
295 for (
auto R : getLiveIns(
B,
MRI, TRI))
296 LiveOnEntry.insert(R);
298 for (
auto R : LiveOnEntry)
301 auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) ->
void {
302 auto LD = LastDef[R], LU = LastUse[R];
307 LiveMap[R].add(LD, LU,
false,
false);
314 if (In.isDebugInstr())
316 IndexType Index = IndexMap.getIndex(&In);
318 for (
auto &
Op : In.operands()) {
319 if (!
Op.isReg() || !
Op.isUse() ||
Op.isUndef())
321 RegisterRef R = {
Op.getReg(),
Op.getSubReg() };
322 if (
R.Reg.isPhysical() && Reserved[
R.Reg])
324 bool IsKill =
Op.isKill();
334 for (
auto &
Op :
In.operands()) {
335 if (!
Op.isReg() || !
Op.isDef() ||
Op.isUndef())
337 RegisterRef
R = {
Op.getReg(),
Op.getSubReg() };
339 if (S.Reg.isPhysical() && Reserved[S.Reg])
348 for (
auto &
Op :
In.operands()) {
352 for (
unsigned PR = 1,
N =
TRI.getNumRegs(); PR !=
N; ++PR) {
356 if (!
TRI.subregs(PR).empty())
360 if (BM[PR/32] & (1u << (PR%32)))
362 RegisterRef
R = { PR, 0 };
369 for (RegisterRef R : Defs)
373 for (RegisterRef S : Defs) {
375 assert(!S.Reg.isPhysical() ||
TRI.subregs(S.Reg).empty());
381 for (RegisterRef S : Clobbers) {
383 assert(!S.Reg.isPhysical() ||
TRI.subregs(S.Reg).empty());
387 LastDef[S] = LastUse[S] =
Index;
394 for (
auto *SB :
B.successors())
395 for (
auto R : getLiveIns(*SB,
MRI, TRI))
396 LiveOnExit.insert(R);
398 for (
auto R : LiveOnExit)
403 for (
auto &
I : LastUse)
405 Left.insert(
I.first);
406 for (
auto &
I : LastDef)
408 Left.insert(
I.first);
413 for (
auto &
P : LiveMap)
420 LLVM_DEBUG(
dbgs() << __func__ <<
": index map\n" << IndexMap <<
'\n');
421 computeInitialLiveRanges(IndexMap, LiveMap);
431 auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (
RegisterRef R) ->
void {
432 auto F = LiveMap.find(R);
433 if (
F == LiveMap.end() ||
F->second.empty()) {
439 RangeList::iterator
A = RL.begin(), Z = RL.end()-1;
456 DeadMap[R].add(DS, DE,
false,
false);
470 unsigned NumRegs =
TRI.getNumRegs();
472 for (
unsigned R = 1; R < NumRegs; ++R) {
474 if (Reserved[S.Reg] || Visited[S.Reg])
477 Visited[S.Reg] =
true;
480 for (
auto &
P : LiveMap)
481 if (
P.first.Reg.isVirtual())
482 addDeadRanges(
P.first);
503 OS <<
'[' <<
IR.start() <<
':' <<
IR.end() << (
IR.TiedEnd ?
'}' :
']');
511 for (
const auto &R : RL)
518 for (
auto &In : M.Block) {
520 OS <<
Idx << (
Idx == M.Last ?
". " :
" ") << In;
527 for (
const auto &
I :
P.Map) {
529 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