Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit b928706

Browse files
author
Quentin Colombet
committed
[MachineRegisterInfo] Track register bank for virtual registers.
A virtual register may have either a register bank or a register class. This is represented by a PointerUnion between the related classes. Typically, a virtual register went through the following states regarding register class and register bank: 1. Creation: None is set. Virtual registers are fully generic. 2. Register bank assignment: Register bank is set. Virtual registers live into a register bank, but we do not know the constraints they need to fulfil. 3. Instruction selection: Register class is set. Virtual registers are bound by encoding constraints. To map these states to GlobalISel, the IRTranslator implements #1, RegBankSelect #2, and Select #3. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265696 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8074e60 commit b928706

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

include/llvm/CodeGen/MachineRegisterInfo.h

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
#include "llvm/ADT/BitVector.h"
1818
#include "llvm/ADT/IndexedMap.h"
19+
#include "llvm/ADT/PointerUnion.h"
1920
#include "llvm/ADT/iterator_range.h"
21+
// PointerUnion needs to have access to the full RegisterBank type.
22+
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
2023
#include "llvm/CodeGen/MachineFunction.h"
2124
#include "llvm/CodeGen/MachineInstrBundle.h"
2225
#include "llvm/Target/TargetRegisterInfo.h"
@@ -26,6 +29,10 @@
2629
namespace llvm {
2730
class PSetIterator;
2831

32+
/// Convenient type to represent either a register class or a register bank.
33+
typedef PointerUnion<const TargetRegisterClass *, const RegisterBank *>
34+
RegClassOrRegBank;
35+
2936
/// MachineRegisterInfo - Keep track of information for virtual and physical
3037
/// registers, including vreg register classes, use/def chains for registers,
3138
/// etc.
@@ -55,8 +62,9 @@ class MachineRegisterInfo {
5562
///
5663
/// Each element in this list contains the register class of the vreg and the
5764
/// start of the use/def list for the register.
58-
IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
59-
VirtReg2IndexFunctor> VRegInfo;
65+
IndexedMap<std::pair<RegClassOrRegBank, MachineOperand *>,
66+
VirtReg2IndexFunctor>
67+
VRegInfo;
6068

6169
/// RegAllocHints - This vector records register allocation hints for virtual
6270
/// registers. For each virtual register, it keeps a register and hint type
@@ -564,16 +572,62 @@ class MachineRegisterInfo {
564572
// Virtual Register Info
565573
//===--------------------------------------------------------------------===//
566574

567-
/// getRegClass - Return the register class of the specified virtual register.
575+
/// Return the register class of the specified virtual register.
576+
/// This shouldn't be used directly unless \p Reg has a register class.
577+
/// \see getRegClassOrNull when this might happen.
568578
///
569579
const TargetRegisterClass *getRegClass(unsigned Reg) const {
580+
assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() &&
581+
"Register class not set, wrong accessor");
582+
return VRegInfo[Reg].first.get<const TargetRegisterClass *>();
583+
}
584+
585+
/// Return the register class of \p Reg, or null if Reg has not been assigned
586+
/// a register class yet.
587+
///
588+
/// \note A null register class can only happen when these two
589+
/// conditions are met:
590+
/// 1. Generic virtual registers are created.
591+
/// 2. The machine function has not completely been through the
592+
/// instruction selection process.
593+
/// None of this condition is possible without GlobalISel for now.
594+
/// In other words, if GlobalISel is not used or if the query happens after
595+
/// the select pass, using getRegClass is safe.
596+
const TargetRegisterClass *getRegClassOrNull(unsigned Reg) const {
597+
const RegClassOrRegBank &Val = VRegInfo[Reg].first;
598+
if (Val.is<const TargetRegisterClass *>())
599+
return Val.get<const TargetRegisterClass *>();
600+
return nullptr;
601+
}
602+
603+
/// Return the register bank of \p Reg, or null if Reg has not been assigned
604+
/// a register bank or has been assigned a register class.
605+
/// \note It is possible to get the register bank from the register class via
606+
/// RegisterBankInfo::getRegBankFromRegClass.
607+
///
608+
const RegisterBank *getRegBankOrNull(unsigned Reg) const {
609+
const RegClassOrRegBank &Val = VRegInfo[Reg].first;
610+
if (Val.is<const RegisterBank *>())
611+
return Val.get<const RegisterBank *>();
612+
return nullptr;
613+
}
614+
615+
/// Return the register bank or register class of \p Reg.
616+
/// \note Before the register bank gets assigned (i.e., before the
617+
/// RegBankSelect pass) \p Reg may not have either.
618+
///
619+
const RegClassOrRegBank &getRegClassOrRegBank(unsigned Reg) const {
570620
return VRegInfo[Reg].first;
571621
}
572622

573623
/// setRegClass - Set the register class of the specified virtual register.
574624
///
575625
void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
576626

627+
/// Set the register bank to \p RegBank for \p Reg.
628+
///
629+
void setRegBank(unsigned Reg, const RegisterBank &RegBank);
630+
577631
/// constrainRegClass - Constrain the register class of the specified virtual
578632
/// register to be a common subclass of RC and the current register class,
579633
/// but only if the new class has at least MinNumRegs registers. Return the

lib/CodeGen/MachineRegisterInfo.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ MachineRegisterInfo::setRegClass(unsigned Reg, const TargetRegisterClass *RC) {
4242
VRegInfo[Reg].first = RC;
4343
}
4444

45+
void MachineRegisterInfo::setRegBank(unsigned Reg,
46+
const RegisterBank &RegBank) {
47+
VRegInfo[Reg].first = &RegBank;
48+
}
49+
4550
const TargetRegisterClass *
4651
MachineRegisterInfo::constrainRegClass(unsigned Reg,
4752
const TargetRegisterClass *RC,
@@ -121,7 +126,7 @@ MachineRegisterInfo::createGenericVirtualRegister(unsigned Size) {
121126
unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
122127
VRegInfo.grow(Reg);
123128
// FIXME: Should we use a dummy register class?
124-
VRegInfo[Reg].first = nullptr;
129+
VRegInfo[Reg].first = static_cast<TargetRegisterClass *>(nullptr);
125130
getVRegToSize()[Reg] = Size;
126131
RegAllocHints.grow(Reg);
127132
if (TheDelegate)

0 commit comments

Comments
 (0)