//===- X86CompressEVEX.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This pass compresses instructions from EVEX space to legacy/VEX/EVEX space // when possible in order to reduce code size or facilitate HW decoding. // // Possible compression: // a. AVX512 instruction (EVEX) -> AVX instruction (VEX) // b. Promoted instruction (EVEX) -> pre-promotion instruction (legacy/VEX) // c. NDD (EVEX) -> non-NDD (legacy) // d. NF_ND (EVEX) -> NF (EVEX) // e. NonNF (EVEX) -> NF (EVEX) // // Compression a, b and c can always reduce code size, with some exceptions // such as promoted 16-bit CRC32 which is as long as the legacy version. // // legacy: // crc32w %si, %eax ## encoding: [0x66,0xf2,0x0f,0x38,0xf1,0xc6] // promoted: // crc32w %si, %eax ## encoding: [0x62,0xf4,0x7d,0x08,0xf1,0xc6] // // From performance perspective, these should be same (same uops and same EXE // ports). From a FMV perspective, an older legacy encoding is preferred b/c it // can execute in more places (broader HW install base). So we will still do // the compression. // // Compression d can help hardware decode (HW may skip reading the NDD // register) although the instruction length remains unchanged. // // Compression e can help hardware skip updating EFLAGS although the instruction // length remains unchanged. //===----------------------------------------------------------------------===// #include "MCTargetDesc/X86BaseInfo.h" #include "MCTargetDesc/X86InstComments.h" #include "X86.h" #include "X86InstrInfo.h" #include "X86Subtarget.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Pass.h" #include <atomic> #include <cassert> #include <cstdint> usingnamespacellvm; #define COMP_EVEX_DESC … #define COMP_EVEX_NAME … #define DEBUG_TYPE … namespace { // Including the generated EVEX compression tables. #define GET_X86_COMPRESS_EVEX_TABLE #include "X86GenInstrMapping.inc" class CompressEVEXPass : public MachineFunctionPass { … }; } // end anonymous namespace char CompressEVEXPass::ID = …; static bool usesExtendedRegister(const MachineInstr &MI) { … } // Do any custom cleanup needed to finalize the conversion. static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc) { … } static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) { … } bool CompressEVEXPass::runOnMachineFunction(MachineFunction &MF) { … } INITIALIZE_PASS(…) FunctionPass *llvm::createX86CompressEVEXPass() { … }