[llvm] r243173 - MIR Serialization: Serialize MachineFrameInfo's callee saved information.

Alex Lorenz arphaman at gmail.com
Fri Jul 24 15:22:50 PDT 2015


Author: arphaman
Date: Fri Jul 24 17:22:50 2015
New Revision: 243173

URL: http://llvm.org/viewvc/llvm-project?rev=243173&view=rev
Log:
MIR Serialization: Serialize MachineFrameInfo's callee saved information.

This commit serializes the callee saved information from the class
'MachineFrameInfo'. This commit extends the YAML mappings for the fixed and
the ordinary stack objects and adds an optional 'callee-saved-register'
attribute. This attribute is used to serialize the callee save information.

Added:
    llvm/trunk/test/CodeGen/MIR/X86/callee-saved-info.mir
    llvm/trunk/test/CodeGen/MIR/X86/expected-named-register-in-callee-saved-register.mir
Modified:
    llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h?rev=243173&r1=243172&r2=243173&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Fri Jul 24 17:22:50 2015
@@ -159,6 +159,7 @@ struct MachineStackObject {
   int64_t Offset = 0;
   uint64_t Size = 0;
   unsigned Alignment = 0;
+  StringValue CalleeSavedRegister;
 };
 
 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
@@ -181,6 +182,8 @@ template <> struct MappingTraits<Machine
     if (Object.Type != MachineStackObject::VariableSized)
       YamlIO.mapRequired("size", Object.Size);
     YamlIO.mapOptional("alignment", Object.Alignment);
+    YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
+                       StringValue()); // Don't print it out when it's empty.
   }
 
   static const bool flow = true;
@@ -197,6 +200,7 @@ struct FixedMachineStackObject {
   unsigned Alignment = 0;
   bool IsImmutable = false;
   bool IsAliased = false;
+  StringValue CalleeSavedRegister;
 };
 
 template <>
@@ -221,6 +225,8 @@ template <> struct MappingTraits<FixedMa
       YamlIO.mapOptional("isImmutable", Object.IsImmutable);
       YamlIO.mapOptional("isAliased", Object.IsAliased);
     }
+    YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
+                       StringValue()); // Don't print it out when it's empty.
   }
 
   static const bool flow = true;
@@ -296,7 +302,6 @@ struct MachineFrameInfo {
   bool HasCalls = false;
   // TODO: Serialize StackProtectorIdx and FunctionContextIdx
   unsigned MaxCallFrameSize = 0;
-  // TODO: Serialize callee saved info.
   // TODO: Serialize local frame objects.
   bool HasOpaqueSPAdjustment = false;
   bool HasVAStart = false;

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=243173&r1=243172&r2=243173&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Fri Jul 24 17:22:50 2015
@@ -107,10 +107,15 @@ public:
                               const yaml::MachineFunction &YamlMF,
                               PerFunctionMIParsingState &PFS);
 
-  bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI,
+  bool initializeFrameInfo(MachineFunction &MF, MachineFrameInfo &MFI,
                            const yaml::MachineFunction &YamlMF,
-                           DenseMap<unsigned, int> &StackObjectSlots,
-                           DenseMap<unsigned, int> &FixedStackObjectSlots);
+                           PerFunctionMIParsingState &PFS);
+
+  bool parseCalleeSavedRegister(MachineFunction &MF,
+                                PerFunctionMIParsingState &PFS,
+                                std::vector<CalleeSavedInfo> &CSIInfo,
+                                const yaml::StringValue &RegisterSource,
+                                int FrameIdx);
 
   bool initializeConstantPool(MachineConstantPool &ConstantPool,
                               const yaml::MachineFunction &YamlMF,
@@ -273,8 +278,7 @@ bool MIRParserImpl::initializeMachineFun
   PerFunctionMIParsingState PFS;
   if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF, PFS))
     return true;
-  if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
-                          PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
+  if (initializeFrameInfo(MF, *MF.getFrameInfo(), YamlMF, PFS))
     return true;
   if (!YamlMF.Constants.empty()) {
     auto *ConstantPool = MF.getConstantPool();
@@ -401,11 +405,11 @@ bool MIRParserImpl::initializeRegisterIn
   return false;
 }
 
-bool MIRParserImpl::initializeFrameInfo(
-    const Function &F, MachineFrameInfo &MFI,
-    const yaml::MachineFunction &YamlMF,
-    DenseMap<unsigned, int> &StackObjectSlots,
-    DenseMap<unsigned, int> &FixedStackObjectSlots) {
+bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
+                                        MachineFrameInfo &MFI,
+                                        const yaml::MachineFunction &YamlMF,
+                                        PerFunctionMIParsingState &PFS) {
+  const Function &F = *MF.getFunction();
   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
@@ -422,6 +426,7 @@ bool MIRParserImpl::initializeFrameInfo(
   MFI.setHasVAStart(YamlMFI.HasVAStart);
   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
 
+  std::vector<CalleeSavedInfo> CSIInfo;
   // Initialize the fixed frame objects.
   for (const auto &Object : YamlMF.FixedStackObjects) {
     int ObjectIdx;
@@ -432,7 +437,10 @@ bool MIRParserImpl::initializeFrameInfo(
       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
     MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
     // TODO: Report an error when objects are redefined.
-    FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
+    PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
+    if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
+                                 ObjectIdx))
+      return true;
   }
 
   // Initialize the ordinary frame objects.
@@ -457,8 +465,29 @@ bool MIRParserImpl::initializeFrameInfo(
           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
     MFI.setObjectOffset(ObjectIdx, Object.Offset);
     // TODO: Report an error when objects are redefined.
-    StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
+    PFS.StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
+    if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
+                                 ObjectIdx))
+      return true;
   }
