diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1517,6 +1517,10 @@ /// instruction to this instruction. void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI); + /// Union implicit register operands from specified + /// instruction to this instruction. + void unionImplicitOps(MachineFunction &MF, const MachineInstr &MI); + /// Debugging support /// @{ /// Determine the generic type to be printed (if needed) on uses and defs. diff --git a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h --- a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -305,6 +305,13 @@ return *this; } + /// Union all the implicit operands from OtherMI onto this one. + const MachineInstrBuilder & + unionImplicitOps(const MachineInstr &OtherMI) const { + MI->unionImplicitOps(*MF, OtherMI); + return *this; + } + bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const { diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -1430,6 +1431,25 @@ } } +/// unionImplicitOps - Union implicit register operands from specified +/// instruction to this instruction. The instruction shouldn't have RegMask +/// operand. +void MachineInstr::unionImplicitOps(MachineFunction &MF, + const MachineInstr &MI) { + SmallSet ImpRegSet; + for (const MachineOperand &MO : implicit_operands()) { + if (MO.isReg()) + ImpRegSet.insert(MO.getReg()); + } + + for (const MachineOperand &MO : MI.implicit_operands()) { + assert(!MO.isRegMask() && "Don't support union for RegMask operand"); + + if (MO.isReg() && !ImpRegSet.count(MO.getReg())) + addOperand(MF, MO); + } +} + bool MachineInstr::hasComplexRegisterTies() const { const MCInstrDesc &MCID = getDesc(); for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {