003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/X86
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
X86
/
📁
..
📁
AsmParser
📁
Disassembler
📄
ImmutableGraph.h
(15.15 KB)
📁
MCTargetDesc
📁
TargetInfo
📄
X86.h
(7.41 KB)
📄
X86.td
(68.44 KB)
📄
X86AsmPrinter.cpp
(27.18 KB)
📄
X86AsmPrinter.h
(5.96 KB)
📄
X86AvoidStoreForwardingBlocks.cpp
(27.94 KB)
📄
X86AvoidTrailingCall.cpp
(4.91 KB)
📄
X86CallFrameOptimization.cpp
(23.07 KB)
📄
X86CallLowering.cpp
(17.62 KB)
📄
X86CallLowering.h
(1.74 KB)
📄
X86CallingConv.cpp
(13.34 KB)
📄
X86CallingConv.h
(1.09 KB)
📄
X86CallingConv.td
(46.15 KB)
📄
X86CmovConversion.cpp
(34.07 KB)
📄
X86CondBrFolding.cpp
(18.4 KB)
📄
X86DiscriminateMemOps.cpp
(7.11 KB)
📄
X86DomainReassignment.cpp
(25.87 KB)
📄
X86EvexToVex.cpp
(8.8 KB)
📄
X86ExpandPseudo.cpp
(16.95 KB)
📄
X86FastISel.cpp
(139.28 KB)
📄
X86FixupBWInsts.cpp
(18.09 KB)
📄
X86FixupLEAs.cpp
(24.44 KB)
📄
X86FixupSetCC.cpp
(4.44 KB)
📄
X86FlagsCopyLowering.cpp
(40.36 KB)
📄
X86FloatingPoint.cpp
(62.66 KB)
📄
X86FrameLowering.cpp
(138.71 KB)
📄
X86FrameLowering.h
(11.64 KB)
📄
X86GenRegisterBankInfo.def
(3.32 KB)
📄
X86ISelDAGToDAG.cpp
(208.37 KB)
📄
X86ISelLowering.cpp
(1.94 MB)
📄
X86ISelLowering.h
(60.88 KB)
📄
X86IndirectBranchTracking.cpp
(6.17 KB)
📄
X86IndirectThunks.cpp
(9.78 KB)
📄
X86InsertPrefetch.cpp
(9.64 KB)
📄
X86InsertWait.cpp
(4.47 KB)
📄
X86Instr3DNow.td
(5.24 KB)
📄
X86InstrAMX.td
(5.6 KB)
📄
X86InstrAVX512.td
(653.76 KB)
📄
X86InstrArithmetic.td
(75.61 KB)
📄
X86InstrBuilder.h
(8.45 KB)
📄
X86InstrCMovSetCC.td
(5.76 KB)
📄
X86InstrCompiler.td
(95.78 KB)
📄
X86InstrControl.td
(20.53 KB)
📄
X86InstrExtension.td
(11.64 KB)
📄
X86InstrFMA.td
(33.23 KB)
📄
X86InstrFMA3Info.cpp
(6.21 KB)
📄
X86InstrFMA3Info.h
(3.25 KB)
📄
X86InstrFPStack.td
(39.52 KB)
📄
X86InstrFoldTables.cpp
(393.01 KB)
📄
X86InstrFoldTables.h
(3.03 KB)
📄
X86InstrFormats.td
(41.05 KB)
📄
X86InstrFragmentsSIMD.td
(61.14 KB)
📄
X86InstrInfo.cpp
(322.72 KB)
📄
X86InstrInfo.h
(29.34 KB)
📄
X86InstrInfo.td
(169.76 KB)
📄
X86InstrMMX.td
(29.55 KB)
📄
X86InstrMPX.td
(3.63 KB)
📄
X86InstrSGX.td
(1.12 KB)
📄
X86InstrSSE.td
(385.01 KB)
📄
X86InstrSVM.td
(2.16 KB)
📄
X86InstrShiftRotate.td
(49.56 KB)
📄
X86InstrSystem.td
(34.03 KB)
📄
X86InstrTSX.td
(2.1 KB)
📄
X86InstrVMX.td
(3.53 KB)
📄
X86InstrVecCompiler.td
(21.09 KB)
📄
X86InstrXOP.td
(23.81 KB)
📄
X86InstructionSelector.cpp
(61.11 KB)
📄
X86InterleavedAccess.cpp
(32.7 KB)
📄
X86IntrinsicsInfo.h
(73.96 KB)
📄
X86LegalizerInfo.cpp
(15.6 KB)
📄
X86LegalizerInfo.h
(1.65 KB)
📄
X86LoadValueInjectionLoadHardening.cpp
(32.4 KB)
📄
X86LoadValueInjectionRetHardening.cpp
(4.93 KB)
📄
X86MCInstLower.cpp
(96.53 KB)
📄
X86MachineFunctionInfo.cpp
(1.1 KB)
📄
X86MachineFunctionInfo.h
(8.87 KB)
📄
X86MacroFusion.cpp
(2.62 KB)
📄
X86MacroFusion.h
(992 B)
📄
X86OptimizeLEAs.cpp
(27.47 KB)
📄
X86PadShortFunction.cpp
(7.33 KB)
📄
X86PartialReduction.cpp
(15.46 KB)
📄
X86PfmCounters.td
(10.18 KB)
📄
X86RegisterBankInfo.cpp
(10.55 KB)
📄
X86RegisterBankInfo.h
(2.87 KB)
📄
X86RegisterBanks.td
(629 B)
📄
X86RegisterInfo.cpp
(29 KB)
📄
X86RegisterInfo.h
(5.61 KB)
📄
X86RegisterInfo.td
(26.07 KB)
📄
X86SchedBroadwell.td
(69.45 KB)
📄
X86SchedHaswell.td
(73.96 KB)
📄
X86SchedPredicates.td
(4.23 KB)
📄
X86SchedSandyBridge.td
(50 KB)
📄
X86SchedSkylakeClient.td
(74.65 KB)
📄
X86SchedSkylakeServer.td
(113.85 KB)
📄
X86Schedule.td
(36.9 KB)
📄
X86ScheduleAtom.td
(38.26 KB)
📄
X86ScheduleBdVer2.td
(56.78 KB)
📄
X86ScheduleBtVer2.td
(46.98 KB)
📄
X86ScheduleSLM.td
(22.91 KB)
📄
X86ScheduleZnver1.td
(48.97 KB)
📄
X86ScheduleZnver2.td
(48.12 KB)
📄
X86SelectionDAGInfo.cpp
(12.02 KB)
📄
X86SelectionDAGInfo.h
(1.8 KB)
📄
X86ShuffleDecodeConstantPool.cpp
(11.22 KB)
📄
X86ShuffleDecodeConstantPool.h
(2.13 KB)
📄
X86SpeculativeExecutionSideEffectSuppression.cpp
(6.97 KB)
📄
X86SpeculativeLoadHardening.cpp
(93.16 KB)
📄
X86Subtarget.cpp
(13.25 KB)
📄
X86Subtarget.h
(32.08 KB)
📄
X86TargetMachine.cpp
(18.88 KB)
📄
X86TargetMachine.h
(2.04 KB)
📄
X86TargetObjectFile.cpp
(2.61 KB)
📄
X86TargetObjectFile.h
(2.13 KB)
📄
X86TargetTransformInfo.cpp
(189.14 KB)
📄
X86TargetTransformInfo.h
(9.63 KB)
📄
X86VZeroUpper.cpp
(12.59 KB)
📄
X86WinAllocaExpander.cpp
(9.54 KB)
📄
X86WinEHState.cpp
(28.97 KB)
Editing: X86EvexToVex.cpp
//===- X86EvexToVex.cpp ---------------------------------------------------===// // Compress EVEX instructions to VEX encoding when possible to reduce code size // // 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 // //===----------------------------------------------------------------------===// // /// \file /// This file defines the pass that goes over all AVX-512 instructions which /// are encoded using the EVEX prefix and if possible replaces them by their /// corresponding VEX encoding which is usually shorter by 2 bytes. /// EVEX instructions may be encoded via the VEX prefix when the AVX-512 /// instruction has a corresponding AVX/AVX2 opcode, when vector length /// accessed by instruction is less than 512 bits and when it does not use // the xmm or the mask registers or xmm/ymm registers with indexes higher than 15. /// The pass applies code reduction on the generated code for AVX-512 instrs. // //===----------------------------------------------------------------------===// #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 <cassert> #include <cstdint> using namespace llvm; // Including the generated EVEX2VEX tables. struct X86EvexToVexCompressTableEntry { uint16_t EvexOpcode; uint16_t VexOpcode; bool operator<(const X86EvexToVexCompressTableEntry &RHS) const { return EvexOpcode < RHS.EvexOpcode; } friend bool operator<(const X86EvexToVexCompressTableEntry &TE, unsigned Opc) { return TE.EvexOpcode < Opc; } }; #include "X86GenEVEX2VEXTables.inc" #define EVEX2VEX_DESC "Compressing EVEX instrs to VEX encoding when possible" #define EVEX2VEX_NAME "x86-evex-to-vex-compress" #define DEBUG_TYPE EVEX2VEX_NAME namespace { class EvexToVexInstPass : public MachineFunctionPass { /// For EVEX instructions that can be encoded using VEX encoding, replace /// them by the VEX encoding in order to reduce size. bool CompressEvexToVexImpl(MachineInstr &MI) const; public: static char ID; EvexToVexInstPass() : MachineFunctionPass(ID) { } StringRef getPassName() const override { return EVEX2VEX_DESC; } /// Loop over all of the basic blocks, replacing EVEX instructions /// by equivalent VEX instructions when possible for reducing code size. bool runOnMachineFunction(MachineFunction &MF) override; // This pass runs after regalloc and doesn't support VReg operands. MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( MachineFunctionProperties::Property::NoVRegs); } private: /// Machine instruction info used throughout the class. const X86InstrInfo *TII = nullptr; }; } // end anonymous namespace char EvexToVexInstPass::ID = 0; bool EvexToVexInstPass::runOnMachineFunction(MachineFunction &MF) { TII = MF.getSubtarget<X86Subtarget>().getInstrInfo(); const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>(); if (!ST.hasAVX512()) return false; bool Changed = false; /// Go over all basic blocks in function and replace /// EVEX encoded instrs by VEX encoding when possible. for (MachineBasicBlock &MBB : MF) { // Traverse the basic block. for (MachineInstr &MI : MBB) Changed |= CompressEvexToVexImpl(MI); } return Changed; } static bool usesExtendedRegister(const MachineInstr &MI) { auto isHiRegIdx = [](unsigned Reg) { // Check for XMM register with indexes between 16 - 31. if (Reg >= X86::XMM16 && Reg <= X86::XMM31) return true; // Check for YMM register with indexes between 16 - 31. if (Reg >= X86::YMM16 && Reg <= X86::YMM31) return true; return false; }; // Check that operands are not ZMM regs or // XMM/YMM regs with hi indexes between 16 - 31. for (const MachineOperand &MO : MI.explicit_operands()) { if (!MO.isReg()) continue; Register Reg = MO.getReg(); assert(!(Reg >= X86::ZMM0 && Reg <= X86::ZMM31) && "ZMM instructions should not be in the EVEX->VEX tables"); if (isHiRegIdx(Reg)) return true; } return false; } // Do any custom cleanup needed to finalize the conversion. static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc) { (void)NewOpc; unsigned Opc = MI.getOpcode(); switch (Opc) { case X86::VALIGNDZ128rri: case X86::VALIGNDZ128rmi: case X86::VALIGNQZ128rri: case X86::VALIGNQZ128rmi: { assert((NewOpc == X86::VPALIGNRrri || NewOpc == X86::VPALIGNRrmi) && "Unexpected new opcode!"); unsigned Scale = (Opc == X86::VALIGNQZ128rri || Opc == X86::VALIGNQZ128rmi) ? 8 : 4; MachineOperand &Imm = MI.getOperand(MI.getNumExplicitOperands()-1); Imm.setImm(Imm.getImm() * Scale); break; } case X86::VSHUFF32X4Z256rmi: case X86::VSHUFF32X4Z256rri: case X86::VSHUFF64X2Z256rmi: case X86::VSHUFF64X2Z256rri: case X86::VSHUFI32X4Z256rmi: case X86::VSHUFI32X4Z256rri: case X86::VSHUFI64X2Z256rmi: case X86::VSHUFI64X2Z256rri: { assert((NewOpc == X86::VPERM2F128rr || NewOpc == X86::VPERM2I128rr || NewOpc == X86::VPERM2F128rm || NewOpc == X86::VPERM2I128rm) && "Unexpected new opcode!"); MachineOperand &Imm = MI.getOperand(MI.getNumExplicitOperands()-1); int64_t ImmVal = Imm.getImm(); // Set bit 5, move bit 1 to bit 4, copy bit 0. Imm.setImm(0x20 | ((ImmVal & 2) << 3) | (ImmVal & 1)); break; } case X86::VRNDSCALEPDZ128rri: case X86::VRNDSCALEPDZ128rmi: case X86::VRNDSCALEPSZ128rri: case X86::VRNDSCALEPSZ128rmi: case X86::VRNDSCALEPDZ256rri: case X86::VRNDSCALEPDZ256rmi: case X86::VRNDSCALEPSZ256rri: case X86::VRNDSCALEPSZ256rmi: case X86::VRNDSCALESDZr: case X86::VRNDSCALESDZm: case X86::VRNDSCALESSZr: case X86::VRNDSCALESSZm: case X86::VRNDSCALESDZr_Int: case X86::VRNDSCALESDZm_Int: case X86::VRNDSCALESSZr_Int: case X86::VRNDSCALESSZm_Int: const MachineOperand &Imm = MI.getOperand(MI.getNumExplicitOperands()-1); int64_t ImmVal = Imm.getImm(); // Ensure that only bits 3:0 of the immediate are used. if ((ImmVal & 0xf) != ImmVal) return false; break; } return true; } // For EVEX instructions that can be encoded using VEX encoding // replace them by the VEX encoding in order to reduce size. bool EvexToVexInstPass::CompressEvexToVexImpl(MachineInstr &MI) const { // VEX format. // # of bytes: 0,2,3 1 1 0,1 0,1,2,4 0,1 // [Prefixes] [VEX] OPCODE ModR/M [SIB] [DISP] [IMM] // // EVEX format. // # of bytes: 4 1 1 1 4 / 1 1 // [Prefixes] EVEX Opcode ModR/M [SIB] [Disp32] / [Disp8*N] [Immediate] const MCInstrDesc &Desc = MI.getDesc(); // Check for EVEX instructions only. if ((Desc.TSFlags & X86II::EncodingMask) != X86II::EVEX) return false; // Check for EVEX instructions with mask or broadcast as in these cases // the EVEX prefix is needed in order to carry this information // thus preventing the transformation to VEX encoding. if (Desc.TSFlags & (X86II::EVEX_K | X86II::EVEX_B)) return false; // Check for EVEX instructions with L2 set. These instructions are 512-bits // and can't be converted to VEX. if (Desc.TSFlags & X86II::EVEX_L2) return false; #ifndef NDEBUG // Make sure the tables are sorted. static std::atomic<bool> TableChecked(false); if (!TableChecked.load(std::memory_order_relaxed)) { assert(llvm::is_sorted(X86EvexToVex128CompressTable) && "X86EvexToVex128CompressTable is not sorted!"); assert(llvm::is_sorted(X86EvexToVex256CompressTable) && "X86EvexToVex256CompressTable is not sorted!"); TableChecked.store(true, std::memory_order_relaxed); } #endif // Use the VEX.L bit to select the 128 or 256-bit table. ArrayRef<X86EvexToVexCompressTableEntry> Table = (Desc.TSFlags & X86II::VEX_L) ? makeArrayRef(X86EvexToVex256CompressTable) : makeArrayRef(X86EvexToVex128CompressTable); auto I = llvm::lower_bound(Table, MI.getOpcode()); if (I == Table.end() || I->EvexOpcode != MI.getOpcode()) return false; unsigned NewOpc = I->VexOpcode; if (usesExtendedRegister(MI)) return false; if (!performCustomAdjustments(MI, NewOpc)) return false; MI.setDesc(TII->get(NewOpc)); MI.setAsmPrinterFlag(X86::AC_EVEX_2_VEX); return true; } INITIALIZE_PASS(EvexToVexInstPass, EVEX2VEX_NAME, EVEX2VEX_DESC, false, false) FunctionPass *llvm::createX86EvexToVexInsts() { return new EvexToVexInstPass(); }
Upload File
Create Folder