mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[GlobalISel] NFCI, Getting GlobalISel ~5% faster
by replacing DenseMap with IndexedMap for LLTs within MRI, as benchmarked by cross-compiling sqlite3 amalgamation for AArch64 on x86 machine. Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D46809 llvm-svn: 333125
This commit is contained in:
parent
70950ef979
commit
29117fd386
@ -136,9 +136,9 @@ private:
|
||||
/// started.
|
||||
BitVector ReservedRegs;
|
||||
|
||||
using VRegToTypeMap = DenseMap<unsigned, LLT>;
|
||||
/// Map generic virtual registers to their actual size.
|
||||
mutable std::unique_ptr<VRegToTypeMap> VRegToType;
|
||||
using VRegToTypeMap = IndexedMap<LLT, VirtReg2IndexFunctor>;
|
||||
/// Map generic virtual registers to their low-level type.
|
||||
VRegToTypeMap VRegToType;
|
||||
|
||||
/// Keep track of the physical registers that are live in to the function.
|
||||
/// Live in values are typically arguments in registers. LiveIn values are
|
||||
@ -717,17 +717,13 @@ public:
|
||||
unsigned createVirtualRegister(const TargetRegisterClass *RegClass,
|
||||
StringRef Name = "");
|
||||
|
||||
/// Accessor for VRegToType. This accessor should only be used
|
||||
/// by global-isel related work.
|
||||
VRegToTypeMap &getVRegToType() const {
|
||||
if (!VRegToType)
|
||||
VRegToType.reset(new VRegToTypeMap);
|
||||
return *VRegToType.get();
|
||||
}
|
||||
|
||||
/// Get the low-level type of \p VReg or LLT{} if VReg is not a generic
|
||||
/// Get the low-level type of \p Reg or LLT{} if Reg is not a generic
|
||||
/// (target independent) virtual register.
|
||||
LLT getType(unsigned VReg) const;
|
||||
LLT getType(unsigned Reg) const {
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg) && VRegToType.inBounds(Reg))
|
||||
return VRegToType[Reg];
|
||||
return LLT{};
|
||||
}
|
||||
|
||||
/// Set the low-level type of \p VReg to \p Ty.
|
||||
void setType(unsigned VReg, LLT Ty);
|
||||
|
@ -77,7 +77,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
// FIXME: There are many other MF/MFI fields we need to initialize.
|
||||
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
#ifndef NDEBUG
|
||||
// Check that our input is fully legal: we require the function to have the
|
||||
// Legalized property, so it should be.
|
||||
@ -167,7 +167,6 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
if (TargetRegisterInfo::isVirtualRegister(SrcReg) &&
|
||||
TargetRegisterInfo::isVirtualRegister(DstReg)) {
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
auto SrcRC = MRI.getRegClass(SrcReg);
|
||||
auto DstRC = MRI.getRegClass(DstReg);
|
||||
if (SrcRC == DstRC) {
|
||||
@ -181,27 +180,29 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
// Now that selection is complete, there are no more generic vregs. Verify
|
||||
// that the size of the now-constrained vreg is unchanged and that it has a
|
||||
// register class.
|
||||
for (auto &VRegToType : MRI.getVRegToType()) {
|
||||
unsigned VReg = VRegToType.first;
|
||||
auto *RC = MRI.getRegClassOrNull(VReg);
|
||||
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
|
||||
unsigned VReg = TargetRegisterInfo::index2VirtReg(I);
|
||||
|
||||
MachineInstr *MI = nullptr;
|
||||
if (!MRI.def_empty(VReg))
|
||||
MI = &*MRI.def_instr_begin(VReg);
|
||||
else if (!MRI.use_empty(VReg))
|
||||
MI = &*MRI.use_instr_begin(VReg);
|
||||
if (!MI)
|
||||
continue;
|
||||
|
||||
if (MI && !RC) {
|
||||
const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
|
||||
if (!RC) {
|
||||
reportGISelFailure(MF, TPC, MORE, "gisel-select",
|
||||
"VReg has no regclass after selection", *MI);
|
||||
return false;
|
||||
} else if (!RC)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (VRegToType.second.isValid() &&
|
||||
VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)) {
|
||||
reportGISelFailure(MF, TPC, MORE, "gisel-select",
|
||||
"VReg has explicit size different from class size",
|
||||
*MI);
|
||||
const LLT Ty = MRI.getType(VReg);
|
||||
if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) {
|
||||
reportGISelFailure(
|
||||
MF, TPC, MORE, "gisel-select",
|
||||
"VReg's low-level type and register class have different sizes", *MI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -234,7 +235,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
// If we successfully selected the function nothing is going to use the vreg
|
||||
// types after us (otherwise MIRPrinter would need them). Make sure the types
|
||||
// disappear.
|
||||
MRI.getVRegToType().clear();
|
||||
MRI.clearVirtRegTypes();
|
||||
|
||||
// FIXME: Should we accurately track changes?
|
||||
return true;
|
||||
|
@ -177,17 +177,13 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
|
||||
return Reg;
|
||||
}
|
||||
|
||||
LLT MachineRegisterInfo::getType(unsigned VReg) const {
|
||||
VRegToTypeMap::const_iterator TypeIt = getVRegToType().find(VReg);
|
||||
return TypeIt != getVRegToType().end() ? TypeIt->second : LLT{};
|
||||
}
|
||||
|
||||
void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) {
|
||||
// Check that VReg doesn't have a class.
|
||||
assert((getRegClassOrRegBank(VReg).isNull() ||
|
||||
!getRegClassOrRegBank(VReg).is<const TargetRegisterClass *>()) &&
|
||||
"Can't set the size of a non-generic virtual register");
|
||||
getVRegToType()[VReg] = Ty;
|
||||
VRegToType.grow(VReg);
|
||||
VRegToType[VReg] = Ty;
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -196,15 +192,13 @@ MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) {
|
||||
unsigned Reg = createIncompleteVirtualRegister(Name);
|
||||
// FIXME: Should we use a dummy register class?
|
||||
VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
|
||||
getVRegToType()[Reg] = Ty;
|
||||
setType(Reg, Ty);
|
||||
if (TheDelegate)
|
||||
TheDelegate->MRI_NoteNewVirtualRegister(Reg);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
void MachineRegisterInfo::clearVirtRegTypes() {
|
||||
getVRegToType().clear();
|
||||
}
|
||||
void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); }
|
||||
|
||||
/// clearVirtRegs - Remove all virtual registers (after physreg assignment).
|
||||
void MachineRegisterInfo::clearVirtRegs() {
|
||||
|
@ -49,7 +49,7 @@ namespace {
|
||||
// or not, nothing is going to use the vreg types after us. Make sure they
|
||||
// disappear.
|
||||
auto ClearVRegTypesOnReturn =
|
||||
make_scope_exit([&MF]() { MF.getRegInfo().getVRegToType().clear(); });
|
||||
make_scope_exit([&MF]() { MF.getRegInfo().clearVirtRegTypes(); });
|
||||
|
||||
if (MF.getProperties().hasProperty(
|
||||
MachineFunctionProperties::Property::FailedISel)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user