#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLTraits.h"
void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
const MachineJumpTableInfo &JTI);
void convertStackObjects(yaml::MachineFunction &MF,
- const MachineFrameInfo &MFI, ModuleSlotTracker &MST,
+ const MachineFrameInfo &MFI, MachineModuleInfo &MMI,
+ ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI);
private:
void printStackObjectReference(int FrameIndex);
void printOffset(int64_t Offset);
void printTargetFlags(const MachineOperand &Op);
- void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
+ void print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
+ unsigned I, bool ShouldPrintRegisterTies, bool IsDef = false);
void print(const MachineMemOperand &Op);
void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
ModuleSlotTracker MST(MF.getFunction()->getParent());
MST.incorporateFunction(*MF.getFunction());
convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
- convertStackObjects(YamlMF, *MF.getFrameInfo(), MST,
+ convertStackObjects(YamlMF, *MF.getFrameInfo(), MF.getMMI(), MST,
MF.getSubtarget().getRegisterInfo());
if (const auto *ConstantPool = MF.getConstantPool())
convert(YamlMF, *ConstantPool);
void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
const MachineFrameInfo &MFI,
+ MachineModuleInfo &MMI,
ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI) {
// Process fixed stack objects.
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
.printStackObjectReference(MFI.getStackProtectorIndex());
}
+
+ // Print the debug variable information.
+ for (MachineModuleInfo::VariableDbgInfo &DebugVar :
+ MMI.getVariableDbgInfo()) {
+ auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot);
+ assert(StackObjectInfo != StackObjectOperandMapping.end() &&
+ "Invalid stack object index");
+ const FrameIndexOperand &StackObject = StackObjectInfo->second;
+ assert(!StackObject.IsFixed && "Expected a non-fixed stack object");
+ auto &Object = MF.StackObjects[StackObject.ID];
+ {
+ raw_string_ostream StrOS(Object.DebugVar.Value);
+ DebugVar.Var->printAsOperand(StrOS, MST);
+ }
+ {
+ raw_string_ostream StrOS(Object.DebugExpr.Value);
+ DebugVar.Expr->printAsOperand(StrOS, MST);
+ }
+ {
+ raw_string_ostream StrOS(Object.DebugLoc.Value);
+ DebugVar.Loc->printAsOperand(StrOS, MST);
+ }
+ }
}
void MIRPrinter::convert(yaml::MachineFunction &MF,
OS << "address-taken";
HasAttributes = true;
}
- if (MBB.isLandingPad()) {
+ if (MBB.isEHPad()) {
OS << (HasAttributes ? ", " : " (");
OS << "landing-pad";
HasAttributes = true;
assert(TRI && "Expected target register info");
if (!MBB.livein_empty()) {
OS.indent(2) << "liveins: ";
- for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
- if (I != MBB.livein_begin())
+ bool First = true;
+ for (const auto &LI : MBB.liveins()) {
+ if (!First)
OS << ", ";
- printReg(*I, OS, TRI);
+ First = false;
+ printReg(LI.PhysReg, OS, TRI);
+ if (LI.LaneMask != ~0u)
+ OS << ':' << PrintLaneMask(LI.LaneMask);
}
OS << "\n";
HasLineAttributes = true;
OS.indent(2) << "}\n";
}
+/// Return true when an instruction has tied register that can't be determined
+/// by the instruction's descriptor.
+static bool hasComplexRegisterTies(const MachineInstr &MI) {
+ const MCInstrDesc &MCID = MI.getDesc();
+ for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
+ const auto &Operand = MI.getOperand(I);
+ if (!Operand.isReg() || Operand.isDef())
+ // Ignore the defined registers as MCID marks only the uses as tied.
+ continue;
+ int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
+ int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1;
+ if (ExpectedTiedIdx != TiedIdx)
+ return true;
+ }
+ return false;
+}
+
void MIPrinter::print(const MachineInstr &MI) {
const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
const auto *TRI = SubTarget.getRegisterInfo();
if (MI.isCFIInstruction())
assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
+ bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI);
unsigned I = 0, E = MI.getNumOperands();
for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
!MI.getOperand(I).isImplicit();
++I) {
if (I)
OS << ", ";
- print(MI.getOperand(I), TRI);
+ print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, /*IsDef=*/true);
}
if (I)
for (; I < E; ++I) {
if (NeedComma)
OS << ", ";
- print(MI.getOperand(I), TRI);
+ print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies);
NeedComma = true;
}
}
}
+static void printIRSlotNumber(raw_ostream &OS, int Slot) {
+ if (Slot == -1)
+ OS << "<badref>";
+ else
+ OS << Slot;
+}
+
void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
OS << "%ir-block.";
if (BB.hasName()) {
CustomMST.incorporateFunction(*F);
Slot = CustomMST.getLocalSlot(&BB);
}
- if (Slot == -1)
- OS << "<badref>";
- else
- OS << Slot;
+ printIRSlotNumber(OS, Slot);
}
void MIPrinter::printIRValueReference(const Value &V) {
+ if (isa<GlobalValue>(V)) {
+ V.printAsOperand(OS, /*PrintType=*/false, MST);
+ return;
+ }
+ if (isa<Constant>(V)) {
+ // Machine memory operands can load/store to/from constant value pointers.
+ OS << '`';
+ V.printAsOperand(OS, /*PrintType=*/true, MST);
+ OS << '`';
+ return;
+ }
OS << "%ir.";
if (V.hasName()) {
printLLVMNameWithoutPrefix(OS, V.getName());
return;
}
- // TODO: Serialize the unnamed IR value references.
- OS << "<unserializable ir value>";
+ printIRSlotNumber(OS, MST.getLocalSlot(&V));
}
void MIPrinter::printStackObjectReference(int FrameIndex) {
return nullptr;
}
-void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
+void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
+ unsigned I, bool ShouldPrintRegisterTies, bool IsDef) {
printTargetFlags(Op);
switch (Op.getType()) {
case MachineOperand::MO_Register:
- // FIXME: Serialize the tied register.
if (Op.isImplicit())
OS << (Op.isDef() ? "implicit-def " : "implicit ");
+ else if (!IsDef && Op.isDef())
+ // Print the 'def' flag only when the operand is defined after '='.
+ OS << "def ";
if (Op.isInternalRead())
OS << "internal ";
if (Op.isDead())
// Print the sub register.
if (Op.getSubReg() != 0)
OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
+ if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef())
+ OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")";
break;
case MachineOperand::MO_Immediate:
OS << Op.getImm();
case MachineOperand::MO_Metadata:
Op.getMetadata()->printAsOperand(OS, MST);
break;
+ case MachineOperand::MO_MCSymbol:
+ OS << "<mcsymbol " << *Op.getMCSymbol() << ">";
+ break;
case MachineOperand::MO_CFIIndex: {
const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
break;
}
- default:
- // TODO: Print the other machine operands.
- llvm_unreachable("Can't print this machine operand at the moment");
}
}
cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex());
break;
case PseudoSourceValue::GlobalValueCallEntry:
+ OS << "call-entry ";
cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
OS, /*PrintType=*/false, MST);
break;
case PseudoSourceValue::ExternalSymbolCallEntry:
- OS << '$';
+ OS << "call-entry $";
printLLVMNameWithoutPrefix(
OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
break;