forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9b332d997f
commit
5de20e039e
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<uint8_t>(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);
|
||||
|
|
|
@ -998,42 +998,96 @@ void MIPrinter::print(const MCCFIInstruction &CFI,
|
|||
switch (CFI.getOperation()) {
|
||||
case MCCFIInstruction::OpSameValue:
|
||||
OS << "same_value ";
|
||||
if (CFI.getLabel())
|
||||
OS << "<mcsymbol> ";
|
||||
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 << "<mcsymbol> ";
|
||||
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 << "<mcsymbol> ";
|
||||
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 << "<mcsymbol> ";
|
||||
if (MCSymbol *Label = CFI.getLabel())
|
||||
MachineOperand::printSymbol(OS, *Label);
|
||||
OS << CFI.getOffset();
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfa:
|
||||
OS << "def_cfa ";
|
||||
if (CFI.getLabel())
|
||||
OS << "<mcsymbol> ";
|
||||
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 << "<mcsymbol> ";
|
||||
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 << "<unserializable cfi operation>";
|
||||
|
|
|
@ -472,6 +472,10 @@ void MachineOperand::printTargetFlags(raw_ostream &OS,
|
|||
OS << ") ";
|
||||
}
|
||||
|
||||
void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
|
||||
OS << "<mcsymbol " << Sym << ">";
|
||||
}
|
||||
|
||||
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 << "<mcsymbol " << *getMCSymbol() << ">";
|
||||
printSymbol(OS, *getMCSymbol());
|
||||
break;
|
||||
case MachineOperand::MO_CFIIndex:
|
||||
OS << "<call frame instruction>";
|
||||
|
|
|
@ -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
|
||||
...
|
||||
|
|
|
@ -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 <unserializable cfi operation>, 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
|
||||
|
|
Loading…
Reference in New Issue