mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-08 03:26:34 +00:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331417 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7577f35f34
commit
ecfd97d59f
@ -80,7 +80,21 @@ public:
|
|||||||
FrameDestroy = 1 << 1, // Instruction is used as a part of
|
FrameDestroy = 1 << 1, // Instruction is used as a part of
|
||||||
// function frame destruction code.
|
// function frame destruction code.
|
||||||
BundledPred = 1 << 2, // Instruction has bundled predecessors.
|
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:
|
private:
|
||||||
@ -93,7 +107,7 @@ private:
|
|||||||
using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
|
using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
|
||||||
OperandCapacity CapOperands; // Capacity of the Operands array.
|
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
|
// information about machine
|
||||||
// instruction.
|
// instruction.
|
||||||
|
|
||||||
@ -186,7 +200,7 @@ public:
|
|||||||
|
|
||||||
/// Set a MI flag.
|
/// Set a MI flag.
|
||||||
void setFlag(MIFlag Flag) {
|
void setFlag(MIFlag Flag) {
|
||||||
Flags |= (uint8_t)Flag;
|
Flags |= (uint16_t)Flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFlags(unsigned flags) {
|
void setFlags(unsigned flags) {
|
||||||
@ -197,7 +211,7 @@ public:
|
|||||||
|
|
||||||
/// clearFlag - Clear a MI flag.
|
/// clearFlag - Clear a MI flag.
|
||||||
void clearFlag(MIFlag 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).
|
/// Return true if MI is in a bundle (but not the first MI in a bundle).
|
||||||
|
@ -212,6 +212,13 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
|||||||
.Case("tied-def", MIToken::kw_tied_def)
|
.Case("tied-def", MIToken::kw_tied_def)
|
||||||
.Case("frame-setup", MIToken::kw_frame_setup)
|
.Case("frame-setup", MIToken::kw_frame_setup)
|
||||||
.Case("frame-destroy", MIToken::kw_frame_destroy)
|
.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("debug-location", MIToken::kw_debug_location)
|
||||||
.Case("same_value", MIToken::kw_cfi_same_value)
|
.Case("same_value", MIToken::kw_cfi_same_value)
|
||||||
.Case("offset", MIToken::kw_cfi_offset)
|
.Case("offset", MIToken::kw_cfi_offset)
|
||||||
|
@ -64,6 +64,13 @@ struct MIToken {
|
|||||||
kw_tied_def,
|
kw_tied_def,
|
||||||
kw_frame_setup,
|
kw_frame_setup,
|
||||||
kw_frame_destroy,
|
kw_frame_destroy,
|
||||||
|
kw_nnan,
|
||||||
|
kw_ninf,
|
||||||
|
kw_nsz,
|
||||||
|
kw_arcp,
|
||||||
|
kw_contract,
|
||||||
|
kw_afn,
|
||||||
|
kw_reassoc,
|
||||||
kw_debug_location,
|
kw_debug_location,
|
||||||
kw_cfi_same_value,
|
kw_cfi_same_value,
|
||||||
kw_cfi_offset,
|
kw_cfi_offset,
|
||||||
|
@ -936,13 +936,36 @@ bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
|
bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
|
||||||
// Allow both:
|
// Allow frame and fast math flags for OPCODE
|
||||||
// * frame-setup frame-destroy OPCODE
|
|
||||||
// * frame-destroy frame-setup OPCODE
|
|
||||||
while (Token.is(MIToken::kw_frame_setup) ||
|
while (Token.is(MIToken::kw_frame_setup) ||
|
||||||
Token.is(MIToken::kw_frame_destroy)) {
|
Token.is(MIToken::kw_frame_destroy) ||
|
||||||
Flags |= Token.is(MIToken::kw_frame_setup) ? MachineInstr::FrameSetup
|
Token.is(MIToken::kw_nnan) ||
|
||||||
: MachineInstr::FrameDestroy;
|
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();
|
lex();
|
||||||
}
|
}
|
||||||
if (Token.isNot(MIToken::Identifier))
|
if (Token.isNot(MIToken::Identifier))
|
||||||
|
@ -680,6 +680,20 @@ void MIPrinter::print(const MachineInstr &MI) {
|
|||||||
OS << "frame-setup ";
|
OS << "frame-setup ";
|
||||||
if (MI.getFlag(MachineInstr::FrameDestroy))
|
if (MI.getFlag(MachineInstr::FrameDestroy))
|
||||||
OS << "frame-destroy ";
|
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());
|
OS << TII->getName(MI.getOpcode());
|
||||||
if (I < E)
|
if (I < E)
|
||||||
|
@ -1302,6 +1302,20 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
|
|||||||
OS << "frame-setup ";
|
OS << "frame-setup ";
|
||||||
if (getFlag(MachineInstr::FrameDestroy))
|
if (getFlag(MachineInstr::FrameDestroy))
|
||||||
OS << "frame-destroy ";
|
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.
|
// Print the opcode name.
|
||||||
if (TII)
|
if (TII)
|
||||||
|
36
test/CodeGen/MIR/X86/fastmath.mir
Normal file
36
test/CodeGen/MIR/X86/fastmath.mir
Normal 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
|
||||||
|
|
||||||
|
...
|
Loading…
x
Reference in New Issue
Block a user