From fcca45f0ddb94947009615029bfd480e649abd64 Mon Sep 17 00:00:00 2001 From: Evandro Menezes Date: Fri, 27 Jul 2018 18:16:47 +0000 Subject: [ARM] Add new target feature to fuse literal generation This feature enables the fusion of such operations on Cortex A57 and Cortex A72, as recommended in their Software Optimisation Guides, sections 4.14 and 4.11, respectively. Differential revision: https://reviews.llvm.org/D49563 llvm-svn: 338147 --- llvm/lib/Target/ARM/ARMMacroFusion.cpp | 63 ++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'llvm/lib/Target/ARM/ARMMacroFusion.cpp') diff --git a/llvm/lib/Target/ARM/ARMMacroFusion.cpp b/llvm/lib/Target/ARM/ARMMacroFusion.cpp index f2dc650a6f3..d11fe9d5c50 100644 --- a/llvm/lib/Target/ARM/ARMMacroFusion.cpp +++ b/llvm/lib/Target/ARM/ARMMacroFusion.cpp @@ -19,6 +19,47 @@ namespace llvm { +// Fuse AES crypto encoding or decoding. +static bool isAESPair(const MachineInstr *FirstMI, + const MachineInstr &SecondMI) { + // Assume the 1st instr to be a wildcard if it is unspecified. + unsigned FirstOpcode = + FirstMI ? FirstMI->getOpcode() + : static_cast(ARM::INSTRUCTION_LIST_END); + unsigned SecondOpcode = SecondMI.getOpcode(); + + switch(SecondOpcode) { + // AES encode. + case ARM::AESMC : + return FirstOpcode == ARM::AESE || + FirstOpcode == ARM::INSTRUCTION_LIST_END; + // AES decode. + case ARM::AESIMC: + return FirstOpcode == ARM::AESD || + FirstOpcode == ARM::INSTRUCTION_LIST_END; + } + + return false; +} + +// Fuse literal generation. +static bool isLiteralsPair(const MachineInstr *FirstMI, + const MachineInstr &SecondMI) { + // Assume the 1st instr to be a wildcard if it is unspecified. + unsigned FirstOpcode = + FirstMI ? FirstMI->getOpcode() + : static_cast(ARM::INSTRUCTION_LIST_END); + unsigned SecondOpcode = SecondMI.getOpcode(); + + // 32 bit immediate. + if ((FirstOpcode == ARM::INSTRUCTION_LIST_END || + FirstOpcode == ARM::MOVi16) && + SecondOpcode == ARM::MOVTi16) + return true; + + return false; +} + /// Check if the instr pair, FirstMI and SecondMI, should be fused /// together. Given SecondMI, when FirstMI is unspecified, then check if /// SecondMI may be part of a fused pair at all. @@ -28,24 +69,10 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const MachineInstr &SecondMI) { const ARMSubtarget &ST = static_cast(TSI); - // Assume wildcards for unspecified instrs. - unsigned FirstOpcode = - FirstMI ? FirstMI->getOpcode() - : static_cast(ARM::INSTRUCTION_LIST_END); - unsigned SecondOpcode = SecondMI.getOpcode(); - - if (ST.hasFuseAES()) - // Fuse AES crypto operations. - switch(SecondOpcode) { - // AES encode. - case ARM::AESMC : - return FirstOpcode == ARM::AESE || - FirstOpcode == ARM::INSTRUCTION_LIST_END; - // AES decode. - case ARM::AESIMC: - return FirstOpcode == ARM::AESD || - FirstOpcode == ARM::INSTRUCTION_LIST_END; - } + if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI)) + return true; + if (ST.hasFuseLiterals() && isLiteralsPair(FirstMI, SecondMI)) + return true; return false; } -- cgit v1.2.3