diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -64,6 +64,14 @@ using ParamLoadedValue = std::pair; +struct DestSourcePair { + const MachineOperand *Destination; + const MachineOperand *Source; + + DestSourcePair(const MachineOperand &Dest, const MachineOperand &Src) + : Destination(&Dest), Source(&Src) {} +}; + //--------------------------------------------------------------------------- /// /// TargetInstrInfo - Interface to description of machine instruction set @@ -918,41 +926,36 @@ } protected: - /// Target-dependent implemenation for IsCopyInstr. + /// Target-dependent implementation for IsCopyInstr. /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - virtual bool isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Source, - const MachineOperand *&Destination) const { - return false; + /// value from one register to another register return destination and source + /// registers as machine operands. + virtual Optional + isCopyInstrImpl(const MachineInstr &MI) const { + return None; } public: /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - /// For COPY-instruction the method naturally returns true, for all other - /// instructions the method calls target-dependent implementation. - bool isCopyInstr(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const { + /// value from one register to another register return destination and source + /// registers as machine operands. + /// For COPY-instruction the method naturally returns destination and source + /// registers as machine operands, for all other instructions the method calls + /// target-dependent implementation. + Optional isCopyInstr(const MachineInstr &MI) const { if (MI.isCopy()) { - Destination = &MI.getOperand(0); - Source = &MI.getOperand(1); - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; } - return isCopyInstrImpl(MI, Source, Destination); + return isCopyInstrImpl(MI); } /// If the specific machine instruction is an instruction that adds an - /// immediate value to its \c Source operand and stores it in \c Destination, - /// return true along with \c Destination and \c Source machine operand to - /// which \c Offset has been added. - virtual bool isAddImmediate(const MachineInstr &MI, - const MachineOperand *&Destination, - const MachineOperand *&Source, - int64_t &Offset) const { - return false; + /// immediate value to its source operand and stores it in destination, + /// return destination and source registers as machine operands along with + /// \c Offset which has been added. + virtual Optional isAddImmediate(const MachineInstr &MI, + int64_t &Offset) const { + return None; } /// Store the specified register of the given register class to the specified diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp --- a/llvm/lib/CodeGen/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues.cpp @@ -997,10 +997,14 @@ OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs, TransferMap &Transfers) { - const MachineOperand *SrcRegOp, *DestRegOp; - if (!TII->isCopyInstr(MI, SrcRegOp, DestRegOp) || !SrcRegOp->isKill() || - !DestRegOp->isDef()) + auto DestSrc = TII->isCopyInstr(MI); + if (!DestSrc) + return; + + const MachineOperand *DestRegOp = DestSrc->Destination; + const MachineOperand *SrcRegOp = DestSrc->Source; + if (!SrcRegOp->isKill() || !DestRegOp->isDef()) return; auto isCalleeSavedReg = [&](unsigned Reg) { diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -1124,14 +1124,13 @@ TargetInstrInfo::describeLoadedValue(const MachineInstr &MI) const { const MachineFunction *MF = MI.getMF(); DIExpression *Expr = DIExpression::get(MF->getFunction().getContext(), {}); - const MachineOperand *SrcRegOp, *DestRegOp; int64_t Offset; - if (isCopyInstr(MI, SrcRegOp, DestRegOp)) { - return ParamLoadedValue(*SrcRegOp, Expr); - } else if (isAddImmediate(MI, DestRegOp, SrcRegOp, Offset)) { + if (auto DestSrc = isCopyInstr(MI)) { + return ParamLoadedValue(*DestSrc->Source, Expr); + } else if (auto DestSrc = isAddImmediate(MI, Offset)) { Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, Offset); - return ParamLoadedValue(*SrcRegOp, Expr); + return ParamLoadedValue(*DestSrc->Source, Expr); } return None; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -265,10 +265,8 @@ /// on Windows. static bool isSEHInstruction(const MachineInstr &MI); - bool isAddImmediate(const MachineInstr &MI, - const MachineOperand *&Destination, - const MachineOperand *&Source, - int64_t &Offset) const override; + Optional isAddImmediate(const MachineInstr &MI, + int64_t &Offset) const override; Optional describeLoadedValue(const MachineInstr &MI) const override; @@ -277,11 +275,11 @@ #include "AArch64GenInstrInfo.inc" protected: - /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const override; + /// If the specific machine instruction is an instruction that moves/copies + /// value from one register to another register return destination and source + /// registers as machine operands. + Optional + isCopyInstrImpl(const MachineInstr &MI) const override; private: /// Sets the offsets on outlined instructions in \p MBB which use SP diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5702,39 +5702,33 @@ return MF.getFunction().hasMinSize(); } -bool AArch64InstrInfo::isCopyInstrImpl( - const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const { +Optional +AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { // AArch64::ORRWrs and AArch64::ORRXrs with WZR/XZR reg // and zero immediate operands used as an alias for mov instruction. if (MI.getOpcode() == AArch64::ORRWrs && MI.getOperand(1).getReg() == AArch64::WZR && MI.getOperand(3).getImm() == 0x0) { - Destination = &MI.getOperand(0); - Source = &MI.getOperand(2); - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; } if (MI.getOpcode() == AArch64::ORRXrs && MI.getOperand(1).getReg() == AArch64::XZR && MI.getOperand(3).getImm() == 0x0) { - Destination = &MI.getOperand(0); - Source = &MI.getOperand(2); - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; } - return false; + return None; } -bool AArch64InstrInfo::isAddImmediate(const MachineInstr &MI, - const MachineOperand *&Destination, - const MachineOperand *&Source, - int64_t &Offset) const { +Optional +AArch64InstrInfo::isAddImmediate(const MachineInstr &MI, + int64_t &Offset) const { int Sign = 1; switch (MI.getOpcode()) { default: - return false; + return None; case AArch64::SUBWri: case AArch64::SUBXri: case AArch64::SUBSWri: @@ -5748,16 +5742,14 @@ // TODO: Third operand can be global address (usually some string). if (!MI.getOperand(0).isReg() || !MI.getOperand(1).isReg() || !MI.getOperand(2).isImm()) - return false; - Source = &MI.getOperand(1); + return None; Offset = MI.getOperand(2).getImm() * Sign; int Shift = MI.getOperand(3).getImm(); assert((Shift == 0 || Shift == 12) && "Shift can be either 0 or 12"); Offset = Offset << Shift; } } - Destination = &MI.getOperand(0); - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; } Optional diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -99,12 +99,11 @@ MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override; - - /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const override; + /// If the specific machine instruction is an instruction that moves/copies + /// value from one register to another register return destination and source + /// registers as machine operands. + Optional + isCopyInstrImpl(const MachineInstr &MI) const override; public: // Return whether the target has an explicit NOP encoding. @@ -456,10 +455,8 @@ return MI.getOperand(3).getReg(); } - bool isAddImmediate(const MachineInstr &MI, - const MachineOperand *&Destination, - const MachineOperand *&Source, - int64_t &Offset) const override; + Optional isAddImmediate(const MachineInstr &MI, + int64_t &Offset) const override; }; /// Get the operands corresponding to the given \p Pred value. By default, the diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -993,9 +993,8 @@ Mov->addRegisterKilled(SrcReg, TRI); } -bool ARMBaseInstrInfo::isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Src, - const MachineOperand *&Dest) const { +Optional +ARMBaseInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { // VMOVRRD is also a copy instruction but it requires // special way of handling. It is more complex copy version // and since that we are not considering it. For recognition @@ -1006,10 +1005,8 @@ if (!MI.isMoveReg() || (MI.getOpcode() == ARM::VORRq && MI.getOperand(1).getReg() != MI.getOperand(2).getReg())) - return false; - Dest = &MI.getOperand(0); - Src = &MI.getOperand(1); - return true; + return None; + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; } const MachineInstrBuilder & @@ -5350,10 +5347,9 @@ return makeArrayRef(TargetFlags); } -bool ARMBaseInstrInfo::isAddImmediate(const MachineInstr &MI, - const MachineOperand *&Destination, - const MachineOperand *&Source, - int64_t &Offset) const { +Optional +ARMBaseInstrInfo::isAddImmediate(const MachineInstr &MI, + int64_t &Offset) const { int Sign = 1; unsigned Opcode = MI.getOpcode(); @@ -5361,19 +5357,17 @@ if (Opcode == ARM::SUBri) Sign = -1; else if (Opcode != ARM::ADDri) - return false; + return None; // TODO: Third operand can be global address (usually some string). Since // strings can be relocated we cannot calculate their offsets for // now. if (!MI.getOperand(0).isReg() || !MI.getOperand(1).isReg() || !MI.getOperand(2).isImm()) - return false; + return None; - Destination = &MI.getOperand(0); - Source = &MI.getOperand(1); Offset = MI.getOperand(2).getImm() * Sign; - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; } bool llvm::registerDefinedBetween(unsigned Reg, diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.h b/llvm/lib/Target/Mips/Mips16InstrInfo.h --- a/llvm/lib/Target/Mips/Mips16InstrInfo.h +++ b/llvm/lib/Target/Mips/Mips16InstrInfo.h @@ -104,10 +104,9 @@ protected: /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const override; + /// value from one register to another register return destination and source + /// registers as machine operands. + Optional isCopyInstrImpl(const MachineInstr &MI) const override; private: unsigned getAnalyzableBrOpc(unsigned Opc) const override; diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.cpp b/llvm/lib/Target/Mips/Mips16InstrInfo.cpp --- a/llvm/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/llvm/lib/Target/Mips/Mips16InstrInfo.cpp @@ -96,15 +96,11 @@ MIB.addReg(SrcReg, getKillRegState(KillSrc)); } -bool Mips16InstrInfo::isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Src, - const MachineOperand *&Dest) const { - if (MI.isMoveReg()) { - Dest = &MI.getOperand(0); - Src = &MI.getOperand(1); - return true; - } - return false; +Optional +Mips16InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { + if (MI.isMoveReg()) + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; + return None; } void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h @@ -77,10 +77,10 @@ protected: /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const override; + /// value from one register to another register return destination and source + /// registers as machine operands. + Optional + isCopyInstrImpl(const MachineInstr &MI) const override; private: unsigned getAnalyzableBrOpc(unsigned Opc) const override; diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -221,29 +221,24 @@ /// We check for the common case of 'or', as it's MIPS' preferred instruction /// for GPRs but we have to check the operands to ensure that is the case. /// Other move instructions for MIPS are directly identifiable. -bool MipsSEInstrInfo::isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Src, - const MachineOperand *&Dest) const { +Optional +MipsSEInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { bool isDSPControlWrite = false; // Condition is made to match the creation of WRDSP/RDDSP copy instruction // from copyPhysReg function. if (isReadOrWriteToDSPReg(MI, isDSPControlWrite)) { - if (!MI.getOperand(1).isImm() || MI.getOperand(1).getImm() != (1<<4)) - return false; + if (!MI.getOperand(1).isImm() || MI.getOperand(1).getImm() != (1 << 4)) + return None; else if (isDSPControlWrite) { - Src = &MI.getOperand(0); - Dest = &MI.getOperand(2); + return DestSourcePair{MI.getOperand(2), MI.getOperand(0)}; + } else { - Dest = &MI.getOperand(0); - Src = &MI.getOperand(2); + return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; } - return true; } else if (MI.isMoveReg() || isORCopyInst(MI)) { - Dest = &MI.getOperand(0); - Src = &MI.getOperand(1); - return true; + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; } - return false; + return None; } void MipsSEInstrInfo:: diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -542,10 +542,10 @@ unsigned CommuteOpIdx2) const override; /// If the specific machine instruction is a instruction that moves/copies - /// value from one register to another register return true along with - /// @Source machine operand and @Destination machine operand. - bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, - const MachineOperand *&Destination) const override; + /// value from one register to another register return destination and source + /// registers as machine operands. + Optional + isCopyInstrImpl(const MachineInstr &MI) const override; private: /// This is a helper for convertToThreeAddress for 8 and 16-bit instructions. diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -3046,15 +3046,11 @@ report_fatal_error("Cannot emit physreg copy instruction"); } -bool X86InstrInfo::isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Src, - const MachineOperand *&Dest) const { - if (MI.isMoveReg()) { - Dest = &MI.getOperand(0); - Src = &MI.getOperand(1); - return true; - } - return false; +Optional +X86InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { + if (MI.isMoveReg()) + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; + return None; } static unsigned getLoadStoreRegOpcode(unsigned Reg,