Skip to content

Commit

Permalink
MIR Serialization: Serialize MMI's variable debug information.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245396 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
hyp committed Aug 19, 2015
1 parent 0f33e74 commit a80c044
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 2 deletions.
9 changes: 9 additions & 0 deletions include/llvm/CodeGen/MIRYamlMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ struct MachineStackObject {
unsigned Alignment = 0;
StringValue CalleeSavedRegister;
Optional<int64_t> LocalOffset;
StringValue DebugVar;
StringValue DebugExpr;
StringValue DebugLoc;
};

template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
Expand All @@ -221,6 +224,12 @@ template <> struct MappingTraits<MachineStackObject> {
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("local-offset", Object.LocalOffset);
YamlIO.mapOptional("di-variable", Object.DebugVar,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("di-expression", Object.DebugExpr,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("di-location", Object.DebugLoc,
StringValue()); // Don't print it out when it's empty.
}

static const bool flow = true;
Expand Down
18 changes: 18 additions & 0 deletions lib/CodeGen/MIRParser/MIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class MIParser {
bool parseStandaloneNamedRegister(unsigned &Reg);
bool parseStandaloneVirtualRegister(unsigned &Reg);
bool parseStandaloneStackObject(int &FI);
bool parseStandaloneMDNode(MDNode *&Node);

bool
parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
Expand Down Expand Up @@ -677,6 +678,17 @@ bool MIParser::parseStandaloneStackObject(int &FI) {
return false;
}

bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
lex();
if (Token.isNot(MIToken::exclaim))
return error("expected a metadata node");
if (parseMDNode(Node))
return true;
if (Token.isNot(MIToken::Eof))
return error("expected end of string after the metadata node");
return false;
}

static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
assert(MO.isImplicit());
return MO.isDef() ? "implicit-def" : "implicit";
Expand Down Expand Up @@ -1858,3 +1870,9 @@ bool llvm::parseStackObjectReference(int &FI, SourceMgr &SM,
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
.parseStandaloneStackObject(FI);
}

bool llvm::parseMDNode(MDNode *&Node, SourceMgr &SM, MachineFunction &MF,
StringRef Src, const PerFunctionMIParsingState &PFS,
const SlotMapping &IRSlots, SMDiagnostic &Error) {
return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseStandaloneMDNode(Node);
}
5 changes: 5 additions & 0 deletions lib/CodeGen/MIRParser/MIParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class BasicBlock;
class MachineBasicBlock;
class MachineInstr;
class MachineFunction;
class MDNode;
struct SlotMapping;
class SMDiagnostic;
class SourceMgr;
Expand Down Expand Up @@ -89,6 +90,10 @@ bool parseStackObjectReference(int &FI, SourceMgr &SM, MachineFunction &MF,
const PerFunctionMIParsingState &PFS,
const SlotMapping &IRSlots, SMDiagnostic &Error);

bool parseMDNode(MDNode *&Node, SourceMgr &SM, MachineFunction &MF,
StringRef Src, const PerFunctionMIParsingState &PFS,
const SlotMapping &IRSlots, SMDiagnostic &Error);

} // end namespace llvm

#endif
61 changes: 61 additions & 0 deletions lib/CodeGen/MIRParser/MIRParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/IR/BasicBlock.h"
Expand Down Expand Up @@ -113,6 +114,11 @@ class MIRParserImpl {
const yaml::StringValue &RegisterSource,
int FrameIdx);

bool parseStackObjectsDebugInfo(MachineFunction &MF,
PerFunctionMIParsingState &PFS,
const yaml::MachineStackObject &Object,
int FrameIdx);

bool initializeConstantPool(MachineConstantPool &ConstantPool,
const yaml::MachineFunction &YamlMF,
const MachineFunction &MF,
Expand All @@ -123,6 +129,9 @@ class MIRParserImpl {
PerFunctionMIParsingState &PFS);

private:
bool parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
MachineFunction &MF, const PerFunctionMIParsingState &PFS);

bool parseMBBReference(MachineBasicBlock *&MBB,
const yaml::StringValue &Source, MachineFunction &MF,
const PerFunctionMIParsingState &PFS);
Expand Down Expand Up @@ -489,6 +498,8 @@ bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
return true;
if (Object.LocalOffset)
MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
return true;
}
MFI.setCalleeSavedInfo(CSIInfo);
if (!CSIInfo.empty())
Expand Down Expand Up @@ -522,6 +533,56 @@ bool MIRParserImpl::parseCalleeSavedRegister(
return false;
}

