summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/MachineInstr.cpp470
1 files changed, 205 insertions, 265 deletions
diff --git a/contrib/llvm/lib/CodeGen/MachineInstr.cpp b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
index ce8d520..32d0668 100644
--- a/contrib/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
@@ -12,15 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Constants.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/Function.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
-#include "llvm/Value.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -28,19 +22,24 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
#include "llvm/MC/MCInstrDesc.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/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"
-#include "llvm/ADT/Hashing.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -144,7 +143,7 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
// Change this to a register and set the reg#.
OpKind = MO_Register;
SmallContents.RegNo = Reg;
- SubReg = 0;
+ SubReg_TargetFlags = 0;
IsDef = isDef;
IsImp = isImp;
IsKill = isKill;
@@ -518,89 +517,50 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
// MachineInstr Implementation
//===----------------------------------------------------------------------===//
-/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
-/// MCID NULL and no operands.
-MachineInstr::MachineInstr()
- : MCID(0), Flags(0), AsmPrinterFlags(0),
- NumMemRefs(0), MemRefs(0),
- Parent(0) {
- // Make sure that we get added to a machine basicblock
- LeakDetector::addGarbageObject(this);
-}
-
-void MachineInstr::addImplicitDefUseOperands() {
+void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
if (MCID->ImplicitDefs)
for (const uint16_t *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
- addOperand(MachineOperand::CreateReg(*ImpDefs, true, true));
+ addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true));
if (MCID->ImplicitUses)
for (const uint16_t *ImpUses = MCID->getImplicitUses(); *ImpUses; ++ImpUses)
- addOperand(MachineOperand::CreateReg(*ImpUses, false, true));
+ addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true));
}
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified by
/// the MCInstrDesc.
-MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl,
- bool NoImp)
- : MCID(&tid), Flags(0), AsmPrinterFlags(0),
- NumMemRefs(0), MemRefs(0), Parent(0), debugLoc(dl) {
- unsigned NumImplicitOps = 0;
- if (!NoImp)
- NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();
- Operands.reserve(NumImplicitOps + MCID->getNumOperands());
+MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
+ const DebugLoc dl, bool NoImp)
+ : MCID(&tid), Parent(0), Operands(0), NumOperands(0),
+ Flags(0), AsmPrinterFlags(0),
+ NumMemRefs(0), MemRefs(0), debugLoc(dl) {
+ // Reserve space for the expected number of operands.
+ if (unsigned NumOps = MCID->getNumOperands() +
+ MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) {
+ CapOperands = OperandCapacity::get(NumOps);
+ Operands = MF.allocateOperandArray(CapOperands);
+ }
+
if (!NoImp)
- addImplicitDefUseOperands();
- // Make sure that we get added to a machine basicblock
- LeakDetector::addGarbageObject(this);
-}
-
-/// MachineInstr ctor - Work exactly the same as the ctor two above, except
-/// that the MachineInstr is created and added to the end of the specified
-/// basic block.
-MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
- const MCInstrDesc &tid)
- : MCID(&tid), Flags(0), AsmPrinterFlags(0),
- NumMemRefs(0), MemRefs(0), Parent(0), debugLoc(dl) {
- assert(MBB && "Cannot use inserting ctor with null basic block!");
- unsigned NumImplicitOps =
- MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();
- Operands.reserve(NumImplicitOps + MCID->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!
+ addImplicitDefUseOperands(MF);
}
/// MachineInstr ctor - Copies MachineInstr arg exactly
///
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
- : MCID(&MI.getDesc()), Flags(0), AsmPrinterFlags(0),
+ : MCID(&MI.getDesc()), Parent(0), Operands(0), NumOperands(0),
+ Flags(0), AsmPrinterFlags(0),
NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs),
- Parent(0), debugLoc(MI.getDebugLoc()) {
- Operands.reserve(MI.getNumOperands());
+ debugLoc(MI.getDebugLoc()) {
+ CapOperands = OperandCapacity::get(MI.getNumOperands());
+ Operands = MF.allocateOperandArray(CapOperands);
- // Add operands
+ // Copy operands.
for (unsigned i = 0; i != MI.getNumOperands(); ++i)
- addOperand(MI.getOperand(i));
+ addOperand(MF, MI.getOperand(i));
- // Copy all the flags.
- Flags = MI.Flags;
-
- // Set parent to null.
- Parent = 0;
-
- LeakDetector::addGarbageObject(this);
-}
-
-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
+ // Copy all the sensible flags.
+ setFlags(MI.Flags);
}
/// getRegInfo - If this instruction is embedded into a MachineFunction,
@@ -616,7 +576,7 @@ MachineRegisterInfo *MachineInstr::getRegInfo() {
/// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists.
void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
- for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (Operands[i].isReg())
MRI.removeRegOperandFromUseList(&Operands[i]);
}
@@ -625,40 +585,65 @@ void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
/// this instruction from their respective use lists. This requires that the
/// operands not be on their use lists yet.
void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) {
- for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (Operands[i].isReg())
MRI.addRegOperandToUseList(&Operands[i]);
}
+void MachineInstr::addOperand(const MachineOperand &Op) {
+ MachineBasicBlock *MBB = getParent();
+ assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs");
+ MachineFunction *MF = MBB->getParent();
+ assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs");
+ addOperand(*MF, Op);
+}
+
+/// Move NumOps MachineOperands from Src to Dst, with support for overlapping
+/// ranges. If MRI is non-null also update use-def chains.
+static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
+ unsigned NumOps, MachineRegisterInfo *MRI) {
+ if (MRI)
+ return MRI->moveOperands(Dst, Src, NumOps);
+
+ // Here it would be convenient to call memmove, so that isn't allowed because
+ // MachineOperand has a constructor and so isn't a POD type.
+ if (Dst < Src)
+ for (unsigned i = 0; i != NumOps; ++i)
+ new (Dst + i) MachineOperand(Src[i]);
+ else
+ for (unsigned i = NumOps; i ; --i)
+ new (Dst + i - 1) MachineOperand(Src[i - 1]);
+}
+
/// 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) {
+void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
assert(MCID && "Cannot add operands before providing an instr descriptor");
- bool isImpReg = Op.isReg() && Op.isImplicit();
- MachineRegisterInfo *RegInfo = getRegInfo();
- // If the Operands backing store is reallocated, all register operands must
- // be removed and re-added to RegInfo. It is storing pointers to operands.
- bool Reallocate = RegInfo &&
- !Operands.empty() && Operands.size() == Operands.capacity();
+ // Check if we're adding one of our existing operands.
+ if (&Op >= Operands && &Op < Operands + NumOperands) {
+ // This is unusual: MI->addOperand(MI->getOperand(i)).
+ // If adding Op requires reallocating or moving existing operands around,
+ // the Op reference could go stale. Support it by copying Op.
+ MachineOperand CopyOp(Op);
+ return addOperand(MF, CopyOp);
+ }
// Find the insert location for the new operand. Implicit registers go at
- // the end, everything goes before the implicit regs.
- unsigned OpNo = Operands.size();
-
- // Remove all the implicit operands from RegInfo if they need to be shifted.
+ // the end, everything else goes before the implicit regs.
+ //
// FIXME: Allow mixed explicit and implicit operands on inline asm.
// InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
// implicit-defs, but they must not be moved around. See the FIXME in
// InstrEmitter.cpp.
+ unsigned OpNo = getNumOperands();
+ bool isImpReg = Op.isReg() && Op.isImplicit();
if (!isImpReg && !isInlineAsm()) {
while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
--OpNo;
assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
- if (RegInfo)
- RegInfo->removeRegOperandFromUseList(&Operands[OpNo]);
}
}
@@ -669,55 +654,56 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
OpNo < MCID->getNumOperands()) &&
"Trying to add an operand to a machine instr that is already done!");
- // All operands from OpNo have been removed from RegInfo. If the Operands
- // backing store needs to be reallocated, we also need to remove any other
- // register operands.
- if (Reallocate)
- for (unsigned i = 0; i != OpNo; ++i)
- if (Operands[i].isReg())
- RegInfo->removeRegOperandFromUseList(&Operands[i]);
-
- // Insert the new operand at OpNo.
- Operands.insert(Operands.begin() + OpNo, Op);
- Operands[OpNo].ParentMI = this;
-
- // The Operands backing store has now been reallocated, so we can re-add the
- // operands before OpNo.
- if (Reallocate)
- for (unsigned i = 0; i != OpNo; ++i)
- if (Operands[i].isReg())
- RegInfo->addRegOperandToUseList(&Operands[i]);
-
- // When adding a register operand, tell RegInfo about it.
- if (Operands[OpNo].isReg()) {
+ MachineRegisterInfo *MRI = getRegInfo();
+
+ // Determine if the Operands array needs to be reallocated.
+ // Save the old capacity and operand array.
+ OperandCapacity OldCap = CapOperands;
+ MachineOperand *OldOperands = Operands;
+ if (!OldOperands || OldCap.getSize() == getNumOperands()) {
+ CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
+ Operands = MF.allocateOperandArray(CapOperands);
+ // Move the operands before the insertion point.
+ if (OpNo)
+ moveOperands(Operands, OldOperands, OpNo, MRI);
+ }
+
+ // Move the operands following the insertion point.
+ if (OpNo != NumOperands)
+ moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
+ MRI);
+ ++NumOperands;
+
+ // Deallocate the old operand array.
+ if (OldOperands != Operands && OldOperands)
+ MF.deallocateOperandArray(OldCap, OldOperands);
+
+ // Copy Op into place. It still needs to be inserted into the MRI use lists.
+ MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
+ NewMO->ParentMI = this;
+
+ // When adding a register operand, tell MRI about it.
+ if (NewMO->isReg()) {
// Ensure isOnRegUseList() returns false, regardless of Op's status.
- Operands[OpNo].Contents.Reg.Prev = 0;
+ NewMO->Contents.Reg.Prev = 0;
// Ignore existing ties. This is not a property that can be copied.
- Operands[OpNo].TiedTo = 0;
- // Add the new operand to RegInfo.
- if (RegInfo)
- RegInfo->addRegOperandToUseList(&Operands[OpNo]);
+ NewMO->TiedTo = 0;
+ // Add the new operand to MRI, but only for instructions in an MBB.
+ if (MRI)
+ MRI->addRegOperandToUseList(NewMO);
// The MCID operand information isn't accurate until we start adding
// explicit operands. The implicit operands are added first, then the
// explicits are inserted before them.
if (!isImpReg) {
// Tie uses to defs as indicated in MCInstrDesc.
- if (Operands[OpNo].isUse()) {
+ if (NewMO->isUse()) {
int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
if (DefIdx != -1)
tieOperands(DefIdx, OpNo);
}
// If the register operand is flagged as early, mark the operand as such.
if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
- Operands[OpNo].setIsEarlyClobber(true);
- }
- }
-
- // Re-add all the implicit ops.
- if (RegInfo) {
- for (unsigned i = OpNo + 1, e = Operands.size(); i != e; ++i) {
- assert(Operands[i].isReg() && "Should only be an implicit reg!");
- RegInfo->addRegOperandToUseList(&Operands[i]);
+ NewMO->setIsEarlyClobber(true);
}
}
}
@@ -726,45 +712,27 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
/// fewer operand than it started with.
///
void MachineInstr::RemoveOperand(unsigned OpNo) {
- assert(OpNo < Operands.size() && "Invalid operand number");
+ assert(OpNo < getNumOperands() && "Invalid operand number");
untieRegOperand(OpNo);
- MachineRegisterInfo *RegInfo = getRegInfo();
-
- // Special case removing the last one.
- if (OpNo == Operands.size()-1) {
- // If needed, remove from the reg def/use list.
- if (RegInfo && Operands.back().isReg() && Operands.back().isOnRegUseList())
- RegInfo->removeRegOperandFromUseList(&Operands.back());
-
- 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.
- if (RegInfo) {
- for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {
- if (Operands[i].isReg())
- RegInfo->removeRegOperandFromUseList(&Operands[i]);
- }
- }
#ifndef NDEBUG
// Moving tied operands would break the ties.
- for (unsigned i = OpNo + 1, e = Operands.size(); i != e; ++i)
+ for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
if (Operands[i].isReg())
assert(!Operands[i].isTied() && "Cannot move tied operands");
#endif
- Operands.erase(Operands.begin()+OpNo);
+ MachineRegisterInfo *MRI = getRegInfo();
+ if (MRI && Operands[OpNo].isReg())
+ MRI->removeRegOperandFromUseList(Operands + OpNo);
- if (RegInfo) {
- for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {
- if (Operands[i].isReg())
- RegInfo->addRegOperandToUseList(&Operands[i]);
- }
- }
+ // Don't call the MachineOperand destructor. A lot of this code depends on
+ // MachineOperand having a trivial destructor anyway, and adding a call here
+ // wouldn't make it 'destructor-correct'.
+
+ if (unsigned N = NumOperands - 1 - OpNo)
+ moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
+ --NumOperands;
}
/// addMemOperand - Add a MachineMemOperand to the machine instruction.
@@ -773,33 +741,30 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {
void MachineInstr::addMemOperand(MachineFunction &MF,
MachineMemOperand *MO) {
mmo_iterator OldMemRefs = MemRefs;
- uint16_t OldNumMemRefs = NumMemRefs;
+ unsigned OldNumMemRefs = NumMemRefs;
- uint16_t NewNum = NumMemRefs + 1;
+ unsigned NewNum = NumMemRefs + 1;
mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum);
std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs);
NewMemRefs[NewNum - 1] = MO;
-
- MemRefs = NewMemRefs;
- NumMemRefs = NewNum;
+ setMemRefs(NewMemRefs, NewMemRefs + NewNum);
}
bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const {
- const MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::const_instr_iterator MII = *this; ++MII;
- while (MII != MBB->end() && MII->isInsideBundle()) {
+ assert(!isBundledWithPred() && "Must be called on bundle header");
+ for (MachineBasicBlock::const_instr_iterator MII = this;; ++MII) {
if (MII->getDesc().getFlags() & Mask) {
if (Type == AnyInBundle)
return true;
} else {
- if (Type == AllInBundle)
+ if (Type == AllInBundle && !MII->isBundle())
return false;
}
- ++MII;
+ // This was the last instruction in the bundle.
+ if (!MII->isBundledWithSucc())
+ return Type == AllInBundle;
}
-
- return Type == AllInBundle;
}
bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
@@ -865,46 +830,25 @@ bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
return true;
}
-/// 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!");
-
- // If it's a bundle then remove the MIs inside the bundle as well.
- if (isBundle()) {
- MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::instr_iterator MII = *this; ++MII;
- MachineBasicBlock::instr_iterator E = MBB->instr_end();
- while (MII != E && MII->isInsideBundle()) {
- MachineInstr *MI = &*MII;
- ++MII;
- MBB->remove(MI);
- }
- }
- getParent()->remove(this);
- return this;
+ return getParent()->remove(this);
}
+MachineInstr *MachineInstr::removeFromBundle() {
+ assert(getParent() && "Not embedded in a basic block!");
+ return getParent()->remove_instr(this);
+}
-/// eraseFromParent - This method unlinks 'this' from the containing basic
-/// block, and deletes it.
void MachineInstr::eraseFromParent() {
assert(getParent() && "Not embedded in a basic block!");
- // If it's a bundle then remove the MIs inside the bundle as well.
- if (isBundle()) {
- MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::instr_iterator MII = *this; ++MII;
- MachineBasicBlock::instr_iterator E = MBB->instr_end();
- while (MII != E && MII->isInsideBundle()) {
- MachineInstr *MI = &*MII;
- ++MII;
- MBB->erase(MI);
- }
- }
- // Erase the individual instruction, which may itself be inside a bundle.
- getParent()->erase_instr(this);
+ getParent()->erase(this);
}
+void MachineInstr::eraseFromBundle() {
+ assert(getParent() && "Not embedded in a basic block!");
+ getParent()->erase_instr(this);
+}
/// getNumExplicitOperands - Returns the number of non-implicit operands.
///
@@ -921,14 +865,40 @@ unsigned MachineInstr::getNumExplicitOperands() const {
return NumOperands;
}
-/// isBundled - Return true if this instruction part of a bundle. This is true
-/// if either itself or its following instruction is marked "InsideBundle".
-bool MachineInstr::isBundled() const {
- if (isInsideBundle())
- return true;
- MachineBasicBlock::const_instr_iterator nextMI = this;
- ++nextMI;
- return nextMI != Parent->instr_end() && nextMI->isInsideBundle();
+void MachineInstr::bundleWithPred() {
+ assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
+ setFlag(BundledPred);
+ MachineBasicBlock::instr_iterator Pred = this;
+ --Pred;
+ assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
+ Pred->setFlag(BundledSucc);
+}
+
+void MachineInstr::bundleWithSucc() {
+ assert(!isBundledWithSucc() && "MI is already bundled with its successor");
+ setFlag(BundledSucc);
+ MachineBasicBlock::instr_iterator Succ = this;
+ ++Succ;
+ assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
+ Succ->setFlag(BundledPred);
+}
+
+void MachineInstr::unbundleFromPred() {
+ assert(isBundledWithPred() && "MI isn't bundled with its predecessor");
+ clearFlag(BundledPred);
+ MachineBasicBlock::instr_iterator Pred = this;
+ --Pred;
+ assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags");
+ Pred->clearFlag(BundledSucc);
+}
+
+void MachineInstr::unbundleFromSucc() {
+ assert(isBundledWithSucc() && "MI isn't bundled with its successor");
+ clearFlag(BundledSucc);
+ MachineBasicBlock::instr_iterator Succ = this;
+ ++Succ;
+ assert(Succ->isBundledWithPred() && "Inconsistent bundle flags");
+ Succ->clearFlag(BundledPred);
}
bool MachineInstr::isStackAligningInlineAsm() const {
@@ -1011,18 +981,13 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx,
return NULL;
}
-/// getBundleSize - Return the number of instructions inside the MI bundle.
+/// Return the number of instructions inside the MI bundle, not counting the
+/// header instruction.
unsigned MachineInstr::getBundleSize() const {
- assert(isBundle() && "Expecting a bundle");
-
- const MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::const_instr_iterator I = *this, E = MBB->instr_end();
+ MachineBasicBlock::const_instr_iterator I = this;
unsigned Size = 0;
- while ((++I != E) && I->isInsideBundle()) {
- ++Size;
- }
- assert(Size > 1 && "Malformed bundle");
-
+ while (I->isBundledWithSucc())
+ ++Size, ++I;
return Size;
}
@@ -1231,41 +1196,6 @@ void MachineInstr::clearKillInfo() {
}
}
-/// 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()))
- 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) {
- assert(!isBundle() && "MachineInstr::copyPredicates() can't handle bundles");
-
- const MCInstrDesc &MCID = MI->getDesc();
- if (!MCID.isPredicable())
- return;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- if (MCID.OpInfo[i].isPredicate()) {
- // Predicated operands must be last operands.
- addOperand(MI->getOperand(i));
- }
- }
-}
-
void MachineInstr::substituteRegister(unsigned FromReg,
unsigned ToReg,
unsigned SubIdx,
@@ -1460,12 +1390,13 @@ bool MachineInstr::allDefsAreDead() const {
/// copyImplicitOps - Copy implicit register operands from specified
/// instruction to this instruction.
-void MachineInstr::copyImplicitOps(const MachineInstr *MI) {
+void MachineInstr::copyImplicitOps(MachineFunction &MF,
+ const MachineInstr *MI) {
for (unsigned i = MI->getDesc().getNumOperands(), e = MI->getNumOperands();
i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.isImplicit())
- addOperand(MO);
+ addOperand(MF, MO);
}
}
@@ -1497,7 +1428,8 @@ static void printDebugLoc(DebugLoc DL, const MachineFunction *MF,
}
}
-void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
+void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
+ bool SkipOpers) const {
// We can be a bit tidier if we know the TargetMachine and/or MachineFunction.
const MachineFunction *MF = 0;
const MachineRegisterInfo *MRI = 0;
@@ -1534,6 +1466,9 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
else
OS << "UNKNOWN";
+ if (SkipOpers)
+ return;
+
// Print the rest of the operands.
bool OmittedAnyCallClobbers = false;
bool FirstOp = true;
@@ -1545,10 +1480,14 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
OS << " ";
getOperand(InlineAsm::MIOp_AsmString).print(OS, TM);
- // Print HasSideEffects, IsAlignStack
+ // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
OS << " [sideeffect]";
+ if (ExtraInfo & InlineAsm::Extra_MayLoad)
+ OS << " [mayload]";
+ if (ExtraInfo & InlineAsm::Extra_MayStore)
+ OS << " [maystore]";
if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
OS << " [alignstack]";
if (getInlineAsmDialect() == InlineAsm::AD_ATT)
@@ -1576,12 +1515,12 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
const MachineRegisterInfo &MRI = MF->getRegInfo();
- if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) {
+ if (MRI.use_empty(Reg)) {
bool HasAliasLive = false;
for (MCRegAliasIterator AI(Reg, TM->getRegisterInfo(), true);
AI.isValid(); ++AI) {
unsigned AliasReg = *AI;
- if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) {
+ if (!MRI.use_empty(AliasReg)) {
HasAliasLive = true;
break;
}
@@ -1653,7 +1592,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
}
bool HaveSemi = false;
- if (Flags) {
+ const unsigned PrintableFlags = FrameSetup;
+ if (Flags & PrintableFlags) {
if (!HaveSemi) OS << ";"; HaveSemi = true;
OS << " flags: ";
OpenPOWER on IntegriCloud