-//===-- 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.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
+#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 <ostream>
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 << "<fi#" << getIndex() << ">";
+ break;
+ case MachineOperand::MO_ConstantPoolIndex:
+ OS << "<cp#" << getIndex();
+ if (getOffset()) OS << "+" << getOffset();
+ OS << ">";
+ break;
+ case MachineOperand::MO_JumpTableIndex:
+ OS << "<jt#" << getIndex() << ">";
+ break;
+ case MachineOperand::MO_GlobalAddress:
+ OS << "<ga:" << ((Value*)getGlobal())->getName();
+ if (getOffset()) OS << "+" << getOffset();
+ OS << ">";
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ OS << "<es:" << getSymbolName();
+ if (getOffset()) OS << "+" << getOffset();
+ 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, bool NoImp)
- : TID(&tid), NumImplicitOps(0), parent(0) {
- if (!NoImp && 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 (!NoImp && 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);
+ Operands.reserve(NumImplicitOps + TID->getNumOperands());
if (!NoImp)
addImplicitDefUseOperands();
// Make sure that we get added to a machine basicblock
/// 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);
/// 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.
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() {
/// 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;
}
/// 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) {
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();
- }
+
+/// 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) const {
+int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill,
+ const TargetRegisterInfo *TRI) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
- if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg)
+ if (!MO.isRegister() || !MO.isUse())
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (!MOReg)
+ continue;
+ if (MOReg == Reg ||
+ (TRI &&
+ TargetRegisterInfo::isPhysicalRegister(MOReg) &&
+ TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TRI->isSubRegister(MOReg, Reg)))
if (!isKill || MO.isKill())
return i;
}
return -1;
}
-/// findRegisterDefOperand() - Returns the MachineOperand that is a def of
-/// the specific register or NULL if it is not found.
-MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) {
+/// findRegisterDefOperandIdx() - Returns the operand index that is a def of
+/// the specific register or -1 if it is not found. It further tightening
+ /// the search criteria to a def that is dead the register if isDead is true.
+int MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead,
+ const TargetRegisterInfo *TRI) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- MachineOperand &MO = getOperand(i);
- if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg)
- return &MO;
+ const MachineOperand &MO = getOperand(i);
+ if (!MO.isRegister() || !MO.isDef())
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (MOReg == Reg ||
+ (TRI &&
+ TargetRegisterInfo::isPhysicalRegister(MOReg) &&
+ TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TRI->isSubRegister(MOReg, Reg)))
+ if (!isDead || MO.isDead())
+ return i;
}
- return NULL;
+ return -1;
}
/// 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 = 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;
}
/// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due
/// to two addr elimination.
bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const {
- const TargetInstrDescriptor *TID = getInstrDescriptor();
+ 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)
+ TID.getOperandConstraint(j, TOI::TIED_TO) == (int)i)
return true;
}
}
/// 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.isRegister())
- addRegOperand(MO.getReg(), false);
- else {
- addImmOperand(MO.getImm());
- }
+ addOperand(MI->getOperand(i));
}
}
}
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 << "<fi#" << MO.getFrameIndex() << ">";
- break;
- case MachineOperand::MO_ConstantPoolIndex:
- OS << "<cp#" << MO.getConstantPoolIndex() << ">";
- break;
- case MachineOperand::MO_JumpTableIndex:
- OS << "<jt#" << MO.getJumpTableIndex() << ">";
- break;
- case MachineOperand::MO_GlobalAddress:
- OS << "<ga:" << ((Value*)MO.getGlobal())->getName();
- if (MO.getOffset()) OS << "+" << MO.getOffset();
- OS << ">";
- break;
- case MachineOperand::MO_ExternalSymbol:
- OS << "<es:" << MO.getSymbolName();
- if (MO.getOffset()) OS << "+" << MO.getOffset();
- 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).isRegister() && getOperand(0).isDef()) {
- ::print(getOperand(0), OS, TM);
- if (getOperand(0).isDead())
- OS << "<dead>";
+ 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.isRegister()) {
- 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 << "<unknown>";
+ else if (!V->getName().empty())
+ OS << V->getName();
+ else if (isa<PseudoSourceValue>(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) {
+ // Go through the machine instruction's operands to eliminate any potentially
+ // illegal conditions. I.e., a super- and sub-register both marked "kill".
+ for (unsigned i = 0, e = getNumOperands(); i < e;) {
+ MachineOperand &MO = getOperand(i);
+ if (MO.isRegister() && MO.isUse()) {
+ unsigned Reg = MO.getReg();
+
+ if (!Reg || IncomingReg == Reg ||
+ !TargetRegisterInfo::isPhysicalRegister(Reg) ||
+ !TargetRegisterInfo::isPhysicalRegister(IncomingReg)) {
+ ++i;
+ continue;
+ }
+
+ if (RegInfo->isSuperRegister(IncomingReg, Reg) && MO.isKill())
+ // The kill information is already handled by a super-register. Don't
+ // add this sub-register as a kill.
+ return true;
+
+ if (RegInfo->isSubRegister(IncomingReg, Reg) && MO.isKill()) {
+ if (MO.isImplicit()) {
+ // Remove this implicit use that marks the sub-register
+ // "kill". Let the super-register take care of this
+ // information.
+ RemoveOperand(i);
+ --e;
+ continue;
+ } else {
+ // The super-register is going to take care of this kill
+ // information.
+ MO.setIsKill(false);
+ }
+ }
+ }
+
+ ++i;
}
- // Otherwise, print it out in the "raw" format without symbolic register names
- // and such.
- os << getInstrDescriptor()->Name;
+ // If the register already exists, then make sure it or its super-register is
+ // marked "kill".
+ 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;
- for (unsigned i = 0, N = getNumOperands(); i < N; i++) {
- os << "\t" << getOperand(i);
- if (getOperand(i).isRegister() && getOperand(i).isDef())
- os << "<d>";
+ if (Reg == IncomingReg) {
+ MO.setIsKill();
+ return true;
+ }
+
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TargetRegisterInfo::isPhysicalRegister(IncomingReg) &&
+ RegInfo->isSuperRegister(IncomingReg, Reg) &&
+ MO.isKill())
+ // A super-register kill already exists.
+ return true;
+ }
+ }
+
+ // If not found, this means an alias of one of the operands is killed. Add a
+ // new implicit operand if required.
+ if (AddIfNotFound) {
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ false /*IsDef*/,
+ true /*IsImp*/,
+ true /*IsKill*/));
+ return true;
}
- os << "\n";
+ return false;
}
-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 << "<mbb:"
- << ((Value*)getMachineBasicBlock()->getBasicBlock())->getName()
- << "@" << (void*)getMachineBasicBlock() << ">";
- break;
- case MO_FrameIndex:
- OS << "<fi#" << getFrameIndex() << ">";
- break;
- case MO_ConstantPoolIndex:
- OS << "<cp#" << getConstantPoolIndex() << ">";
- break;
- case MO_JumpTableIndex:
- OS << "<jt#" << getJumpTableIndex() << ">";
- break;
- case MO_GlobalAddress:
- OS << "<ga:" << ((Value*)getGlobal())->getName() << ">";
- break;
- case MO_ExternalSymbol:
- OS << "<es:" << getSymbolName() << ">";
- break;
- default:
- assert(0 && "Unrecognized operand type");
- break;
+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;
+ }
}
+
+ // 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;
}
+/// 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);
+ }
+ }
+ }
+}