[MIR] Add support for missing CFI directives
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>
Fri, 15 Dec 2017 15:17:18 +0000 (15:17 +0000)
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>
Fri, 15 Dec 2017 15:17:18 +0000 (15:17 +0000)
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

llvm/include/llvm/CodeGen/MachineOperand.h
llvm/lib/CodeGen/MIRParser/MILexer.cpp
llvm/lib/CodeGen/MIRParser/MILexer.h
llvm/lib/CodeGen/MIRParser/MIParser.cpp
llvm/lib/CodeGen/MIRPrinter.cpp
llvm/lib/CodeGen/MachineOperand.cpp
llvm/test/CodeGen/MIR/AArch64/cfi.mir
llvm/test/CodeGen/MIR/X86/shrink_wrap_dbg_value.mir

index a4c84be..f387604 100644 (file)
@@ -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
index fe6d075..6adb7f1 100644 (file)
@@ -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)
index f7027be..0204d54 100644 (file)
@@ -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,
index 15399c2..c147152 100644 (file)
@@ -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);
index ac94e96..8cc9ad2 100644 (file)
@@ -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>";
index 1640d57..c95fb12 100644 (file)
@@ -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>";
index 8d9a277..2a39c27 100644 (file)
     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
-...
index f667946..bdc214c 100644 (file)
@@ -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