From 5de20e039ed65ae729cf0502b71cfafbd0f9617e Mon Sep 17 00:00:00 2001 From: Francis Visoiu Mistrih Date: Fri, 15 Dec 2017 15:17:18 +0000 Subject: [PATCH] [MIR] Add support for missing CFI directives The following CFI directives are suported by MC but not by MIR: * .cfi_rel_offset * .cfi_adjust_cfa_offset * .cfi_escape * .cfi_remember_state * .cfi_restore_state * .cfi_undefined * .cfi_register * .cfi_window_save Add support for printing, parsing and update tests. Differential Revision: https://reviews.llvm.org/D41230 llvm-svn: 320819 --- llvm/include/llvm/CodeGen/MachineOperand.h | 3 + llvm/lib/CodeGen/MIRParser/MILexer.cpp | 8 ++ llvm/lib/CodeGen/MIRParser/MILexer.h | 8 ++ llvm/lib/CodeGen/MIRParser/MIParser.cpp | 67 ++++++++++++++++ llvm/lib/CodeGen/MIRPrinter.cpp | 78 ++++++++++++++++--- llvm/lib/CodeGen/MachineOperand.cpp | 6 +- llvm/test/CodeGen/MIR/AArch64/cfi.mir | 57 ++++++-------- .../CodeGen/MIR/X86/shrink_wrap_dbg_value.mir | 2 +- 8 files changed, 181 insertions(+), 48 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h index a4c84be02e43..f38760471ba5 100644 --- a/llvm/include/llvm/CodeGen/MachineOperand.h +++ b/llvm/include/llvm/CodeGen/MachineOperand.h @@ -242,6 +242,9 @@ public: /// Print operand target flags. static void printTargetFlags(raw_ostream& OS, const MachineOperand &Op); + /// Print a MCSymbol as an operand. + static void printSymbol(raw_ostream &OS, MCSymbol &Sym); + /// Print the MachineOperand to \p os. /// Providing a valid \p TRI and \p IntrinsicInfo results in a more /// target-specific printing. If \p TRI and \p IntrinsicInfo are null, the diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index fe6d075726e5..6adb7f1288d7 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -214,10 +214,18 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("debug-location", MIToken::kw_debug_location) .Case("same_value", MIToken::kw_cfi_same_value) .Case("offset", MIToken::kw_cfi_offset) + .Case("rel_offset", MIToken::kw_cfi_rel_offset) .Case("def_cfa_register", MIToken::kw_cfi_def_cfa_register) .Case("def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) + .Case("adjust_cfa_offset", MIToken::kw_cfi_adjust_cfa_offset) + .Case("escape", MIToken::kw_cfi_escape) .Case("def_cfa", MIToken::kw_cfi_def_cfa) + .Case("remember_state", MIToken::kw_cfi_remember_state) .Case("restore", MIToken::kw_cfi_restore) + .Case("restore_state", MIToken::kw_cfi_restore_state) + .Case("undefined", MIToken::kw_cfi_undefined) + .Case("register", MIToken::kw_cfi_register) + .Case("window_save", MIToken::kw_cfi_window_save) .Case("blockaddress", MIToken::kw_blockaddress) .Case("intrinsic", MIToken::kw_intrinsic) .Case("target-index", MIToken::kw_target_index) diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index f7027bea1814..0204d549d5d4 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -66,10 +66,18 @@ struct MIToken { kw_debug_location, kw_cfi_same_value, kw_cfi_offset, + kw_cfi_rel_offset, kw_cfi_def_cfa_register, kw_cfi_def_cfa_offset, + kw_cfi_adjust_cfa_offset, + kw_cfi_escape, kw_cfi_def_cfa, + kw_cfi_register, + kw_cfi_remember_state, kw_cfi_restore, + kw_cfi_restore_state, + kw_cfi_undefined, + kw_cfi_window_save, kw_blockaddress, kw_intrinsic, kw_target_index, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 15399c240dc4..c1471520d243 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -213,6 +213,7 @@ public: bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); + bool parseCFIEscapeValues(std::string& Values); bool parseCFIOperand(MachineOperand &Dest); bool parseIRBlock(BasicBlock *&BB, const Function &F); bool parseBlockAddressOperand(MachineOperand &Dest); @@ -1599,6 +1600,21 @@ bool MIParser::parseCFIRegister(unsigned &Reg) { return false; } +bool MIParser::parseCFIEscapeValues(std::string &Values) { + do { + if (Token.isNot(MIToken::HexLiteral)) + return error("expected a hexadecimal literal"); + unsigned Value; + if (getUnsigned(Value)) + return true; + if (Value > UINT8_MAX) + return error("expected a 8-bit integer (too large)"); + Values.push_back(static_cast(Value)); + lex(); + } while (consumeIfPresent(MIToken::comma)); + return false; +} + bool MIParser::parseCFIOperand(MachineOperand &Dest) { auto Kind = Token.kind(); lex(); @@ -1618,6 +1634,13 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); break; + case MIToken::kw_cfi_rel_offset: + if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || + parseCFIOffset(Offset)) + return true; + CFIIndex = MF.addFrameInst( + MCCFIInstruction::createRelOffset(nullptr, Reg, Offset)); + break; case MIToken::kw_cfi_def_cfa_register: if (parseCFIRegister(Reg)) return true; @@ -1631,6 +1654,12 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { CFIIndex = MF.addFrameInst( MCCFIInstruction::createDefCfaOffset(nullptr, -Offset)); break; + case MIToken::kw_cfi_adjust_cfa_offset: + if (parseCFIOffset(Offset)) + return true; + CFIIndex = MF.addFrameInst( + MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset)); + break; case MIToken::kw_cfi_def_cfa: if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || parseCFIOffset(Offset)) @@ -1639,12 +1668,42 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); break; + case MIToken::kw_cfi_remember_state: + CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); + break; case MIToken::kw_cfi_restore: if (parseCFIRegister(Reg)) return true; CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); break; + case MIToken::kw_cfi_restore_state: + CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); + break; + case MIToken::kw_cfi_undefined: + if (parseCFIRegister(Reg)) + return true; + CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg)); + break; + case MIToken::kw_cfi_register: { + unsigned Reg2; + if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || + parseCFIRegister(Reg2)) + return true; + CFIIndex = + MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2)); + break; + } + case MIToken::kw_cfi_window_save: + CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); + break; + case MIToken::kw_cfi_escape: { + std::string Values; + if (parseCFIEscapeValues(Values)) + return true; + CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values)); + break; + } default: // TODO: Parse the other CFI operands. llvm_unreachable("The current token should be a cfi operand"); @@ -1921,10 +1980,18 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, return parseMetadataOperand(Dest); case MIToken::kw_cfi_same_value: case MIToken::kw_cfi_offset: + case MIToken::kw_cfi_rel_offset: case MIToken::kw_cfi_def_cfa_register: case MIToken::kw_cfi_def_cfa_offset: + case MIToken::kw_cfi_adjust_cfa_offset: + case MIToken::kw_cfi_escape: case MIToken::kw_cfi_def_cfa: + case MIToken::kw_cfi_register: + case MIToken::kw_cfi_remember_state: case MIToken::kw_cfi_restore: + case MIToken::kw_cfi_restore_state: + case MIToken::kw_cfi_undefined: + case MIToken::kw_cfi_window_save: return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index ac94e96bea88..8cc9ad28c2a7 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -998,42 +998,96 @@ void MIPrinter::print(const MCCFIInstruction &CFI, switch (CFI.getOperation()) { case MCCFIInstruction::OpSameValue: OS << "same_value "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; + case MCCFIInstruction::OpRememberState: + OS << "remember_state "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + break; + case MCCFIInstruction::OpRestoreState: + OS << "restore_state "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + break; case MCCFIInstruction::OpOffset: OS << "offset "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; case MCCFIInstruction::OpDefCfaRegister: OS << "def_cfa_register "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; case MCCFIInstruction::OpDefCfaOffset: OS << "def_cfa_offset "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); OS << CFI.getOffset(); break; case MCCFIInstruction::OpDefCfa: OS << "def_cfa "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; + case MCCFIInstruction::OpRelOffset: + OS << "rel_offset "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + printCFIRegister(CFI.getRegister(), OS, TRI); + OS << ", " << CFI.getOffset(); + break; + case MCCFIInstruction::OpAdjustCfaOffset: + OS << "adjust_cfa_offset "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + OS << CFI.getOffset(); + break; case MCCFIInstruction::OpRestore: OS << "restore "; - if (CFI.getLabel()) - OS << " "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; + case MCCFIInstruction::OpEscape: { + OS << "escape "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + if (!CFI.getValues().empty()) { + size_t e = CFI.getValues().size() - 1; + for (size_t i = 0; i < e; ++i) + OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; + OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", "; + } + break; + } + case MCCFIInstruction::OpUndefined: + OS << "undefined "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + printCFIRegister(CFI.getRegister(), OS, TRI); + break; + case MCCFIInstruction::OpRegister: + OS << "register "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + printCFIRegister(CFI.getRegister(), OS, TRI); + OS << ", "; + printCFIRegister(CFI.getRegister2(), OS, TRI); + break; + case MCCFIInstruction::OpWindowSave: + OS << "window_save "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); + break; default: // TODO: Print the other CFI Operations. OS << ""; diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp index 1640d57eb488..c95fb127d7bb 100644 --- a/llvm/lib/CodeGen/MachineOperand.cpp +++ b/llvm/lib/CodeGen/MachineOperand.cpp @@ -472,6 +472,10 @@ void MachineOperand::printTargetFlags(raw_ostream &OS, OS << ") "; } +void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) { + OS << ""; +} + void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, const TargetIntrinsicInfo *IntrinsicInfo) const { tryToGetTargetInfo(*this, TRI, IntrinsicInfo); @@ -660,7 +664,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: - OS << ""; + printSymbol(OS, *getMCSymbol()); break; case MachineOperand::MO_CFIIndex: OS << ""; diff --git a/llvm/test/CodeGen/MIR/AArch64/cfi.mir b/llvm/test/CodeGen/MIR/AArch64/cfi.mir index 8d9a2772afa0..2a39c272ec68 100644 --- a/llvm/test/CodeGen/MIR/AArch64/cfi.mir +++ b/llvm/test/CodeGen/MIR/AArch64/cfi.mir @@ -11,49 +11,38 @@ ret void } - define void @trivial_fp_func_restore() { - entry: - call void @foo() - ret void - } - ... --- name: trivial_fp_func # CHECK-LABEL: name: trivial_fp_func body: | bb.0.entry: - liveins: %lr, %fp, %lr, %fp - - %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2 - %fp = frame-setup ADDXri %sp, 0, 0 ; CHECK: CFI_INSTRUCTION def_cfa %w29, 16 frame-setup CFI_INSTRUCTION def_cfa %w29, 16 - frame-setup CFI_INSTRUCTION offset %w30, -8 - frame-setup CFI_INSTRUCTION offset %w29, -16 - BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp - %sp, %fp, %lr = LDPXpost %sp, 2 - RET_ReallyLR -... ---- -name: trivial_fp_func_restore -# CHECK-LABEL: name: trivial_fp_func_restore -body: | - bb.0.entry: - liveins: %lr, %fp - - %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2 - %fp = frame-setup ADDXri %sp, 0, 0 - frame-setup CFI_INSTRUCTION def_cfa %w29, 16 - frame-setup CFI_INSTRUCTION offset %w30, -8 + ; CHECK: CFI_INSTRUCTION def_cfa_register %w29 + frame-setup CFI_INSTRUCTION def_cfa_register %w29 + ; CHECK: CFI_INSTRUCTION def_cfa_offset -8 + frame-setup CFI_INSTRUCTION def_cfa_offset -8 ; CHECK: CFI_INSTRUCTION offset %w30, -8 - frame-setup CFI_INSTRUCTION offset %w29, -16 - ; CHECK: CFI_INSTRUCTION offset %w29, -16 - BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp - %sp, %fp, %lr = LDPXpost %sp, 2 + frame-setup CFI_INSTRUCTION offset %w30, -8 + ; CHECK: CFI_INSTRUCTION rel_offset %w30, -8 + frame-setup CFI_INSTRUCTION rel_offset %w30, -8 + ; CHECK: CFI_INSTRUCTION adjust_cfa_offset -8 + frame-setup CFI_INSTRUCTION adjust_cfa_offset -8 CFI_INSTRUCTION restore %w30 ; CHECK: CFI_INSTRUCTION restore %w30 - CFI_INSTRUCTION restore %w29 - ; CHECK: CFI_INSTRUCTION restore %w29 + CFI_INSTRUCTION undefined %w30 + ; CHECK: CFI_INSTRUCTION undefined %w30 + CFI_INSTRUCTION same_value %w29 + ; CHECK: CFI_INSTRUCTION same_value %w29 + CFI_INSTRUCTION register %w20, %w30 + ; CHECK: CFI_INSTRUCTION register %w20, %w30 + CFI_INSTRUCTION remember_state + ; CHECK: CFI_INSTRUCTION remember_state + CFI_INSTRUCTION restore_state + ; CHECK: CFI_INSTRUCTION restore_state + CFI_INSTRUCTION escape 0x61, 0x62, 0x63 + ; CHECK: CFI_INSTRUCTION escape 0x61, 0x62, 0x63 + CFI_INSTRUCTION window_save + ; CHECK: CFI_INSTRUCTION window_save RET_ReallyLR -... diff --git a/llvm/test/CodeGen/MIR/X86/shrink_wrap_dbg_value.mir b/llvm/test/CodeGen/MIR/X86/shrink_wrap_dbg_value.mir index f66794670567..bdc214c8e7b9 100644 --- a/llvm/test/CodeGen/MIR/X86/shrink_wrap_dbg_value.mir +++ b/llvm/test/CodeGen/MIR/X86/shrink_wrap_dbg_value.mir @@ -162,7 +162,7 @@ body: | ADJCALLSTACKDOWN32 4, 0, 4, implicit-def dead %esp, implicit-def dead %eflags, implicit-def dead %ssp, implicit %esp, implicit %ssp, debug-location !33 DBG_VALUE %fixed-stack.1, 0, !14, !DIExpression(), debug-location !20 PUSH32r %ebx, implicit-def %esp, implicit %esp, debug-location !33 - ;CFI_INSTRUCTION , debug-location !33 + CFI_INSTRUCTION adjust_cfa_offset 4, debug-location !33 CALLpcrel32 @doSomething, csr_32, implicit %esp, implicit %ssp, implicit-def %esp, implicit-def %ssp, implicit-def %eax, debug-location !33 ADJCALLSTACKUP32 4, 0, implicit-def dead %esp, implicit-def dead %eflags, implicit-def dead %ssp, implicit %esp, implicit %ssp, debug-location !33 %edi = INC32r killed %edi, implicit-def dead %eflags, debug-location !30