Skip to content
MachineInstr.cpp 59.3 KiB
Newer Older
//===-- 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.
//
Chris Lattner's avatar
 
Chris Lattner committed
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Function.h"
#include "llvm/Metadata.h"
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/DebugInfo.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/FoldingSet.h"
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;
  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;
  }
/// RemoveRegOperandFromRegInfo - Remove this register operand from the
/// MachineRegisterInfo it is linked with.
void MachineOperand::RemoveRegOperandFromRegInfo() {
  assert(isOnRegUseList() && "Reg operand is not on a use list");
  // Unlink this from the doubly linked list of operands.
  MachineOperand *NextOp = Contents.Reg.Next;
  *Contents.Reg.Prev = NextOp;
  if (NextOp) {
    assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
    NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
  }
  Contents.Reg.Prev = 0;
  Contents.Reg.Next = 0;
}

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();
        AddRegOperandToRegInfo(&MF->getRegInfo());
        return;
      }
  // Otherwise, just change the register, no problem.  :)
void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx,
                                  const TargetRegisterInfo &TRI) {
  assert(TargetRegisterInfo::isVirtualRegister(Reg));
  if (SubIdx && getSubReg())
    SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
  setReg(Reg);
}

void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {
  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
  if (getSubReg()) {
    Reg = TRI.getSubReg(Reg, getSubReg());
    // Note that getSubReg() may return 0 if the sub-register doesn't exist.
    // That won't happen in legal code.
/// 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, bool isUndef,
                                      bool isDebug) {
  // If this operand is already a register operand, use setReg to update the
    assert(!isEarlyClobber());
    setReg(Reg);
  } else {
    // Otherwise, change this to a register and set the reg#.
    OpKind = MO_Register;

    // 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;
  IsEarlyClobber = false;
/// isIdenticalTo - Return true if this operand is identical to the specified
/// operand.
bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
  if (getType() != Other.getType() ||
      getTargetFlags() != Other.getTargetFlags())
    return false;
  switch (getType()) {
  default: llvm_unreachable("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_CImmediate:
Loading
Loading full blame...