MachineInst support mapping SDNode fast math flags for support in Back End code generation

Summary:
Machine Instruction flags for fast math support and MIR print support


Reviewers: spatel, arsenm

Reviewed By: arsenm

Subscribers: wdng

Differential Revision: https://reviews.llvm.org/D45781

llvm-svn: 331417
This commit is contained in:
Michael Berg 2018-05-03 00:07:56 +00:00
parent 01e2e79abf
commit 7d1b25d053
7 changed files with 125 additions and 10 deletions

View File

@ -80,7 +80,21 @@ public:
FrameDestroy = 1 << 1, // Instruction is used as a part of
// function frame destruction code.
BundledPred = 1 << 2, // Instruction has bundled predecessors.
BundledSucc = 1 << 3 // Instruction has bundled successors.
BundledSucc = 1 << 3, // Instruction has bundled successors.
FmNoNans = 1 << 4, // Instruction does not support Fast
// math nan values.
FmNoInfs = 1 << 5, // Instruction does not support Fast
// math infinity values.
FmNsz = 1 << 6, // Instruction is not required to retain
// signed zero values.
FmArcp = 1 << 7, // Instruction supports Fast math
// reciprocal approximations.
FmContract = 1 << 8, // Instruction supports Fast math
// contraction operations like fma.
FmAfn = 1 << 9, // Instruction may map to Fast math
// instrinsic approximation.
FmReassoc = 1 << 10 // Instruction supports Fast math
// reassociation of operand order.
};
private:
@ -93,7 +107,7 @@ private:
using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
OperandCapacity CapOperands; // Capacity of the Operands array.
uint8_t Flags = 0; // Various bits of additional
uint16_t Flags = 0; // Various bits of additional
// information about machine
// instruction.
@ -186,7 +200,7 @@ public:
/// Set a MI flag.
void setFlag(MIFlag Flag) {
Flags |= (uint8_t)Flag;
Flags |= (uint16_t)Flag;
}
void setFlags(unsigned flags) {
@ -197,7 +211,7 @@ public:
/// clearFlag - Clear a MI flag.
void clearFlag(MIFlag Flag) {
Flags &= ~((uint8_t)Flag);
Flags &= ~((uint16_t)Flag);
}
/// Return true if MI is in a bundle (but not the first MI in a bundle).

View File

@ -212,6 +212,13 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("tied-def", MIToken::kw_tied_def)
.Case("frame-setup", MIToken::kw_frame_setup)
.Case("frame-destroy", MIToken::kw_frame_destroy)
.Case("nnan", MIToken::kw_nnan)
.Case("ninf", MIToken::kw_ninf)
.Case("nsz", MIToken::kw_nsz)
.Case("arcp", MIToken::kw_arcp)
.Case("contract", MIToken::kw_contract)
.Case("afn", MIToken::kw_afn)
.Case("reassoc", MIToken::kw_reassoc)
.Case("debug-location", MIToken::kw_debug_location)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)

View File

@ -64,6 +64,13 @@ struct MIToken {
kw_tied_def,
kw_frame_setup,
kw_frame_destroy,
kw_nnan,
kw_ninf,
kw_nsz,
kw_arcp,
kw_contract,
kw_afn,
kw_reassoc,
kw_debug_location,
kw_cfi_same_value,
kw_cfi_offset,

View File

@ -936,13 +936,36 @@ bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
}
bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
// Allow both:
// * frame-setup frame-destroy OPCODE
// * frame-destroy frame-setup OPCODE
// Allow frame and fast math flags for OPCODE
while (Token.is(MIToken::kw_frame_setup) ||
Token.is(MIToken::kw_frame_destroy)) {
Flags |= Token.is(MIToken::kw_frame_setup) ? MachineInstr::FrameSetup
: MachineInstr::FrameDestroy;
Token.is(MIToken::kw_frame_destroy) ||
Token.is(MIToken::kw_nnan) ||
Token.is(MIToken::kw_ninf) ||
Token.is(MIToken::kw_nsz) ||
Token.is(MIToken::kw_arcp) ||
Token.is(MIToken::kw_contract) ||
Token.is(MIToken::kw_afn) ||
Token.is(MIToken::kw_reassoc)) {
// Mine frame and fast math flags
if (Token.is(MIToken::kw_frame_setup))
Flags |= MachineInstr::FrameSetup;
if (Token.is(MIToken::kw_frame_destroy))
Flags |= MachineInstr::FrameDestroy;
if (Token.is(MIToken::kw_nnan))
Flags |= MachineInstr::FmNoNans;
if (Token.is(MIToken::kw_ninf))
Flags |= MachineInstr::FmNoInfs;
if (Token.is(MIToken::kw_nsz))
Flags |= MachineInstr::FmNsz;
if (Token.is(MIToken::kw_arcp))
Flags |= MachineInstr::FmArcp;
if (Token.is(MIToken::kw_contract))
Flags |= MachineInstr::FmContract;
if (Token.is(MIToken::kw_afn))
Flags |= MachineInstr::FmAfn;
if (Token.is(MIToken::kw_reassoc))
Flags |= MachineInstr::FmReassoc;
lex();
}
if (Token.isNot(MIToken::Identifier))

