llvm.org GIT mirror llvm / b838969
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241922 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 5 years ago
4 changed file(s) with 121 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
120120 }
121121 };
122122
123 /// Serializable representation of stack object from the MachineFrameInfo class.
124 ///
125 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
126 /// determined by the object's type and frame information flags.
127 /// Dead stack objects aren't serialized.
128 ///
129 /// TODO: Determine isPreallocated flag by mapping between objects and local
130 /// objects (Serialize local objects).
131 /// TODO: Serialize variable sized and fixed stack objects.
132 struct MachineStackObject {
133 enum ObjectType { DefaultType, SpillSlot };
134 // TODO: Serialize LLVM alloca reference.
135 unsigned ID;
136 ObjectType Type = DefaultType;
137 int64_t Offset = 0;
138 uint64_t Size = 0;
139 unsigned Alignment = 0;
140 };
141
142 template <> struct ScalarEnumerationTraits {
143 static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
144 IO.enumCase(Type, "default", MachineStackObject::DefaultType);
145 IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
146 }
147 };
148
149 template <> struct MappingTraits {
150 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
151 YamlIO.mapRequired("id", Object.ID);
152 YamlIO.mapOptional(
153 "type", Object.Type,
154 MachineStackObject::DefaultType); // Don't print the default type.
155 YamlIO.mapOptional("offset", Object.Offset);
156 YamlIO.mapRequired("size", Object.Size);
157 YamlIO.mapOptional("alignment", Object.Alignment);
158 }
159
160 static const bool flow = true;
161 };
162
123163 } // end namespace yaml
124164 } // end namespace llvm
125165
126166 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
127167 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
168 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
128169
129170 namespace llvm {
130171 namespace yaml {
137178 /// It also doesn't serialize attributes like 'NumFixedObject' and
138179 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
139180 struct MachineFrameInfo {
140 // TODO: Serialize stack objects.
141181 bool IsFrameAddressTaken = false;
142182 bool IsReturnAddressTaken = false;
143183 bool HasStackMap = false;
189229 // TODO: Serialize live in registers.
190230 // Frame information
191231 MachineFrameInfo FrameInfo;
232 std::vector StackObjects;
192233
193234 std::vector BasicBlocks;
194235 };
204245 YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
205246 YamlIO.mapOptional("registers", MF.VirtualRegisters);
206247 YamlIO.mapOptional("frameInfo", MF.FrameInfo);
248 YamlIO.mapOptional("stack", MF.StackObjects);
207249 YamlIO.mapOptional("body", MF.BasicBlocks);
208250 }
209251 };
106106 const yaml::MachineFunction &YamlMF);
107107
108108 bool initializeFrameInfo(MachineFrameInfo &MFI,
109 const yaml::MachineFrameInfo &YamlMFI);
109 const yaml::MachineFunction &YamlMF);
110110
111111 private:
112112 /// Return a MIR diagnostic converted from an MI string diagnostic.
259259 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
260260 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
261261 return true;
262 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF.FrameInfo))
262 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF))
263263 return true;
264264
265265 PerFunctionMIParsingState PFS;
353353 }
354354
355355 bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI,
356 const yaml::MachineFrameInfo &YamlMFI) {
356 const yaml::MachineFunction &YamlMF) {
357 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
357358 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
358359 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
359360 MFI.setHasStackMap(YamlMFI.HasStackMap);
368369 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
369370 MFI.setHasVAStart(YamlMFI.HasVAStart);
370371 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
372
373 // Initialize the frame objects.
374 for (const auto &Object : YamlMF.StackObjects) {
375 int ObjectIdx = MFI.CreateStackObject(
376 Object.Size, Object.Alignment,
377 Object.Type == yaml::MachineStackObject::SpillSlot);
378 MFI.setObjectOffset(ObjectIdx, Object.Offset);
379 // TODO: Store the mapping between object IDs and object indices to parse
380 // stack object references correctly.
381 }
371382 return false;
372383 }
373384
4646 void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
4747 void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
4848 const MachineBasicBlock &MBB);
49 void convertStackObjects(yaml::MachineFunction &MF,
50 const MachineFrameInfo &MFI);
4951
5052 private:
5153 void initRegisterMaskIds(const MachineFunction &MF);
9799 YamlMF.HasInlineAsm = MF.hasInlineAsm();
98100 convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
99101 convert(YamlMF.FrameInfo, *MF.getFrameInfo());
102 convertStackObjects(YamlMF, *MF.getFrameInfo());
100103
101104 int I = 0;
102105 ModuleSlotTracker MST(MF.getFunction()->getParent());
149152 YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
150153 YamlMFI.HasVAStart = MFI.hasVAStart();
151154 YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
155 }
156
157 void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
158 const MachineFrameInfo &MFI) {
159 unsigned ID = 0;
160 for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
161 if (MFI.isDeadObjectIndex(I))
162 continue;
163
164 yaml::MachineStackObject YamlObject;
165 YamlObject.ID = ID++;
166 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
167 ? yaml::MachineStackObject::SpillSlot
168 : yaml::MachineStackObject::DefaultType;
169 YamlObject.Offset = MFI.getObjectOffset(I);
170 YamlObject.Size = MFI.getObjectSize(I);
171 YamlObject.Alignment = MFI.getObjectAlignment(I);
172
173 MF.StackObjects.push_back(YamlObject);
174 // TODO: Store the mapping between object IDs and object indices to print
175 // the stack object references correctly.
176 }
152177 }
153178
154179 void MIRPrinter::convert(ModuleSlotTracker &MST,
0 # RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
1 # This test ensures that the MIR parser parses stack objects correctly.
2
3 --- |
4
5 define i32 @test(i32 %a) #0 {
6 entry:
7 %b = alloca i32
8 %x = alloca i64
9 store i32 %a, i32* %b
10 store i64 2, i64* %x
11 %c = load i32, i32* %b
12 ret i32 %c
13 }
14
15 attributes #0 = { "no-frame-pointer-elim"="false" }
16
17 ...
18 ---
19 name: test
20 frameInfo:
21 maxAlignment: 8
22 # CHECK: stack:
23 # CHECK-NEXT: - { id: 0, offset: -12, size: 4, alignment: 4 }
24 # CHECK-NEXT: - { id: 1, offset: -24, size: 8, alignment: 8 }
25 # CHECK-NEXT: - { id: 2, type: spill-slot, offset: -32, size: 4, alignment: 4 }
26 stack:
27 - { id: 0, offset: -12, size: 4, alignment: 4 }
28 - { id: 1, offset: -24, size: 8, alignment: 8 }
29 - { id: 2, type: spill-slot, offset: -32, size: 4, alignment: 4 }
30 body:
31 - id: 0
32 name: entry
33 instructions:
34 - 'MOV32mr %rsp, 1, _, -4, _, %edi'
35 - 'MOV64mi32 %rsp, 1, _, -16, _, 2'
36 - '%eax = MOV32rm %rsp, 1, _, -4, _'
37 - 'RETQ %eax'
38 ...