X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstr.cpp;h=911d5caa1d331d5267a569acd336552d00db3582;hb=d70dbb5d627a0408eccf88033143efa62ee0e6c0;hp=1c0d9cc4eb1c195d1efb270f2d6e6f5352d0b9d0;hpb=faa510726f4b40aa4495e60e4d341c6467e3fb01;p=oota-llvm.git diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 1c0d9cc4eb1..911d5caa1d3 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. // //===----------------------------------------------------------------------===// // @@ -11,65 +11,269 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Value.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/Streams.h" #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_FPImmediate: + return getFPImm() == Other.getFPImm(); + 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 || TargetRegisterInfo::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_FPImmediate: + if (getFPImm()->getType() == Type::FloatTy) { + OS << getFPImm()->getValueAPF().convertToFloat(); + } else { + OS << getFPImm()->getValueAPF().convertToDouble(); + } + 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; - Op.offset = 0; - 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; - Op.offset = 0; - 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); } @@ -78,16 +282,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); @@ -97,31 +301,194 @@ 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()); + MemOperands = MI.MemOperands; // 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() { @@ -134,48 +501,41 @@ 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; } -/// 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(); +/// getNumExplicitOperands - Returns the number of non-implicit operands. +/// +unsigned MachineInstr::getNumExplicitOperands() const { + unsigned NumOperands = TID->getNumOperands(); + if (!TID->isVariadic()) + return NumOperands; + + for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { + const MachineOperand &MO = getOperand(NumOperands); + if (!MO.isRegister() || !MO.isImplicit()) + NumOperands++; } + return NumOperands; +} + + +/// isDebugLabel - Returns true if the MachineInstr represents a debug label. +/// +bool MachineInstr::isDebugLabel() const { + return getOpcode() == TargetInstrInfo::LABEL && getOperand(1).getImm() == 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) { +int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == Reg) + const MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg) if (!isKill || MO.isKill()) return i; } @@ -187,18 +547,50 @@ int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) { 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; } + +/// 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 TargetInstrDesc &TID = getDesc(); + if (TID.isPredicable()) { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + 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); @@ -213,167 +605,163 @@ void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { } } -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; +/// copyPredicates - Copies predicate operand(s) from MI. +void MachineInstr::copyPredicates(const MachineInstr *MI) { + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isPredicable()) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + if (TID.OpInfo[i].isPredicate()) { + // Predicated operands must be last operands. + addOperand(MI->getOperand(i)); + } + } + } } -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::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).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); + } + + if (getNumMemOperands() > 0) { + OS << ", Mem:"; + for (unsigned i = 0; i < getNumMemOperands(); i++) { + const MemOperand &MRO = getMemOperand(i); + const Value *V = MRO.getValue(); + + assert((MRO.isLoad() || MRO.isStore()) && + "SV has to be a load, store or both."); + + if (MRO.isVolatile()) + OS << "Volatile "; + + if (MRO.isLoad()) + OS << "LD"; + if (MRO.isStore()) + OS << "ST"; + + OS << "(" << MRO.getSize() << "," << MRO.getAlignment() << ") ["; + + if (!V) + OS << ""; + else if (!V->getName().empty()) + OS << V->getName(); + else if (isa(V)) + OS << *V; + else + OS << V; + + OS << " + " << MRO.getOffset() << "]"; } } 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); +bool MachineInstr::addRegisterKilled(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo, + bool AddIfNotFound) { + bool Found = false; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isUse()) { + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg == IncomingReg) { + MO.setIsKill(); + Found = true; + break; + } else if (TargetRegisterInfo::isPhysicalRegister(Reg) && + TargetRegisterInfo::isPhysicalRegister(IncomingReg) && + RegInfo->isSuperRegister(IncomingReg, Reg) && + MO.isKill()) + // A super-register kill already exists. + Found = true; + } } - // Otherwise, print it out in the "raw" format without symbolic register names - // and such. - os << getInstrDescriptor()->Name; + // If not found, this means an alias of one of the operand is killed. Add a + // new implicit operand if required. + if (!Found && AddIfNotFound) { + addOperand(MachineOperand::CreateReg(IncomingReg, false/*IsDef*/, + true/*IsImp*/,true/*IsKill*/)); + return true; + } + return Found; +} - for (unsigned i = 0, N = getNumOperands(); i < N; i++) { - os << "\t" << getOperand(i); - if (getOperand(i).isReg() && getOperand(i).isDef()) - os << ""; +bool MachineInstr::addRegisterDead(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo, + bool AddIfNotFound) { + bool Found = false; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isDef()) { + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg == IncomingReg) { + MO.setIsDead(); + Found = true; + break; + } else if (TargetRegisterInfo::isPhysicalRegister(Reg) && + TargetRegisterInfo::isPhysicalRegister(IncomingReg) && + RegInfo->isSuperRegister(IncomingReg, Reg) && + MO.isDead()) + // There exists a super-register that's marked dead. + return true; + } } - os << "\n"; + // If not found, this means an alias of one of the operand is dead. Add a + // new implicit operand. + if (!Found && AddIfNotFound) { + addOperand(MachineOperand::CreateReg(IncomingReg, true/*IsDef*/, + true/*IsImp*/,false/*IsKill*/, + true/*IsDead*/)); + return true; + } + return Found; } -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; +/// copyKillDeadInfo - copies killed/dead information from one instr to another +void MachineInstr::copyKillDeadInfo(MachineInstr *OldMI, + const TargetRegisterInfo *RegInfo) { + // If the instruction defines any virtual registers, update the VarInfo, + // kill and dead information for the instruction. + for (unsigned i = 0, e = OldMI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = OldMI->getOperand(i); + if (MO.isRegister() && MO.getReg() && + TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + unsigned Reg = MO.getReg(); + if (MO.isDef()) { + if (MO.isDead()) { + MO.setIsDead(false); + addRegisterDead(Reg, RegInfo); + } + } + if (MO.isKill()) { + MO.setIsKill(false); + addRegisterKilled(Reg, RegInfo); + } + } } } -