/// Verify that given node is of a certain type. Return true on error.
template <typename T>
static bool typecheckMDNode(T *&Result, MDNode *Node,
const yaml::StringValue &Source,
StringRef TypeString, MIRParserImpl &Parser) {
if (!Node)
return false;
Result = dyn_cast<T>(Node);
if (!Result)
return Parser.error(Source.SourceRange.Start,
"expected a reference to a '" + TypeString +
"' metadata node");
return false;
}

bool MIRParserImpl::parseStackObjectsDebugInfo(
MachineFunction &MF, PerFunctionMIParsingState &PFS,
const yaml::MachineStackObject &Object, int FrameIdx) {
// Debug information can only be attached to stack objects; Fixed stack
// objects aren't supported.
assert(FrameIdx >= 0 && "Expected a stack object frame index");
MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
parseMDNode(Loc, Object.DebugLoc, MF, PFS))
return true;
if (!Var && !Expr && !Loc)
return false;
DILocalVariable *DIVar = nullptr;
DIExpression *DIExpr = nullptr;
DILocation *DILoc = nullptr;
if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
return true;
MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
return false;
}

bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
MachineFunction &MF,
const PerFunctionMIParsingState &PFS) {
if (Source.Value.empty())
return false;
SMDiagnostic Error;
if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
return error(Error, Source.SourceRange);
return false;
}

bool MIRParserImpl::initializeConstantPool(
MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
const MachineFunction &MF,
Expand Down
29 changes: 27 additions & 2 deletions lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class MIRPrinter {
void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
const MachineJumpTableInfo &JTI);
void convertStackObjects(yaml::MachineFunction &MF,
const MachineFrameInfo &MFI, ModuleSlotTracker &MST,
const MachineFrameInfo &MFI, MachineModuleInfo &MMI,
ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI);

private:
Expand Down Expand Up @@ -171,7 +172,7 @@ void MIRPrinter::print(const MachineFunction &MF) {
ModuleSlotTracker MST(MF.getFunction()->getParent());
MST.incorporateFunction(*MF.getFunction());
convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
convertStackObjects(YamlMF, *MF.getFrameInfo(), MST,
convertStackObjects(YamlMF, *MF.getFrameInfo(), MF.getMMI(), MST,
MF.getSubtarget().getRegisterInfo());
if (const auto *ConstantPool = MF.getConstantPool())
convert(YamlMF, *ConstantPool);
Expand Down Expand Up @@ -265,6 +266,7 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,

void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
const MachineFrameInfo &MFI,
MachineModuleInfo &MMI,
ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI) {
// Process fixed stack objects.
Expand Down Expand Up @@ -342,6 +344,29 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
.printStackObjectReference(MFI.getStackProtectorIndex());
}

// Print the debug variable information.
for (MachineModuleInfo::VariableDbgInfo &DebugVar :
MMI.getVariableDbgInfo()) {
auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot);
assert(StackObjectInfo != StackObjectOperandMapping.end() &&
"Invalid stack object index");
const FrameIndexOperand &StackObject = StackObjectInfo->second;
assert(!StackObject.IsFixed && "Expected a non-fixed stack object");
auto &Object = MF.StackObjects[StackObject.ID];
{
raw_string_ostream StrOS(Object.DebugVar.Value);
DebugVar.Var->printAsOperand(StrOS, MST);
}
{
raw_string_ostream StrOS(Object.DebugExpr.Value);
DebugVar.Expr->printAsOperand(StrOS, MST);
}
{
raw_string_ostream StrOS(Object.DebugLoc.Value);
DebugVar.Loc->printAsOperand(StrOS, MST);
}
}
}

