X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstr.cpp;h=40ab4c2dd93dbd99f54a8065235f0fe0db070036;hb=69244300b8a0112efb44b6273ecea4ca6264b8cf;hp=3dce6fc85deb8f62e6b99b36625c8c107fa91d77;hpb=ca4f6ebefc4dc55d13a0182a0be5b02e92fc63ea;p=oota-llvm.git diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 3dce6fc85de..40ab4c2dd93 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1,59 +1,266 @@ -//===-- MachineInstr.cpp --------------------------------------------------===// -// +//===-- lib/CodeGen/MachineInstr.cpp --------------------------------------===// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// // // Methods common to all machine instructions. // -// FIXME: Now that MachineInstrs have parent pointers, they should always -// print themselves using their MachineFunction's TargetMachine. -// //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/Value.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Support/LeakDetector.h" -#include - +#include "llvm/Support/Streams.h" +#include using namespace llvm; -// Global variable holding an array of descriptors for machine instructions. -// The actual object needs to be created separately for each target machine. -// This variable is initialized and reset by class TargetInstrInfo. -// -// FIXME: This should be a property of the target so that more than one target -// at a time can be active... -// -namespace llvm { - extern const TargetInstrDescriptor *TargetInstrDescriptors; +//===----------------------------------------------------------------------===// +// MachineOperand Implementation +//===----------------------------------------------------------------------===// + +/// AddRegOperandToRegInfo - Add this register operand to the specified +/// MachineRegisterInfo. If it is null, then the next/prev fields should be +/// explicitly nulled out. +void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { + assert(isReg() && "Can only add reg operand to use lists"); + + // If the reginfo pointer is null, just explicitly null out or next/prev + // pointers, to ensure they are not garbage. + if (RegInfo == 0) { + Contents.Reg.Prev = 0; + Contents.Reg.Next = 0; + return; + } + + // Otherwise, add this operand to the head of the registers use/def list. + MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg()); + + // For SSA values, we prefer to keep the definition at the start of the list. + // we do this by skipping over the definition if it is at the head of the + // list. + if (*Head && (*Head)->isDef()) + Head = &(*Head)->Contents.Reg.Next; + + Contents.Reg.Next = *Head; + if (Contents.Reg.Next) { + assert(getReg() == Contents.Reg.Next->getReg() && + "Different regs on the same list!"); + Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next; + } + + Contents.Reg.Prev = Head; + *Head = this; +} + +void MachineOperand::setReg(unsigned Reg) { + if (getReg() == Reg) return; // No change. + + // Otherwise, we have to change the register. If this operand is embedded + // into a machine function, we need to update the old and new register's + // use/def lists. + if (MachineInstr *MI = getParent()) + if (MachineBasicBlock *MBB = MI->getParent()) + if (MachineFunction *MF = MBB->getParent()) { + RemoveRegOperandFromRegInfo(); + Contents.Reg.RegNo = Reg; + AddRegOperandToRegInfo(&MF->getRegInfo()); + return; + } + + // Otherwise, just change the register, no problem. :) + Contents.Reg.RegNo = Reg; +} + +/// ChangeToImmediate - Replace this operand with a new immediate operand of +/// the specified value. If an operand is known to be an immediate already, +/// the setImm method should be used. +void MachineOperand::ChangeToImmediate(int64_t ImmVal) { + // If this operand is currently a register operand, and if this is in a + // function, deregister the operand from the register's use/def list. + if (isReg() && getParent() && getParent()->getParent() && + getParent()->getParent()->getParent()) + RemoveRegOperandFromRegInfo(); + + OpKind = MO_Immediate; + Contents.ImmVal = ImmVal; +} + +/// ChangeToRegister - Replace this operand with a new register operand of +/// the specified value. If an operand is known to be an register already, +/// the setReg method should be used. +void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, + bool isKill, bool isDead) { + // If this operand is already a register operand, use setReg to update the + // register's use/def lists. + if (isReg()) { + setReg(Reg); + } else { + // Otherwise, change this to a register and set the reg#. + OpKind = MO_Register; + Contents.Reg.RegNo = Reg; + + // If this operand is embedded in a function, add the operand to the + // register's use/def list. + if (MachineInstr *MI = getParent()) + if (MachineBasicBlock *MBB = MI->getParent()) + if (MachineFunction *MF = MBB->getParent()) + AddRegOperandToRegInfo(&MF->getRegInfo()); + } + + IsDef = isDef; + IsImp = isImp; + IsKill = isKill; + IsDead = isDead; + SubReg = 0; } -// Constructor for instructions with variable #operands -MachineInstr::MachineInstr(short opcode, unsigned numOperands) - : Opcode(opcode), - numImplicitRefs(0), - operands(numOperands, MachineOperand()), - parent(0) { +/// isIdenticalTo - Return true if this operand is identical to the specified +/// operand. +bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { + if (getType() != Other.getType()) return false; + + switch (getType()) { + default: assert(0 && "Unrecognized operand type"); + case MachineOperand::MO_Register: + return getReg() == Other.getReg() && isDef() == Other.isDef() && + getSubReg() == Other.getSubReg(); + case MachineOperand::MO_Immediate: + return getImm() == Other.getImm(); + case MachineOperand::MO_MachineBasicBlock: + return getMBB() == Other.getMBB(); + case MachineOperand::MO_FrameIndex: + return getIndex() == Other.getIndex(); + case MachineOperand::MO_ConstantPoolIndex: + return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); + case MachineOperand::MO_JumpTableIndex: + return getIndex() == Other.getIndex(); + case MachineOperand::MO_GlobalAddress: + return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); + case MachineOperand::MO_ExternalSymbol: + return !strcmp(getSymbolName(), Other.getSymbolName()) && + getOffset() == Other.getOffset(); + } +} + +/// print - Print the specified machine operand. +/// +void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const { + switch (getType()) { + case MachineOperand::MO_Register: + if (getReg() == 0 || MRegisterInfo::isVirtualRegister(getReg())) { + OS << "%reg" << getReg(); + } else { + // If the instruction is embedded into a basic block, we can find the + // target info for the instruction. + if (TM == 0) + if (const MachineInstr *MI = getParent()) + if (const MachineBasicBlock *MBB = MI->getParent()) + if (const MachineFunction *MF = MBB->getParent()) + TM = &MF->getTarget(); + + if (TM) + OS << "%" << TM->getRegisterInfo()->get(getReg()).Name; + else + OS << "%mreg" << getReg(); + } + + if (isDef() || isKill() || isDead() || isImplicit()) { + OS << "<"; + bool NeedComma = false; + if (isImplicit()) { + OS << (isDef() ? "imp-def" : "imp-use"); + NeedComma = true; + } else if (isDef()) { + OS << "def"; + NeedComma = true; + } + if (isKill() || isDead()) { + if (NeedComma) OS << ","; + if (isKill()) OS << "kill"; + if (isDead()) OS << "dead"; + } + OS << ">"; + } + break; + case MachineOperand::MO_Immediate: + OS << getImm(); + break; + case MachineOperand::MO_MachineBasicBlock: + OS << "mbb<" + << ((Value*)getMBB()->getBasicBlock())->getName() + << "," << (void*)getMBB() << ">"; + break; + case MachineOperand::MO_FrameIndex: + OS << ""; + break; + case MachineOperand::MO_ConstantPoolIndex: + OS << ""; + break; + case MachineOperand::MO_JumpTableIndex: + OS << ""; + break; + case MachineOperand::MO_GlobalAddress: + OS << "getName(); + if (getOffset()) OS << "+" << getOffset(); + OS << ">"; + break; + case MachineOperand::MO_ExternalSymbol: + OS << ""; + break; + default: + assert(0 && "Unrecognized operand type"); + } +} + +//===----------------------------------------------------------------------===// +// MachineInstr Implementation +//===----------------------------------------------------------------------===// + +/// MachineInstr ctor - This constructor creates a dummy MachineInstr with +/// TID NULL and no operands. +MachineInstr::MachineInstr() + : TID(0), NumImplicitOps(0), Parent(0) { // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } -/// MachineInstr ctor - This constructor only does a _reserve_ of the operands, -/// not a resize for them. It is expected that if you use this that you call -/// add* methods below to fill up the operands, instead of the Set methods. -/// Eventually, the "resizing" ctors will be phased out. -/// -MachineInstr::MachineInstr(short opcode, unsigned numOperands, bool XX, bool YY) - : Opcode(opcode), numImplicitRefs(0), parent(0) { - operands.reserve(numOperands); +void MachineInstr::addImplicitDefUseOperands() { + if (TID->ImplicitDefs) + for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + addOperand(MachineOperand::CreateReg(*ImpDefs, true, true)); + if (TID->ImplicitUses) + for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + addOperand(MachineOperand::CreateReg(*ImpUses, false, true)); +} + +/// MachineInstr ctor - This constructor create a MachineInstr and add the +/// implicit operands. It reserves space for number of operands specified by +/// TargetInstrDescriptor or the numOperands if it is not zero. (for +/// instructions with variable number of operands). +MachineInstr::MachineInstr(const TargetInstrDescriptor &tid, bool NoImp) + : TID(&tid), NumImplicitOps(0), Parent(0) { + if (!NoImp && TID->ImplicitDefs) + for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (!NoImp && TID->ImplicitUses) + for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + TID->numOperands); + if (!NoImp) + addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } @@ -61,11 +268,18 @@ MachineInstr::MachineInstr(short opcode, unsigned numOperands, bool XX, bool YY) /// MachineInstr ctor - Work exactly the same as the ctor above, except that the /// MachineInstr is created and added to the end of the specified basic block. /// -MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode, - unsigned numOperands) - : Opcode(opcode), numImplicitRefs(0), parent(0) { +MachineInstr::MachineInstr(MachineBasicBlock *MBB, + const TargetInstrDescriptor &tid) + : TID(&tid), NumImplicitOps(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); - operands.reserve(numOperands); + if (TID->ImplicitDefs) + for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (TID->ImplicitUses) + for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + TID->numOperands); + addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); MBB->push_back(this); // Add instruction to end of basic block! @@ -74,416 +288,339 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(const MachineInstr &MI) { - Opcode = MI.getOpcode(); - numImplicitRefs = MI.getNumImplicitRefs(); - operands.reserve(MI.getNumOperands()); + TID = MI.getDesc(); + NumImplicitOps = MI.NumImplicitOps; + Operands.reserve(MI.getNumOperands()); // Add operands - for (unsigned i = 0; i < MI.getNumOperands(); ++i) - operands.push_back(MachineOperand(MI.getOperand(i))); + for (unsigned i = 0; i != MI.getNumOperands(); ++i) { + Operands.push_back(MI.getOperand(i)); + Operands.back().ParentMI = this; + } // Set parent, next, and prev to null - parent = 0; - prev = 0; - next = 0; + Parent = 0; + Prev = 0; + Next = 0; } MachineInstr::~MachineInstr() { LeakDetector::removeGarbageObject(this); +#ifndef NDEBUG + for (unsigned i = 0, e = Operands.size(); i != e; ++i) { + assert(Operands[i].ParentMI == this && "ParentMI mismatch!"); + assert((!Operands[i].isReg() || !Operands[i].isOnRegUseList()) && + "Reg operand def/use list corrupted"); + } +#endif } -/// clone - Create a copy of 'this' instruction that is identical in all ways -/// except the following: the new instruction has no parent and it has no name -/// -MachineInstr* MachineInstr::clone() const { - return new MachineInstr(*this); -} - -/// OperandComplete - Return true if it's illegal to add a new operand +/// getOpcode - Returns the opcode of this MachineInstr. /// -bool MachineInstr::OperandsComplete() const { - int NumOperands = TargetInstrDescriptors[Opcode].numOperands; - if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands) - return true; // Broken: we have all the operands of this instruction! - return false; +int MachineInstr::getOpcode() const { + return TID->Opcode; } -/// replace - Support for replacing opcode and operands of a MachineInstr in -/// place. This only resets the size of the operand vector and initializes it. -/// The new operands must be set explicitly later. -/// -void MachineInstr::replace(short opcode, unsigned numOperands) { - assert(getNumImplicitRefs() == 0 && - "This is probably broken because implicit refs are going to be lost."); - Opcode = opcode; - operands.clear(); - operands.resize(numOperands, MachineOperand()); +/// getRegInfo - If this instruction is embedded into a MachineFunction, +/// return the MachineRegisterInfo object for the current function, otherwise +/// return null. +MachineRegisterInfo *MachineInstr::getRegInfo() { + if (MachineBasicBlock *MBB = getParent()) + if (MachineFunction *MF = MBB->getParent()) + return &MF->getRegInfo(); + return 0; } -void MachineInstr::SetMachineOperandVal(unsigned i, - MachineOperand::MachineOperandType opTy, - Value* V) { - assert(i < operands.size()); // may be explicit or implicit op - operands[i].opType = opTy; - operands[i].contents.value = V; - operands[i].extra.regNum = -1; +/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in +/// this instruction from their respective use lists. This requires that the +/// operands already be on their use lists. +void MachineInstr::RemoveRegOperandsFromUseLists() { + for (unsigned i = 0, e = Operands.size(); i != e; ++i) { + if (Operands[i].isReg()) + Operands[i].RemoveRegOperandFromRegInfo(); + } } -void -MachineInstr::SetMachineOperandConst(unsigned i, - MachineOperand::MachineOperandType opTy, - int intValue) { - assert(i < getNumOperands()); // must be explicit op - assert(TargetInstrDescriptors[Opcode].resultPos != (int) i && - "immed. constant cannot be defined"); - - operands[i].opType = opTy; - operands[i].contents.value = NULL; - operands[i].contents.immedVal = intValue; - operands[i].extra.regNum = -1; - operands[i].flags = 0; +/// AddRegOperandsToUseLists - Add all of the register operands in +/// this instruction from their respective use lists. This requires that the +/// operands not be on their use lists yet. +void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) { + for (unsigned i = 0, e = Operands.size(); i != e; ++i) { + if (Operands[i].isReg()) + Operands[i].AddRegOperandToRegInfo(&RegInfo); + } } -void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) { - assert(i < getNumOperands()); // must be explicit op - - operands[i].opType = MachineOperand::MO_MachineRegister; - operands[i].contents.value = NULL; - operands[i].extra.regNum = regNum; -} -// Used only by the SPARC back-end. -void MachineInstr::SetRegForOperand(unsigned i, int regNum) { - assert(i < getNumOperands()); // must be explicit op - operands[i].setRegForValue(regNum); -} +/// addOperand - Add the specified operand to the instruction. If it is an +/// implicit operand, it is added to the end of the operand list. If it is +/// an explicit operand it is added at the end of the explicit operand list +/// (before the first implicit operand). +void MachineInstr::addOperand(const MachineOperand &Op) { + bool isImpReg = Op.isReg() && Op.isImplicit(); + assert((isImpReg || !OperandsComplete()) && + "Trying to add an operand to a machine instr that is already done!"); + + // If we are adding the operand to the end of the list, our job is simpler. + // This is true most of the time, so this is a reasonable optimization. + if (isImpReg || NumImplicitOps == 0) { + // We can only do this optimization if we know that the operand list won't + // reallocate. + if (Operands.empty() || Operands.size()+1 <= Operands.capacity()) { + Operands.push_back(Op); + + // Set the parent of the operand. + Operands.back().ParentMI = this; + + // If the operand is a register, update the operand's use list. + if (Op.isReg()) + Operands.back().AddRegOperandToRegInfo(getRegInfo()); + return; + } + } + + // Otherwise, we have to insert a real operand before any implicit ones. + unsigned OpNo = Operands.size()-NumImplicitOps; + + MachineRegisterInfo *RegInfo = getRegInfo(); + + // If this instruction isn't embedded into a function, then we don't need to + // update any operand lists. + if (RegInfo == 0) { + // Simple insertion, no reginfo update needed for other register operands. + Operands.insert(Operands.begin()+OpNo, Op); + Operands[OpNo].ParentMI = this; + + // Do explicitly set the reginfo for this operand though, to ensure the + // next/prev fields are properly nulled out. + if (Operands[OpNo].isReg()) + Operands[OpNo].AddRegOperandToRegInfo(0); + + } else if (Operands.size()+1 <= Operands.capacity()) { + // Otherwise, we have to remove register operands from their register use + // list, add the operand, then add the register operands back to their use + // list. This also must handle the case when the operand list reallocates + // to somewhere else. + + // If insertion of this operand won't cause reallocation of the operand + // list, just remove the implicit operands, add the operand, then re-add all + // the rest of the operands. + for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { + assert(Operands[i].isReg() && "Should only be an implicit reg!"); + Operands[i].RemoveRegOperandFromRegInfo(); + } + + // Add the operand. If it is a register, add it to the reg list. + Operands.insert(Operands.begin()+OpNo, Op); + Operands[OpNo].ParentMI = this; -// Used only by the SPARC back-end. -void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) { - getImplicitOp(i).setRegForValue(regNum); + if (Operands[OpNo].isReg()) + Operands[OpNo].AddRegOperandToRegInfo(RegInfo); + + // Re-add all the implicit ops. + for (unsigned i = OpNo+1, e = Operands.size(); i != e; ++i) { + assert(Operands[i].isReg() && "Should only be an implicit reg!"); + Operands[i].AddRegOperandToRegInfo(RegInfo); + } + } else { + // Otherwise, we will be reallocating the operand list. Remove all reg + // operands from their list, then readd them after the operand list is + // reallocated. + RemoveRegOperandsFromUseLists(); + + Operands.insert(Operands.begin()+OpNo, Op); + Operands[OpNo].ParentMI = this; + + // Re-add all the operands. + AddRegOperandsToUseLists(*RegInfo); + } } -/// substituteValue - Substitute all occurrences of Value* oldVal with newVal -/// in all operands and all implicit refs. If defsOnly == true, substitute defs -/// only. -/// -/// FIXME: Fold this into its single caller, at SparcInstrSelection.cpp:2865, -/// or make it a static function in that file. +/// RemoveOperand - Erase an operand from an instruction, leaving it with one +/// fewer operand than it started with. /// -unsigned -MachineInstr::substituteValue(const Value* oldVal, Value* newVal, - bool defsOnly, bool notDefsAndUses, - bool& someArgsWereIgnored) -{ - assert((!defsOnly || !notDefsAndUses) && - "notDefsAndUses is irrelevant if defsOnly == true."); +void MachineInstr::RemoveOperand(unsigned OpNo) { + assert(OpNo < Operands.size() && "Invalid operand number"); + + // Special case removing the last one. + if (OpNo == Operands.size()-1) { + // If needed, remove from the reg def/use list. + if (Operands.back().isReg() && Operands.back().isOnRegUseList()) + Operands.back().RemoveRegOperandFromRegInfo(); + + Operands.pop_back(); + return; + } + + // Otherwise, we are removing an interior operand. If we have reginfo to + // update, remove all operands that will be shifted down from their reg lists, + // move everything down, then re-add them. + MachineRegisterInfo *RegInfo = getRegInfo(); + if (RegInfo) { + for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { + if (Operands[i].isReg()) + Operands[i].RemoveRegOperandFromRegInfo(); + } + } - unsigned numSubst = 0; - - // Substitute operands - for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O) - if (*O == oldVal) - if (!defsOnly || - notDefsAndUses && (O.isDef() && !O.isUse()) || - !notDefsAndUses && O.isDef()) - { - O.getMachineOperand().contents.value = newVal; - ++numSubst; - } else - someArgsWereIgnored = true; - - // Substitute implicit refs - for (unsigned i = 0, N = getNumImplicitRefs(); i < N; ++i) - if (getImplicitRef(i) == oldVal) { - MachineOperand Op = getImplicitOp(i); - if (!defsOnly || - notDefsAndUses && (Op.isDef() && !Op.isUse()) || - !notDefsAndUses && Op.isDef()) - { - Op.contents.value = newVal; - ++numSubst; - } else - someArgsWereIgnored = true; + Operands.erase(Operands.begin()+OpNo); + + if (RegInfo) { + for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { + if (Operands[i].isReg()) + Operands[i].AddRegOperandToRegInfo(RegInfo); } - return numSubst; + } } -void MachineInstr::dump() const { - std::cerr << " " << *this; + +/// removeFromParent - This method unlinks 'this' from the containing basic +/// block, and returns it, but does not delete it. +MachineInstr *MachineInstr::removeFromParent() { + assert(getParent() && "Not embedded in a basic block!"); + getParent()->remove(this); + return this; } -static inline std::ostream& OutputValue(std::ostream &os, const Value* val) { - os << "(val "; - os << (void*) val; // print address always - if (val && val->hasName()) - os << " " << val->getName(); // print name also, if available - os << ")"; - return os; + +/// OperandComplete - Return true if it's illegal to add a new operand +/// +bool MachineInstr::OperandsComplete() const { + unsigned short NumOperands = TID->numOperands; + if ((TID->Flags & M_VARIABLE_OPS) == 0 && + getNumOperands()-NumImplicitOps >= NumOperands) + return true; // Broken: we have all the operands of this instruction! + return false; } -static inline void OutputReg(std::ostream &os, unsigned RegNo, - const MRegisterInfo *MRI = 0) { - if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) { - if (MRI) - os << "%" << MRI->get(RegNo).Name; - else - os << "%mreg(" << RegNo << ")"; - } else - os << "%reg" << RegNo; +/// getNumExplicitOperands - Returns the number of non-implicit operands. +/// +unsigned MachineInstr::getNumExplicitOperands() const { + unsigned NumOperands = TID->numOperands; + if ((TID->Flags & M_VARIABLE_OPS) == 0) + return NumOperands; + + for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { + const MachineOperand &MO = getOperand(NumOperands); + if (!MO.isRegister() || !MO.isImplicit()) + NumOperands++; + } + return NumOperands; } -static void print(const MachineOperand &MO, std::ostream &OS, - const TargetMachine *TM) { - const MRegisterInfo *MRI = 0; + +/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of +/// the specific register or -1 if it is not found. It further tightening +/// the search criteria to a use that kills the register if isKill is true. +int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + const MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg) + if (!isKill || MO.isKill()) + return i; + } + return -1; +} - if (TM) MRI = TM->getRegisterInfo(); - - bool CloseParen = true; - if (MO.isHiBits32()) - OS << "%lm("; - else if (MO.isLoBits32()) - OS << "%lo("; - else if (MO.isHiBits64()) - OS << "%hh("; - else if (MO.isLoBits64()) - OS << "%hm("; - else - CloseParen = false; +/// findRegisterDefOperand() - Returns the MachineOperand that is a def of +/// the specific register or NULL if it is not found. +MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg) + return &MO; + } + return NULL; +} + +/// findFirstPredOperandIdx() - Find the index of the first operand in the +/// operand list that is used to represent the predicate. It returns -1 if +/// none is found. +int MachineInstr::findFirstPredOperandIdx() const { + const TargetInstrDescriptor *TID = getDesc(); + if (TID->isPredicable()) { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) + return i; + } + + return -1; +} - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - if (MO.getVRegValue()) { - OS << "%reg"; - OutputValue(OS, MO.getVRegValue()); - if (MO.hasAllocatedReg()) - OS << "=="; +/// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due +/// to two addr elimination. +bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const { + const TargetInstrDescriptor *TID = getDesc(); + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + const MachineOperand &MO1 = getOperand(i); + if (MO1.isRegister() && MO1.isDef() && MO1.getReg() == Reg) { + for (unsigned j = i+1; j < e; ++j) { + const MachineOperand &MO2 = getOperand(j); + if (MO2.isRegister() && MO2.isUse() && MO2.getReg() == Reg && + TID->getOperandConstraint(j, TOI::TIED_TO) == (int)i) + return true; + } } - if (MO.hasAllocatedReg()) - OutputReg(OS, MO.getReg(), MRI); - break; - case MachineOperand::MO_CCRegister: - OS << "%ccreg"; - OutputValue(OS, MO.getVRegValue()); - if (MO.hasAllocatedReg()) { - OS << "=="; - OutputReg(OS, MO.getReg(), MRI); + } + return false; +} + +/// copyKillDeadInfo - Copies kill / dead operand properties from MI. +/// +void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isRegister() || (!MO.isKill() && !MO.isDead())) + continue; + for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) { + MachineOperand &MOp = getOperand(j); + if (!MOp.isIdenticalTo(MO)) + continue; + if (MO.isKill()) + MOp.setIsKill(); + else + MOp.setIsDead(); + break; } - break; - case MachineOperand::MO_MachineRegister: - OutputReg(OS, MO.getMachineRegNum(), MRI); - break; - case MachineOperand::MO_SignExtendedImmed: - OS << (long)MO.getImmedValue(); - break; - case MachineOperand::MO_UnextendedImmed: - OS << (long)MO.getImmedValue(); - break; - case MachineOperand::MO_PCRelativeDisp: { - const Value* opVal = MO.getVRegValue(); - bool isLabel = isa(opVal) || isa(opVal); - OS << "%disp(" << (isLabel? "label " : "addr-of-val "); - if (opVal->hasName()) - OS << opVal->getName(); - else - OS << (const void*) opVal; - OS << ")"; - break; } - case MachineOperand::MO_MachineBasicBlock: - OS << "mbb<" - << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() - << "," << (void*)MO.getMachineBasicBlock() << ">"; - break; - case MachineOperand::MO_FrameIndex: - OS << ""; - break; - case MachineOperand::MO_ConstantPoolIndex: - OS << ""; - break; - case MachineOperand::MO_GlobalAddress: - OS << "getName(); - if (MO.getOffset()) OS << "+" << MO.getOffset(); - OS << ">"; - break; - case MachineOperand::MO_ExternalSymbol: - OS << ""; - break; - default: - assert(0 && "Unrecognized operand type"); +} + +/// copyPredicates - Copies predicate operand(s) from MI. +void MachineInstr::copyPredicates(const MachineInstr *MI) { + const TargetInstrDescriptor *TID = MI->getDesc(); + if (TID->isPredicable()) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) { + // Predicated operands must be last operands. + addOperand(MI->getOperand(i)); + } + } } +} - if (CloseParen) - OS << ")"; +void MachineInstr::dump() const { + cerr << " " << *this; } void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { + // Specialize printing if op#0 is definition unsigned StartOp = 0; - - // Specialize printing if op#0 is definition - if (getNumOperands() && getOperand(0).isDef() && !getOperand(0).isUse()) { - ::print(getOperand(0), OS, TM); + if (getNumOperands() && getOperand(0).isRegister() && getOperand(0).isDef()) { + getOperand(0).print(OS, TM); OS << " = "; ++StartOp; // Don't print this operand again! } - // Must check if Target machine is not null because machine BB could not - // be attached to a Machine function yet - if (TM) - OS << TM->getInstrInfo()->getName(getOpcode()); - + OS << getDesc()->Name; + for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { - const MachineOperand& mop = getOperand(i); if (i != StartOp) OS << ","; OS << " "; - ::print(mop, OS, TM); - - if (mop.isDef()) - if (mop.isUse()) - OS << ""; - else - OS << ""; - } - - // code for printing implicit references - if (getNumImplicitRefs()) { - OS << "\tImplicitRefs: "; - for (unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) { - OS << "\t"; - OutputValue(OS, getImplicitRef(i)); - if (getImplicitOp(i).isDef()) - if (getImplicitOp(i).isUse()) - OS << ""; - else - OS << ""; - } - } - - OS << "\n"; -} - -namespace llvm { -std::ostream &operator<<(std::ostream &os, const MachineInstr &MI) { - // If the instruction is embedded into a basic block, we can find the target - // info for the instruction. - if (const MachineBasicBlock *MBB = MI.getParent()) { - const MachineFunction *MF = MBB->getParent(); - if (MF) - MI.print(os, &MF->getTarget()); - else - MI.print(os, 0); - return os; + getOperand(i).print(OS, TM); } - // Otherwise, print it out in the "raw" format without symbolic register names - // and such. - os << TargetInstrDescriptors[MI.getOpcode()].Name; - - for (unsigned i = 0, N = MI.getNumOperands(); i < N; i++) { - os << "\t" << MI.getOperand(i); - if (MI.getOperand(i).isDef()) - if (MI.getOperand(i).isUse()) - os << ""; - else - os << ""; - } - - // code for printing implicit references - unsigned NumOfImpRefs = MI.getNumImplicitRefs(); - if (NumOfImpRefs > 0) { - os << "\tImplicit: "; - for (unsigned z = 0; z < NumOfImpRefs; z++) { - OutputValue(os, MI.getImplicitRef(z)); - if (MI.getImplicitOp(z).isDef()) - if (MI.getImplicitOp(z).isUse()) - os << ""; - else - os << ""; - os << "\t"; - } - } - - return os << "\n"; -} - -std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) { - if (MO.isHiBits32()) - OS << "%lm("; - else if (MO.isLoBits32()) - OS << "%lo("; - else if (MO.isHiBits64()) - OS << "%hh("; - else if (MO.isLoBits64()) - OS << "%hm("; - - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - if (MO.hasAllocatedReg()) - OutputReg(OS, MO.getReg()); - - if (MO.getVRegValue()) { - if (MO.hasAllocatedReg()) OS << "=="; - OS << "%vreg"; - OutputValue(OS, MO.getVRegValue()); - } - break; - case MachineOperand::MO_CCRegister: - OS << "%ccreg"; - OutputValue(OS, MO.getVRegValue()); - if (MO.hasAllocatedReg()) { - OS << "=="; - OutputReg(OS, MO.getReg()); - } - break; - case MachineOperand::MO_MachineRegister: - OutputReg(OS, MO.getMachineRegNum()); - break; - case MachineOperand::MO_SignExtendedImmed: - OS << (long)MO.getImmedValue(); - break; - case MachineOperand::MO_UnextendedImmed: - OS << (long)MO.getImmedValue(); - break; - case MachineOperand::MO_PCRelativeDisp: { - const Value* opVal = MO.getVRegValue(); - bool isLabel = isa(opVal) || isa(opVal); - OS << "%disp(" << (isLabel? "label " : "addr-of-val "); - if (opVal->hasName()) - OS << opVal->getName(); - else - OS << (const void*) opVal; - OS << ")"; - break; - } - case MachineOperand::MO_MachineBasicBlock: - OS << "getBasicBlock())->getName() - << "@" << (void*)MO.getMachineBasicBlock() << ">"; - break; - case MachineOperand::MO_FrameIndex: - OS << ""; - break; - case MachineOperand::MO_ConstantPoolIndex: - OS << ""; - break; - case MachineOperand::MO_GlobalAddress: - OS << "getName() << ">"; - break; - case MachineOperand::MO_ExternalSymbol: - OS << ""; - break; - default: - assert(0 && "Unrecognized operand type"); - break; - } - - if (MO.isHiBits32() || MO.isLoBits32() || MO.isHiBits64() || MO.isLoBits64()) - OS << ")"; - - return OS; + OS << "\n"; } -}