#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;
//===----------------------------------------------------------------------===//
OS << '>';
break;
case MachineOperand::MO_BlockAddress:
- OS << "<";
+ OS << '<';
WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
OS << '>';
break;
+ case MachineOperand::MO_Metadata:
+ OS << '<';
+ WriteAsOperand(OS, getMetadata(), /*PrintType=*/false);
+ OS << '>';
+ break;
default:
llvm_unreachable("Unrecognized operand type");
}
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 {
if (FirstOp) FirstOp = false; else OS << ",";
OS << " ";
+ 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) FirstOp = false; else OS << ",";
+ if (!FirstOp) OS << ",";
OS << " ...";
}
}
if (!debugLoc.isUnknown() && MF) {
- if (!HaveSemi) OS << ";"; HaveSemi = true;
+ if (!HaveSemi) OS << ";";
// TODO: print InlinedAtLoc information
- DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc);
- DICompileUnit CU(DLT.Scope);
- if (!CU.isNull())
- OS << " dbg:" << CU.getDirectory() << '/' << CU.getFilename() << ":"
- << DLT.Line << ":" << DLT.Col;
+ 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*/));
+}