summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRoman Tereshin <rtereshin@apple.com>2018-06-12 18:30:37 +0000
committerRoman Tereshin <rtereshin@apple.com>2018-06-12 18:30:37 +0000
commitb2d3f2e5da501e8d3eea6ddaaad07fc6dc924114 (patch)
tree71b67110015f82af7db3e2bab630e91f25e4b409 /llvm/lib
parent00f2cb1116c4efd972c5ed72e641cdfebc47a1e2 (diff)
downloadbcm5719-llvm-b2d3f2e5da501e8d3eea6ddaaad07fc6dc924114.tar.gz
bcm5719-llvm-b2d3f2e5da501e8d3eea6ddaaad07fc6dc924114.zip
[MIR][MachineCSE] Implementing proper MachineInstr::getNumExplicitDefs()
Apparently, MachineInstr class definition as well as pretty much all of the machine passes assume that the only kind of MachineInstr's operands that is variadic for variadic opcodes is explicit non-definitions. In particular, this assumption is made by MachineInstr::defs(), uses(), and explicit_uses() methods, as well as by MachineCSE pass. The assumption is incorrect judging from at least TableGen backend implementation, that recognizes variable_ops in OutOperandList, and the very existence of G_UNMERGE_VALUES generic opcode, or ARM load multiple instructions, all of which have variadic defs. In particular, MachineCSE pass breaks MIR with CSE'able G_UNMERGE_VALUES instructions in it. This commit implements MachineInstr::getNumExplicitDefs() similar to pre-existing MachineInstr::getNumExplicitOperands(), fixes MachineInstr::defs(), uses(), and explicit_uses(), and fixes MachineCSE pass. As the issue addressed seems to affect only machine passes that could be ran mid-GlobalISel pipeline at the moment, the other passes aren't fixed by this commit, like MachineLICM: that could be done on per-pass basis when (if ever) they get adopted for GlobalISel. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D45640 llvm-svn: 334520
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/MachineCSE.cpp3
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp30
2 files changed, 25 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index cca4aa86bb0..6c92b1d426d 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -550,8 +550,7 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
// Check if it's profitable to perform this CSE.
bool DoCSE = true;
- unsigned NumDefs = MI->getDesc().getNumDefs() +
- MI->getDesc().getNumImplicitDefs();
+ unsigned NumDefs = MI->getNumDefs();
for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 9686018b1fe..e4a3c5b0470 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -519,21 +519,39 @@ void MachineInstr::eraseFromBundle() {
getParent()->erase_instr(this);
}
-/// getNumExplicitOperands - Returns the number of non-implicit operands.
-///
unsigned MachineInstr::getNumExplicitOperands() const {
unsigned NumOperands = MCID->getNumOperands();
if (!MCID->isVariadic())
return NumOperands;
- for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = getOperand(i);
- if (!MO.isReg() || !MO.isImplicit())
- NumOperands++;
+ for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) {
+ const MachineOperand &MO = getOperand(I);
+ // The operands must always be in the following order:
+ // - explicit reg defs,
+ // - other explicit operands (reg uses, immediates, etc.),
+ // - implicit reg defs
+ // - implicit reg uses
+ if (MO.isReg() && MO.isImplicit())
+ break;
+ ++NumOperands;
}
return NumOperands;
}
+unsigned MachineInstr::getNumExplicitDefs() const {
+ unsigned NumDefs = MCID->getNumDefs();
+ if (!MCID->isVariadic())
+ return NumDefs;
+
+ for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) {
+ const MachineOperand &MO = getOperand(I);
+ if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
+ break;
+ ++NumDefs;
+ }
+ return NumDefs;
+}
+
void MachineInstr::bundleWithPred() {
assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
setFlag(BundledPred);
OpenPOWER on IntegriCloud