mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
MIR Serialization: Serialize the unnamed basic block references.
This commit serializes the references from the machine basic blocks to the unnamed basic blocks. This commit adds a new attribute to the machine basic block's YAML mapping called 'ir-block'. This attribute contains the actual reference to the basic block. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243340 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -135,6 +135,7 @@ template <> struct MappingTraits<MachineFunctionLiveIn> {
|
|||||||
struct MachineBasicBlock {
|
struct MachineBasicBlock {
|
||||||
unsigned ID;
|
unsigned ID;
|
||||||
StringValue Name;
|
StringValue Name;
|
||||||
|
StringValue IRBlock;
|
||||||
unsigned Alignment = 0;
|
unsigned Alignment = 0;
|
||||||
bool IsLandingPad = false;
|
bool IsLandingPad = false;
|
||||||
bool AddressTaken = false;
|
bool AddressTaken = false;
|
||||||
@@ -149,6 +150,8 @@ template <> struct MappingTraits<MachineBasicBlock> {
|
|||||||
YamlIO.mapRequired("id", MBB.ID);
|
YamlIO.mapRequired("id", MBB.ID);
|
||||||
YamlIO.mapOptional("name", MBB.Name,
|
YamlIO.mapOptional("name", MBB.Name,
|
||||||
StringValue()); // Don't print out an empty name.
|
StringValue()); // Don't print out an empty name.
|
||||||
|
YamlIO.mapOptional("ir-block", MBB.IRBlock,
|
||||||
|
StringValue()); // Don't print out an empty BB reference.
|
||||||
YamlIO.mapOptional("alignment", MBB.Alignment);
|
YamlIO.mapOptional("alignment", MBB.Alignment);
|
||||||
YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
|
YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
|
||||||
YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
|
YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
|
||||||
|
@@ -219,6 +219,10 @@ static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) {
|
|||||||
return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
|
return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Cursor maybeLexIRBlock(Cursor C, MIToken &Token) {
|
||||||
|
return maybeLexIndex(C, Token, "%ir-block.", MIToken::IRBlock);
|
||||||
|
}
|
||||||
|
|
||||||
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
||||||
auto Range = C;
|
auto Range = C;
|
||||||
C.advance(); // Skip '%'
|
C.advance(); // Skip '%'
|
||||||
@@ -351,6 +355,8 @@ StringRef llvm::lexMIToken(
|
|||||||
return R.remaining();
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexConstantPoolItem(C, Token))
|
if (Cursor R = maybeLexConstantPoolItem(C, Token))
|
||||||
return R.remaining();
|
return R.remaining();
|
||||||
|
if (Cursor R = maybeLexIRBlock(C, Token))
|
||||||
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexRegister(C, Token))
|
if (Cursor R = maybeLexRegister(C, Token))
|
||||||
return R.remaining();
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
|
if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
|
||||||
|
@@ -66,7 +66,8 @@ struct MIToken {
|
|||||||
IntegerLiteral,
|
IntegerLiteral,
|
||||||
VirtualRegister,
|
VirtualRegister,
|
||||||
ConstantPoolItem,
|
ConstantPoolItem,
|
||||||
JumpTableIndex
|
JumpTableIndex,
|
||||||
|
IRBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -132,7 +133,8 @@ public:
|
|||||||
return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
|
return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
|
||||||
Kind == StackObject || Kind == FixedStackObject ||
|
Kind == StackObject || Kind == FixedStackObject ||
|
||||||
Kind == GlobalValue || Kind == VirtualRegister ||
|
Kind == GlobalValue || Kind == VirtualRegister ||
|
||||||
Kind == ConstantPoolItem || Kind == JumpTableIndex;
|
Kind == ConstantPoolItem || Kind == JumpTableIndex ||
|
||||||
|
Kind == IRBlock;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/ModuleSlotTracker.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/SourceMgr.h"
|
#include "llvm/Support/SourceMgr.h"
|
||||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||||
@@ -77,6 +78,8 @@ class MIParser {
|
|||||||
StringMap<const uint32_t *> Names2RegMasks;
|
StringMap<const uint32_t *> Names2RegMasks;
|
||||||
/// Maps from subregister names to subregister indices.
|
/// Maps from subregister names to subregister indices.
|
||||||
StringMap<unsigned> Names2SubRegIndices;
|
StringMap<unsigned> Names2SubRegIndices;
|
||||||
|
/// Maps from slot numbers to function's unnamed basic blocks.
|
||||||
|
DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
|
MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
|
||||||
@@ -99,6 +102,7 @@ public:
|
|||||||
bool parseStandaloneMBB(MachineBasicBlock *&MBB);
|
bool parseStandaloneMBB(MachineBasicBlock *&MBB);
|
||||||
bool parseStandaloneNamedRegister(unsigned &Reg);
|
bool parseStandaloneNamedRegister(unsigned &Reg);
|
||||||
bool parseStandaloneVirtualRegister(unsigned &Reg);
|
bool parseStandaloneVirtualRegister(unsigned &Reg);
|
||||||
|
bool parseStandaloneIRBlockReference(const BasicBlock *&BB);
|
||||||
|
|
||||||
bool parseRegister(unsigned &Reg);
|
bool parseRegister(unsigned &Reg);
|
||||||
bool parseRegisterFlag(unsigned &Flags);
|
bool parseRegisterFlag(unsigned &Flags);
|
||||||
@@ -160,6 +164,10 @@ private:
|
|||||||
///
|
///
|
||||||
/// Return 0 if the name isn't a subregister index class.
|
/// Return 0 if the name isn't a subregister index class.
|
||||||
unsigned getSubRegIndex(StringRef Name);
|
unsigned getSubRegIndex(StringRef Name);
|
||||||
|
|
||||||
|
void initSlots2BasicBlocks();
|
||||||
|
|
||||||
|
const BasicBlock *getIRBlock(unsigned Slot);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
@@ -302,6 +310,23 @@ bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MIParser::parseStandaloneIRBlockReference(const BasicBlock *&BB) {
|
||||||
|
lex();
|
||||||
|
if (Token.isNot(MIToken::IRBlock))
|
||||||
|
return error("expected an IR block reference");
|
||||||
|
unsigned SlotNumber = 0;
|
||||||
|
if (getUnsigned(SlotNumber))
|
||||||
|
return true;
|
||||||
|
BB = getIRBlock(SlotNumber);
|
||||||
|
if (!BB)
|
||||||
|
return error(Twine("use of undefined IR block '%ir-block.") +
|
||||||
|
Twine(SlotNumber) + "'");
|
||||||
|
lex();
|
||||||
|
if (Token.isNot(MIToken::Eof))
|
||||||
|
return error("expected end of string after the IR block 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";
|
||||||
@@ -842,6 +867,30 @@ unsigned MIParser::getSubRegIndex(StringRef Name) {
|
|||||||
return SubRegInfo->getValue();
|
return SubRegInfo->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MIParser::initSlots2BasicBlocks() {
|
||||||
|
if (!Slots2BasicBlocks.empty())
|
||||||
|
return;
|
||||||
|
const auto &F = *MF.getFunction();
|
||||||
|
ModuleSlotTracker MST(F.getParent());
|
||||||
|
MST.incorporateFunction(F);
|
||||||
|
for (auto &BB : F) {
|
||||||
|
if (BB.hasName())
|
||||||
|
continue;
|
||||||
|
int Slot = MST.getLocalSlot(&BB);
|
||||||
|
if (Slot == -1)
|
||||||
|
continue;
|
||||||
|
Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
|
||||||
|
initSlots2BasicBlocks();
|
||||||
|
auto BlockInfo = Slots2BasicBlocks.find(Slot);
|
||||||
|
if (BlockInfo == Slots2BasicBlocks.end())
|
||||||
|
return nullptr;
|
||||||
|
return BlockInfo->second;
|
||||||
|
}
|
||||||
|
|
||||||
bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM,
|
bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM,
|
||||||
MachineFunction &MF, StringRef Src,
|
MachineFunction &MF, StringRef Src,
|
||||||
const PerFunctionMIParsingState &PFS,
|
const PerFunctionMIParsingState &PFS,
|
||||||
@@ -873,3 +922,12 @@ bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
|
|||||||
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
|
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
|
||||||
.parseStandaloneVirtualRegister(Reg);
|
.parseStandaloneVirtualRegister(Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool llvm::parseIRBlockReference(const BasicBlock *&BB, SourceMgr &SM,
|
||||||
|
MachineFunction &MF, StringRef Src,
|
||||||
|
const PerFunctionMIParsingState &PFS,
|
||||||
|
const SlotMapping &IRSlots,
|
||||||
|
SMDiagnostic &Error) {
|
||||||
|
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
|
||||||
|
.parseStandaloneIRBlockReference(BB);
|
||||||
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
class BasicBlock;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
@@ -56,6 +57,11 @@ bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
|
|||||||
const SlotMapping &IRSlots,
|
const SlotMapping &IRSlots,
|
||||||
SMDiagnostic &Error);
|
SMDiagnostic &Error);
|
||||||
|
|
||||||
|
bool parseIRBlockReference(const BasicBlock *&BB, SourceMgr &SM,
|
||||||
|
MachineFunction &MF, StringRef Src,
|
||||||
|
const PerFunctionMIParsingState &PFS,
|
||||||
|
const SlotMapping &IRSlots, SMDiagnostic &Error);
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -292,6 +292,7 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
|
|||||||
for (const auto &YamlMBB : YamlMF.BasicBlocks) {
|
for (const auto &YamlMBB : YamlMF.BasicBlocks) {
|
||||||
const BasicBlock *BB = nullptr;
|
const BasicBlock *BB = nullptr;
|
||||||
const yaml::StringValue &Name = YamlMBB.Name;
|
const yaml::StringValue &Name = YamlMBB.Name;
|
||||||
|
const yaml::StringValue &IRBlock = YamlMBB.IRBlock;
|
||||||
if (!Name.Value.empty()) {
|
if (!Name.Value.empty()) {
|
||||||
BB = dyn_cast_or_null<BasicBlock>(
|
BB = dyn_cast_or_null<BasicBlock>(
|
||||||
F.getValueSymbolTable().lookup(Name.Value));
|
F.getValueSymbolTable().lookup(Name.Value));
|
||||||
@@ -301,6 +302,12 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
|
|||||||
"' is not defined in the function '" + MF.getName() +
|
"' is not defined in the function '" + MF.getName() +
|
||||||
"'");
|
"'");
|
||||||
}
|
}
|
||||||
|
if (!IRBlock.Value.empty()) {
|
||||||
|
// TODO: Report an error when both name and ir block are specified.
|
||||||
|
SMDiagnostic Error;
|
||||||
|
if (parseIRBlockReference(BB, SM, MF, IRBlock.Value, PFS, IRSlots, Error))
|
||||||
|
return error(Error, IRBlock.SourceRange);
|
||||||
|
}
|
||||||
auto *MBB = MF.CreateMachineBasicBlock(BB);
|
auto *MBB = MF.CreateMachineBasicBlock(BB);
|
||||||
MF.insert(MF.end(), MBB);
|
MF.insert(MF.end(), MBB);
|
||||||
bool WasInserted =
|
bool WasInserted =
|
||||||
|
@@ -163,6 +163,7 @@ void MIRPrinter::print(const MachineFunction &MF) {
|
|||||||
convert(YamlMF, *ConstantPool);
|
convert(YamlMF, *ConstantPool);
|
||||||
|
|
||||||
ModuleSlotTracker MST(MF.getFunction()->getParent());
|
ModuleSlotTracker MST(MF.getFunction()->getParent());
|
||||||
|
MST.incorporateFunction(*MF.getFunction());
|
||||||
if (const auto *JumpTableInfo = MF.getJumpTableInfo())
|
if (const auto *JumpTableInfo = MF.getJumpTableInfo())
|
||||||
convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
|
convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
|
||||||
int I = 0;
|
int I = 0;
|
||||||
@@ -336,11 +337,17 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
|
|||||||
const MachineBasicBlock &MBB) {
|
const MachineBasicBlock &MBB) {
|
||||||
assert(MBB.getNumber() >= 0 && "Invalid MBB number");
|
assert(MBB.getNumber() >= 0 && "Invalid MBB number");
|
||||||
YamlMBB.ID = (unsigned)MBB.getNumber();
|
YamlMBB.ID = (unsigned)MBB.getNumber();
|
||||||
// TODO: Serialize unnamed BB references.
|
if (const auto *BB = MBB.getBasicBlock()) {
|
||||||
if (const auto *BB = MBB.getBasicBlock())
|
if (BB->hasName()) {
|
||||||
YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>";
|
YamlMBB.Name.Value = BB->getName();
|
||||||
else
|
} else {
|
||||||
YamlMBB.Name.Value = "";
|
int Slot = MST.getLocalSlot(BB);
|
||||||
|
if (Slot == -1)
|
||||||
|
YamlMBB.IRBlock.Value = "<badref>";
|
||||||
|
else
|
||||||
|
YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str();
|
||||||
|
}
|
||||||
|
}
|
||||||
YamlMBB.Alignment = MBB.getAlignment();
|
YamlMBB.Alignment = MBB.getAlignment();
|
||||||
YamlMBB.AddressTaken = MBB.hasAddressTaken();
|
YamlMBB.AddressTaken = MBB.hasAddressTaken();
|
||||||
YamlMBB.IsLandingPad = MBB.isLandingPad();
|
YamlMBB.IsLandingPad = MBB.isLandingPad();
|
||||||
|
16
test/CodeGen/MIR/machine-basic-block-expected-ir-block.mir
Normal file
16
test/CodeGen/MIR/machine-basic-block-expected-ir-block.mir
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @foo() {
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
# CHECK: [[@LINE+1]]:19: expected an IR block reference
|
||||||
|
ir-block: '0'
|
||||||
|
...
|
19
test/CodeGen/MIR/machine-basic-block-ir-block-reference.mir
Normal file
19
test/CodeGen/MIR/machine-basic-block-ir-block-reference.mir
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# RUN: llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
|
||||||
|
# This test ensures that the MIR parser preserves unnamed LLVM IR block
|
||||||
|
# references.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @foo() {
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
body:
|
||||||
|
# CHECK: id: 0
|
||||||
|
# CHECK: ir-block: '%ir-block.0'
|
||||||
|
- id: 0
|
||||||
|
ir-block: '%ir-block.0'
|
||||||
|
...
|
16
test/CodeGen/MIR/machine-basic-block-undefined-ir-block.mir
Normal file
16
test/CodeGen/MIR/machine-basic-block-undefined-ir-block.mir
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @foo() {
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
# CHECK: [[@LINE+1]]:19: use of undefined IR block '%ir-block.10'
|
||||||
|
ir-block: '%ir-block.10'
|
||||||
|
...
|
Reference in New Issue
Block a user