aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/MachineRegisterInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen/MachineRegisterInfo.h')
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h149
1 files changed, 109 insertions, 40 deletions
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 04191bc1b74f..07d2d016f274 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -16,7 +16,10 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator_range.h"
+// PointerUnion needs to have access to the full RegisterBank type.
+#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -26,6 +29,10 @@
namespace llvm {
class PSetIterator;
+/// Convenient type to represent either a register class or a register bank.
+typedef PointerUnion<const TargetRegisterClass *, const RegisterBank *>
+ RegClassOrRegBank;
+
/// MachineRegisterInfo - Keep track of information for virtual and physical
/// registers, including vreg register classes, use/def chains for registers,
/// etc.
@@ -40,18 +47,9 @@ public:
};
private:
- const MachineFunction *MF;
+ MachineFunction *MF;
Delegate *TheDelegate;
- /// IsSSA - True when the machine function is in SSA form and virtual
- /// registers have a single def.
- bool IsSSA;
-
- /// TracksLiveness - True while register liveness is being tracked accurately.
- /// Basic block live-in lists, kill flags, and implicit defs may not be
- /// accurate when after this flag is cleared.
- bool TracksLiveness;
-
/// True if subregister liveness is tracked.
bool TracksSubRegLiveness;
@@ -59,8 +57,9 @@ private:
///
/// Each element in this list contains the register class of the vreg and the
/// start of the use/def list for the register.
- IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
- VirtReg2IndexFunctor> VRegInfo;
+ IndexedMap<std::pair<RegClassOrRegBank, MachineOperand *>,
+ VirtReg2IndexFunctor>
+ VRegInfo;
/// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and hint type
@@ -105,6 +104,18 @@ private:
/// started.
BitVector ReservedRegs;
+ typedef DenseMap<unsigned, unsigned> VRegToSizeMap;
+ /// Map generic virtual registers to their actual size.
+ mutable std::unique_ptr<VRegToSizeMap> VRegToSize;
+
+ /// Accessor for VRegToSize. This accessor should only be used
+ /// by global-isel related work.
+ VRegToSizeMap &getVRegToSize() const {
+ if (!VRegToSize)
+ VRegToSize.reset(new VRegToSizeMap);
+ return *VRegToSize.get();
+ }
+
/// Keep track of the physical registers that are live in to the function.
/// Live in values are typically arguments in registers. LiveIn values are
/// allowed to have virtual registers associated with them, stored in the
@@ -114,7 +125,7 @@ private:
MachineRegisterInfo(const MachineRegisterInfo&) = delete;
void operator=(const MachineRegisterInfo&) = delete;
public:
- explicit MachineRegisterInfo(const MachineFunction *MF);
+ explicit MachineRegisterInfo(MachineFunction *MF);
const TargetRegisterInfo *getTargetRegisterInfo() const {
return MF->getSubtarget().getRegisterInfo();
@@ -148,27 +159,32 @@ public:
// The TwoAddressInstructionPass and PHIElimination passes take the machine
// function out of SSA form when they introduce multiple defs per virtual
// register.
- bool isSSA() const { return IsSSA; }
+ bool isSSA() const {
+ return MF->getProperties().hasProperty(
+ MachineFunctionProperties::Property::IsSSA);
+ }
// leaveSSA - Indicates that the machine function is no longer in SSA form.
- void leaveSSA() { IsSSA = false; }
+ void leaveSSA() {
+ MF->getProperties().clear(MachineFunctionProperties::Property::IsSSA);
+ }
/// tracksLiveness - Returns true when tracking register liveness accurately.
- ///
- /// While this flag is true, register liveness information in basic block
- /// live-in lists and machine instruction operands is accurate. This means it
- /// can be used to change the code in ways that affect the values in
- /// registers, for example by the register scavenger.
- ///
- /// When this flag is false, liveness is no longer reliable.
- bool tracksLiveness() const { return TracksLiveness; }
+ /// (see MachineFUnctionProperties::Property description for details)
+ bool tracksLiveness() const {
+ return MF->getProperties().hasProperty(
+ MachineFunctionProperties::Property::TracksLiveness);
+ }
/// invalidateLiveness - Indicates that register liveness is no longer being
/// tracked accurately.
///
/// This should be called by late passes that invalidate the liveness
/// information.
- void invalidateLiveness() { TracksLiveness = false; }
+ void invalidateLiveness() {
+ MF->getProperties().clear(
+ MachineFunctionProperties::Property::TracksLiveness);
+ }
/// Returns true if liveness for register class @p RC should be tracked at
/// the subregister level.
@@ -375,8 +391,8 @@ public:
/// specified register (it may be live-in).
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
- /// hasOneDef - Return true if there is exactly one instruction defining the
- /// specified register.
+ /// Return true if there is exactly one operand defining the specified
+ /// register.
bool hasOneDef(unsigned RegNo) const {
def_iterator DI = def_begin(RegNo);
if (DI == def_end())
@@ -551,9 +567,47 @@ public:
// Virtual Register Info
//===--------------------------------------------------------------------===//
- /// getRegClass - Return the register class of the specified virtual register.
+ /// Return the register class of the specified virtual register.
+ /// This shouldn't be used directly unless \p Reg has a register class.
+ /// \see getRegClassOrNull when this might happen.
///
const TargetRegisterClass *getRegClass(unsigned Reg) const {
+ assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() &&
+ "Register class not set, wrong accessor");
+ return VRegInfo[Reg].first.get<const TargetRegisterClass *>();
+ }
+
+ /// Return the register class of \p Reg, or null if Reg has not been assigned
+ /// a register class yet.
+ ///
+ /// \note A null register class can only happen when these two
+ /// conditions are met:
+ /// 1. Generic virtual registers are created.
+ /// 2. The machine function has not completely been through the
+ /// instruction selection process.
+ /// None of this condition is possible without GlobalISel for now.
+ /// In other words, if GlobalISel is not used or if the query happens after
+ /// the select pass, using getRegClass is safe.
+ const TargetRegisterClass *getRegClassOrNull(unsigned Reg) const {
+ const RegClassOrRegBank &Val = VRegInfo[Reg].first;
+ return Val.dyn_cast<const TargetRegisterClass *>();
+ }
+
+ /// Return the register bank of \p Reg, or null if Reg has not been assigned
+ /// a register bank or has been assigned a register class.
+ /// \note It is possible to get the register bank from the register class via
+ /// RegisterBankInfo::getRegBankFromRegClass.
+ ///
+ const RegisterBank *getRegBankOrNull(unsigned Reg) const {
+ const RegClassOrRegBank &Val = VRegInfo[Reg].first;
+ return Val.dyn_cast<const RegisterBank *>();
+ }
+
+ /// Return the register bank or register class of \p Reg.
+ /// \note Before the register bank gets assigned (i.e., before the
+ /// RegBankSelect pass) \p Reg may not have either.
+ ///
+ const RegClassOrRegBank &getRegClassOrRegBank(unsigned Reg) const {
return VRegInfo[Reg].first;
}
@@ -561,6 +615,10 @@ public:
///
void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
+ /// Set the register bank to \p RegBank for \p Reg.
+ ///
+ void setRegBank(unsigned Reg, const RegisterBank &RegBank);
+
/// constrainRegClass - Constrain the register class of the specified virtual
/// register to be a common subclass of RC and the current register class,
/// but only if the new class has at least MinNumRegs registers. Return the
@@ -587,6 +645,19 @@ public:
///
unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
+ /// Get the size in bits of \p VReg or 0 if VReg is not a generic
+ /// (target independent) virtual register.
+ unsigned getSize(unsigned VReg) const;
+
+ /// Set the size in bits of \p VReg to \p Size.
+ /// Although the size should be set at build time, mir infrastructure
+ /// is not yet able to do it.
+ void setSize(unsigned VReg, unsigned Size);
+
+ /// Create and return a new generic virtual register with a size of \p Size.
+ /// \pre Size > 0.
+ unsigned createGenericVirtualRegister(unsigned Size);
+
/// getNumVirtRegs - Return the number of virtual registers created.
///
unsigned getNumVirtRegs() const { return VRegInfo.size(); }
@@ -632,9 +703,10 @@ public:
/// Return true if the specified register is modified in this function.
/// This checks that no defining machine operands exist for the register or
/// any of its aliases. Definitions found on functions marked noreturn are
- /// ignored. The register is also considered modified when it is set in the
- /// UsedPhysRegMask.
- bool isPhysRegModified(unsigned PhysReg) const;
+ /// ignored, to consider them pass 'true' for optional parameter
+ /// SkipNoReturnDef. The register is also considered modified when it is set
+ /// in the UsedPhysRegMask.
+ bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef = false) const;
/// Return true if the specified register is modified or read in this
/// function. This checks that no machine operands exist for the register or
@@ -820,10 +892,10 @@ public:
advance();
} while (Op && Op->getParent() == P);
} else if (ByBundle) {
- MachineInstr *P = getBundleStart(Op->getParent());
+ MachineInstr &P = getBundleStart(*Op->getParent());
do {
advance();
- } while (Op && getBundleStart(Op->getParent()) == P);
+ } while (Op && &getBundleStart(*Op->getParent()) == &P);
}
return *this;
@@ -922,10 +994,10 @@ public:
advance();
} while (Op && Op->getParent() == P);
} else if (ByBundle) {
- MachineInstr *P = getBundleStart(Op->getParent());
+ MachineInstr &P = getBundleStart(*Op->getParent());
do {
advance();
- } while (Op && getBundleStart(Op->getParent()) == P);
+ } while (Op && &getBundleStart(*Op->getParent()) == &P);
}
return *this;
@@ -937,15 +1009,12 @@ public:
// Retrieve a reference to the current operand.
MachineInstr &operator*() const {
assert(Op && "Cannot dereference end iterator!");
- if (ByBundle) return *(getBundleStart(Op->getParent()));
+ if (ByBundle)
+ return getBundleStart(*Op->getParent());
return *Op->getParent();
}
- MachineInstr *operator->() const {
- assert(Op && "Cannot dereference end iterator!");
- if (ByBundle) return getBundleStart(Op->getParent());
- return Op->getParent();
- }
+ MachineInstr *operator->() const { return &operator*(); }
};
};