| //===-- CodeTemplate.h ------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// A set of structures and functions to craft instructions for the |
| /// SnippetGenerator. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H |
| #define LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H |
| |
| #include "MCInstrDescView.h" |
| #include "llvm/ADT/BitmaskEnum.h" |
| |
| namespace llvm { |
| namespace exegesis { |
| |
| // A template for an Instruction holding values for each of its Variables. |
| struct InstructionTemplate { |
| InstructionTemplate(const Instruction &Instr); |
| |
| InstructionTemplate(const InstructionTemplate &); // default |
| InstructionTemplate &operator=(const InstructionTemplate &); // default |
| InstructionTemplate(InstructionTemplate &&); // default |
| InstructionTemplate &operator=(InstructionTemplate &&); // default |
| |
| unsigned getOpcode() const; |
| llvm::MCOperand &getValueFor(const Variable &Var); |
| const llvm::MCOperand &getValueFor(const Variable &Var) const; |
| llvm::MCOperand &getValueFor(const Operand &Op); |
| const llvm::MCOperand &getValueFor(const Operand &Op) const; |
| bool hasImmediateVariables() const; |
| |
| // Builds an llvm::MCInst from this InstructionTemplate setting its operands |
| // to the corresponding variable values. Precondition: All VariableValues must |
| // be set. |
| llvm::MCInst build() const; |
| |
| Instruction Instr; |
| llvm::SmallVector<llvm::MCOperand, 4> VariableValues; |
| }; |
| |
| enum class ExecutionMode : uint8_t { |
| UNKNOWN = 0U, |
| // The instruction is always serial because implicit Use and Def alias. |
| // e.g. AAA (alias via EFLAGS) |
| ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS = 1u << 0, |
| |
| // The instruction is always serial because one Def is tied to a Use. |
| // e.g. AND32ri (alias via tied GR32) |
| ALWAYS_SERIAL_TIED_REGS_ALIAS = 1u << 1, |
| |
| // The execution can be made serial by inserting a second instruction that |
| // clobbers/reads memory. |
| // e.g. MOV8rm |
| SERIAL_VIA_MEMORY_INSTR = 1u << 2, |
| |
| // The execution can be made serial by picking one Def that aliases with one |
| // Use. |
| // e.g. VXORPSrr XMM1, XMM1, XMM2 |
| SERIAL_VIA_EXPLICIT_REGS = 1u << 3, |
| |
| // The execution can be made serial by inserting a second instruction that |
| // uses one of the Defs and defs one of the Uses. |
| // e.g. |
| // 1st instruction: MMX_PMOVMSKBrr ECX, MM7 |
| // 2nd instruction: MMX_MOVD64rr MM7, ECX |
| // or instruction: MMX_MOVD64to64rr MM7, ECX |
| // or instruction: MMX_PINSRWrr MM7, MM7, ECX, 1 |
| SERIAL_VIA_NON_MEMORY_INSTR = 1u << 4, |
| |
| // The execution is always parallel because the instruction is missing Use or |
| // Def operands. |
| ALWAYS_PARALLEL_MISSING_USE_OR_DEF = 1u << 5, |
| |
| // The execution can be made parallel by repeating the same instruction but |
| // making sure that Defs of one instruction do not alias with Uses of the |
| // second one. |
| PARALLEL_VIA_EXPLICIT_REGS = 1u << 6, |
| |
| LLVM_MARK_AS_BITMASK_ENUM(/*Largest*/ PARALLEL_VIA_EXPLICIT_REGS) |
| }; |
| |
| // Returns whether Execution is one of the values defined in the enum above. |
| bool isEnumValue(ExecutionMode Execution); |
| |
| // Returns a human readable string for the enum. |
| llvm::StringRef getName(ExecutionMode Execution); |
| |
| // Returns a sequence of increasing powers of two corresponding to all the |
| // Execution flags. |
| llvm::ArrayRef<ExecutionMode> getAllExecutionBits(); |
| |
| // Decomposes Execution into individual set bits. |
| llvm::SmallVector<ExecutionMode, 4> getExecutionModeBits(ExecutionMode); |
| |
| LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); |
| |
| // A CodeTemplate is a set of InstructionTemplates that may not be fully |
| // specified (i.e. some variables are not yet set). This allows the |
| // SnippetGenerator to instantiate it many times with specific values to study |
| // their impact on instruction's performance. |
| struct CodeTemplate { |
| CodeTemplate() = default; |
| |
| CodeTemplate(CodeTemplate &&); // default |
| CodeTemplate &operator=(CodeTemplate &&); // default |
| CodeTemplate(const CodeTemplate &) = delete; |
| CodeTemplate &operator=(const CodeTemplate &) = delete; |
| |
| ExecutionMode Execution = ExecutionMode::UNKNOWN; |
| // Some information about how this template has been created. |
| std::string Info; |
| // The list of the instructions for this template. |
| std::vector<InstructionTemplate> Instructions; |
| // If the template uses the provided scratch memory, the register in which |
| // the pointer to this memory is passed in to the function. |
| unsigned ScratchSpacePointerInReg = 0; |
| }; |
| |
| } // namespace exegesis |
| } // namespace llvm |
| |
| #endif // LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H |