-// $Id$
-//***************************************************************************
-// File:
-// MachineInstr.cpp
-//
-// Purpose:
-//
-//
-// Strategy:
-//
-// History:
-// 7/2/01 - Vikram Adve - Created
-//**************************************************************************/
+//===-- lib/CodeGen/MachineInstr.cpp --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods common to all machine instructions.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Constants.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/ConstPoolVals.h"
-#include "llvm/Instruction.h"
-#include <strstream>
-
-//************************ Class Implementations **************************/
-
-
-bool
-MachineInstrInfo::constantFitsInImmedField(int64_t intValue) const
-{
- // First, check if opCode has an immed field.
- bool isSignExtended;
- uint64_t maxImmedValue = this->maxImmedConstant(isSignExtended);
- if (maxImmedValue != 0)
- {
- // Now check if the constant fits
- if (intValue <= (int64_t) maxImmedValue &&
- intValue >= -((int64_t) maxImmedValue+1))
- return true;
- }
+#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/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");
- return false;
+ // 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;
}
-MachineInstr::MachineInstr(MachineOpCode _opCode,
- OpCodeMask _opCodeMask)
- : opCode(_opCode),
- opCodeMask(_opCodeMask),
- operands(TargetMachineInstrInfo[_opCode].numOperands)
-{
+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;
}
-void
-MachineInstr::SetMachineOperand(unsigned int i,
- MachineOperand::MachineOperandType operandType,
- Value* _val)
-{
- assert(i < TargetMachineInstrInfo[opCode].numOperands);
- operands[i].Initialize(operandType, _val);
+/// 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;
}
-void
-MachineInstr::SetMachineOperand(unsigned int i,
- MachineOperand::MachineOperandType operandType,
- int64_t intValue)
-{
- assert(i < TargetMachineInstrInfo[opCode].numOperands);
- operands[i].InitializeConst(operandType, intValue);
-}
+/// 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;
-void
-MachineInstr::SetMachineOperand(unsigned int i,
- unsigned int regNum)
-{
- assert(i < TargetMachineInstrInfo[opCode].numOperands);
- operands[i].InitializeReg(regNum);
-}
+ // 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());
+ }
-void
-MachineInstr::dump(unsigned int indent)
-{
- for (unsigned i=0; i < indent; i++)
- cout << " ";
-
- cout << *this;
+ IsDef = isDef;
+ IsImp = isImp;
+ IsKill = isKill;
+ IsDead = isDead;
+ SubReg = 0;
}
-ostream&
-operator<< (ostream& os, const MachineInstr& minstr)
-{
- os << TargetMachineInstrInfo[minstr.opCode].opCodeString;
-
- for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
- os << "\t" << minstr.getOperand(i);
+/// 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;
- return os;
+ 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();
+ }
}
-ostream&
-operator<< (ostream& os, const MachineOperand& mop)
-{
- strstream regInfo;
- if (mop.machineOperandType == MachineOperand::MO_Register)
- {
- if (mop.vregType == MachineOperand::MO_VirtualReg)
- regInfo << "(val " << mop.value << ")" << ends;
+/// 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
- regInfo << "(" << mop.regNum << ")" << ends;
+ OS << "%mreg" << getReg();
}
- else if (mop.machineOperandType == MachineOperand::MO_CCRegister)
- regInfo << "(val " << mop.value << ")" << ends;
-
- switch(mop.machineOperandType)
- {
- case MachineOperand::MO_Register:
- os << "%reg" << regInfo.str();
- free(regInfo.str());
- break;
- case MachineOperand::MO_CCRegister:
- os << "%ccreg" << regInfo.str();
- free(regInfo.str());
- break;
+ 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");
+ }
+}
- case MachineOperand::MO_SignExtendedImmed:
- os << mop.immedVal;
- break;
+//===----------------------------------------------------------------------===//
+// MachineInstr Implementation
+//===----------------------------------------------------------------------===//
- case MachineOperand::MO_UnextendedImmed:
- os << mop.immedVal;
- break;
+/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+/// TID NULL and no operands.
+MachineInstr::MachineInstr()
+ : TID(0), NumImplicitOps(0), Parent(0) {
+ // Make sure that we get added to a machine basicblock
+ LeakDetector::addGarbageObject(this);
+}
- case MachineOperand::MO_PCRelativeDisp:
- os << "%disp(label " << mop.value << ")";
- break;
+void MachineInstr::addImplicitDefUseOperands() {
+ if (TID->ImplicitDefs)
+ for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs)
+ addOperand(MachineOperand::CreateReg(*ImpDefs, true, true));
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses)
+ addOperand(MachineOperand::CreateReg(*ImpUses, false, true));
+}
- default:
- assert(0 && "Unrecognized operand type");
- break;
- }
+/// MachineInstr ctor - This constructor create a MachineInstr and add the
+/// implicit operands. It reserves space for number of operands specified by
+/// TargetInstrDesc or the numOperands if it is not zero. (for
+/// instructions with variable number of operands).
+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->getImplicitUses())
+ for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses)
+ NumImplicitOps++;
+ Operands.reserve(NumImplicitOps + TID->getNumOperands());
+ if (!NoImp)
+ addImplicitDefUseOperands();
+ // Make sure that we get added to a machine basicblock
+ LeakDetector::addGarbageObject(this);
+}
- return os;
-}
-
-
-//---------------------------------------------------------------------------
-// Target-independent utility routines for creating machine instructions
-//---------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------
-// Function Set2OperandsFromInstr
-// Function Set3OperandsFromInstr
-//
-// For the common case of 2- and 3-operand arithmetic/logical instructions,
-// set the m/c instr. operands directly from the VM instruction's operands.
-// Check whether the first or second operand is 0 and can use a dedicated "0" register.
-// Check whether the second operand should use an immediate field or register.
-// (First and third operands are never immediates for such instructions.)
-//
-// Arguments:
-// canDiscardResult: Specifies that the result operand can be discarded
-// by using the dedicated "0"
-//
-// op1position, op2position and resultPosition: Specify in which position
-// in the machine instruction the 3 operands (arg1, arg2
-// and result) should go.
-//
-// RETURN VALUE: unsigned int flags, where
-// flags & 0x01 => operand 1 is constant and needs a register
-// flags & 0x02 => operand 2 is constant and needs a register
-//------------------------------------------------------------------------
-
-void
-Set2OperandsFromInstr(MachineInstr* minstr,
- InstructionNode* vmInstrNode,
- const TargetMachine& targetMachine,
- bool canDiscardResult,
- int op1Position,
- int resultPosition)
-{
- Set3OperandsFromInstr(minstr, vmInstrNode, targetMachine,
- canDiscardResult, op1Position,
- /*op2Position*/ -1, resultPosition);
-}
-
-
-unsigned
-Set3OperandsFromInstrJUNK(MachineInstr* minstr,
- InstructionNode* vmInstrNode,
- const TargetMachine& targetMachine,
- bool canDiscardResult,
- int op1Position,
- int op2Position,
- int resultPosition)
-{
- assert(op1Position >= 0);
- assert(resultPosition >= 0);
-
- unsigned returnFlags = 0x0;
-
- // Check if operand 1 is 0 and if so, try to use the register that gives 0, if any.
- Value* op1Value = vmInstrNode->leftChild()->getValue();
- bool isValidConstant;
- int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
- if (isValidConstant && intValue == 0 && targetMachine.zeroRegNum >= 0)
- minstr->SetMachineOperand(op1Position, /*regNum*/ targetMachine.zeroRegNum);
- else
- {
- if (op1Value->getValueType() == Value::ConstantVal)
- {// value is constant and must be loaded from constant pool
- returnFlags = returnFlags | (1 << op1Position);
- }
- minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
- op1Value);
- }
+/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
+/// MachineInstr is created and added to the end of the specified basic block.
+///
+MachineInstr::MachineInstr(MachineBasicBlock *MBB,
+ 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->getImplicitDefs(); *ImpDefs; ++ImpDefs)
+ NumImplicitOps++;
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses)
+ NumImplicitOps++;
+ Operands.reserve(NumImplicitOps + TID->getNumOperands());
+ addImplicitDefUseOperands();
+ // Make sure that we get added to a machine basicblock
+ LeakDetector::addGarbageObject(this);
+ MBB->push_back(this); // Add instruction to end of basic block!
+}
+
+/// MachineInstr ctor - Copies MachineInstr arg exactly
+///
+MachineInstr::MachineInstr(const MachineInstr &MI) {
+ TID = &MI.getDesc();
+ NumImplicitOps = MI.NumImplicitOps;
+ Operands.reserve(MI.getNumOperands());
+ MemOperands = MI.MemOperands;
+
+ // Add operands
+ 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;
+}
+
+
+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.
+///
+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;
- // Check if operand 2 (if any) fits in the immediate field of the instruction,
- // of if it is 0 and can use a dedicated machine register
- if (op2Position >= 0)
- {
- Value* op2Value = vmInstrNode->rightChild()->getValue();
- int64_t immedValue;
- MachineOperand::VirtualRegisterType vregType;
- unsigned int machineRegNum;
-
- MachineOperand::MachineOperandType
- op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(),targetMachine,
- /*canUseImmed*/ true,
- vregType, machineRegNum, immedValue);
-
- if (op2type == MachineOperand::MO_Register)
- {
- if (vregType == MachineOperand::MO_MachineReg)
- minstr->SetMachineOperand(op2Position, machineRegNum);
- else
- {
- if (op2Value->getValueType() == Value::ConstantVal)
- {// value is constant and must be loaded from constant pool
- returnFlags = returnFlags | (1 << op2Position);
- }
- minstr->SetMachineOperand(op2Position, op2type, op2Value);
- }
- }
- else
- minstr->SetMachineOperand(op2Position, op2type, immedValue);
+ // If the operand is a register, update the operand's use list.
+ if (Op.isReg())
+ Operands.back().AddRegOperandToRegInfo(getRegInfo());
+ return;
}
+ }
- // If operand 3 (result) can be discarded, use a dead register if one exists
- if (canDiscardResult && targetMachine.zeroRegNum >= 0)
- minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
- else
- minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
- vmInstrNode->getValue());
-
- return returnFlags;
-}
-
-
-void
-Set3OperandsFromInstr(MachineInstr* minstr,
- InstructionNode* vmInstrNode,
- const TargetMachine& targetMachine,
- bool canDiscardResult,
- int op1Position,
- int op2Position,
- int resultPosition)
-{
- assert(op1Position >= 0);
- assert(resultPosition >= 0);
+ // 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.
- // operand 1
- minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
- vmInstrNode->leftChild()->getValue());
+ // 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;
- // operand 2 (if any)
- if (op2Position >= 0)
- minstr->SetMachineOperand(op2Position, MachineOperand::MO_Register,
- vmInstrNode->rightChild()->getValue());
+ // 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");
- // result operand: if it can be discarded, use a dead register if one exists
- if (canDiscardResult && targetMachine.zeroRegNum >= 0)
- minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
- else
- minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
- vmInstrNode->getValue());
-}
-
-
-MachineOperand::MachineOperandType
-ChooseRegOrImmed(Value* val,
- MachineOpCode opCode,
- const TargetMachine& targetMachine,
- bool canUseImmed,
- MachineOperand::VirtualRegisterType& getVRegType,
- unsigned int& getMachineRegNum,
- int64_t& getImmedValue)
-{
- MachineOperand::MachineOperandType opType = MachineOperand::MO_Register;
- getVRegType = MachineOperand::MO_VirtualReg;
- getMachineRegNum = 0;
- getImmedValue = 0;
+ // 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();
+ }
+ }
- // Check for the common case first: argument is not constant
- //
- if (val->getValueType() != Value::ConstantVal)
- return opType;
+ 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() {
+ assert(getParent() && "Not embedded in a basic block!");
+ getParent()->remove(this);
+ return this;
+}
+
+
+/// OperandComplete - Return true if it's illegal to add a new operand
+///
+bool MachineInstr::OperandsComplete() const {
+ 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->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) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = getOperand(i);
+ if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg)
+ if (!isKill || MO.isKill())
+ return i;
+ }
+ return -1;
+}
- // Now get the constant value and check if it fits in the IMMED field.
- // Take advantage of the fact that the max unsigned value will rarely
- // fit into any IMMED field and ignore that case (i.e., cast smaller
- // unsigned constants to signed).
- //
- bool isValidConstant;
- int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
+/// findRegisterDefOperand() - Returns the MachineOperand that is a def of
+/// the specific register or NULL if it is not found.
+MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = getOperand(i);
+ if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg)
+ return &MO;
+ }
+ return NULL;
+}
+
+/// findFirstPredOperandIdx() - Find the index of the first operand in the
+/// operand list that is used to represent the predicate. It returns -1 if
+/// none is found.
+int MachineInstr::findFirstPredOperandIdx() const {
+ const TargetInstrDesc &TID = getDesc();
+ if (TID.isPredicable()) {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (TID.OpInfo[i].isPredicate())
+ return i;
+ }
+
+ return -1;
+}
- if (isValidConstant)
- {
- if (intValue == 0 && targetMachine.zeroRegNum >= 0)
- {
- getVRegType = MachineOperand::MO_MachineReg;
- getMachineRegNum = targetMachine.zeroRegNum;
- }
- else if (canUseImmed &&
- targetMachine.machineInstrInfo[opCode].constantFitsInImmedField(intValue))
- {
- opType = MachineOperand::MO_SignExtendedImmed;
- getImmedValue = intValue;
- }
+/// 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 opType;
+ }
+ return false;
+}
+
+/// copyKillDeadInfo - Copies kill / dead operand properties from MI.
+///
+void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) {
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isRegister() || (!MO.isKill() && !MO.isDead()))
+ continue;
+ for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) {
+ MachineOperand &MOp = getOperand(j);
+ if (!MOp.isIdenticalTo(MO))
+ continue;
+ if (MO.isKill())
+ MOp.setIsKill();
+ else
+ MOp.setIsDead();
+ break;
+ }
+ }
+}
+
+/// 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));
+ }
+ }
+ }
+}
+
+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;
+ if (getNumOperands() && getOperand(0).isRegister() && getOperand(0).isDef()) {
+ getOperand(0).print(OS, TM);
+ OS << " = ";
+ ++StartOp; // Don't print this operand again!
+ }
+
+ OS << getDesc().getName();
+
+ for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
+ if (i != StartOp)
+ OS << ",";
+ 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";
+}
+
+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;
+ }
+ }
+
+ // 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;
+}
+
+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);
+ }
+ }
+ }
}