+  MFI.setCalleeSavedInfo(CSIInfo);
+  if (!CSIInfo.empty())
+    MFI.setCalleeSavedInfoValid(true);
+  return false;
+}
+
+bool MIRParserImpl::parseCalleeSavedRegister(
+    MachineFunction &MF, PerFunctionMIParsingState &PFS,
+    std::vector<CalleeSavedInfo> &CSIInfo,
+    const yaml::StringValue &RegisterSource, int FrameIdx) {
+  if (RegisterSource.Value.empty())
+    return false;
+  unsigned Reg = 0;
+  SMDiagnostic Error;
+  if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
+                                  IRSlots, Error))
+    return error(Error, RegisterSource.SourceRange);
+  CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
   return false;
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=243173&r1=243172&r2=243173&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Fri Jul 24 17:22:50 2015
@@ -79,7 +79,8 @@ public:
   void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
                const MachineBasicBlock &MBB);
   void convertStackObjects(yaml::MachineFunction &MF,
-                           const MachineFrameInfo &MFI);
+                           const MachineFrameInfo &MFI,
+                           const TargetRegisterInfo *TRI);
 
 private:
   void initRegisterMaskIds(const MachineFunction &MF);
@@ -156,7 +157,8 @@ void MIRPrinter::print(const MachineFunc
   YamlMF.HasInlineAsm = MF.hasInlineAsm();
   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
   convert(YamlMF.FrameInfo, *MF.getFrameInfo());
-  convertStackObjects(YamlMF, *MF.getFrameInfo());
+  convertStackObjects(YamlMF, *MF.getFrameInfo(),
+                      MF.getSubtarget().getRegisterInfo());
   if (const auto *ConstantPool = MF.getConstantPool())
     convert(YamlMF, *ConstantPool);
 
@@ -219,7 +221,8 @@ void MIRPrinter::convert(yaml::MachineFr
 }
 
 void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
-                                     const MachineFrameInfo &MFI) {
+                                     const MachineFrameInfo &MFI,
+                                     const TargetRegisterInfo *TRI) {
   // Process fixed stack objects.
   unsigned ID = 0;
   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
@@ -265,6 +268,19 @@ void MIRPrinter::convertStackObjects(yam
     StackObjectOperandMapping.insert(std::make_pair(
         I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
   }
+
+  for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
+    yaml::StringValue Reg;
+    printReg(CSInfo.getReg(), Reg, TRI);
+    auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
+    assert(StackObjectInfo != StackObjectOperandMapping.end() &&
+           "Invalid stack object index");
+    const FrameIndexOperand &StackObject = StackObjectInfo->second;
+    if (StackObject.IsFixed)
+      MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
+    else
+      MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
+  }
 }
 
 void MIRPrinter::convert(yaml::MachineFunction &MF,

Added: llvm/trunk/test/CodeGen/MIR/X86/callee-saved-info.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/callee-saved-info.mir?rev=243173&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/callee-saved-info.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/callee-saved-info.mir Fri Jul 24 17:22:50 2015
@@ -0,0 +1,98 @@
+# RUN: llc -march=x86-64 -start-after prologepilog -stop-after prologepilog -o /dev/null %s | FileCheck %s
+# This test ensures that the MIR parser parses callee saved information in the
+# stack objects correctly.
+
+--- |
+
+  define i32 @compute(i32 %a) {
+  body:
+    ret i32 %a
+  }
+
+  define i32 @func(i32 %a) {
+  entry:
+    %b = alloca i32
+    store i32 %a, i32* %b
+    br label %check
+
+  check:
+    %comp = icmp sle i32 %a, 10
+    br i1 %comp, label %loop, label %exit
+
+  loop:
+    %c = load i32, i32* %b
+    %d = call i32 @compute(i32 %c)
+    %e = sub i32 %d, 1
+    store i32 %e, i32* %b
+    br label %check
+
+  exit:
+    ret i32 0
+  }
+
+...
+---
+name:            compute
+tracksRegLiveness: true
+body:
+  - id:          0
+    name:        body
+    liveins:     [ '%edi' ]
+    instructions:
+      - '%eax = COPY killed %edi'
+      - 'RETQ killed %eax'
+...
+---
+name:            func
+tracksRegLiveness: true
+frameInfo:
+  stackSize:       24
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+# CHECK: fixedStack:
+# CHECK-NEXT: , callee-saved-register: '%rbx' }
+fixedStack:
+  - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%rbx' }
+# CHECK: stack:
+# CHECK-NEXT: - { id: 0
+# CHECK-NEXT: , callee-saved-register: '%edi' }
+stack:
+  - { id: 0, name: b, offset: -20, size: 4, alignment: 4 }
+  - { id: 1, offset: -24, size: 4, alignment: 4, callee-saved-register: '%edi' }
+body:
+  - id:          0
+    name:        entry
+    successors:  [ '%bb.1.check' ]
+    liveins:     [ '%edi', '%rbx' ]
+    instructions:
+      - 'frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
+      - '%rsp = frame-setup SUB64ri8 %rsp, 16, implicit-def dead %eflags'
+      - '%ebx = COPY %edi'
+      - 'MOV32mr %rsp, 1, _, 12, _, %ebx'
+  - id:          1
+    name:        check
+    successors:  [ '%bb.2.loop', '%bb.3.exit' ]
+    liveins:     [ '%ebx' ]
+    instructions:
+      - 'CMP32ri8 %ebx, 10, implicit-def %eflags'
+      - 'JG_1 %bb.3.exit, implicit killed %eflags'
+      - 'JMP_1 %bb.2.loop'
+  - id:          2
+    name:        loop
+    successors:  [ '%bb.1.check' ]
+    liveins:     [ '%ebx' ]
+    instructions:
+      - '%edi = MOV32rm %rsp, 1, _, 12, _'
+      - 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
+      - '%eax = DEC32r killed %eax, implicit-def dead %eflags'
+      - 'MOV32mr %rsp, 1, _, 12, _, killed %eax'
+      - 'JMP_1 %bb.1.check'
+  - id:          3
+    name:        exit
+    instructions:
+      - '%eax = MOV32r0 implicit-def dead %eflags'
+      - '%rsp = ADD64ri8 %rsp, 16, implicit-def dead %eflags'
+      - '%rbx = POP64r implicit-def %rsp, implicit %rsp'
+      - 'RETQ %eax'
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-named-register-in-callee-saved-register.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-named-register-in-callee-saved-register.mir?rev=243173&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-named-register-in-callee-saved-register.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-named-register-in-callee-saved-register.mir Fri Jul 24 17:22:50 2015
@@ -0,0 +1,91 @@
+# RUN: not llc -march=x86-64 -start-after prologepilog -stop-after prologepilog -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  define i32 @compute(i32 %a) {
+  body:
+    ret i32 %a
+  }
+
+  define i32 @func(i32 %a) {
+  entry:
+    %b = alloca i32
+    store i32 %a, i32* %b
+    br label %check
+
+  check:
+    %comp = icmp sle i32 %a, 10
+    br i1 %comp, label %loop, label %exit
+
+  loop:
+    %c = load i32, i32* %b
+    %d = call i32 @compute(i32 %c)
+    %e = sub i32 %d, 1
+    store i32 %e, i32* %b
+    br label %check
+
+  exit:
+    ret i32 0
+  }
+
+...
+---
+name:            compute
+tracksRegLiveness: true
+body:
+  - id:          0
+    name:        body
+    liveins:     [ '%edi' ]
+    instructions:
+      - '%eax = COPY killed %edi'
+      - 'RETQ killed %eax'
+...
+---
+name:            func
+tracksRegLiveness: true
+frameInfo:
+  stackSize:       24
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+fixedStack:
+  # CHECK: [[@LINE+1]]:93: expected a named register
+  - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%0' }
+stack:
+  - { id: 0, name: b, offset: -20, size: 4, alignment: 4 }
+body:
+  - id:          0
+    name:        entry
+    successors:  [ '%bb.1.check' ]
+    liveins:     [ '%edi', '%rbx' ]
+    instructions:
+      - 'frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
+      - '%rsp = frame-setup SUB64ri8 %rsp, 16, implicit-def dead %eflags'
+      - '%ebx = COPY %edi'
+      - 'MOV32mr %rsp, 1, _, 12, _, %ebx'
+  - id:          1
+    name:        check
+    successors:  [ '%bb.2.loop', '%bb.3.exit' ]
+    liveins:     [ '%ebx' ]
+    instructions:
+      - 'CMP32ri8 %ebx, 10, implicit-def %eflags'
+      - 'JG_1 %bb.3.exit, implicit killed %eflags'
+      - 'JMP_1 %bb.2.loop'
+  - id:          2
+    name:        loop
+    successors:  [ '%bb.1.check' ]
+    liveins:     [ '%ebx' ]
+    instructions:
+      - '%edi = MOV32rm %rsp, 1, _, 12, _'
+      - 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
+      - '%eax = DEC32r killed %eax, implicit-def dead %eflags'
+      - 'MOV32mr %rsp, 1, _, 12, _, killed %eax'
+      - 'JMP_1 %bb.1.check'
+  - id:          3
+    name:        exit
+    instructions:
+      - '%eax = MOV32r0 implicit-def dead %eflags'
+      - '%rsp = ADD64ri8 %rsp, 16, implicit-def dead %eflags'
+      - '%rbx = POP64r implicit-def %rsp, implicit %rsp'
+      - 'RETQ %eax'
+...





More information about the llvm-commits mailing list