[llvm] r241922 - MIR Serialization: Initial serialization of stack objects.

Alex Lorenz arphaman at gmail.com
Fri Jul 10 11:13:57 PDT 2015


Author: arphaman
Date: Fri Jul 10 13:13:57 2015
New Revision: 241922

URL: http://llvm.org/viewvc/llvm-project?rev=241922&view=rev
Log:
MIR Serialization: Initial serialization of stack objects.

This commit implements the initial serialization of stack objects from the
MachineFrameInfo class. It can only serialize the ordinary stack objects
(including ordinary spill slots), but it doesn't serialize variable sized or
fixed stack objects yet.

The stack objects are serialized using a YAML sequence of YAML inline mappings.
Each mapping has the object's ID, type, size, offset and alignment. The stack
objects are a part of machine function's YAML mapping.

Reviewers: Duncan P. N. Exon Smith

Added:
    llvm/trunk/test/CodeGen/MIR/X86/stack-objects.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=241922&r1=241921&r2=241922&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Fri Jul 10 13:13:57 2015
@@ -121,11 +121,52 @@ template <> struct MappingTraits<Machine
   }
 };
 
+/// Serializable representation of stack object from the MachineFrameInfo class.
+///
+/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
+/// determined by the object's type and frame information flags.
+/// Dead stack objects aren't serialized.
+///
+/// TODO: Determine isPreallocated flag by mapping between objects and local
+/// objects (Serialize local objects).
+/// TODO: Serialize variable sized and fixed stack objects.
+struct MachineStackObject {
+  enum ObjectType { DefaultType, SpillSlot };
+  // TODO: Serialize LLVM alloca reference.
+  unsigned ID;
+  ObjectType Type = DefaultType;
+  int64_t Offset = 0;
+  uint64_t Size = 0;
+  unsigned Alignment = 0;
+};
+
+template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
+  static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
+    IO.enumCase(Type, "default", MachineStackObject::DefaultType);
+    IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
+  }
+};
+
+template <> struct MappingTraits<MachineStackObject> {
+  static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
+    YamlIO.mapRequired("id", Object.ID);
+    YamlIO.mapOptional(
+        "type", Object.Type,
+        MachineStackObject::DefaultType); // Don't print the default type.
+    YamlIO.mapOptional("offset", Object.Offset);
+    YamlIO.mapRequired("size", Object.Size);
+    YamlIO.mapOptional("alignment", Object.Alignment);
+  }
+
+  static const bool flow = true;
+};
+
 } // end namespace yaml
 } // end namespace llvm
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
 
 namespace llvm {
 namespace yaml {
@@ -138,7 +179,6 @@ namespace yaml {
 /// It also doesn't serialize attributes like 'NumFixedObject' and
 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
 struct MachineFrameInfo {
-  // TODO: Serialize stack objects.
   bool IsFrameAddressTaken = false;
   bool IsReturnAddressTaken = false;
   bool HasStackMap = false;
@@ -190,6 +230,7 @@ struct MachineFunction {
   // TODO: Serialize live in registers.
   // Frame information
   MachineFrameInfo FrameInfo;
+  std::vector<MachineStackObject> StackObjects;
 
   std::vector<MachineBasicBlock> BasicBlocks;
 };
@@ -205,6 +246,7 @@ template <> struct MappingTraits<Machine
     YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
     YamlIO.mapOptional("registers", MF.VirtualRegisters);
     YamlIO.mapOptional("frameInfo", MF.FrameInfo);
+    YamlIO.mapOptional("stack", MF.StackObjects);
     YamlIO.mapOptional("body", MF.BasicBlocks);
   }
 };

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=241922&r1=241921&r2=241922&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Fri Jul 10 13:13:57 2015
@@ -107,7 +107,7 @@ public:
                               const yaml::MachineFunction &YamlMF);
 
   bool initializeFrameInfo(MachineFrameInfo &MFI,
-                           const yaml::MachineFrameInfo &YamlMFI);
+                           const yaml::MachineFunction &YamlMF);
 
 private:
   /// Return a MIR diagnostic converted from an MI string diagnostic.
@@ -260,7 +260,7 @@ bool MIRParserImpl::initializeMachineFun
   MF.setHasInlineAsm(YamlMF.HasInlineAsm);
   if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
     return true;
-  if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF.FrameInfo))
+  if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF))
     return true;
 
   PerFunctionMIParsingState PFS;
