Index: llvm/include/llvm/CodeGen/TargetInstrInfo.h =================================================================== --- llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -1309,6 +1309,13 @@ /// Returns true if the instruction is already predicated. virtual bool isPredicated(const MachineInstr &MI) const { return false; } + // Returns a MIRPrinter comment for this machine operand. + virtual std::string createMIROperandComment(const MachineInstr &MI, + const MachineOperand &Op, + unsigned OpIdx) const { + return std::string(); + }; + /// Returns true if the instruction is a /// terminator instruction that has not been predicated. virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const; Index: llvm/lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -104,6 +104,20 @@ return C; } +/// Machine operands can have comments, enclosed between /* and */. +/// This eats up all tokens, including /* and */. +static Cursor skipMachineOperandComment(Cursor C) { + if (C.peek() != '/' || C.peek(1) != '*') + return C; + + while (C.peek() != '*' || C.peek(1) != '/') + C.advance(); + + C.advance(); + C.advance(); + return C; +} + /// Return true if the given character satisfies the following regular /// expression: [-a-zA-Z$._0-9] static bool isIdentifierChar(char C) { @@ -691,6 +705,8 @@ return C.remaining(); } + C = skipMachineOperandComment(C); + if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) return R.remaining(); if (Cursor R = maybeLexIdentifier(C, Token)) Index: llvm/lib/CodeGen/MIRPrinter.cpp =================================================================== --- llvm/lib/CodeGen/MIRPrinter.cpp +++ llvm/lib/CodeGen/MIRPrinter.cpp @@ -162,8 +162,9 @@ void print(const MachineInstr &MI); void printStackObjectReference(int FrameIndex); void print(const MachineInstr &MI, unsigned OpIdx, - const TargetRegisterInfo *TRI, bool ShouldPrintRegisterTies, - LLT TypeToPrint, bool PrintDef = true); + const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, + bool ShouldPrintRegisterTies, LLT TypeToPrint, + bool PrintDef = true); }; } // end namespace llvm @@ -721,7 +722,7 @@ ++I) { if (I) OS << ", "; - print(MI, I, TRI, ShouldPrintRegisterTies, + print(MI, I, TRI, TII, ShouldPrintRegisterTies, MI.getTypeToPrint(I, PrintedTypes, MRI), /*PrintDef=*/false); } @@ -763,7 +764,7 @@ for (; I < E; ++I) { if (NeedComma) OS << ", "; - print(MI, I, TRI, ShouldPrintRegisterTies, + print(MI, I, TRI, TII, ShouldPrintRegisterTies, MI.getTypeToPrint(I, PrintedTypes, MRI)); NeedComma = true; } @@ -822,11 +823,20 @@ Operand.Name); } +static std::string formatOperandComment(std::string Comment) { + if (Comment.empty()) + return Comment; + return std::string(" /* " + Comment + " */"); +} + void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo *TRI, + const TargetInstrInfo *TII, bool ShouldPrintRegisterTies, LLT TypeToPrint, bool PrintDef) { const MachineOperand &Op = MI.getOperand(OpIdx); + std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx); + switch (Op.getType()) { case MachineOperand::MO_Immediate: if (MI.isOperandSubregIdx(OpIdx)) { @@ -858,6 +868,7 @@ const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo(); Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false, ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII); + OS << formatOperandComment(MOComment); break; } case MachineOperand::MO_FrameIndex: Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.h =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -146,6 +146,11 @@ // Predication support. bool isPredicated(const MachineInstr &MI) const override; + // MIR printer helper function to annotate Operands with a comment. + std::string createMIROperandComment(const MachineInstr &MI, + const MachineOperand &Op, + unsigned OpIdx) const override; + ARMCC::CondCodes getPredicate(const MachineInstr &MI) const { int PIdx = MI.findFirstPredOperandIdx(); return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm() Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -495,6 +495,23 @@ return PIdx != -1 && MI.getOperand(PIdx).getImm() != ARMCC::AL; } +std::string ARMBaseInstrInfo::createMIROperandComment(const MachineInstr &MI, + const MachineOperand &Op, + unsigned OpIdx) const { + // Only support immediates for now + if (Op.getType() != MachineOperand::MO_Immediate) + return std::string(); + + // And print its corresponding condition code if the immediate is a predicate + int FirstPredOp = MI.findFirstPredOperandIdx(); + if (FirstPredOp != (int) OpIdx) + return std::string(); + + std::string CC = "CC::"; + CC += ARMCondCodeToString((ARMCC::CondCodes)Op.getImm()); + return CC; +} + bool ARMBaseInstrInfo::PredicateInstruction( MachineInstr &MI, ArrayRef Pred) const { unsigned Opc = MI.getOpcode(); Index: llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir =================================================================== --- llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir +++ llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir @@ -100,38 +100,38 @@ ; CHECK: bb.0.entry: ; CHECK: successors: %bb.2(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: t2B %bb.2, 14, $noreg + ; CHECK: t2B %bb.2, 14 /* CC::al */, $noreg ; CHECK: bb.1.while.body.end: ; CHECK: successors: %bb.2(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i.14) - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next.i.14) + ; CHECK: tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 { ; CHECK: t2IT 0, 8, implicit-def $itstate - ; CHECK: tBX_RET 0, killed $cpsr, implicit $r0, implicit internal killed $itstate + ; CHECK: tBX_RET 0 /* CC::eq */, killed $cpsr, implicit $r0, implicit internal killed $itstate ; CHECK: } ; CHECK: bb.2.while.begin: ; CHECK: successors: %bb.4(0x04000000), %bb.3(0x7c000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 14, $noreg :: (load 4 from %ir.info.i) - ; CHECK: renamable $r2 = tLDRHi killed renamable $r2, 0, 14, $noreg :: (load 2 from %ir.data16.i1) - ; CHECK: dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg - ; CHECK: t2Bcc %bb.4, 0, killed $cpsr + ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 14 /* CC::al */, $noreg :: (load 4 from %ir.info.i) + ; CHECK: renamable $r2 = tLDRHi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load 2 from %ir.data16.i1) + ; CHECK: dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14 /* CC::al */, $noreg + ; CHECK: t2Bcc %bb.4, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.3.while.body.a: ; CHECK: successors: %bb.4(0x4207fef8), %bb.1(0x3df80108) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i2) - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next.i2) + ; CHECK: tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 { ; CHECK: t2IT 1, 30, implicit-def $itstate - ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 1, $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) - ; CHECK: renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) - ; CHECK: t2TEQrr internal killed renamable $r2, renamable $r1, 1, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate + ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 1 /* CC::ne */, $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) + ; CHECK: renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1 /* CC::ne */, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) + ; CHECK: t2TEQrr internal killed renamable $r2, renamable $r1, 1 /* CC::ne */, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate ; CHECK: } - ; CHECK: t2Bcc %bb.1, 1, killed $cpsr + ; CHECK: t2Bcc %bb.1, 1 /* CC::ne */, killed $cpsr ; CHECK: bb.4.exit: ; CHECK: liveins: $r0 - ; CHECK: tBX_RET 14, $noreg, implicit killed $r0 + ; CHECK: tBX_RET 14 /* CC::al */, $noreg, implicit killed $r0 bb.0.entry: successors: %bb.1(0x80000000) liveins: $r0, $r1 @@ -189,36 +189,36 @@ ; CHECK: bb.0.entry: ; CHECK: successors: %bb.1(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: $r2 = tMOVr $r0, 14, $noreg + ; CHECK: $r2 = tMOVr $r0, 14 /* CC::al */, $noreg ; CHECK: bb.1.while.begin: ; CHECK: successors: %bb.5(0x04000000), %bb.2(0x7c000000) ; CHECK: liveins: $r1, $r2 - ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i) - ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i1) - ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14 /* CC::al */, $noreg :: (load 4 from %ir.info.i) + ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 2 from %ir.data16.i1) + ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.2.while.body.a: ; CHECK: successors: %bb.5(0x04000000), %bb.3(0x7c000000) ; CHECK: liveins: $r0, $r1, $r2 - ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i2) - ; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next.i2) + ; CHECK: tCMPi8 renamable $r2, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.3.it.block: ; CHECK: successors: %bb.5(0x04000000), %bb.4(0x7c000000) ; CHECK: liveins: $r1, $r2 - ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i.1) - ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i.13) - ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14 /* CC::al */, $noreg :: (load 4 from %ir.info.i.1) + ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 2 from %ir.data16.i.13) + ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.4.while.body.end: ; CHECK: successors: %bb.5(0x04000000), %bb.1(0x7c000000) ; CHECK: liveins: $r0, $r1, $r2 - ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i.14) - ; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.1, 1, killed $cpsr + ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next.i.14) + ; CHECK: tCMPi8 renamable $r2, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.1, 1 /* CC::ne */, killed $cpsr ; CHECK: bb.5.exit: ; CHECK: liveins: $r0 - ; CHECK: tBX_RET 14, $noreg, implicit $r0 + ; CHECK: tBX_RET 14 /* CC::al */, $noreg, implicit $r0 bb.0.entry: successors: %bb.1(0x80000000) liveins: $r0, $r1