summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineRegisterInfo.cpp
diff options
context:
space:
mode:
authorRoman Tereshin <rtereshin@apple.com>2018-10-20 00:06:15 +0000
committerRoman Tereshin <rtereshin@apple.com>2018-10-20 00:06:15 +0000
commit8d6ff4c0af843e1a61b76d89812aed91e358de34 (patch)
tree4c37f232d2aabe8250f41e5634276f4e1b0a4fc0 /llvm/lib/CodeGen/MachineRegisterInfo.cpp
parent1fc51f29d7443be52edaf17145a9608368a7154d (diff)
downloadbcm5719-llvm-8d6ff4c0af843e1a61b76d89812aed91e358de34.tar.gz
bcm5719-llvm-8d6ff4c0af843e1a61b76d89812aed91e358de34.zip
[MachineCSE][GlobalISel] Making sure MachineCSE works mid-GlobalISel (again)
Change of approach, it looks like it's a much better idea to deal with the vregs that have LLTs and reg classes both properly, than trying to avoid creating those across all GlobalISel passes and all targets. The change mostly touches MachineRegisterInfo::constrainRegClass, which is apparently only used by MachineCSE. The changes are NFC for any pipeline but one that contains MachineCSE mid-GlobalISel. NOTE on isCallerPreservedOrConstPhysReg change in MachineCSE: There is no test covering it as the only way to insert a new pass (MachineCSE) from a command line I know of is llc's -run-pass option, which only works with MIR, but MIRParser freezes reserved registers upon MachineFunctions creation, making it impossible to reproduce the state that exposes the issue. Reviwed By: aditya_nandakumar Differential Revision: https://reviews.llvm.org/D53144 llvm-svn: 344822
Diffstat (limited to 'llvm/lib/CodeGen/MachineRegisterInfo.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineRegisterInfo.cpp55
1 files changed, 22 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 1da99d91760..6e5ca45d5e5 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -93,36 +93,29 @@ bool
MachineRegisterInfo::constrainRegAttrs(unsigned Reg,
unsigned ConstrainingReg,
unsigned MinNumRegs) {
- auto const *OldRC = getRegClassOrNull(Reg);
- auto const *RC = getRegClassOrNull(ConstrainingReg);
- // A virtual register at any point must have either a low-level type
- // or a class assigned, but not both. The only exception is the internals of
- // GlobalISel's instruction selection pass, which is allowed to temporarily
- // introduce registers with types and classes both.
- assert((OldRC || getType(Reg).isValid()) && "Reg has neither class nor type");
- assert((!OldRC || !getType(Reg).isValid()) && "Reg has class and type both");
- assert((RC || getType(ConstrainingReg).isValid()) &&
- "ConstrainingReg has neither class nor type");
- assert((!RC || !getType(ConstrainingReg).isValid()) &&
- "ConstrainingReg has class and type both");
- if (OldRC && RC)
- return ::constrainRegClass(*this, Reg, OldRC, RC, MinNumRegs);
- // If one of the virtual registers is generic (used in generic machine
- // instructions, has a low-level type, doesn't have a class), and the other is
- // concrete (used in target specific instructions, doesn't have a low-level
- // type, has a class), we can not unify them.
- if (OldRC || RC)
+ const LLT RegTy = getType(Reg);
+ const LLT ConstrainingRegTy = getType(ConstrainingReg);
+ if (RegTy.isValid() && ConstrainingRegTy.isValid() &&
+ RegTy != ConstrainingRegTy)
return false;
- // At this point, both registers are guaranteed to have a valid low-level
- // type, and they must agree.
- if (getType(Reg) != getType(ConstrainingReg))
- return false;
- auto const *OldRB = getRegBankOrNull(Reg);
- auto const *RB = getRegBankOrNull(ConstrainingReg);
- if (OldRB)
- return !RB || RB == OldRB;
- if (RB)
- setRegBank(Reg, *RB);
+ const auto ConstrainingRegCB = getRegClassOrRegBank(ConstrainingReg);
+ if (!ConstrainingRegCB.isNull()) {
+ const auto RegCB = getRegClassOrRegBank(Reg);
+ if (RegCB.isNull())
+ setRegClassOrRegBank(Reg, ConstrainingRegCB);
+ else if (RegCB.is<const TargetRegisterClass *>() !=
+ ConstrainingRegCB.is<const TargetRegisterClass *>())
+ return false;
+ else if (RegCB.is<const TargetRegisterClass *>()) {
+ if (!::constrainRegClass(
+ *this, Reg, RegCB.get<const TargetRegisterClass *>(),
+ ConstrainingRegCB.get<const TargetRegisterClass *>(), MinNumRegs))
+ return false;
+ } else if (RegCB != ConstrainingRegCB)
+ return false;
+ }
+ if (ConstrainingRegTy.isValid())
+ setType(Reg, ConstrainingRegTy);
return true;
}
@@ -188,10 +181,6 @@ unsigned MachineRegisterInfo::cloneVirtualRegister(unsigned VReg,
}
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");
VRegToType.grow(VReg);
VRegToType[VReg] = Ty;
}
OpenPOWER on IntegriCloud