-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MC][AsmPrinter] Introduce llvm_reg_offset pseudo cfi instruction. #125104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -265,6 +265,8 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) { | |
case MCCFIInstruction::OpLabel: | ||
case MCCFIInstruction::OpValOffset: | ||
break; | ||
case MCCFIInstruction::OpLLVMRegOffset: | ||
llvm_unreachable("Can't handle llvm_reg_offset yet!"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the impact of not handling this yet? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing emits |
||
} | ||
if (CSRReg || CSROffset) { | ||
auto It = CSRLocMap.find(CFI.getRegister()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,45 @@ | |
|
||
using namespace llvm; | ||
|
||
void MCCFIInstruction::createRegOffsetExpression(unsigned Reg, | ||
unsigned FrameReg, | ||
int64_t Offset, | ||
SmallString<64> &CFAExpr) { | ||
// Below all the comments about specific CFI instructions and opcodes are | ||
// taken directly from DWARF Standard version 5. | ||
// | ||
// Encode the expression: (Offset + FrameReg) into Expr: | ||
SmallString<64> Expr; | ||
uint8_t Buffer[16]; | ||
// Encode offset: | ||
Expr.push_back(dwarf::DW_OP_consts); | ||
// The single operand of the DW_OP_consts operation provides a signed | ||
// LEB128 integer constant | ||
Expr.append(Buffer, Buffer + encodeSLEB128(Offset, Buffer)); | ||
// Encode FrameReg: | ||
Expr.push_back((uint8_t)dwarf::DW_OP_bregx); | ||
// The DW_OP_bregx operation provides the sum of two values specified by its | ||
// two operands. The first operand is a register number which is specified by | ||
// an unsigned LEB128 number. The second operand is a signed LEB128 offset. | ||
Expr.append(Buffer, Buffer + encodeULEB128(FrameReg, Buffer)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this using llvm's internal numbering for registers? That's not stable across releases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it's using DwarfEH register numbers like all other CFIs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see other code does stuff like this:
Do we need to do something similar? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't find a good way to pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need MRI->getDwarfRegNumFromDwarfEHRegNum(FrameReg);`? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I don't think so |
||
Expr.push_back(0); | ||
// The DW_OP_plus operation pops the top two stack entries, adds them | ||
// together, and pushes the result. | ||
Expr.push_back((uint8_t)dwarf::DW_OP_plus); | ||
// Now pass the encoded Expr to DW_CFA_expression: | ||
// | ||
// The DW_CFA_expression instruction takes two operands: an unsigned | ||
// LEB128 value representing a register number, and a DW_FORM_block value | ||
// representing a DWARF expression | ||
CFAExpr.push_back(dwarf::DW_CFA_expression); | ||
CFAExpr.append(Buffer, Buffer + encodeULEB128(Reg, Buffer)); | ||
// DW_FORM_block value is unsigned LEB128 length followed by the number of | ||
// bytes specified by the length | ||
CFAExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer)); | ||
CFAExpr.append(Expr.str()); | ||
return; | ||
} | ||
|
||
MCSymbol *mcdwarf::emitListsTableHeaderStart(MCStreamer &S) { | ||
MCSymbol *Start = S.getContext().createTempSymbol("debug_list_header_start"); | ||
MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end"); | ||
|
@@ -1514,6 +1553,8 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) { | |
} | ||
return; | ||
} | ||
case MCCFIInstruction::OpLLVMRegOffset: | ||
llvm_unreachable("Should emit llvm_reg_offset as escape"); | ||
michaelmaitland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
llvm_unreachable("Unhandled case in switch"); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 | ||
# RUN: llc -mtriple=riscv64 -run-pass none -o - %s \ | ||
# RUN: | FileCheck %s | ||
|
||
# This test ensures that the MIR parser parses the llvm_reg_offset cfi instruction correctly. | ||
|
||
name: func | ||
body: | | ||
bb.0: | ||
; CHECK: CFI_INSTRUCTION llvm_reg_offset $x1, $x2, -42 | ||
michaelmaitland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
CFI_INSTRUCTION llvm_reg_offset $x1, $x2, -42 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# RUN: llc -mtriple=riscv64 -start-after=unpack-mi-bundles -o - %s \ | ||
# RUN: | FileCheck %s | ||
|
||
# Check that `llvm_reg_offset` generates an escape expression corresponding to `deref(FrameReg + Offset)`. See comments in `MCCFIInstruction::createRegOffsetExpression`. | ||
# DW_CFA_expression = 0x10 | ||
# $x1 = 0x01 - the register to be defined | ||
# 0x06 - length of expression encoding the (FrameReg + Offset) | ||
# DW_OP_consts = 0x11 | ||
# le128 signed encoding of -42 = 0x56 | ||
# DW_OP_bregx = 0x92 | ||
# $x2 = 0x02 | ||
# the second argument of DW_OP_bregx = 0x0 | ||
# DW_OP_plus = 0x92 | ||
name: func | ||
body: | | ||
bb.0: | ||
CFI_INSTRUCTION llvm_reg_offset $x1, $x2, -42 | ||
PseudoRET | ||
#CHECK-LABEL: func: | ||
#CHECK: .cfi_startproc | ||
#CHECK: .cfi_escape 0x10, 0x01, 0x06, 0x11, 0x56, 0x92, 0x02, 0x00, 0x22 | ||
#CHECK: ret | ||
#CHECK: .Lfunc_end0: | ||
#CHECK: .size func, .Lfunc_end0-func | ||
#CHECK: .cfi_endproc |
Uh oh!
There was an error while loading. Please reload this page.