View File

@ -680,6 +680,20 @@ void MIPrinter::print(const MachineInstr &MI) {
OS << "frame-setup ";
if (MI.getFlag(MachineInstr::FrameDestroy))
OS << "frame-destroy ";
if (MI.getFlag(MachineInstr::FmNoNans))
OS << "nnan ";
if (MI.getFlag(MachineInstr::FmNoInfs))
OS << "ninf ";
if (MI.getFlag(MachineInstr::FmNsz))
OS << "nsz ";
if (MI.getFlag(MachineInstr::FmArcp))
OS << "arcp ";
if (MI.getFlag(MachineInstr::FmContract))
OS << "contract ";
if (MI.getFlag(MachineInstr::FmAfn))
OS << "afn ";
if (MI.getFlag(MachineInstr::FmReassoc))
OS << "reassoc ";
OS << TII->getName(MI.getOpcode());
if (I < E)

View File

@ -1302,6 +1302,20 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << "frame-setup ";
if (getFlag(MachineInstr::FrameDestroy))
OS << "frame-destroy ";
if (getFlag(MachineInstr::FmNoNans))
OS << "nnan ";
if (getFlag(MachineInstr::FmNoInfs))
OS << "ninf ";
if (getFlag(MachineInstr::FmNsz))
OS << "nsz ";
if (getFlag(MachineInstr::FmArcp))
OS << "arcp ";
if (getFlag(MachineInstr::FmContract))
OS << "contract ";
if (getFlag(MachineInstr::FmAfn))
OS << "afn ";
if (getFlag(MachineInstr::FmReassoc))
OS << "reassoc ";
// Print the opcode name.
if (TII)

View File

@ -0,0 +1,36 @@
# RUN: llc -march=x86-64 -run-pass none -o - %s | FileCheck %s
# This test ensures that the MIR parser parses the fast math instruction flags.
...
---
name: baz
body: |
bb.0.entry:
liveins: $xmm0
; CHECK: %0:fr32 = COPY $xmm0
%0:fr32 = COPY $xmm0
; CHECK: %1:fr32 = nnan VMULSSrr %0, %0
%1:fr32 = nnan VMULSSrr %0, %0
; CHECK: %2:fr32 = ninf VMULSSrr %1, %1
%2:fr32 = ninf VMULSSrr %1, %1
; CHECK: %3:fr32 = nsz VMULSSrr %2, %2
%3:fr32 = nsz VMULSSrr %2, %2
; CHECK: %4:fr32 = arcp VMULSSrr %3, %3
%4:fr32 = arcp VMULSSrr %3, %3
; CHECK: %5:fr32 = contract VMULSSrr %4, %4
%5:fr32 = contract VMULSSrr %4, %4
; CHECK: %6:fr32 = afn VMULSSrr %5, %5
%6:fr32 = afn VMULSSrr %5, %5
; CHECK: %7:fr32 = reassoc VMULSSrr %6, %6
%7:fr32 = reassoc VMULSSrr %6, %6
; CHECK: %8:fr32 = nsz arcp contract afn reassoc VMULSSrr %7, %7
%8:fr32 = nsz arcp contract afn reassoc VMULSSrr %7, %7
; CHECK: %9:fr32 = contract afn reassoc VMULSSrr %8, %8
%9:fr32 = contract afn reassoc VMULSSrr %8, %8
; CHECK: $xmm0 = COPY %9
$xmm0 = COPY %9
; CHECK: RET 0, $xmm0
RET 0, $xmm0
...