123#define DEBUG_TYPE "expand-condsets"
145 StringRef getPassName()
const override {
return "Hexagon Expand Condsets"; }
147 void getAnalysisUsage(AnalysisUsage &AU)
const override {
156 bool runOnMachineFunction(MachineFunction &MF)
override;
159 const HexagonInstrInfo *HII =
nullptr;
160 const TargetRegisterInfo *TRI =
nullptr;
161 MachineDominatorTree *MDT;
162 MachineRegisterInfo *MRI =
nullptr;
163 LiveIntervals *LIS =
nullptr;
164 bool CoaLimitActive =
false;
165 bool TfrLimitActive =
false;
168 unsigned CoaCounter = 0;
169 unsigned TfrCounter = 0;
173 RegisterRef(
const MachineOperand &
Op) : Reg(
Op.
getReg()),
174 Sub(
Op.getSubReg()) {}
175 RegisterRef(
unsigned R = 0,
unsigned S = 0) : Reg(
R), Sub(S) {}
178 return Reg == RR.Reg && Sub == RR.Sub;
182 return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub);
189 using ReferenceMap = DenseMap<unsigned, unsigned>;
190 enum { Sub_Low = 0x1, Sub_High = 0x2, Sub_None = (Sub_Low | Sub_High) };
191 enum { Exec_Then = 0x10, Exec_Else = 0x20 };
193 unsigned getMaskForSub(
unsigned Sub);
194 bool isCondset(
const MachineInstr &
MI);
197 void addRefToMap(RegisterRef RR, ReferenceMap &Map,
unsigned Exec);
198 bool isRefInMap(RegisterRef, ReferenceMap &Map,
unsigned Exec);
204 void removeInstr(MachineInstr &
MI);
205 void updateLiveness(
const std::set<Register> &RegSet,
bool Recalc,
206 bool UpdateKills,
bool UpdateDeads);
207 void distributeLiveIntervals(
const std::set<Register> &Regs);
209 unsigned getCondTfrOpcode(
const MachineOperand &SO,
bool Cond);
210 MachineInstr *genCondTfrFor(MachineOperand &SrcOp,
212 unsigned DstSR,
const MachineOperand &PredOp,
bool PredSense,
213 bool ReadUndef,
bool ImpUse);
214 bool split(MachineInstr &
MI, std::set<Register> &UpdRegs);
216 bool isPredicable(MachineInstr *
MI);
217 MachineInstr *getReachingDefForPred(RegisterRef RD,
219 bool canMoveOver(MachineInstr &
MI, ReferenceMap &Defs, ReferenceMap &
Uses);
220 bool canMoveMemTo(MachineInstr &
MI, MachineInstr &ToI,
bool IsDown);
221 void predicateAt(
const MachineOperand &DefOp, MachineInstr &
MI,
223 const MachineOperand &PredOp,
bool Cond,
224 std::set<Register> &UpdRegs);
225 void renameInRange(RegisterRef RO, RegisterRef RN,
unsigned PredR,
228 bool predicate(MachineInstr &TfrI,
bool Cond, std::set<Register> &UpdRegs);
229 bool predicateInBlock(MachineBasicBlock &
B, std::set<Register> &UpdRegs);
231 bool isIntReg(RegisterRef RR,
unsigned &BW);
232 bool isIntraBlocks(LiveInterval &LI);
233 bool coalesceRegisters(RegisterRef R1, RegisterRef
R2);
234 bool coalesceSegments(
const SmallVectorImpl<MachineInstr *> &
Condsets,
235 std::set<Register> &UpdRegs);
240char HexagonExpandCondsets::ID = 0;
244 "Hexagon Expand Condsets",
false,
false)
251unsigned HexagonExpandCondsets::getMaskForSub(
unsigned Sub) {
253 case Hexagon::isub_lo:
254 case Hexagon::vsub_lo:
256 case Hexagon::isub_hi:
257 case Hexagon::vsub_hi:
259 case Hexagon::NoSubRegister:
266 unsigned Opc =
MI.getOpcode();
268 case Hexagon::C2_mux:
269 case Hexagon::C2_muxii:
270 case Hexagon::C2_muxir:
271 case Hexagon::C2_muxri:
272 case Hexagon::PS_pselect:
279LaneBitmask HexagonExpandCondsets::getLaneMask(
Register Reg,
unsigned Sub) {
281 return Sub != 0 ?
TRI->getSubRegIndexLaneMask(
Sub)
282 :
MRI->getMaxLaneMaskForVReg(
Reg);
285void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map,
287 unsigned Mask = getMaskForSub(RR.Sub) |
Exec;
291bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map,
293 ReferenceMap::iterator
F =
Map.find(RR.Reg);
296 unsigned Mask = getMaskForSub(RR.Sub) |
Exec;
297 if (Mask &
F->second)
302void HexagonExpandCondsets::updateKillFlags(
Register Reg) {
303 auto KillAt = [
this,
Reg] (SlotIndex
K, LaneBitmask LM) ->
void {
306 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
307 MachineOperand &
Op =
MI->getOperand(i);
308 if (!
Op.isReg() || !
Op.isUse() ||
Op.getReg() !=
Reg ||
309 MI->isRegTiedToDefOperand(i))
311 LaneBitmask SLM = getLaneMask(
Reg,
Op.getSubReg());
312 if ((SLM & LM) == SLM) {
323 if (!
I->end.isRegister())
327 auto NextI = std::next(
I);
328 if (NextI !=
E && NextI->start.isRegister()) {
333 bool WholeReg =
true;
335 auto EndsAtI = [
I] (LiveInterval::SubRange &S) ->
bool {
336 LiveRange::iterator
F = S.find(
I->end);
337 return F != S.end() &&
I->end ==
F->end;
341 for (LiveInterval::SubRange &S : LI.
subranges()) {
343 KillAt(
I->end, S.LaneMask);
349 KillAt(
I->end,
MRI->getMaxLaneMaskForVReg(
Reg));
353void HexagonExpandCondsets::updateDeadsInRange(
Register Reg, LaneBitmask LM,
360 auto IsRegDef = [
this,
Reg,LM] (MachineOperand &
Op) -> std::pair<bool,bool> {
361 if (!
Op.isReg() || !
Op.isDef())
362 return {
false,
false };
365 return {
false,
false };
366 LaneBitmask SLM = getLaneMask(DR, DSR);
367 LaneBitmask
A = SLM & LM;
368 return {
A.any(),
A == SLM };
378 auto Dominate = [
this] (SetVector<MachineBasicBlock*> &Defs,
379 MachineBasicBlock *Dest) ->
bool {
380 for (MachineBasicBlock *
D : Defs) {
384 MachineBasicBlock *
Entry = &Dest->getParent()->front();
385 SetVector<MachineBasicBlock *> Work(
llvm::from_range, Dest->predecessors());
386 for (
unsigned i = 0; i < Work.size(); ++i) {
387 MachineBasicBlock *
B = Work[i];
392 Work.insert_range(
B->predecessors());
400 SetVector<MachineBasicBlock*> Defs;
402 for (
auto &Seg :
Range) {
403 if (!Seg.start.isRegister())
415 for (
auto &SI : PredDefs) {
418 if (
P.first !=
nullptr ||
P.second)
425 for (
auto &SI : PredDefs) {
441 if (Dominate(Defs, BB))
455 std::set<RegisterRef> DefRegs;
456 for (
auto &Seg :
Range) {
457 if (!Seg.start.isRegister())
461 auto P = IsRegDef(
Op);
462 if (
P.second && Seg.end.isDead()) {
464 }
else if (
P.first) {
473 for (
auto &Seg :
Range) {
474 if (!Seg.start.isRegister() || !
Range.liveAt(Seg.start.getPrevSlot()))
482 std::map<RegisterRef,unsigned> ImpUses;
485 if (!
Op.isReg() || !DefRegs.count(
Op))
491 ImpUses.insert({
Op, i});
505 for (
auto [R, DefIdx] : ImpUses) {
512void HexagonExpandCondsets::updateDeadFlags(
Register Reg) {
515 for (LiveInterval::SubRange &S : LI.
subranges()) {
516 updateDeadsInRange(
Reg, S.LaneMask, S);
522 updateDeadsInRange(
Reg,
MRI->getMaxLaneMaskForVReg(
Reg), LI);
526void HexagonExpandCondsets::recalculateLiveInterval(
Register Reg) {
531void HexagonExpandCondsets::removeInstr(MachineInstr &
MI) {
533 MI.eraseFromParent();
536void HexagonExpandCondsets::updateLiveness(
const std::set<Register> &RegSet,
537 bool Recalc,
bool UpdateKills,
539 UpdateKills |= UpdateDeads;
541 if (!
R.isVirtual()) {
549 recalculateLiveInterval(R);
551 MRI->clearKillFlags(R);
562void HexagonExpandCondsets::distributeLiveIntervals(
563 const std::set<Register> &Regs) {
564 ConnectedVNInfoEqClasses EQC(*LIS);
569 unsigned NumComp = EQC.Classify(LI);
574 const TargetRegisterClass *RC =
MRI->getRegClass(LI.
reg());
575 for (
unsigned I = 1;
I < NumComp; ++
I) {
579 EQC.Distribute(LI, NewLIs.
begin(), *
MRI);
585unsigned HexagonExpandCondsets::getCondTfrOpcode(
const MachineOperand &SO,
590 if (RS.Reg.isVirtual()) {
591 const TargetRegisterClass *
VC =
MRI->getRegClass(RS.Reg);
592 assert(
VC->begin() !=
VC->end() &&
"Empty register class");
593 PhysR = *
VC->begin();
597 MCRegister PhysS = (RS.Sub == 0) ? PhysR :
TRI->getSubReg(PhysR, RS.
Sub);
598 const TargetRegisterClass *RC =
TRI->getMinimalPhysRegClass(PhysS);
599 switch (
TRI->getRegSizeInBits(*RC)) {
601 return IfTrue ? Hexagon::A2_tfrt : Hexagon::A2_tfrf;
603 return IfTrue ? Hexagon::A2_tfrpt : Hexagon::A2_tfrpf;
616 return IfTrue ? Hexagon::C2_cmoveit : Hexagon::C2_cmoveif;
627MachineInstr *HexagonExpandCondsets::genCondTfrFor(MachineOperand &SrcOp,
629 unsigned DstR,
unsigned DstSR,
const MachineOperand &PredOp,
630 bool PredSense,
bool ReadUndef,
bool ImpUse) {
632 MachineBasicBlock &
B = *At->getParent();
641 unsigned Opc = getCondTfrOpcode(SrcOp, PredSense);
643 unsigned PredState =
getRegState(PredOp) & ~RegState::Kill;
644 MachineInstrBuilder MIB;
648 if (RegisterRef(SrcOp) == RegisterRef(DstR, DstSR))
649 SrcState &= ~RegState::Kill;
651 .
addReg(DstR, DstState, DstSR)
656 .
addReg(DstR, DstState, DstSR)
667bool HexagonExpandCondsets::split(MachineInstr &
MI,
668 std::set<Register> &UpdRegs) {
669 if (TfrLimitActive) {
670 if (TfrCounter >= TfrLimit)
676 MachineOperand &MD =
MI.getOperand(0);
677 MachineOperand &MP =
MI.getOperand(1);
683 auto updateRegs = [&UpdRegs] (
const MachineInstr &
MI) ->
void {
684 for (
auto &
Op :
MI.operands()) {
686 UpdRegs.insert(
Op.getReg());
693 MachineOperand &
ST =
MI.getOperand(2);
694 MachineOperand &SF =
MI.getOperand(3);
695 if (
ST.isReg() && SF.
isReg()) {
697 if (RT == RegisterRef(SF)) {
700 MI.setDesc(HII->get(TargetOpcode::COPY));
702 while (
MI.getNumOperands() > 1)
703 MI.removeOperand(
MI.getNumOperands()-1);
704 MachineFunction &MF = *
MI.getParent()->getParent();
705 MachineInstrBuilder(MF,
MI).addReg(RT.Reg, S, RT.Sub);
714 genCondTfrFor(ST, At, DR, DSR, MP,
true, ReadUndef,
false);
716 genCondTfrFor(SF, At, DR, DSR, MP,
false, ReadUndef,
true);
727bool HexagonExpandCondsets::isPredicable(MachineInstr *
MI) {
730 if (
MI->hasUnmodeledSideEffects() ||
MI->mayStore())
734 for (
auto &
Op :
MI->operands()) {
735 if (!
Op.isReg() || !
Op.isDef())
741 for (
auto &Mo :
MI->memoperands()) {
742 if (Mo->isVolatile() || Mo->isAtomic())
751MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD,
753 MachineBasicBlock &
B = *UseIt->getParent();
758 bool PredValid =
true;
761 MachineInstr *
MI = &*
I;
765 if (
MI->readsRegister(PredR,
nullptr) &&
772 for (
auto &
Op :
MI->operands()) {
773 if (!
Op.isReg() || !
Op.isDef())
776 if (RR.Reg == PredR) {
780 if (RR.Reg != RD.Reg)
785 if (RR.Sub == RD.Sub)
787 if (RR.Sub == 0 || RD.Sub == 0)
801bool HexagonExpandCondsets::canMoveOver(MachineInstr &
MI, ReferenceMap &Defs,
802 ReferenceMap &
Uses) {
806 for (
auto &
Op :
MI.operands()) {
813 if (!RR.Reg.isVirtual())
816 if (isRefInMap(RR, Defs, Exec_Then))
819 if (
Op.isDef() && isRefInMap(RR,
Uses, Exec_Then))
827bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI,
830 if (!IsLoad && !IsStore)
843 if (
MI.hasUnmodeledSideEffects())
845 bool L =
MI.mayLoad(), S =
MI.mayStore();
848 if (Ordered &&
MI.hasOrderedMemoryRef())
851 bool Conflict = (
L && IsStore) || S;
860void HexagonExpandCondsets::predicateAt(
const MachineOperand &DefOp,
863 const MachineOperand &PredOp,
bool Cond,
864 std::set<Register> &UpdRegs) {
876 MachineBasicBlock &
B = *
MI.getParent();
878 unsigned Opc =
MI.getOpcode();
880 MachineInstrBuilder MB =
BuildMI(
B, Where,
DL, HII->get(PredOpc));
881 unsigned Ox = 0, NP =
MI.getNumOperands();
884 MachineOperand &MO =
MI.getOperand(Ox);
895 MachineOperand &MO =
MI.getOperand(Ox);
902 MachineInstr *NewI = MB;
908 UpdRegs.insert(
Op.getReg());
915void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN,
924 if (!
MI.readsRegister(PredR,
nullptr) ||
928 for (
auto &
Op :
MI.operands()) {
929 if (!
Op.isReg() || RO != RegisterRef(
Op))
932 Op.setSubReg(
RN.Sub);
934 assert(!
Op.isDef() &&
"Not expecting a def");
942bool HexagonExpandCondsets::predicate(MachineInstr &TfrI,
bool Cond,
943 std::set<Register> &UpdRegs) {
947 assert(
Opc == Hexagon::A2_tfrt ||
Opc == Hexagon::A2_tfrf);
966 MachineInstr *DefI = getReachingDefForPred(RT, TfrI, PredR,
Cond);
967 if (!DefI || !isPredicable(DefI))
975 ReferenceMap
Uses, Defs;
981 bool PredValid =
true;
983 if (!
MI.modifiesRegister(PredR,
nullptr))
994 unsigned Exec = Exec_Then | Exec_Else;
996 MI.readsRegister(PredR,
nullptr))
999 for (
auto &
Op :
MI.operands()) {
1009 RegisterRef RR =
Op;
1010 if (!RR.Reg.isVirtual())
1013 ReferenceMap &
Map =
Op.isDef() ? Defs :
Uses;
1014 if (
Op.isDef() &&
Op.isUndef()) {
1015 assert(RR.Sub &&
"Expecting a subregister on <def,read-undef>");
1021 addRefToMap(RR, Map, Exec);
1038 if (isRefInMap(RT, Defs, Exec_Then) || isRefInMap(RT,
Uses, Exec_Else))
1040 RegisterRef RD = MD;
1047 bool CanUp = canMoveOver(TfrI, Defs,
Uses);
1048 bool CanDown = canMoveOver(*DefI, Defs,
Uses);
1052 if (!canMoveMemTo(*DefI, TfrI,
true))
1057 <<
", can move down: " << (CanDown ?
"yes\n" :
"no\n"));
1060 predicateAt(MD, *DefI, PastDefIt, MP,
Cond, UpdRegs);
1062 predicateAt(MD, *DefI, TfrIt, MP,
Cond, UpdRegs);
1067 renameInRange(RT, RD, PredR,
Cond, PastDefIt, TfrIt);
1068 UpdRegs.insert(RT.Reg);
1077bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &
B,
1078 std::set<Register> &UpdRegs) {
1081 unsigned Opc =
MI.getOpcode();
1082 if (
Opc == Hexagon::A2_tfrt ||
Opc == Hexagon::A2_tfrf) {
1083 bool Done = predicate(
MI, (
Opc == Hexagon::A2_tfrt), UpdRegs);
1087 if (RegisterRef(
MI.getOperand(0)) == RegisterRef(
MI.getOperand(2))) {
1088 for (
auto &
Op :
MI.operands()) {
1090 UpdRegs.insert(
Op.getReg());
1101bool HexagonExpandCondsets::isIntReg(RegisterRef RR,
unsigned &BW) {
1102 if (!RR.Reg.isVirtual())
1104 const TargetRegisterClass *RC =
MRI->getRegClass(RR.Reg);
1105 if (RC == &Hexagon::IntRegsRegClass) {
1109 if (RC == &Hexagon::DoubleRegsRegClass) {
1110 BW = (RR.Sub != 0) ? 32 : 64;
1116bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) {
1117 for (LiveRange::Segment &LR : LI) {
1119 if (!LR.start.isRegister())
1122 if (!LR.end.isRegister() && !LR.end.isDead())
1128bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef
R2) {
1129 if (CoaLimitActive) {
1130 if (CoaCounter >= CoaLimit)
1137 if (
MRI->isLiveIn(R1.Reg))
1139 if (
MRI->isLiveIn(
R2.Reg))
1151 << (Overlap ?
"overlap" :
"disjoint") <<
")\n "
1152 <<
printReg(R1.Reg,
TRI, R1.Sub) <<
" " << L1 <<
"\n "
1154 if (R1.Sub ||
R2.Sub)
1162 if (!isIntraBlocks(L1) && !isIntraBlocks(L2))
1165 MRI->replaceRegWith(
R2.Reg, R1.Reg);
1168 using ValueInfoMap = DenseMap<VNInfo *, VNInfo *>;
1170 for (LiveRange::Segment &
I : L2) {
1171 VNInfo *NewVN, *OldVN =
I.valno;
1172 ValueInfoMap::iterator
F = VM.find(OldVN);
1173 if (
F == VM.end()) {
1175 VM.insert(std::make_pair(OldVN, NewVN));
1179 L1.
addSegment(LiveRange::Segment(
I.start,
I.end, NewVN));
1182 L2.removeSegment(*L2.begin());
1185 updateKillFlags(R1.Reg);
1195bool HexagonExpandCondsets::coalesceSegments(
1196 const SmallVectorImpl<MachineInstr *> &
Condsets,
1197 std::set<Register> &UpdRegs) {
1200 MachineOperand &
S1 =
MI->getOperand(2), &S2 =
MI->getOperand(3);
1201 if (!
S1.isReg() && !S2.isReg())
1207 for (MachineInstr *CI : TwoRegs) {
1208 RegisterRef RD = CI->getOperand(0);
1209 RegisterRef
RP = CI->getOperand(1);
1210 MachineOperand &
S1 = CI->getOperand(2), &S2 = CI->getOperand(3);
1231 RegisterRef RS =
S1;
1232 MachineInstr *RDef = getReachingDefForPred(RS, CI,
RP.Reg,
true);
1234 Done = coalesceRegisters(RD, RegisterRef(
S1));
1236 UpdRegs.insert(RD.Reg);
1237 UpdRegs.insert(
S1.getReg());
1241 if (!
Done && S2.isReg()) {
1242 RegisterRef RS = S2;
1243 MachineInstr *RDef = getReachingDefForPred(RS, CI,
RP.Reg,
false);
1245 Done = coalesceRegisters(RD, RegisterRef(S2));
1247 UpdRegs.insert(RD.Reg);
1248 UpdRegs.insert(S2.getReg());
1257bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
1261 HII =
static_cast<const HexagonInstrInfo*
>(MF.
getSubtarget().getInstrInfo());
1263 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1264 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
1270 std::set<Register> CoalUpd, PredUpd;
1273 for (
auto &
B : MF) {
1289 std::set<Register> KillUpd;
1291 for (MachineOperand &
Op :
MI->operands()) {
1292 if (
Op.isReg() &&
Op.isUse()) {
1293 if (!CoalUpd.count(
Op.getReg()))
1294 KillUpd.insert(
Op.getReg());
1322 Changed |= predicateInBlock(
B, PredUpd);
1325 PredUpd.insert(CoalUpd.begin(), CoalUpd.end());
1329 distributeLiveIntervals(PredUpd);
1333 LIS->
print(
dbgs() <<
"After expand-condsets\n");
1343 return new HexagonExpandCondsets();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
static cl::opt< unsigned > OptCoaLimit("expand-condsets-coa-limit", cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings"))
static cl::opt< unsigned > OptTfrLimit("expand-condsets-tfr-limit", cl::init(~0U), cl::Hidden, cl::desc("Max number of mux expansions"))
expand Hexagon Expand Condsets
A common definition of LaneBitmask for use in TableGen and CodeGen.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static void updateLiveness(MachineFunction &MF)
Helper function to update the liveness information for the callee-saved registers.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
SI Optimize VGPR LiveRange
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
int getCondOpcode(int Opc, bool sense) const
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
bool isPredicatedTrue(const MachineInstr &MI) const
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
bool verify(const MachineRegisterInfo *MRI=nullptr) const
Walks the interval and assert if any invariants fail to hold.
LLVM_ABI void computeSubRangeUndefs(SmallVectorImpl< SlotIndex > &Undefs, LaneBitmask LaneMask, const MachineRegisterInfo &MRI, const SlotIndexes &Indexes) const
For a given lane mask LaneMask, compute indexes at which the lane is marked undefined by subregister ...
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndexes * getSlotIndexes() const
void RemoveMachineInstrFromMaps(MachineInstr &MI)
VNInfo::Allocator & getVNInfoAllocator()
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void constructMainRangeFromSubranges(LiveInterval &LI)
For live interval LI with correct SubRanges construct matching information for the main live range.
LiveInterval & createEmptyInterval(Register Reg)
Interval creation.
LLVM_ABI void extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
LLVM_ABI void print(raw_ostream &O) const
Implement the dump method.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
LLVM_ABI void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void clearKillInfo()
Clears kill flags on all operands.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
@ MO_TargetIndex
Target-dependent index+offset operand.
@ MO_FPImmediate
Floating-point immediate operand.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isIntReg(MCRegister Reg)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Undef
Value of the register doesn't matter.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createHexagonExpandCondsets()
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
iterator_range< SplittingIterator > split(StringRef Str, StringRef Separator)
Split the specified string over a separator and return a range-compatible iterable over its partition...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
@ Sub
Subtraction of integers.
char & HexagonExpandCondsetsID
DWARFExpression::Operation Op
LLVM_ABI 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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.