void MIRPrinter::convert(yaml::MachineFunction &MF,
Expand Down
25 changes: 25 additions & 0 deletions test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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 %x) {
entry:
%xa = alloca i32, align 4
store i32 %x, i32* %xa, align 4
%0 = load i32, i32* %xa, align 4
ret i32 %0
}
...
---
name: test
liveins:
- { reg: '%edi' }
stack:
# CHECK: [[@LINE+1]]:74: expected a metadata node
- { id: 0, name: xa, offset: -12, size: 4, alignment: 4, di-variable: '0' }
body: |
bb.0.entry:
liveins: %edi
MOV32mr %rsp, 1, _, -4, _, %edi :: (store 4 into %ir.xa)
%eax = COPY killed %edi
RETQ killed %eax
...
53 changes: 53 additions & 0 deletions test/CodeGen/MIR/X86/invalid-metadata-node-type.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
--- |
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0

define void @foo() #1 {
entry:
%x.i = alloca i8, align 1
%y.i = alloca [256 x i8], align 16
%0 = bitcast [256 x i8]* %y.i to i8*
br label %for.body

for.body:
%1 = bitcast [256 x i8]* %y.i to i8*
call void @llvm.dbg.declare(metadata i8* %0, metadata !4, metadata !7) #3, !dbg !8
br label %for.body
}

attributes #0 = { nounwind readnone }
attributes #1 = { nounwind ssp uwtable }
attributes #3 = { nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}

!0 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: 0, enums: !2, retainedTypes: !2)
!1 = !DIFile(filename: "t.c", directory: "")
!2 = !{}
!3 = !{i32 1, !"Debug Info Version", i32 3}
!4 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 16, type: !6)
!5 = !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false)
!6 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
!7 = !DIExpression()
!8 = !DILocation(line: 0, scope: !5)
...
---
name: foo
isSSA: true
tracksRegLiveness: true
frameInfo:
maxAlignment: 16
stack:
# CHECK: [[@LINE+1]]:75: expected a reference to a 'DILocalVariable' metadata node
- { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!8',
di-expression: '!7', di-location: '!8' }
body: |
bb.0.entry:
successors: %bb.1.for.body
bb.1.for.body:
successors: %bb.1.for.body
DBG_VALUE %stack.0.y.i, 0, !4, !7, debug-location !8
JMP_1 %bb.1.for.body
...
65 changes: 65 additions & 0 deletions test/CodeGen/MIR/X86/stack-object-debug-info.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# RUN: llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s | FileCheck %s
# This test ensures that the MIR parser parses the stack object's debug info
# correctly.
--- |
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0

define void @foo() #1 {
entry:
%x.i = alloca i8, align 1
%y.i = alloca [256 x i8], align 16
%0 = bitcast [256 x i8]* %y.i to i8*
br label %for.body

for.body:
%1 = bitcast [256 x i8]* %y.i to i8*
call void @llvm.lifetime.end(i64 -1, i8* %1) #3
call void @llvm.lifetime.start(i64 -1, i8* %0) #3
call void @llvm.dbg.declare(metadata i8* %0, metadata !4, metadata !7) #3, !dbg !8
br label %for.body
}

declare void @llvm.lifetime.start(i64, i8* nocapture) #2

declare void @llvm.lifetime.end(i64, i8* nocapture) #2

attributes #0 = { nounwind readnone }
attributes #1 = { nounwind ssp uwtable }
attributes #2 = { nounwind argmemonly }
attributes #3 = { nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}

!0 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: 0, enums: !2, retainedTypes: !2)
!1 = !DIFile(filename: "t.c", directory: "")
!2 = !{}
!3 = !{i32 1, !"Debug Info Version", i32 3}
!4 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 16, type: !6)
!5 = !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false)
!6 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
!7 = !DIExpression()
!8 = !DILocation(line: 0, scope: !5)
...
---
name: foo
isSSA: true
tracksRegLiveness: true
frameInfo:
maxAlignment: 16
# CHECK-LABEL: foo
# CHECK: stack:
# CHECK: - { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!4',
# CHECK-NEXT: di-expression: '!7', di-location: '!8' }
stack:
- { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!4',
di-expression: '!7', di-location: '!8' }
body: |
bb.0.entry:
successors: %bb.1.for.body
bb.1.for.body:
successors: %bb.1.for.body
DBG_VALUE %stack.0.y.i, 0, !4, !7, debug-location !8
JMP_1 %bb.1.for.body
...

0 comments on commit a80c044

Please sign in to comment.