mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
MIR Serialization: Serialize the machine function's liveins.
Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243288 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -116,6 +116,22 @@ template <> struct MappingTraits<VirtualRegisterDefinition> {
|
|||||||
static const bool flow = true;
|
static const bool flow = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MachineFunctionLiveIn {
|
||||||
|
StringValue Register;
|
||||||
|
StringValue VirtualRegister;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct MappingTraits<MachineFunctionLiveIn> {
|
||||||
|
static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
|
||||||
|
YamlIO.mapRequired("reg", LiveIn.Register);
|
||||||
|
YamlIO.mapOptional(
|
||||||
|
"virtual-reg", LiveIn.VirtualRegister,
|
||||||
|
StringValue()); // Don't print the virtual register when it's empty.
|
||||||
|
}
|
||||||
|
|
||||||
|
static const bool flow = true;
|
||||||
|
};
|
||||||
|
|
||||||
struct MachineBasicBlock {
|
struct MachineBasicBlock {
|
||||||
unsigned ID;
|
unsigned ID;
|
||||||
StringValue Name;
|
StringValue Name;
|
||||||
@ -266,6 +282,7 @@ template <> struct MappingTraits<MachineJumpTable::Entry> {
|
|||||||
} // end namespace yaml
|
} // end namespace yaml
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
|
||||||
@ -337,8 +354,8 @@ struct MachineFunction {
|
|||||||
bool TracksRegLiveness = false;
|
bool TracksRegLiveness = false;
|
||||||
bool TracksSubRegLiveness = false;
|
bool TracksSubRegLiveness = false;
|
||||||
std::vector<VirtualRegisterDefinition> VirtualRegisters;
|
std::vector<VirtualRegisterDefinition> VirtualRegisters;
|
||||||
|
std::vector<MachineFunctionLiveIn> LiveIns;
|
||||||
// TODO: Serialize the various register masks.
|
// TODO: Serialize the various register masks.
|
||||||
// TODO: Serialize live in registers.
|
|
||||||
// Frame information
|
// Frame information
|
||||||
MachineFrameInfo FrameInfo;
|
MachineFrameInfo FrameInfo;
|
||||||
std::vector<FixedMachineStackObject> FixedStackObjects;
|
std::vector<FixedMachineStackObject> FixedStackObjects;
|
||||||
@ -359,6 +376,7 @@ template <> struct MappingTraits<MachineFunction> {
|
|||||||
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
|
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
|
||||||
YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
|
YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
|
||||||
YamlIO.mapOptional("registers", MF.VirtualRegisters);
|
YamlIO.mapOptional("registers", MF.VirtualRegisters);
|
||||||
|
YamlIO.mapOptional("liveins", MF.LiveIns);
|
||||||
YamlIO.mapOptional("frameInfo", MF.FrameInfo);
|
YamlIO.mapOptional("frameInfo", MF.FrameInfo);
|
||||||
YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
|
YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
|
||||||
YamlIO.mapOptional("stack", MF.StackObjects);
|
YamlIO.mapOptional("stack", MF.StackObjects);
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
bool parse(MachineInstr *&MI);
|
bool parse(MachineInstr *&MI);
|
||||||
bool parseMBB(MachineBasicBlock *&MBB);
|
bool parseMBB(MachineBasicBlock *&MBB);
|
||||||
bool parseNamedRegister(unsigned &Reg);
|
bool parseNamedRegister(unsigned &Reg);
|
||||||
|
bool parseStandaloneVirtualRegister(unsigned &Reg);
|
||||||
|
|
||||||
bool parseRegister(unsigned &Reg);
|
bool parseRegister(unsigned &Reg);
|
||||||
bool parseRegisterFlag(unsigned &Flags);
|
bool parseRegisterFlag(unsigned &Flags);
|
||||||
@ -289,6 +290,18 @@ bool MIParser::parseNamedRegister(unsigned &Reg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) {
|
||||||
|
lex();
|
||||||
|
if (Token.isNot(MIToken::VirtualRegister))
|
||||||
|
return error("expected a virtual register");
|
||||||
|
if (parseRegister(Reg))
|
||||||
|
return 0;
|
||||||
|
lex();
|
||||||
|
if (Token.isNot(MIToken::Eof))
|
||||||
|
return error("expected end of string after the register reference");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
|
static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
|
||||||
assert(MO.isImplicit());
|
assert(MO.isImplicit());
|
||||||
return MO.isDef() ? "implicit-def" : "implicit";
|
return MO.isDef() ? "implicit-def" : "implicit";
|
||||||
@ -843,3 +856,12 @@ bool llvm::parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM,
|
|||||||
SMDiagnostic &Error) {
|
SMDiagnostic &Error) {
|
||||||
return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseNamedRegister(Reg);
|
return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseNamedRegister(Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
|
||||||
|
MachineFunction &MF, StringRef Src,
|
||||||
|
const PerFunctionMIParsingState &PFS,
|
||||||
|
const SlotMapping &IRSlots,
|
||||||
|
SMDiagnostic &Error) {
|
||||||
|
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
|
||||||
|
.parseStandaloneVirtualRegister(Reg);
|
||||||
|
}
|
||||||
|
@ -50,6 +50,12 @@ bool parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM,
|
|||||||
const SlotMapping &IRSlots,
|
const SlotMapping &IRSlots,
|
||||||
SMDiagnostic &Error);
|
SMDiagnostic &Error);
|
||||||
|
|
||||||
|
bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
|
||||||
|
MachineFunction &MF, StringRef Src,
|
||||||
|
const PerFunctionMIParsingState &PFS,
|
||||||
|
const SlotMapping &IRSlots,
|
||||||
|
SMDiagnostic &Error);
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -402,6 +402,21 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
|
|||||||
RegInfo.setSimpleHint(Reg, PreferredReg);
|
RegInfo.setSimpleHint(Reg, PreferredReg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the liveins.
|
||||||
|
for (const auto &LiveIn : YamlMF.LiveIns) {
|
||||||
|
unsigned Reg = 0;
|
||||||
|
if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
|
||||||
|
IRSlots, Error))
|
||||||
|
return error(Error, LiveIn.Register.SourceRange);
|
||||||
|
unsigned VReg = 0;
|
||||||
|
if (!LiveIn.VirtualRegister.Value.empty()) {
|
||||||
|
if (parseVirtualRegisterReference(
|
||||||
|
VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
|
||||||
|
return error(Error, LiveIn.VirtualRegister.SourceRange);
|
||||||
|
}
|
||||||
|
RegInfo.addLiveIn(Reg, VReg);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +201,15 @@ void MIRPrinter::convert(yaml::MachineFunction &MF,
|
|||||||
printReg(PreferredReg, VReg.PreferredRegister, TRI);
|
printReg(PreferredReg, VReg.PreferredRegister, TRI);
|
||||||
MF.VirtualRegisters.push_back(VReg);
|
MF.VirtualRegisters.push_back(VReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print the live ins.
|
||||||
|
for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
|
||||||
|
yaml::MachineFunctionLiveIn LiveIn;
|
||||||
|
printReg(I->first, LiveIn.Register, TRI);
|
||||||
|
if (I->second)
|
||||||
|
printReg(I->second, LiveIn.VirtualRegister, TRI);
|
||||||
|
MF.LiveIns.push_back(LiveIn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
|
void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @test(i32 %a) {
|
||||||
|
body:
|
||||||
|
ret i32 %a
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
isSSA: true
|
||||||
|
tracksRegLiveness: true
|
||||||
|
registers:
|
||||||
|
- { id: 0, class: gr32 }
|
||||||
|
liveins:
|
||||||
|
# CHECK: [[@LINE+1]]:13: expected a named register
|
||||||
|
- { reg: '%0' }
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: body
|
||||||
|
liveins: [ '%edi' ]
|
||||||
|
instructions:
|
||||||
|
- '%0 = COPY %edi'
|
||||||
|
- '%eax = COPY %0'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
@ -0,0 +1,28 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @test(i32 %a) {
|
||||||
|
body:
|
||||||
|
ret i32 %a
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
isSSA: true
|
||||||
|
tracksRegLiveness: true
|
||||||
|
registers:
|
||||||
|
- { id: 0, class: gr32 }
|
||||||
|
liveins:
|
||||||
|
# CHECK: [[@LINE+1]]:34: expected a virtual register
|
||||||
|
- { reg: '%edi', virtual-reg: '%edi' }
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: body
|
||||||
|
liveins: [ '%edi' ]
|
||||||
|
instructions:
|
||||||
|
- '%0 = COPY %edi'
|
||||||
|
- '%eax = COPY %0'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
38
test/CodeGen/MIR/X86/function-liveins.mir
Normal file
38
test/CodeGen/MIR/X86/function-liveins.mir
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# 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 machine function's liveins
|
||||||
|
# correctly.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @test(i32 %a, i32 %b) {
|
||||||
|
body:
|
||||||
|
%c = add i32 %a, %b
|
||||||
|
ret i32 %c
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
isSSA: true
|
||||||
|
tracksRegLiveness: true
|
||||||
|
registers:
|
||||||
|
- { id: 0, class: gr32 }
|
||||||
|
- { id: 1, class: gr32 }
|
||||||
|
- { id: 2, class: gr32 }
|
||||||
|
# CHECK: liveins:
|
||||||
|
# CHECK-NEXT: - { reg: '%edi', virtual-reg: '%0' }
|
||||||
|
# CHECK-NEXT: - { reg: '%esi', virtual-reg: '%1' }
|
||||||
|
liveins:
|
||||||
|
- { reg: '%edi', virtual-reg: '%0' }
|
||||||
|
- { reg: '%esi', virtual-reg: '%1' }
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: body
|
||||||
|
liveins: [ '%edi', '%esi' ]
|
||||||
|
instructions:
|
||||||
|
- '%1 = COPY %esi'
|
||||||
|
- '%0 = COPY %edi'
|
||||||
|
- '%2 = ADD32rr %0, %1, implicit-def dead %eflags'
|
||||||
|
- '%eax = COPY %2'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
Reference in New Issue
Block a user