From: Francis Visoiu Mistrih Date: Thu, 2 Nov 2017 12:00:58 +0000 (+0000) Subject: [AsmPrinterDwarf] Add support for .cfi_restore directive X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4352a046c591aec0915c4f16d54d03b1d00c1efa;p=llvm [AsmPrinterDwarf] Add support for .cfi_restore directive As of today we only use .cfi_offset to specify the offset of a CSR, but we never use .cfi_restore when the CSR is restored. If we want to perform a more advanced type of shrink-wrapping, we need to use .cfi_restore in order to switch the CFI state between blocks. This patch only aims at adding support for the directive. Differential Revision: https://reviews.llvm.org/D36114 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317199 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 7b3fe05db76..3f144c0659f 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -219,6 +219,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { case MCCFIInstruction::OpEscape: OutStreamer->EmitCFIEscape(Inst.getValues()); break; + case MCCFIInstruction::OpRestore: + OutStreamer->EmitCFIRestore(Inst.getRegister()); + break; } } diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index 0ba346c510f..d23df9c137b 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -216,6 +216,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("def_cfa_register", MIToken::kw_cfi_def_cfa_register) .Case("def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) .Case("def_cfa", MIToken::kw_cfi_def_cfa) + .Case("restore", MIToken::kw_cfi_restore) .Case("blockaddress", MIToken::kw_blockaddress) .Case("intrinsic", MIToken::kw_intrinsic) .Case("target-index", MIToken::kw_target_index) diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 886916b470f..6894fe8b0ac 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -68,6 +68,7 @@ struct MIToken { kw_cfi_def_cfa_register, kw_cfi_def_cfa_offset, kw_cfi_def_cfa, + kw_cfi_restore, kw_blockaddress, kw_intrinsic, kw_target_index, diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 1000eb0b268..9c8743a7164 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -1634,6 +1634,12 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); break; + case MIToken::kw_cfi_restore: + if (parseCFIRegister(Reg)) + return true; + CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); + break; + default: // TODO: Parse the other CFI operands. llvm_unreachable("The current token should be a cfi operand"); @@ -1912,6 +1918,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, case MIToken::kw_cfi_def_cfa_register: case MIToken::kw_cfi_def_cfa_offset: case MIToken::kw_cfi_def_cfa: + case MIToken::kw_cfi_restore: return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index f8da8d32d6a..aae48587c5b 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -1243,6 +1243,12 @@ void MIPrinter::print(const MCCFIInstruction &CFI, printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; + case MCCFIInstruction::OpRestore: + OS << "restore "; + if (CFI.getLabel()) + OS << " "; + printCFIRegister(CFI.getRegister(), OS, TRI); + break; default: // TODO: Print the other CFI Operations. OS << ""; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index f48ae84950e..44bac8eabdc 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -260,6 +260,7 @@ public: void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override; void EmitCFIRememberState() override; void EmitCFIRestoreState() override; + void EmitCFIRestore(int64_t Register) override; void EmitCFISameValue(int64_t Register) override; void EmitCFIRelOffset(int64_t Register, int64_t Offset) override; void EmitCFIAdjustCfaOffset(int64_t Adjustment) override; @@ -1385,6 +1386,13 @@ void MCAsmStreamer::EmitCFIRestoreState() { EmitEOL(); } +void MCAsmStreamer::EmitCFIRestore(int64_t Register) { + MCStreamer::EmitCFIRestore(Register); + OS << "\t.cfi_restore "; + EmitRegisterName(Register); + EmitEOL(); +} + void MCAsmStreamer::EmitCFISameValue(int64_t Register) { MCStreamer::EmitCFISameValue(Register); OS << "\t.cfi_same_value "; diff --git a/test/CodeGen/AArch64/cfi_restore.mir b/test/CodeGen/AArch64/cfi_restore.mir new file mode 100644 index 00000000000..92351f99cd2 --- /dev/null +++ b/test/CodeGen/AArch64/cfi_restore.mir @@ -0,0 +1,37 @@ +# RUN: llc -mtriple=aarch64-- -start-after prologepilog -o - %s | FileCheck %s +--- +name: fun +# CHECK: .cfi_startproc +tracksRegLiveness: true +frameInfo: + stackSize: 16 + maxAlignment: 8 + hasCalls: true +stack: + - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: 0, + callee-saved-register: '%lr' } + - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, stack-id: 0, + callee-saved-register: '%fp' } +body: | + bb.0: + liveins: %fp, %lr + + %sp = frame-setup SUBXri %sp, 16, 0 + frame-setup STRXui killed %fp, %sp, 0 :: (store 8 into %stack.1) + frame-setup CFI_INSTRUCTION offset %w29, -16 + ; CHECK: .cfi_offset w29, -16 + frame-setup STRXui killed %lr, %sp, 1 :: (store 8 into %stack.0) + frame-setup CFI_INSTRUCTION offset %w30, -8 + ; CHECK: .cfi_offset w30, -8 + %fp = frame-setup ADDXri %sp, 0, 0 + frame-setup CFI_INSTRUCTION def_cfa %w29, 16 + %lr = LDRXui %sp, 1 :: (load 8 from %stack.0) + CFI_INSTRUCTION restore %w30 + ; CHECK: .cfi_restore w30 + %fp = LDRXui %sp, 0 :: (load 8 from %stack.1) + CFI_INSTRUCTION restore %w29 + ; CHECK: .cfi_restore w29 + %sp = ADDXri %sp, 16, 0 + RET_ReallyLR + ; CHECK: .cfi_endproc +... diff --git a/test/CodeGen/MIR/AArch64/cfi-def-cfa.mir b/test/CodeGen/MIR/AArch64/cfi-def-cfa.mir deleted file mode 100644 index a946b9f9f4a..00000000000 --- a/test/CodeGen/MIR/AArch64/cfi-def-cfa.mir +++ /dev/null @@ -1,31 +0,0 @@ -# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s -# This test ensures that the MIR parser parses the def_cfa operands -# correctly. - ---- | - - declare void @foo() - - define void @trivial_fp_func() { - entry: - call void @foo() - ret void - } - -... ---- -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 -... diff --git a/test/CodeGen/MIR/AArch64/cfi.mir b/test/CodeGen/MIR/AArch64/cfi.mir new file mode 100644 index 00000000000..8d9a2772afa --- /dev/null +++ b/test/CodeGen/MIR/AArch64/cfi.mir @@ -0,0 +1,59 @@ +# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s +# This test ensures that the MIR parser parses the cfi directives correctly. + +--- | + + declare void @foo() + + define void @trivial_fp_func() { + entry: + call void @foo() + 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 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 + CFI_INSTRUCTION restore %w30 + ; CHECK: CFI_INSTRUCTION restore %w30 + CFI_INSTRUCTION restore %w29 + ; CHECK: CFI_INSTRUCTION restore %w29 + RET_ReallyLR +... diff --git a/test/MC/AArch64/cfi.s b/test/MC/AArch64/cfi.s new file mode 100644 index 00000000000..a1b328a4400 --- /dev/null +++ b/test/MC/AArch64/cfi.s @@ -0,0 +1,26 @@ +// RUN: llvm-mc -triple aarch64-- -o - %s | FileCheck %s + +fun: + .cfi_startproc +// CHECK: .cfi_startproc + stp x29, x30, [sp, #-16]! +.Lcfi0: + .cfi_offset w29, -16 +// CHECK: .cfi_offset w29, -16 +.Lcfi1: + .cfi_offset w30, -8 +// CHECK: .cfi_offset w30, -8 + mov x29, sp +.Lcfi2: + .cfi_def_cfa w29, 16 +// CHECK: .cfi_def_cfa w29, 16 +.Lcfi3: + .cfi_restore w30 +// CHECK: .cfi_restore w30 + ldr x29, [sp], #16 +.Lcfi4: + .cfi_restore w29 +// CHECK: .cfi_restore w29 + ret + .cfi_endproc +// CHECK: .cfi_endproc