mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-18 19:28:16 +00:00
MIR Serialization: Serialize the '.cfi_offset' CFI instruction.
Reviewers: Duncan P. N. Exon Smith llvm-svn: 243062
This commit is contained in:
parent
de4046e8c5
commit
1ba189db4e
@ -124,6 +124,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
||||
.Case("undef", MIToken::kw_undef)
|
||||
.Case("frame-setup", MIToken::kw_frame_setup)
|
||||
.Case("debug-location", MIToken::kw_debug_location)
|
||||
.Case(".cfi_offset", MIToken::kw_cfi_offset)
|
||||
.Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
|
||||
.Default(MIToken::Identifier);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ struct MIToken {
|
||||
kw_undef,
|
||||
kw_frame_setup,
|
||||
kw_debug_location,
|
||||
kw_cfi_offset,
|
||||
kw_cfi_def_cfa_offset,
|
||||
|
||||
// Identifier tokens
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
bool parseMDNode(MDNode *&Node);
|
||||
bool parseMetadataOperand(MachineOperand &Dest);
|
||||
bool parseCFIOffset(int &Offset);
|
||||
bool parseCFIRegister(unsigned &Reg);
|
||||
bool parseCFIOperand(MachineOperand &Dest);
|
||||
bool parseMachineOperand(MachineOperand &Dest);
|
||||
|
||||
@ -124,6 +125,10 @@ private:
|
||||
/// Return true if an error occurred.
|
||||
bool getUnsigned(unsigned &Result);
|
||||
|
||||
/// If the current token is of the given kind, consume it and return false.
|
||||
/// Otherwise report an error and return true.
|
||||
bool expectAndConsume(MIToken::TokenKind TokenKind);
|
||||
|
||||
void initNames2InstrOpCodes();
|
||||
|
||||
/// Try to convert an instruction name to an opcode. Return true if the
|
||||
@ -181,6 +186,22 @@ bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *toString(MIToken::TokenKind TokenKind) {
|
||||
switch (TokenKind) {
|
||||
case MIToken::comma:
|
||||
return "','";
|
||||
default:
|
||||
return "<unknown token>";
|
||||
}
|
||||
}
|
||||
|
||||
bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) {
|
||||
if (Token.isNot(TokenKind))
|
||||
return error(Twine("expected ") + toString(TokenKind));
|
||||
lex();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parse(MachineInstr *&MI) {
|
||||
lex();
|
||||
|
||||
@ -623,16 +644,49 @@ bool MIParser::parseCFIOffset(int &Offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseCFIOperand(MachineOperand &Dest) {
|
||||
// TODO: Parse the other CFI operands.
|
||||
assert(Token.is(MIToken::kw_cfi_def_cfa_offset));
|
||||
lex();
|
||||
int Offset;
|
||||
if (parseCFIOffset(Offset))
|
||||
bool MIParser::parseCFIRegister(unsigned &Reg) {
|
||||
if (Token.isNot(MIToken::NamedRegister))
|
||||
return error("expected a cfi register");
|
||||
unsigned LLVMReg;
|
||||
if (parseRegister(LLVMReg))
|
||||
return true;
|
||||
// NB: MCCFIInstruction::createDefCfaOffset negates the offset.
|
||||
Dest = MachineOperand::CreateCFIIndex(MF.getMMI().addFrameInst(
|
||||
MCCFIInstruction::createDefCfaOffset(nullptr, -Offset)));
|
||||
const auto *TRI = MF.getSubtarget().getRegisterInfo();
|
||||
assert(TRI && "Expected target register info");
|
||||
int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
|
||||
if (DwarfReg < 0)
|
||||
return error("invalid DWARF register");
|
||||
Reg = (unsigned)DwarfReg;
|
||||
lex();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseCFIOperand(MachineOperand &Dest) {
|
||||
auto Kind = Token.kind();
|
||||
lex();
|
||||
auto &MMI = MF.getMMI();
|
||||
int Offset;
|
||||
unsigned Reg;
|
||||
unsigned CFIIndex;
|
||||
switch (Kind) {
|
||||
case MIToken::kw_cfi_offset:
|
||||
if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
|
||||
parseCFIOffset(Offset))
|
||||
return true;
|
||||
CFIIndex =
|
||||
MMI.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
|
||||
break;
|
||||
case MIToken::kw_cfi_def_cfa_offset:
|
||||
if (parseCFIOffset(Offset))
|
||||
return true;
|
||||
// NB: MCCFIInstruction::createDefCfaOffset negates the offset.
|
||||
CFIIndex = MMI.addFrameInst(
|
||||
MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
|
||||
break;
|
||||
default:
|
||||
// TODO: Parse the other CFI operands.
|
||||
llvm_unreachable("The current token should be a cfi operand");
|
||||
}
|
||||
Dest = MachineOperand::CreateCFIIndex(CFIIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -668,6 +722,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
||||
return parseExternalSymbolOperand(Dest);
|
||||
case MIToken::exclaim:
|
||||
return parseMetadataOperand(Dest);
|
||||
case MIToken::kw_cfi_offset:
|
||||
case MIToken::kw_cfi_def_cfa_offset:
|
||||
return parseCFIOperand(Dest);
|
||||
case MIToken::Error:
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
void printStackObjectReference(int FrameIndex);
|
||||
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
|
||||
|
||||
void print(const MCCFIInstruction &CFI);
|
||||
void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -465,7 +465,7 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
||||
break;
|
||||
case MachineOperand::MO_CFIIndex: {
|
||||
const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
|
||||
print(MMI.getFrameInstructions()[Op.getCFIIndex()]);
|
||||
print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -474,8 +474,26 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
||||
}
|
||||
}
|
||||
|
||||
void MIPrinter::print(const MCCFIInstruction &CFI) {
|
||||
static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
int Reg = TRI->getLLVMRegNum(DwarfReg, true);
|
||||
if (Reg == -1) {
|
||||
OS << "<badreg>";
|
||||
return;
|
||||
}
|
||||
printReg(Reg, OS, TRI);
|
||||
}
|
||||
|
||||
void MIPrinter::print(const MCCFIInstruction &CFI,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
switch (CFI.getOperation()) {
|
||||
case MCCFIInstruction::OpOffset:
|
||||
OS << ".cfi_offset ";
|
||||
if (CFI.getLabel())
|
||||
OS << "<mcsymbol> ";
|
||||
printCFIRegister(CFI.getRegister(), OS, TRI);
|
||||
OS << ", " << CFI.getOffset();
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfaOffset:
|
||||
OS << ".cfi_def_cfa_offset ";
|
||||
if (CFI.getLabel())
|
||||
|
47
test/CodeGen/MIR/X86/cfi-offset.mir
Normal file
47
test/CodeGen/MIR/X86/cfi-offset.mir
Normal file
@ -0,0 +1,47 @@
|
||||
# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
|
||||
# This test ensures that the MIR parser parses the .cfi_offset operands
|
||||
# correctly.
|
||||
|
||||
--- |
|
||||
|
||||
declare void @foo(i32)
|
||||
|
||||
define i32 @test(i32 %a, i32 %b, i32 %c, i32 %d) {
|
||||
entry:
|
||||
%add = add nsw i32 %b, %a
|
||||
%add1 = add nsw i32 %add, %c
|
||||
%add2 = add nsw i32 %add1, %d
|
||||
tail call void @foo(i32 %add2)
|
||||
%add6 = add nsw i32 %add2, %add2
|
||||
ret i32 %add6
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
tracksRegLiveness: true
|
||||
frameInfo:
|
||||
stackSize: 8
|
||||
adjustsStack: true
|
||||
hasCalls: true
|
||||
fixedStack:
|
||||
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- 'PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
|
||||
- 'CFI_INSTRUCTION .cfi_def_cfa_offset 16'
|
||||
# CHECK: CFI_INSTRUCTION .cfi_offset %rbx, -16
|
||||
- 'CFI_INSTRUCTION .cfi_offset %rbx, -16'
|
||||
- '%ebx = COPY %edi, implicit-def %rbx'
|
||||
- '%ebx = ADD32rr %ebx, killed %esi, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %edx, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %ecx, implicit-def dead %eflags'
|
||||
- '%edi = COPY %ebx'
|
||||
- 'CALL64pcrel32 @foo, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp'
|
||||
- '%eax = LEA64_32r killed %rbx, 1, %rbx, 0, _'
|
||||
- '%rbx = POP64r implicit-def %rsp, implicit %rsp'
|
||||
- 'RETQ %eax'
|
||||
...
|
||||
|
44
test/CodeGen/MIR/X86/expected-comma-after-cfi-register.mir
Normal file
44
test/CodeGen/MIR/X86/expected-comma-after-cfi-register.mir
Normal file
@ -0,0 +1,44 @@
|
||||
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||
|
||||
--- |
|
||||
|
||||
declare void @foo(i32)
|
||||
|
||||
define i32 @test(i32 %a, i32 %b, i32 %c, i32 %d) {
|
||||
entry:
|
||||
%add = add nsw i32 %b, %a
|
||||
%add1 = add nsw i32 %add, %c
|
||||
%add2 = add nsw i32 %add1, %d
|
||||
tail call void @foo(i32 %add2)
|
||||
%add6 = add nsw i32 %add2, %add2
|
||||
ret i32 %add6
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
tracksRegLiveness: true
|
||||
frameInfo:
|
||||
stackSize: 8
|
||||
adjustsStack: true
|
||||
hasCalls: true
|
||||
fixedStack:
|
||||
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- 'PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
|
||||
- 'CFI_INSTRUCTION .cfi_def_cfa_offset 16'
|
||||
# CHECK: [[@LINE+1]]:43: expected ','
|
||||
- 'CFI_INSTRUCTION .cfi_offset %rbx -16'
|
||||
- '%ebx = COPY %edi, implicit-def %rbx'
|
||||
- '%ebx = ADD32rr %ebx, killed %esi, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %edx, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %ecx, implicit-def dead %eflags'
|
||||
- '%edi = COPY %ebx'
|
||||
- 'CALL64pcrel32 @foo, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp'
|
||||
- '%eax = LEA64_32r killed %rbx, 1, %rbx, 0, _'
|
||||
- '%rbx = POP64r implicit-def %rsp, implicit %rsp'
|
||||
- 'RETQ %eax'
|
||||
...
|
44
test/CodeGen/MIR/X86/expected-register-after-cfi-operand.mir
Normal file
44
test/CodeGen/MIR/X86/expected-register-after-cfi-operand.mir
Normal file
@ -0,0 +1,44 @@
|
||||
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||
|
||||
--- |
|
||||
|
||||
declare void @foo(i32)
|
||||
|
||||
define i32 @test(i32 %a, i32 %b, i32 %c, i32 %d) {
|
||||
entry:
|
||||
%add = add nsw i32 %b, %a
|
||||
%add1 = add nsw i32 %add, %c
|
||||
%add2 = add nsw i32 %add1, %d
|
||||
tail call void @foo(i32 %add2)
|
||||
%add6 = add nsw i32 %add2, %add2
|
||||
ret i32 %add6
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
tracksRegLiveness: true
|
||||
frameInfo:
|
||||
stackSize: 8
|
||||
adjustsStack: true
|
||||
hasCalls: true
|
||||
fixedStack:
|
||||
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- 'PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
|
||||
- 'CFI_INSTRUCTION .cfi_def_cfa_offset 16'
|
||||
# CHECK: [[@LINE+1]]:38: expected a cfi register
|
||||
- 'CFI_INSTRUCTION .cfi_offset %0, -16'
|
||||
- '%ebx = COPY %edi, implicit-def %rbx'
|
||||
- '%ebx = ADD32rr %ebx, killed %esi, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %edx, implicit-def dead %eflags'
|
||||
- '%ebx = ADD32rr %ebx, killed %ecx, implicit-def dead %eflags'
|
||||
- '%edi = COPY %ebx'
|
||||
- 'CALL64pcrel32 @foo, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp'
|
||||
- '%eax = LEA64_32r killed %rbx, 1, %rbx, 0, _'
|
||||
- '%rbx = POP64r implicit-def %rsp, implicit %rsp'
|
||||
- 'RETQ %eax'
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user