diff options
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 123 |
1 files changed, 82 insertions, 41 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index bc2a545..dce05d3 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -227,24 +227,11 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { if (const MachineBasicBlock *MBB = MI->getParent()) if (const MachineFunction *MF = MBB->getParent()) TM = &MF->getTarget(); + const TargetRegisterInfo *TRI = TM ? TM->getRegisterInfo() : 0; switch (getType()) { case MachineOperand::MO_Register: - if (getReg() == 0 || TargetRegisterInfo::isVirtualRegister(getReg())) { - OS << "%reg" << getReg(); - } else { - if (TM) - OS << "%" << TM->getRegisterInfo()->get(getReg()).Name; - else - OS << "%physreg" << getReg(); - } - - if (getSubReg() != 0) { - if (TM) - OS << ':' << TM->getRegisterInfo()->getSubRegIndexName(getSubReg()); - else - OS << ':' << getSubReg(); - } + OS << PrintReg(getReg(), TRI, getSubReg()); if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || isEarlyClobber()) { @@ -464,7 +451,8 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { /// MachineInstr ctor - This constructor creates a dummy MachineInstr with /// TID NULL and no operands. MachineInstr::MachineInstr() - : TID(0), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), + : TID(0), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + MemRefs(0), MemRefsEnd(0), Parent(0) { // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); @@ -483,7 +471,7 @@ void MachineInstr::addImplicitDefUseOperands() { /// implicit operands. It reserves space for the number of operands specified by /// the TargetInstrDesc. MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) - : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), + : TID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0) { if (!NoImp) NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); @@ -497,8 +485,8 @@ MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) /// MachineInstr ctor - As above, but with a DebugLoc. MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl, bool NoImp) - : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), - Parent(0), debugLoc(dl) { + : TID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) { if (!NoImp) NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + TID->getNumOperands()); @@ -512,7 +500,7 @@ MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl, /// 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), AsmPrinterFlags(0), + : TID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); @@ -527,8 +515,8 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid) /// MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const TargetInstrDesc &tid) - : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), - Parent(0), debugLoc(dl) { + : TID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) { assert(MBB && "Cannot use inserting ctor with null basic block!"); NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + TID->getNumOperands()); @@ -541,7 +529,7 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) - : TID(&MI.getDesc()), NumImplicitOps(0), AsmPrinterFlags(0), + : TID(&MI.getDesc()), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), MemRefs(MI.MemRefs), MemRefsEnd(MI.MemRefsEnd), Parent(0), debugLoc(MI.getDebugLoc()) { Operands.reserve(MI.getNumOperands()); @@ -551,6 +539,9 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) addOperand(MI.getOperand(i)); NumImplicitOps = MI.NumImplicitOps; + // Copy all the flags. + Flags = MI.Flags; + // Set parent to null. Parent = 0; @@ -826,6 +817,14 @@ unsigned MachineInstr::getNumExplicitOperands() const { return NumOperands; } +bool MachineInstr::isStackAligningInlineAsm() const { + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_IsAlignStack) + return true; + } + return false; +} /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of /// the specific register or -1 if it is not found. It further tightens @@ -925,14 +924,15 @@ int MachineInstr::findFirstPredOperandIdx() const { bool MachineInstr:: isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const { if (isInlineAsm()) { - assert(DefOpIdx >= 3); + assert(DefOpIdx > InlineAsm::MIOp_FirstOperand); const MachineOperand &MO = getOperand(DefOpIdx); if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0) return false; // Determine the actual operand index that corresponds to this index. unsigned DefNo = 0; unsigned DefPart = 0; - for (unsigned i = 2, e = getNumOperands(); i < e; ) { + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); + i < e; ) { const MachineOperand &FMO = getOperand(i); // After the normal asm operands there may be additional imp-def regs. if (!FMO.isImm()) @@ -947,7 +947,8 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const { } ++DefNo; } - for (unsigned i = 2, e = getNumOperands(); i != e; ++i) { + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); + i != e; ++i) { const MachineOperand &FMO = getOperand(i); if (!FMO.isImm()) continue; @@ -990,7 +991,8 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const { // Find the flag operand corresponding to UseOpIdx unsigned FlagIdx, NumOps=0; - for (FlagIdx = 2; FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { + for (FlagIdx = InlineAsm::MIOp_FirstOperand; + FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { const MachineOperand &UFMO = getOperand(FlagIdx); // After the normal asm operands there may be additional imp-def regs. if (!UFMO.isImm()) @@ -1008,9 +1010,9 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const { if (!DefOpIdx) return true; - unsigned DefIdx = 2; + unsigned DefIdx = InlineAsm::MIOp_FirstOperand; // Remember to adjust the index. First operand is asm string, second is - // the AlignStack bit, then there is a flag for each. + // the HasSideEffects and AlignStack bits, then there is a flag for each. while (DefNo) { const MachineOperand &FMO = getOperand(DefIdx); assert(FMO.isImm()); @@ -1115,7 +1117,9 @@ bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, SawStore = true; return false; } - if (TID->isTerminator() || TID->hasUnmodeledSideEffects()) + + if (isLabel() || isDebugValue() || + TID->isTerminator() || hasUnmodeledSideEffects()) return false; // See if this instruction does a load. If so, we have to guarantee that the @@ -1166,7 +1170,7 @@ bool MachineInstr::hasVolatileMemoryRef() const { if (!TID->mayStore() && !TID->mayLoad() && !TID->isCall() && - !TID->hasUnmodeledSideEffects()) + !hasUnmodeledSideEffects()) return false; // Otherwise, if the instruction has no memory reference information, @@ -1240,6 +1244,18 @@ unsigned MachineInstr::isConstantValuePHI() const { return Reg; } +bool MachineInstr::hasUnmodeledSideEffects() const { + if (getDesc().hasUnmodeledSideEffects()) + return true; + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_HasSideEffects) + return true; + } + + return false; +} + /// allDefsAreDead - Return true if all the defs of this instruction are dead. /// bool MachineInstr::allDefsAreDead() const { @@ -1314,7 +1330,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { if (StartOp != 0) OS << ", "; getOperand(StartOp).print(OS, TM); unsigned Reg = getOperand(StartOp).getReg(); - if (Reg && TargetRegisterInfo::isVirtualRegister(Reg)) + if (TargetRegisterInfo::isVirtualRegister(Reg)) VirtRegs.push_back(Reg); } @@ -1327,11 +1343,28 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { // Print the rest of the operands. bool OmittedAnyCallClobbers = false; bool FirstOp = true; + + if (isInlineAsm()) { + // Print asm string. + OS << " "; + getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); + + // Print HasSideEffects, IsAlignStack + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_HasSideEffects) + OS << " [sideeffect]"; + if (ExtraInfo & InlineAsm::Extra_IsAlignStack) + OS << " [alignstack]"; + + StartOp = InlineAsm::MIOp_FirstOperand; + FirstOp = false; + } + + for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); - if (MO.isReg() && MO.getReg() && - TargetRegisterInfo::isVirtualRegister(MO.getReg())) + if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) VirtRegs.push_back(MO.getReg()); // Omit call-clobbered registers which aren't used anywhere. This makes @@ -1341,7 +1374,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { if (MF && getDesc().isCall() && MO.isReg() && MO.isImplicit() && MO.isDef()) { unsigned Reg = MO.getReg(); - if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { const MachineRegisterInfo &MRI = MF->getRegInfo(); if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) { bool HasAliasLive = false; @@ -1388,6 +1421,14 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { } bool HaveSemi = false; + if (Flags) { + if (!HaveSemi) OS << ";"; HaveSemi = true; + OS << " flags: "; + + if (Flags & FrameSetup) + OS << "FrameSetup"; + } + if (!memoperands_empty()) { if (!HaveSemi) OS << ";"; HaveSemi = true; @@ -1405,26 +1446,27 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { if (!HaveSemi) OS << ";"; HaveSemi = true; for (unsigned i = 0; i != VirtRegs.size(); ++i) { const TargetRegisterClass *RC = MRI->getRegClass(VirtRegs[i]); - OS << " " << RC->getName() << ":%reg" << VirtRegs[i]; + OS << " " << RC->getName() << ':' << PrintReg(VirtRegs[i]); for (unsigned j = i+1; j != VirtRegs.size();) { if (MRI->getRegClass(VirtRegs[j]) != RC) { ++j; continue; } if (VirtRegs[i] != VirtRegs[j]) - OS << "," << VirtRegs[j]; + OS << "," << PrintReg(VirtRegs[j]); VirtRegs.erase(VirtRegs.begin()+j); } } } + // Print debug location information. if (!debugLoc.isUnknown() && MF) { - if (!HaveSemi) OS << ";"; + if (!HaveSemi) OS << ";"; HaveSemi = true; OS << " dbg:"; printDebugLoc(debugLoc, MF, OS); } - OS << "\n"; + OS << '\n'; } bool MachineInstr::addRegisterKilled(unsigned IncomingReg, @@ -1590,8 +1632,7 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { switch (MO.getType()) { default: break; case MachineOperand::MO_Register: - if (MO.isDef() && MO.getReg() && - TargetRegisterInfo::isVirtualRegister(MO.getReg())) + if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue; // Skip virtual register defs. Key |= MO.getReg(); break; |