Skip to content

Commit

Permalink
MIR Serialization: Serialize the variable sized stack objects.
Browse files Browse the repository at this point in the history
llvm-svn: 242095
  • Loading branch information
hyp committed Jul 14, 2015
1 parent ce18a18 commit 418f3ec
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 7 deletions.
7 changes: 4 additions & 3 deletions llvm/include/llvm/CodeGen/MIRYamlMapping.h
Expand Up @@ -129,9 +129,8 @@ template <> struct MappingTraits<MachineBasicBlock> {
///
/// TODO: Determine isPreallocated flag by mapping between objects and local
/// objects (Serialize local objects).
/// TODO: Serialize variable sized objects.
struct MachineStackObject {
enum ObjectType { DefaultType, SpillSlot };
enum ObjectType { DefaultType, SpillSlot, VariableSized };
// TODO: Serialize LLVM alloca reference.
unsigned ID;
ObjectType Type = DefaultType;
Expand All @@ -144,6 +143,7 @@ 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);
IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
}
};

Expand All @@ -154,7 +154,8 @@ template <> struct MappingTraits<MachineStackObject> {
"type", Object.Type,
MachineStackObject::DefaultType); // Don't print the default type.
YamlIO.mapOptional("offset", Object.Offset);
YamlIO.mapRequired("size", Object.Size);
if (Object.Type != MachineStackObject::VariableSized)
YamlIO.mapRequired("size", Object.Size);
YamlIO.mapOptional("alignment", Object.Alignment);
}

Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/CodeGen/MachineFrameInfo.h
Expand Up @@ -541,6 +541,14 @@ class MachineFrameInfo {
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
}

/// Returns true if the specified index corresponds to a variable sized
/// object.
bool isVariableSizedObjectIndex(int ObjectIdx) const {
assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
return Objects[ObjectIdx + NumFixedObjects].Size == 0;
}

/// Create a new statically sized stack object, returning
/// a nonnegative identifier to represent it.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
Expand Down
11 changes: 8 additions & 3 deletions llvm/lib/CodeGen/MIRParser/MIRParser.cpp
Expand Up @@ -391,9 +391,14 @@ bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI,

// Initialize the ordinary frame objects.
for (const auto &Object : YamlMF.StackObjects) {
int ObjectIdx = MFI.CreateStackObject(
Object.Size, Object.Alignment,
Object.Type == yaml::MachineStackObject::SpillSlot);
int ObjectIdx;
if (Object.Type == yaml::MachineStackObject::VariableSized)
ObjectIdx =
MFI.CreateVariableSizedObject(Object.Alignment, /*Alloca=*/nullptr);
else
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.
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/CodeGen/MIRPrinter.cpp
Expand Up @@ -188,7 +188,9 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
YamlObject.ID = ID++;
YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
? yaml::MachineStackObject::SpillSlot
: yaml::MachineStackObject::DefaultType;
: MFI.isVariableSizedObjectIndex(I)
? yaml::MachineStackObject::VariableSized
: yaml::MachineStackObject::DefaultType;
YamlObject.Offset = MFI.getObjectOffset(I);
YamlObject.Size = MFI.getObjectSize(I);
YamlObject.Alignment = MFI.getObjectAlignment(I);
Expand Down
@@ -0,0 +1,36 @@
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
--- |

define i32 @test(i32 %a) {
entry:
%b = alloca i32
%x = alloca i64
%y = alloca i32, i32 %a
store i32 %a, i32* %b
store i64 2, i64* %x
%c = load i32, i32* %b
ret i32 %c
}

...
---
name: test
frameInfo:
stackSize: 24
offsetAdjustment: -16
maxAlignment: 8
adjustsStack: true
stack:
- { id: 0, offset: -20, size: 4, alignment: 4 }
- { id: 1, offset: -32, size: 8, alignment: 8 }
# CHECK: [[@LINE+1]]:55: unknown key 'size'
- { id: 2, type: variable-sized, offset: -32, size: 42, alignment: 1 }
body:
- id: 0
name: entry
instructions:
- 'MOV32mr %rsp, 1, _, -4, _, %edi'
- 'MOV64mi32 %rsp, 1, _, -16, _, 2'
- '%eax = MOV32rm %rsp, 1, _, -4, _'
- 'RETQ %eax'
...
42 changes: 42 additions & 0 deletions llvm/test/CodeGen/MIR/X86/variable-sized-stack-objects.mir
@@ -0,0 +1,42 @@
# 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 variable sized stack objects
# correctly.

--- |

define i32 @test(i32 %a) {
entry:
%b = alloca i32
%x = alloca i64
%y = alloca i32, i32 %a
store i32 %a, i32* %b
store i64 2, i64* %x
%c = load i32, i32* %b
ret i32 %c
}

...
---
name: test
frameInfo:
stackSize: 24
offsetAdjustment: -16
maxAlignment: 8
adjustsStack: true
# CHECK: stack:
# CHECK-NEXT: - { id: 0, offset: -20, size: 4, alignment: 4 }
# CHECK-NEXT: - { id: 1, offset: -32, size: 8, alignment: 8 }
# CHECK-NEXT: - { id: 2, type: variable-sized, offset: -32, alignment: 1 }
stack:
- { id: 0, offset: -20, size: 4, alignment: 4 }
- { id: 1, offset: -32, size: 8, alignment: 8 }
- { id: 2, type: variable-sized, offset: -32, alignment: 1 }
body:
- id: 0
name: entry
instructions:
- 'MOV32mr %rsp, 1, _, -4, _, %edi'
- 'MOV64mi32 %rsp, 1, _, -16, _, 2'
- '%eax = MOV32rm %rsp, 1, _, -4, _'
- 'RETQ %eax'
...

0 comments on commit 418f3ec

Please sign in to comment.