#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/InlineAsm.h"
+#include "llvm/Type.h"
#include "llvm/Value.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/DebugInfo.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/Metadata.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
/// print - Print the specified machine operand.
///
void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
+ // If the instruction is embedded into a basic block, we can find the
+ // target info for the instruction.
+ if (!TM)
+ if (const MachineInstr *MI = getParent())
+ if (const MachineBasicBlock *MBB = MI->getParent())
+ if (const MachineFunction *MF = MBB->getParent())
+ TM = &MF->getTarget();
+
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
- OS << "%mreg" << getReg();
+ OS << "%physreg" << getReg();
}
if (getSubReg() != 0)
OS << getFPImm()->getValueAPF().convertToDouble();
break;
case MachineOperand::MO_MachineBasicBlock:
- OS << "mbb<"
- << ((Value*)getMBB()->getBasicBlock())->getName()
- << "," << (void*)getMBB() << '>';
+ OS << "<BB#" << getMBB()->getNumber() << ">";
break;
case MachineOperand::MO_FrameIndex:
OS << "<fi#" << getIndex() << '>';
OS << "<jt#" << getIndex() << '>';
break;
case MachineOperand::MO_GlobalAddress:
- OS << "<ga:" << ((Value*)getGlobal())->getName();
+ OS << "<ga:";
+ WriteAsOperand(OS, getGlobal(), /*PrintType=*/false);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
OS << '>';
break;
case MachineOperand::MO_BlockAddress:
- OS << "<blockaddress: ";
- WriteAsOperand(OS, getBlockAddress()->getFunction(), /*PrintType=*/false);
- OS << ", ";
- WriteAsOperand(OS, getBlockAddress()->getBasicBlock(), /*PrintType=*/false);
+ OS << '<';
+ WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
+ OS << '>';
+ break;
+ case MachineOperand::MO_Metadata:
+ OS << '<';
+ WriteAsOperand(OS, getMetadata(), /*PrintType=*/false);
OS << '>';
break;
default:
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
/// TID NULL and no operands.
MachineInstr::MachineInstr()
- : TID(0), NumImplicitOps(0), MemRefs(0), MemRefsEnd(0),
+ : TID(0), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0),
Parent(0), debugLoc(DebugLoc::getUnknownLoc()) {
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
/// 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), MemRefs(0), MemRefsEnd(0), Parent(0),
+ : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0),
+ MemRefs(0), MemRefsEnd(0), Parent(0),
debugLoc(DebugLoc::getUnknownLoc()) {
if (!NoImp && TID->getImplicitDefs())
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
/// MachineInstr ctor - As above, but with a DebugLoc.
MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl,
bool NoImp)
- : TID(&tid), NumImplicitOps(0), MemRefs(0), MemRefsEnd(0),
+ : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0),
Parent(0), debugLoc(dl) {
if (!NoImp && TID->getImplicitDefs())
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
/// basic block.
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid)
- : TID(&tid), NumImplicitOps(0), MemRefs(0), MemRefsEnd(0), Parent(0),
+ : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0),
+ MemRefs(0), MemRefsEnd(0), Parent(0),
debugLoc(DebugLoc::getUnknownLoc()) {
assert(MBB && "Cannot use inserting ctor with null basic block!");
if (TID->ImplicitDefs)
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
const TargetInstrDesc &tid)
- : TID(&tid), NumImplicitOps(0), MemRefs(0), MemRefsEnd(0),
+ : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0),
Parent(0), debugLoc(dl) {
assert(MBB && "Cannot use inserting ctor with null basic block!");
if (TID->ImplicitDefs)
/// MachineInstr ctor - Copies MachineInstr arg exactly
///
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
- : TID(&MI.getDesc()), NumImplicitOps(0),
+ : TID(&MI.getDesc()), NumImplicitOps(0), AsmPrinterFlags(0),
MemRefs(MI.MemRefs), MemRefsEnd(MI.MemRefsEnd),
Parent(0), debugLoc(MI.getDebugLoc()) {
Operands.reserve(MI.getNumOperands());
Operands.back().ParentMI = this;
// If the operand is a register, update the operand's use list.
- if (Op.isReg())
+ if (Op.isReg()) {
Operands.back().AddRegOperandToRegInfo(RegInfo);
+ // If the register operand is flagged as early, mark the operand as such
+ unsigned OpNo = Operands.size() - 1;
+ if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1)
+ Operands[OpNo].setIsEarlyClobber(true);
+ }
return;
}
}
// Do explicitly set the reginfo for this operand though, to ensure the
// next/prev fields are properly nulled out.
- if (Operands[OpNo].isReg())
+ if (Operands[OpNo].isReg()) {
Operands[OpNo].AddRegOperandToRegInfo(0);
+ // If the register operand is flagged as early, mark the operand as such
+ if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1)
+ Operands[OpNo].setIsEarlyClobber(true);
+ }
} else if (Operands.size()+1 <= Operands.capacity()) {
// Otherwise, we have to remove register operands from their register use
Operands.insert(Operands.begin()+OpNo, Op);
Operands[OpNo].ParentMI = this;
- if (Operands[OpNo].isReg())
+ if (Operands[OpNo].isReg()) {
Operands[OpNo].AddRegOperandToRegInfo(RegInfo);
+ // If the register operand is flagged as early, mark the operand as such
+ if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1)
+ Operands[OpNo].setIsEarlyClobber(true);
+ }
// Re-add all the implicit ops.
for (unsigned i = OpNo+1, e = Operands.size(); i != e; ++i) {
// Re-add all the operands.
AddRegOperandsToUseLists(*RegInfo);
+
+ // If the register operand is flagged as early, mark the operand as such
+ if (Operands[OpNo].isReg()
+ && TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1)
+ Operands[OpNo].setIsEarlyClobber(true);
}
}
return true;
}
+/// isConstantValuePHI - If the specified instruction is a PHI that always
+/// merges together the same virtual register, return the register, otherwise
+/// return 0.
+unsigned MachineInstr::isConstantValuePHI() const {
+ if (getOpcode() != TargetInstrInfo::PHI)
+ return 0;
+ assert(getNumOperands() >= 3 &&
+ "It's illegal to have a PHI without source operands");
+
+ unsigned Reg = getOperand(1).getReg();
+ for (unsigned i = 3, e = getNumOperands(); i < e; i += 2)
+ if (getOperand(i).getReg() != Reg)
+ return 0;
+ return Reg;
+}
+
void MachineInstr::dump() const {
- errs() << " " << *this;
+ dbgs() << " " << *this;
}
void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
- // Specialize printing if op#0 is definition
- unsigned StartOp = 0;
- if (getNumOperands() && getOperand(0).isReg() && getOperand(0).isDef()) {
- getOperand(0).print(OS, TM);
- OS << " = ";
- ++StartOp; // Don't print this operand again!
+ // We can be a bit tidier if we know the TargetMachine and/or MachineFunction.
+ const MachineFunction *MF = 0;
+ if (const MachineBasicBlock *MBB = getParent()) {
+ MF = MBB->getParent();
+ if (!TM && MF)
+ TM = &MF->getTarget();
+ }
+
+ // Print explicitly defined operands on the left of an assignment syntax.
+ unsigned StartOp = 0, e = getNumOperands();
+ for (; StartOp < e && getOperand(StartOp).isReg() &&
+ getOperand(StartOp).isDef() &&
+ !getOperand(StartOp).isImplicit();
+ ++StartOp) {
+ if (StartOp != 0) OS << ", ";
+ getOperand(StartOp).print(OS, TM);
}
+ if (StartOp != 0)
+ OS << " = ";
+
+ // Print the opcode name.
OS << getDesc().getName();
+ // Print the rest of the operands.
+ bool OmittedAnyCallClobbers = false;
+ bool FirstOp = true;
for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
- if (i != StartOp)
- OS << ",";
+ const MachineOperand &MO = getOperand(i);
+
+ // Omit call-clobbered registers which aren't used anywhere. This makes
+ // call instructions much less noisy on targets where calls clobber lots
+ // of registers. Don't rely on MO.isDead() because we may be called before
+ // LiveVariables is run, or we may be looking at a non-allocatable reg.
+ if (MF && getDesc().isCall() &&
+ MO.isReg() && MO.isImplicit() && MO.isDef()) {
+ unsigned Reg = MO.getReg();
+ if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
+ if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) {
+ bool HasAliasLive = false;
+ for (const unsigned *Alias = TM->getRegisterInfo()->getAliasSet(Reg);
+ unsigned AliasReg = *Alias; ++Alias)
+ if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) {
+ HasAliasLive = true;
+ break;
+ }
+ if (!HasAliasLive) {
+ OmittedAnyCallClobbers = true;
+ continue;
+ }
+ }
+ }
+ }
+
+ if (FirstOp) FirstOp = false; else OS << ",";
OS << " ";
- getOperand(i).print(OS, TM);
+ if (i < getDesc().NumOperands) {
+ const TargetOperandInfo &TOI = getDesc().OpInfo[i];
+ if (TOI.isPredicate())
+ OS << "pred:";
+ if (TOI.isOptionalDef())
+ OS << "opt:";
+ }
+ MO.print(OS, TM);
+ }
+
+ // Briefly indicate whether any call clobbers were omitted.
+ if (OmittedAnyCallClobbers) {
+ if (!FirstOp) OS << ",";
+ OS << " ...";
}
+ bool HaveSemi = false;
if (!memoperands_empty()) {
- OS << ", Mem:";
+ if (!HaveSemi) OS << ";"; HaveSemi = true;
+
+ OS << " mem:";
for (mmo_iterator i = memoperands_begin(), e = memoperands_end();
i != e; ++i) {
OS << **i;
}
}
- if (!debugLoc.isUnknown()) {
- const MachineFunction *MF = getParent()->getParent();
- DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc);
- DICompileUnit CU(DLT.Scope);
- if (!CU.isNull())
- OS << " [dbg: "
- << CU.getDirectory() << '/' << CU.getFilename() << ","
- << DLT.Line << ","
- << DLT.Col << "]";
+ if (!debugLoc.isUnknown() && MF) {
+ if (!HaveSemi) OS << ";";
+
+ // TODO: print InlinedAtLoc information
+
+ DILocation DLT = MF->getDILocation(debugLoc);
+ DIScope Scope = DLT.getScope();
+ OS << " dbg:";
+ // Omit the directory, since it's usually long and uninteresting.
+ if (!Scope.isNull())
+ OS << Scope.getFilename();
+ else
+ OS << "<unknown>";
+ OS << ':' << DLT.getLineNumber();
+ if (DLT.getColumnNumber() != 0)
+ OS << ':' << DLT.getColumnNumber();
}
OS << "\n";
true /*IsDead*/));
return true;
}
+
+void MachineInstr::addRegisterDefined(unsigned IncomingReg,
+ const TargetRegisterInfo *RegInfo) {
+ MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo);
+ if (!MO || MO->getSubReg())
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ true /*IsDef*/,
+ true /*IsImp*/));
+}