diff options
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 129 |
1 files changed, 113 insertions, 16 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 65c164a4ee..849e647a1f 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -38,20 +38,74 @@ namespace llvm { /// Eventually, the "resizing" ctors will be phased out. /// MachineInstr::MachineInstr(short opcode, unsigned numOperands) - : Opcode(opcode), parent(0) { + : Opcode(opcode), parent(0), NumImplicitOps(0) { Operands.reserve(numOperands); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } +void MachineInstr::addImplicitDefUseOperands(const TargetInstrDescriptor &TID) { + if (TID.ImplicitDefs) + for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) { + MachineOperand Op; + Op.opType = MachineOperand::MO_Register; + Op.IsDef = true; + Op.IsImp = true; + Op.IsKill = false; + Op.IsDead = false; + Op.contents.RegNo = *ImpDefs; + Op.offset = 0; + Operands.push_back(Op); + } + if (TID.ImplicitUses) + for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) { + MachineOperand Op; + Op.opType = MachineOperand::MO_Register; + Op.IsDef = false; + Op.IsImp = true; + Op.IsKill = false; + Op.IsDead = false; + Op.contents.RegNo = *ImpUses; + Op.offset = 0; + Operands.push_back(Op); + } +} + +/// MachineInstr ctor - This constructor create a MachineInstr and add the +/// implicit operands. It reserves space for numOperand operands. +MachineInstr::MachineInstr(const TargetInstrInfo &TII, short opcode, + unsigned numOperands) + : Opcode(opcode), parent(0), NumImplicitOps(0) { + const TargetInstrDescriptor &TID = TII.get(opcode); + if (TID.ImplicitDefs) + for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (TID.ImplicitUses) + for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + numOperands); + addImplicitDefUseOperands(TID); + // Make sure that we get added to a machine basicblock + LeakDetector::addGarbageObject(this); +} + /// 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, short opcode, unsigned numOperands) - : Opcode(opcode), parent(0) { + : Opcode(opcode), parent(0), NumImplicitOps(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); - Operands.reserve(numOperands); + const TargetInstrDescriptor &TID = MBB->getParent()->getTarget(). + getInstrInfo()->get(opcode); + if (TID.ImplicitDefs) + for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (TID.ImplicitUses) + for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + numOperands); + addImplicitDefUseOperands(TID); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); MBB->push_back(this); // Add instruction to end of basic block! @@ -63,6 +117,7 @@ MachineInstr::MachineInstr(const MachineInstr &MI) { Opcode = MI.getOpcode(); Operands.reserve(MI.getNumOperands()); + NumImplicitOps = MI.NumImplicitOps; // Add operands for (unsigned i = 0; i != MI.getNumOperands(); ++i) Operands.push_back(MI.getOperand(i)); @@ -92,7 +147,7 @@ MachineInstr *MachineInstr::removeFromParent() { bool MachineInstr::OperandsComplete() const { int NumOperands = TargetInstrDescriptors[Opcode].numOperands; if ((TargetInstrDescriptors[Opcode].Flags & M_VARIABLE_OPS) == 0 && - getNumOperands() >= (unsigned)NumOperands) + getNumOperands()-NumImplicitOps >= (unsigned)NumOperands) return true; // Broken: we have all the operands of this instruction! return false; } @@ -125,16 +180,42 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { } } -/// addImplicitDefUseOperands - Add all implicit def and use operands to -/// this instruction. -void MachineInstr::addImplicitDefUseOperands() { - const TargetInstrDescriptor &TID = TargetInstrDescriptors[Opcode]; +/// setOpcode - Replace the opcode of the current instruction with a new one. +/// +void MachineInstr::setOpcode(unsigned Op) { + Operands.erase(Operands.begin(), Operands.begin()+NumImplicitOps); + NumImplicitOps = 0; + Opcode = Op; + if (!getParent()) + return; + const TargetInstrDescriptor &TID = getParent()->getParent()-> + getTarget().getInstrInfo()->get(Op); if (TID.ImplicitDefs) - for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) - addRegOperand(*ImpDefs, true, true); + for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) { + MachineOperand Op; + Op.opType = MachineOperand::MO_Register; + Op.IsDef = true; + Op.IsImp = true; + Op.IsKill = false; + Op.IsDead = false; + Op.contents.RegNo = *ImpDefs; + Op.offset = 0; + Operands.insert(Operands.begin()+NumImplicitOps, Op); + NumImplicitOps++; + } if (TID.ImplicitUses) - for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) - addRegOperand(*ImpUses, false, true); + for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) { + MachineOperand Op; + Op.opType = MachineOperand::MO_Register; + Op.IsDef = false; + Op.IsImp = true; + Op.IsKill = false; + Op.IsDead = false; + Op.contents.RegNo = *ImpUses; + Op.offset = 0; + Operands.insert(Operands.begin()+NumImplicitOps, Op); + NumImplicitOps++; + } } @@ -218,10 +299,26 @@ void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { ::print(mop, OS, TM); if (mop.isReg()) { - if (mop.isImplicit()) - OS << (mop.isDef() ? "<imp-def>" : "<imp-use>"); - else if (mop.isDef()) - OS << "<def>"; + 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 << ">"; + } } } |