[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
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index fe6d075..6adb7f1 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -214,10 +214,18 @@
.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 f7027be..0204d54 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -66,10 +66,18 @@
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 15399c2..c147152 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -213,6 +213,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);