From a36fe736458d242e1ae4200c1a8dd42f662851fb Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 29 Feb 2012 01:40:37 +0000 Subject: [PATCH] Add an analyzeVirtReg() function. This function does more or less the same as MI::readsWritesVirtualRegister(), but it supports bundles as well. It also determines if any constraint requires reading and writing operands to use the same register. Most clients want to know. Use the more modern MO.readsReg() instead of trying to sort out undefs and partial redefines. Stop supporting the extra full operand as an alternative to sub-register defines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151690 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstrBundle.h | 33 +++++++++++++++++++++++ lib/CodeGen/MachineInstrBundle.cpp | 33 +++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h index f6525a827b5..9552e21fca2 100644 --- a/include/llvm/CodeGen/MachineInstrBundle.h +++ b/include/llvm/CodeGen/MachineInstrBundle.h @@ -107,6 +107,39 @@ public: advance(); } + /// getOperandNo - Returns the number of the current operand relative to its + /// instruction. + /// + unsigned getOperandNo() const { + return OpI - InstrI->operands_begin(); + } + + /// RegInfo - Information about a virtual register used by a set of operands. + /// + struct RegInfo { + /// Reads - One of the operands read the virtual register. This does not + /// include or use operands, see MO::readsReg(). + bool Reads; + + /// Writes - One of the operands writes the virtual register. + bool Writes; + + /// Tied - Uses and defs must use the same register. This can be because of + /// a two-address constraint, or there may be a partial redefinition of a + /// sub-register. + bool Tied; + }; + + /// analyzeVirtReg - Analyze how the current instruction or bundle uses a + /// virtual register. This function should not be called after operator++(), + /// it expects a fresh iterator. + /// + /// @param Reg The virtual register to analyze. + /// @param Ops When set, this vector will receive an (MI, OpNum) entry for + /// each operand referring to Reg. + /// @returns A filled-in RegInfo struct. + RegInfo analyzeVirtReg(unsigned Reg, + SmallVectorImpl > *Ops = 0); }; /// MIOperands - Iterate over operands of a single instruction. diff --git a/lib/CodeGen/MachineInstrBundle.cpp b/lib/CodeGen/MachineInstrBundle.cpp index d8b2b3a6cec..81d2abeb1d7 100644 --- a/lib/CodeGen/MachineInstrBundle.cpp +++ b/lib/CodeGen/MachineInstrBundle.cpp @@ -241,3 +241,36 @@ bool llvm::finalizeBundles(MachineFunction &MF) { return Changed; } + +//===----------------------------------------------------------------------===// +// MachineOperand iterator +//===----------------------------------------------------------------------===// + +MachineOperandIteratorBase::RegInfo +MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg, + SmallVectorImpl > *Ops) { + RegInfo RI = { false, false, false }; + for(; isValid(); ++*this) { + MachineOperand &MO = deref(); + if (!MO.isReg() || MO.getReg() != Reg) + continue; + + // Remember each (MI, OpNo) that refers to Reg. + if (Ops) + Ops->push_back(std::make_pair(MO.getParent(), getOperandNo())); + + // Both defs and uses can read virtual registers. + if (MO.readsReg()) { + RI.Reads = true; + if (MO.isDef()) + RI.Tied = true; + } + + // Only defs can write. + if (MO.isDef()) + RI.Writes = true; + else if (!RI.Tied && MO.getParent()->isRegTiedToDefOperand(getOperandNo())) + RI.Tied = true; + } + return RI; +}