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;
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 {
MachineFrameInfo FrameInfo;
std::vector<FixedMachineStackObject> FixedStackObjects;
std::vector<MachineStackObject> StackObjects;
+ std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
MachineJumpTable JumpTableInfo;
std::vector<MachineBasicBlock> BasicBlocks;
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);
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 '%'
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))
// Other tokens
IntegerLiteral,
VirtualRegister,
+ ConstantPoolItem,
JumpTableIndex
};
return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
Kind == StackObject || Kind == FixedStackObject ||
Kind == GlobalValue || Kind == VirtualRegister ||
- Kind == JumpTableIndex;
+ Kind == ConstantPoolItem || Kind == JumpTableIndex;
}
};
bool parseStackObjectOperand(MachineOperand &Dest);
bool parseFixedStackObjectOperand(MachineOperand &Dest);
bool parseGlobalAddressOperand(MachineOperand &Dest);
+ bool parseConstantPoolIndexOperand(MachineOperand &Dest);
bool parseJumpTableIndexOperand(MachineOperand &Dest);
bool parseMachineOperand(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;
case MIToken::NamedGlobalValue:
case MIToken::QuotedNamedGlobalValue:
return parseGlobalAddressOperand(Dest);
+ case MIToken::ConstantPoolItem:
+ return parseConstantPoolIndexOperand(Dest);
case MIToken::JumpTableIndex:
return parseJumpTableIndexOperand(Dest);
case MIToken::Error:
DenseMap<unsigned, unsigned> VirtualRegisterSlots;
DenseMap<unsigned, int> FixedStackObjectSlots;
DenseMap<unsigned, int> StackObjectSlots;
+ DenseMap<unsigned, unsigned> ConstantPoolSlots;
DenseMap<unsigned, unsigned> JumpTableSlots;
};
#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"
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);
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) {
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) {
#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"
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,
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())
}
}
+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) {
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.
--- /dev/null
+# 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'
+...
--- /dev/null
+# 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'
+...
+
--- /dev/null
+# 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'
+...
+