+/// Go up the super-register chain until we hit a valid dwarf register number.
+static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
+ int RegNo = TRI->getDwarfRegNum(Reg, false);
+ for (MCSuperRegIterator SR(Reg, TRI); SR.isValid() && RegNo < 0; ++SR)
+ RegNo = TRI->getDwarfRegNum(*SR, false);
+
+ assert(RegNo >= 0 && "Invalid Dwarf register number.");
+ return (unsigned) RegNo;
+}
+
+/// Create a live-out register record for the given register Reg.
+StackMaps::LiveOutReg
+StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const {
+ unsigned RegNo = getDwarfRegNum(Reg, TRI);
+ unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
+ return LiveOutReg(Reg, RegNo, Size);
+}
+
+/// Parse the register live-out mask and return a vector of live-out registers
+/// that need to be recorded in the stackmap.
+StackMaps::LiveOutVec
+StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
+ assert(Mask && "No register mask specified");
+ const TargetRegisterInfo *TRI = AP.TM.getSubtargetImpl()->getRegisterInfo();
+ LiveOutVec LiveOuts;
+
+ // Create a LiveOutReg for each bit that is set in the register mask.
+ for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg)
+ if ((Mask[Reg / 32] >> Reg % 32) & 1)
+ LiveOuts.push_back(createLiveOutReg(Reg, TRI));
+
+ // We don't need to keep track of a register if its super-register is already
+ // in the list. Merge entries that refer to the same dwarf register and use
+ // the maximum size that needs to be spilled.
+ std::sort(LiveOuts.begin(), LiveOuts.end());
+ for (LiveOutVec::iterator I = LiveOuts.begin(), E = LiveOuts.end();
+ I != E; ++I) {
+ for (LiveOutVec::iterator II = std::next(I); II != E; ++II) {
+ if (I->RegNo != II->RegNo) {
+ // Skip all the now invalid entries.
+ I = --II;
+ break;
+ }
+ I->Size = std::max(I->Size, II->Size);
+ if (TRI->isSuperRegister(I->Reg, II->Reg))
+ I->Reg = II->Reg;
+ II->MarkInvalid();
+ }
+ }
+ LiveOuts.erase(std::remove_if(LiveOuts.begin(), LiveOuts.end(),
+ LiveOutReg::IsInvalid), LiveOuts.end());
+ return LiveOuts;
+}
+
+void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,