@@ -354,7 +354,8 @@ bool MIRParserImpl::initializeRegisterIn
 }
 
 bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI,
-                                        const yaml::MachineFrameInfo &YamlMFI) {
+                                        const yaml::MachineFunction &YamlMF) {
+  const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
   MFI.setHasStackMap(YamlMFI.HasStackMap);
@@ -369,6 +370,16 @@ bool MIRParserImpl::initializeFrameInfo(
   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
   MFI.setHasVAStart(YamlMFI.HasVAStart);
   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
+
+  // Initialize the frame objects.
+  for (const auto &Object : YamlMF.StackObjects) {
+    int ObjectIdx = MFI.CreateStackObject(
+        Object.Size, Object.Alignment,
+        Object.Type == yaml::MachineStackObject::SpillSlot);
+    MFI.setObjectOffset(ObjectIdx, Object.Offset);
+    // TODO: Store the mapping between object IDs and object indices to parse
+    // stack object references correctly.
+  }
   return false;
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=241922&r1=241921&r2=241922&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Fri Jul 10 13:13:57 2015
@@ -47,6 +47,8 @@ public:
   void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
   void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
                const MachineBasicBlock &MBB);
+  void convertStackObjects(yaml::MachineFunction &MF,
+                           const MachineFrameInfo &MFI);
 
 private:
   void initRegisterMaskIds(const MachineFunction &MF);
@@ -98,6 +100,7 @@ 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());
 
   int I = 0;
   ModuleSlotTracker MST(MF.getFunction()->getParent());
@@ -152,6 +155,28 @@ void MIRPrinter::convert(yaml::MachineFr
   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
 }
 
+void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
+                                     const MachineFrameInfo &MFI) {
+  unsigned ID = 0;
+  for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
+    if (MFI.isDeadObjectIndex(I))
+      continue;
+
+    yaml::MachineStackObject YamlObject;
+    YamlObject.ID = ID++;
+    YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
+                          ? yaml::MachineStackObject::SpillSlot
+                          : yaml::MachineStackObject::DefaultType;
+    YamlObject.Offset = MFI.getObjectOffset(I);
+    YamlObject.Size = MFI.getObjectSize(I);
+    YamlObject.Alignment = MFI.getObjectAlignment(I);
+
+    MF.StackObjects.push_back(YamlObject);
+    // TODO: Store the mapping between object IDs and object indices to print
+    // the stack object references correctly.
+  }
+}
+
 void MIRPrinter::convert(ModuleSlotTracker &MST,
                          yaml::MachineBasicBlock &YamlMBB,
                          const MachineBasicBlock &MBB) {

Added: llvm/trunk/test/CodeGen/MIR/X86/stack-objects.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/stack-objects.mir?rev=241922&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/stack-objects.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/stack-objects.mir Fri Jul 10 13:13:57 2015
@@ -0,0 +1,39 @@
+# 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 stack objects correctly.
+
+--- |
+
+  define i32 @test(i32 %a) #0 {
+  entry:
+    %b = alloca i32
+    %x = alloca i64
+    store i32 %a, i32* %b
+    store i64 2, i64* %x
+    %c = load i32, i32* %b
+    ret i32 %c
+  }
+
+  attributes #0 = { "no-frame-pointer-elim"="false" }
+
+...
+---
+name:            test
+frameInfo:
+  maxAlignment:    8
+# CHECK: stack:
+# CHECK-NEXT: - { id: 0, offset: -12, size: 4, alignment: 4 }
+# CHECK-NEXT: - { id: 1, offset: -24, size: 8, alignment: 8 }
+# CHECK-NEXT: - { id: 2, type: spill-slot, offset: -32, size: 4, alignment: 4 }
+stack:
+  - { id: 0, offset: -12, size: 4, alignment: 4 }
+  - { id: 1, offset: -24, size: 8, alignment: 8 }
+  - { id: 2, type: spill-slot, offset: -32, size: 4, alignment: 4 }
+body:
+  - id:          0
+    name:        entry
+    instructions:
+      - 'MOV32mr %rsp, 1, _, -4, _, %edi'
+      - 'MOV64mi32 %rsp, 1, _, -16, _, 2'
+      - '%eax = MOV32rm %rsp, 1, _, -4, _'
+      - 'RETQ %eax'
+...





More information about the llvm-commits mailing list