X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstr.cpp;h=72f5a4c1420b10ea0026292ceb37848f908f1d08;hb=749c6f6b5ed301c84aac562e414486549d7b98eb;hp=8a592318c51c5db53d4c63f61e10608fcacee7bb;hpb=6f95014158208ad6cd6f6d1996c821fca61d7915;p=oota-llvm.git diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 8a592318c51..72f5a4c1420 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1,9 +1,9 @@ -//===-- 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. // //===----------------------------------------------------------------------===// // @@ -12,7 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineInstr.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" @@ -21,53 +23,244 @@ #include using namespace llvm; +//===----------------------------------------------------------------------===// +// 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; +} + +/// 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) { + : TID(0), NumImplicitOps(0), Parent(0) { // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } void MachineInstr::addImplicitDefUseOperands() { if (TID->ImplicitDefs) - for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) { - MachineOperand Op; - Op.opType = MachineOperand::MO_Register; - Op.IsDef = true; - Op.IsImp = true; - Op.IsKill = false; - Op.IsDead = false; - Op.contents.RegNo = *ImpDefs; - Operands.push_back(Op); - } + 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) { - MachineOperand Op; - Op.opType = MachineOperand::MO_Register; - Op.IsDef = false; - Op.IsImp = true; - Op.IsKill = false; - Op.IsDead = false; - Op.contents.RegNo = *ImpUses; - Operands.push_back(Op); - } + 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 +/// TargetInstrDesc or the numOperands if it is not zero. (for /// instructions with variable number of operands). -MachineInstr::MachineInstr(const TargetInstrDescriptor &tid) - : TID(&tid), NumImplicitOps(0), parent(0) { - if (TID->ImplicitDefs) - for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) +MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) + : TID(&tid), NumImplicitOps(0), Parent(0) { + if (!NoImp && TID->getImplicitDefs()) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) NumImplicitOps++; - if (TID->ImplicitUses) - for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + if (!NoImp && TID->getImplicitUses()) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) NumImplicitOps++; - Operands.reserve(NumImplicitOps + TID->numOperands); - addImplicitDefUseOperands(); + Operands.reserve(NumImplicitOps + TID->getNumOperands()); + if (!NoImp) + addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } @@ -76,16 +269,16 @@ MachineInstr::MachineInstr(const TargetInstrDescriptor &tid) /// MachineInstr is created and added to the end of the specified basic block. /// MachineInstr::MachineInstr(MachineBasicBlock *MBB, - const TargetInstrDescriptor &tid) - : TID(&tid), NumImplicitOps(0), parent(0) { + const TargetInstrDesc &tid) + : TID(&tid), NumImplicitOps(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); if (TID->ImplicitDefs) - for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) NumImplicitOps++; if (TID->ImplicitUses) - for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) NumImplicitOps++; - Operands.reserve(NumImplicitOps + TID->numOperands); + Operands.reserve(NumImplicitOps + TID->getNumOperands()); addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); @@ -95,31 +288,193 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(const MachineInstr &MI) { - TID = MI.getInstrDescriptor(); + TID = &MI.getDesc(); NumImplicitOps = MI.NumImplicitOps; Operands.reserve(MI.getNumOperands()); // Add operands - for (unsigned i = 0; i != MI.getNumOperands(); ++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 } /// getOpcode - Returns the opcode of this MachineInstr. /// -const int MachineInstr::getOpcode() const { +int MachineInstr::getOpcode() const { return TID->Opcode; } +/// 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; +} + +/// 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(); + } +} + +/// 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); + } +} + + +/// 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; + + 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); + } +} + +/// RemoveOperand - Erase an operand from an instruction, leaving it with one +/// fewer operand than it started with. +/// +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(); + } + } + + 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); + } + } +} + + /// removeFromParent - This method unlinks 'this' from the containing basic /// block, and returns it, but does not delete it. MachineInstr *MachineInstr::removeFromParent() { @@ -132,9 +487,8 @@ MachineInstr *MachineInstr::removeFromParent() { /// 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) + unsigned short NumOperands = TID->getNumOperands(); + if (!TID->isVariadic() && getNumOperands()-NumImplicitOps >= NumOperands) return true; // Broken: we have all the operands of this instruction! return false; } @@ -142,8 +496,8 @@ bool MachineInstr::OperandsComplete() const { /// getNumExplicitOperands - Returns the number of non-implicit operands. /// unsigned MachineInstr::getNumExplicitOperands() const { - unsigned NumOperands = TID->numOperands; - if ((TID->Flags & M_VARIABLE_OPS) == 0) + unsigned NumOperands = TID->getNumOperands(); + if (!TID->isVariadic()) return NumOperands; for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { @@ -154,33 +508,6 @@ unsigned MachineInstr::getNumExplicitOperands() const { return NumOperands; } -/// 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(); - case MachineOperand::MO_Immediate: - return getImm() == Other.getImm(); - case MachineOperand::MO_MachineBasicBlock: - return getMBB() == Other.getMBB(); - case MachineOperand::MO_FrameIndex: - return getFrameIndex() == Other.getFrameIndex(); - case MachineOperand::MO_ConstantPoolIndex: - return getConstantPoolIndex() == Other.getConstantPoolIndex() && - getOffset() == Other.getOffset(); - case MachineOperand::MO_JumpTableIndex: - return getJumpTableIndex() == Other.getJumpTableIndex(); - case MachineOperand::MO_GlobalAddress: - return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); - case MachineOperand::MO_ExternalSymbol: - return !strcmp(getSymbolName(), Other.getSymbolName()) && - getOffset() == Other.getOffset(); - } -} /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of /// the specific register or -1 if it is not found. It further tightening @@ -188,7 +515,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == Reg) + if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg) if (!isKill || MO.isKill()) return i; } @@ -200,7 +527,7 @@ int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const { MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { MachineOperand &MO = getOperand(i); - if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) + if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg) return &MO; } return NULL; @@ -210,22 +537,40 @@ MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) { /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int MachineInstr::findFirstPredOperandIdx() const { - const TargetInstrDescriptor *TID = getInstrDescriptor(); - if (TID->Flags & M_PREDICABLE) { + const TargetInstrDesc &TID = getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) + if (TID.OpInfo[i].isPredicate()) return i; } return -1; } +/// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due +/// to two addr elimination. +bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const { + const TargetInstrDesc &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; + } + } + } + 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.isReg() || (!MO.isKill() && !MO.isDead())) + if (!MO.isRegister() || (!MO.isKill() && !MO.isDead())) continue; for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) { MachineOperand &MOp = getOperand(j); @@ -242,17 +587,12 @@ void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { /// copyPredicates - Copies predicate operand(s) from MI. void MachineInstr::copyPredicates(const MachineInstr *MI) { - const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); - if (TID->Flags & M_PREDICABLE) { + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) { - const MachineOperand &MO = MI->getOperand(i); + if (TID.OpInfo[i].isPredicate()) { // Predicated operands must be last operands. - if (MO.isReg()) - addRegOperand(MO.getReg(), false); - else { - addImmOperand(MO.getImm()); - } + addOperand(MI->getOperand(i)); } } } @@ -262,163 +602,24 @@ void MachineInstr::dump() const { cerr << " " << *this; } -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; -} - -static void print(const MachineOperand &MO, std::ostream &OS, - const TargetMachine *TM) { - const MRegisterInfo *MRI = 0; - - if (TM) MRI = TM->getRegisterInfo(); - - switch (MO.getType()) { - case MachineOperand::MO_Register: - OutputReg(OS, MO.getReg(), MRI); - break; - case MachineOperand::MO_Immediate: - OS << MO.getImmedValue(); - 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_JumpTableIndex: - 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"); - } -} - 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).isReg() && getOperand(0).isDef()) { - ::print(getOperand(0), OS, TM); - if (getOperand(0).isDead()) - OS << ""; + if (getNumOperands() && getOperand(0).isRegister() && getOperand(0).isDef()) { + getOperand(0).print(OS, TM); OS << " = "; ++StartOp; // Don't print this operand again! } - if (TID) - OS << TID->Name; + OS << getDesc().getName(); 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.isReg()) { - if (mop.isDef() || mop.isKill() || mop.isDead() || mop.isImplicit()) { - OS << "<"; - bool NeedComma = false; - if (mop.isImplicit()) { - OS << (mop.isDef() ? "imp-def" : "imp-use"); - NeedComma = true; - } else if (mop.isDef()) { - OS << "def"; - NeedComma = true; - } - if (mop.isKill() || mop.isDead()) { - if (NeedComma) - OS << ","; - if (mop.isKill()) - OS << "kill"; - if (mop.isDead()) - OS << "dead"; - } - OS << ">"; - } - } + getOperand(i).print(OS, TM); } OS << "\n"; } -void MachineInstr::print(std::ostream &os) const { - // If the instruction is embedded into a basic block, we can find the target - // info for the instruction. - if (const MachineBasicBlock *MBB = getParent()) { - const MachineFunction *MF = MBB->getParent(); - if (MF) - print(os, &MF->getTarget()); - else - print(os, 0); - } - - // Otherwise, print it out in the "raw" format without symbolic register names - // and such. - os << getInstrDescriptor()->Name; - - for (unsigned i = 0, N = getNumOperands(); i < N; i++) { - os << "\t" << getOperand(i); - if (getOperand(i).isReg() && getOperand(i).isDef()) - os << ""; - } - - os << "\n"; -} - -void MachineOperand::print(std::ostream &OS) const { - switch (getType()) { - case MO_Register: - OutputReg(OS, getReg()); - break; - case MO_Immediate: - OS << (long)getImmedValue(); - break; - case MO_MachineBasicBlock: - OS << "getBasicBlock())->getName() - << "@" << (void*)getMachineBasicBlock() << ">"; - break; - case MO_FrameIndex: - OS << ""; - break; - case MO_ConstantPoolIndex: - OS << ""; - break; - case MO_JumpTableIndex: - OS << ""; - break; - case MO_GlobalAddress: - OS << "getName() << ">"; - break; - case MO_ExternalSymbol: - OS << ""; - break; - default: - assert(0 && "Unrecognized operand type"); - break; - } -} -