mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
MIR Serialization: Initial serialization of machine constant pools.
This commit implements the initial serialization of machine constant pools and the constant pool index machine operands. The constant pool is serialized using a YAML sequence of YAML mappings that represent the constant values. The target-specific constant pool items aren't serialized by this commit. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242707 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ca221d01d0
commit
0e4484f44d
@ -223,6 +223,20 @@ template <> struct MappingTraits<FixedMachineStackObject> {
|
||||
static const bool flow = true;
|
||||
};
|
||||
|
||||
struct MachineConstantPoolValue {
|
||||
unsigned ID;
|
||||
StringValue Value;
|
||||
unsigned Alignment = 0;
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<MachineConstantPoolValue> {
|
||||
static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
|
||||
YamlIO.mapRequired("id", Constant.ID);
|
||||
YamlIO.mapOptional("value", Constant.Value);
|
||||
YamlIO.mapOptional("alignment", Constant.Alignment);
|
||||
}
|
||||
};
|
||||
|
||||
struct MachineJumpTable {
|
||||
struct Entry {
|
||||
unsigned ID;
|
||||
@ -247,6 +261,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
|
||||
|
||||
namespace llvm {
|
||||
@ -320,6 +335,7 @@ struct MachineFunction {
|
||||
MachineFrameInfo FrameInfo;
|
||||
std::vector<FixedMachineStackObject> FixedStackObjects;
|
||||
std::vector<MachineStackObject> StackObjects;
|
||||
std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
|
||||
MachineJumpTable JumpTableInfo;
|
||||
|
||||
std::vector<MachineBasicBlock> BasicBlocks;
|
||||
@ -338,6 +354,7 @@ template <> struct MappingTraits<MachineFunction> {
|
||||
YamlIO.mapOptional("frameInfo", MF.FrameInfo);
|
||||
YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
|
||||
YamlIO.mapOptional("stack", MF.StackObjects);
|
||||
YamlIO.mapOptional("constants", MF.Constants);
|
||||
if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
|
||||
YamlIO.mapOptional("jumpTable", MF.JumpTableInfo);
|
||||
YamlIO.mapOptional("body", MF.BasicBlocks);
|
||||
|
@ -211,6 +211,10 @@ static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) {
|
||||
return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject);
|
||||
}
|
||||
|
||||
static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) {
|
||||
return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
|
||||
}
|
||||
|
||||
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
||||
auto Range = C;
|
||||
C.advance(); // Skip '%'
|
||||
@ -321,6 +325,8 @@ StringRef llvm::lexMIToken(
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexFixedStackObject(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexConstantPoolItem(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexRegister(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
|
||||
|
@ -58,6 +58,7 @@ struct MIToken {
|
||||
// Other tokens
|
||||
IntegerLiteral,
|
||||
VirtualRegister,
|
||||
ConstantPoolItem,
|
||||
JumpTableIndex
|
||||
};
|
||||
|
||||
@ -122,7 +123,7 @@ public:
|
||||
return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
|
||||
Kind == StackObject || Kind == FixedStackObject ||
|
||||
Kind == GlobalValue || Kind == VirtualRegister ||
|
||||
Kind == JumpTableIndex;
|
||||
Kind == ConstantPoolItem || Kind == JumpTableIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
bool parseStackObjectOperand(MachineOperand &Dest);
|
||||
bool parseFixedStackObjectOperand(MachineOperand &Dest);
|
||||
bool parseGlobalAddressOperand(MachineOperand &Dest);
|
||||
bool parseConstantPoolIndexOperand(MachineOperand &Dest);
|
||||
bool parseJumpTableIndexOperand(MachineOperand &Dest);
|
||||
bool parseMachineOperand(MachineOperand &Dest);
|
||||
|
||||
@ -531,6 +532,20 @@ bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
|
||||
assert(Token.is(MIToken::ConstantPoolItem));
|
||||
unsigned ID;
|
||||
if (getUnsigned(ID))
|
||||
return true;
|
||||
auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
|
||||
if (ConstantInfo == PFS.ConstantPoolSlots.end())
|
||||
return error("use of undefined constant '%const." + Twine(ID) + "'");
|
||||
lex();
|
||||
// TODO: Parse offset and target flags.
|
||||
Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
|
||||
assert(Token.is(MIToken::JumpTableIndex));
|
||||
unsigned ID;
|
||||
@ -568,6 +583,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
||||
case MIToken::NamedGlobalValue:
|
||||
case MIToken::QuotedNamedGlobalValue:
|
||||
return parseGlobalAddressOperand(Dest);
|
||||
case MIToken::ConstantPoolItem:
|
||||
return parseConstantPoolIndexOperand(Dest);
|
||||
case MIToken::JumpTableIndex:
|
||||
return parseJumpTableIndexOperand(Dest);
|
||||
case MIToken::Error:
|
||||
|
@ -31,6 +31,7 @@ struct PerFunctionMIParsingState {
|
||||
DenseMap<unsigned, unsigned> VirtualRegisterSlots;
|
||||
DenseMap<unsigned, int> FixedStackObjectSlots;
|
||||
DenseMap<unsigned, int> StackObjectSlots;
|
||||
DenseMap<unsigned, unsigned> ConstantPoolSlots;
|
||||
DenseMap<unsigned, unsigned> JumpTableSlots;
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/AsmParser/Parser.h"
|
||||
#include "llvm/AsmParser/SlotMapping.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
@ -113,6 +114,11 @@ public:
|
||||
DenseMap<unsigned, int> &StackObjectSlots,
|
||||
DenseMap<unsigned, int> &FixedStackObjectSlots);
|
||||
|
||||
bool initializeConstantPool(MachineConstantPool &ConstantPool,
|
||||
const yaml::MachineFunction &YamlMF,
|
||||
const MachineFunction &MF,
|
||||
DenseMap<unsigned, unsigned> &ConstantPoolSlots);
|
||||
|
||||
bool initializeJumpTableInfo(MachineFunction &MF,
|
||||
const yaml::MachineJumpTable &YamlJTI,
|
||||
PerFunctionMIParsingState &PFS);
|
||||
@ -273,6 +279,13 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
|
||||
if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
|
||||
PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
|
||||
return true;
|
||||
if (!YamlMF.Constants.empty()) {
|
||||
auto *ConstantPool = MF.getConstantPool();
|
||||
assert(ConstantPool && "Constant pool must be created");
|
||||
if (initializeConstantPool(*ConstantPool, YamlMF, MF,
|
||||
PFS.ConstantPoolSlots))
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto &F = *MF.getFunction();
|
||||
for (const auto &YamlMBB : YamlMF.BasicBlocks) {
|
||||
@ -439,6 +452,28 @@ bool MIRParserImpl::initializeFrameInfo(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIRParserImpl::initializeConstantPool(
|
||||
MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
|
||||
const MachineFunction &MF,
|
||||
DenseMap<unsigned, unsigned> &ConstantPoolSlots) {
|
||||
const auto &M = *MF.getFunction()->getParent();
|
||||
SMDiagnostic Error;
|
||||
for (const auto &YamlConstant : YamlMF.Constants) {
|
||||
const Constant *Value = dyn_cast_or_null<Constant>(
|
||||
parseConstantValue(YamlConstant.Value.Value, Error, M));
|
||||
if (!Value)
|
||||
return error(Error, YamlConstant.Value.SourceRange);
|
||||
unsigned Alignment =
|
||||
YamlConstant.Alignment
|
||||
? YamlConstant.Alignment
|
||||
: M.getDataLayout().getPrefTypeAlignment(Value->getType());
|
||||
// TODO: Report an error when the same constant pool value ID is redefined.
|
||||
ConstantPoolSlots.insert(std::make_pair(
|
||||
YamlConstant.ID, ConstantPool.getConstantPoolIndex(Value, Alignment)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIRParserImpl::initializeJumpTableInfo(
|
||||
MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
|
||||
PerFunctionMIParsingState &PFS) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "MIRPrinter.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
@ -69,6 +70,8 @@ public:
|
||||
void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
|
||||
const TargetRegisterInfo *TRI);
|
||||
void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
|
||||
void convert(yaml::MachineFunction &MF,
|
||||
const MachineConstantPool &ConstantPool);
|
||||
void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
|
||||
const MachineJumpTableInfo &JTI);
|
||||
void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
|
||||
@ -144,6 +147,8 @@ void MIRPrinter::print(const MachineFunction &MF) {
|
||||
convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
|
||||
convert(YamlMF.FrameInfo, *MF.getFrameInfo());
|
||||
convertStackObjects(YamlMF, *MF.getFrameInfo());
|
||||
if (const auto *ConstantPool = MF.getConstantPool())
|
||||
convert(YamlMF, *ConstantPool);
|
||||
|
||||
ModuleSlotTracker MST(MF.getFunction()->getParent());
|
||||
if (const auto *JumpTableInfo = MF.getJumpTableInfo())
|
||||
@ -249,6 +254,25 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||
}
|
||||
}
|
||||
|
||||
void MIRPrinter::convert(yaml::MachineFunction &MF,
|
||||
const MachineConstantPool &ConstantPool) {
|
||||
unsigned ID = 0;
|
||||
for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
|
||||
// TODO: Serialize target specific constant pool entries.
|
||||
if (Constant.isMachineConstantPoolEntry())
|
||||
llvm_unreachable("Can't print target specific constant pool entries yet");
|
||||
|
||||
yaml::MachineConstantPoolValue YamlConstant;
|
||||
std::string Str;
|
||||
raw_string_ostream StrOS(Str);
|
||||
Constant.Val.ConstVal->printAsOperand(StrOS);
|
||||
YamlConstant.ID = ID++;
|
||||
YamlConstant.Value = StrOS.str();
|
||||
YamlConstant.Alignment = Constant.getAlignment();
|
||||
MF.Constants.push_back(YamlConstant);
|
||||
}
|
||||
}
|
||||
|
||||
void MIRPrinter::convert(ModuleSlotTracker &MST,
|
||||
yaml::MachineJumpTable &YamlJTI,
|
||||
const MachineJumpTableInfo &JTI) {
|
||||
@ -398,6 +422,10 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
||||
case MachineOperand::MO_FrameIndex:
|
||||
printStackObjectReference(Op.getIndex());
|
||||
break;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
OS << "%const." << Op.getIndex();
|
||||
// TODO: Print offset and target flags.
|
||||
break;
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
OS << "%jump-table." << Op.getIndex();
|
||||
// TODO: Print target flags.
|
||||
|
118
test/CodeGen/MIR/X86/constant-pool.mir
Normal file
118
test/CodeGen/MIR/X86/constant-pool.mir
Normal file
@ -0,0 +1,118 @@
|
||||
# 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 constant pool constants and
|
||||
# constant pool operands correctly.
|
||||
|
||||
--- |
|
||||
|
||||
define double @test(double %a, float %b) {
|
||||
entry:
|
||||
%c = fadd double %a, 3.250000e+00
|
||||
%d = fadd float %b, 6.250000e+00
|
||||
%e = fpext float %d to double
|
||||
%f = fmul double %c, %e
|
||||
ret double %f
|
||||
}
|
||||
|
||||
define double @test2(double %a, float %b) {
|
||||
entry:
|
||||
%c = fadd double %a, 3.250000e+00
|
||||
%d = fadd float %b, 6.250000e+00
|
||||
%e = fpext float %d to double
|
||||
%f = fmul double %c, %e
|
||||
ret double %f
|
||||
}
|
||||
|
||||
define double @test3(double %a, float %b) {
|
||||
entry:
|
||||
%c = fadd double %a, 3.250000e+00
|
||||
%d = fadd float %b, 6.250000e+00
|
||||
%e = fpext float %d to double
|
||||
%f = fmul double %c, %e
|
||||
ret double %f
|
||||
}
|
||||
...
|
||||
---
|
||||
# CHECK: name: test
|
||||
# CHECK: constants:
|
||||
# CHECK-NEXT: - id: 0
|
||||
# CHECK-NEXT: value: 'double 3.250000e+00'
|
||||
# CHECK-NEXT: alignment: 8
|
||||
# CHECK-NEXT: - id: 1
|
||||
# CHECK-NEXT: value: 'float 6.250000e+00'
|
||||
# CHECK-NEXT: alignment: 4
|
||||
name: test
|
||||
constants:
|
||||
- id: 0
|
||||
value: 'double 3.250000e+00'
|
||||
alignment: 8
|
||||
- id: 1
|
||||
value: 'float 6.250000e+00'
|
||||
alignment: 4
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
# CHECK: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _
|
||||
# CHECK-NEXT: %xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.1, _
|
||||
- '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _'
|
||||
- '%xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.1, _'
|
||||
- '%xmm1 = CVTSS2SDrr killed %xmm1'
|
||||
- '%xmm0 = MULSDrr killed %xmm0, killed %xmm1'
|
||||
- 'RETQ %xmm0'
|
||||
...
|
||||
---
|
||||
# Verify that alignment can be inferred:
|
||||
# CHECK: name: test2
|
||||
# CHECK: constants:
|
||||
# CHECK-NEXT: - id: 0
|
||||
# CHECK-NEXT: value: 'double 3.250000e+00'
|
||||
# CHECK-NEXT: alignment: 8
|
||||
# CHECK-NEXT: - id: 1
|
||||
# CHECK-NEXT: value: 'float 6.250000e+00'
|
||||
# CHECK-NEXT: alignment: 4
|
||||
name: test2
|
||||
constants:
|
||||
- id: 0
|
||||
value: 'double 3.250000e+00'
|
||||
- id: 1
|
||||
value: 'float 6.250000e+00'
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _'
|
||||
- '%xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.1, _'
|
||||
- '%xmm1 = CVTSS2SDrr killed %xmm1'
|
||||
- '%xmm0 = MULSDrr killed %xmm0, killed %xmm1'
|
||||
- 'RETQ %xmm0'
|
||||
...
|
||||
---
|
||||
# Verify that the non-standard alignments are respected:
|
||||
# CHECK: name: test3
|
||||
# CHECK: constants:
|
||||
# CHECK-NEXT: - id: 0
|
||||
# CHECK-NEXT: value: 'double 3.250000e+00'
|
||||
# CHECK-NEXT: alignment: 128
|
||||
# CHECK-NEXT: - id: 1
|
||||
# CHECK-NEXT: value: 'float 6.250000e+00'
|
||||
# CHECK-NEXT: alignment: 1
|
||||
name: test3
|
||||
constants:
|
||||
- id: 0
|
||||
value: 'double 3.250000e+00'
|
||||
alignment: 128
|
||||
- id: 1
|
||||
value: 'float 6.250000e+00'
|
||||
alignment: 1
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
# CHECK: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _
|
||||
# CHECK-NEXT: %xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.1, _
|
||||
- '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _'
|
||||
- '%xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.1, _'
|
||||
- '%xmm1 = CVTSS2SDrr killed %xmm1'
|
||||
- '%xmm0 = MULSDrr killed %xmm0, killed %xmm1'
|
||||
- 'RETQ %xmm0'
|
||||
...
|
27
test/CodeGen/MIR/X86/constant-value-error.mir
Normal file
27
test/CodeGen/MIR/X86/constant-value-error.mir
Normal file
@ -0,0 +1,27 @@
|
||||
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||
# This test ensures that the MIR parser reports an error when parsing an invalid
|
||||
# constant value.
|
||||
|
||||
--- |
|
||||
|
||||
define double @test(double %a, float %b) {
|
||||
entry:
|
||||
%c = fadd double %a, 3.250000e+00
|
||||
ret double %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
constants:
|
||||
- id: 0
|
||||
# CHECK: [[@LINE+1]]:19: expected type
|
||||
value: 'dub 3.250000e+00'
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _'
|
||||
- 'RETQ %xmm0'
|
||||
...
|
||||
|
27
test/CodeGen/MIR/X86/invalid-constant-pool-item.mir
Normal file
27
test/CodeGen/MIR/X86/invalid-constant-pool-item.mir
Normal file
@ -0,0 +1,27 @@
|
||||
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||
# This test ensures that the MIR parser reports an error when parsing an invalid
|
||||
# constant pool item operand.
|
||||
|
||||
--- |
|
||||
|
||||
define double @test(double %a, float %b) {
|
||||
entry:
|
||||
%c = fadd double %a, 3.250000e+00
|
||||
ret double %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
constants:
|
||||
- id: 0
|
||||
value: 'double 3.250000e+00'
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
# CHECK: [[@LINE+1]]:52: use of undefined constant '%const.10'
|
||||
- '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.10, _'
|
||||
- 'RETQ %xmm0'
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user