Home | History | Annotate | Line # | Download | only in lib
      1 //===-- CodeTemplate.h ------------------------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// A set of structures and functions to craft instructions for the
     11 /// SnippetGenerator.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H
     16 #define LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H
     17 
     18 #include "MCInstrDescView.h"
     19 #include "llvm/ADT/BitmaskEnum.h"
     20 
     21 namespace llvm {
     22 namespace exegesis {
     23 
     24 // A template for an Instruction holding values for each of its Variables.
     25 struct InstructionTemplate {
     26   InstructionTemplate(const Instruction *Instr);
     27 
     28   InstructionTemplate(const InstructionTemplate &);            // default
     29   InstructionTemplate &operator=(const InstructionTemplate &); // default
     30   InstructionTemplate(InstructionTemplate &&);                 // default
     31   InstructionTemplate &operator=(InstructionTemplate &&);      // default
     32 
     33   unsigned getOpcode() const;
     34   MCOperand &getValueFor(const Variable &Var);
     35   const MCOperand &getValueFor(const Variable &Var) const;
     36   MCOperand &getValueFor(const Operand &Op);
     37   const MCOperand &getValueFor(const Operand &Op) const;
     38   bool hasImmediateVariables() const;
     39   const Instruction &getInstr() const { return *Instr; }
     40   ArrayRef<MCOperand> getVariableValues() const { return VariableValues; }
     41   void setVariableValues(ArrayRef<MCOperand> NewVariableValues) {
     42     assert(VariableValues.size() == NewVariableValues.size() &&
     43            "Value count mismatch");
     44     VariableValues.assign(NewVariableValues.begin(), NewVariableValues.end());
     45   }
     46 
     47   // Builds an MCInst from this InstructionTemplate setting its operands
     48   // to the corresponding variable values. Precondition: All VariableValues must
     49   // be set.
     50   MCInst build() const;
     51 
     52 private:
     53   const Instruction *Instr;
     54   SmallVector<MCOperand, 4> VariableValues;
     55 };
     56 
     57 enum class ExecutionMode : uint8_t {
     58   UNKNOWN = 0U,
     59   // The instruction is always serial because implicit Use and Def alias.
     60   // e.g. AAA (alias via EFLAGS)
     61   ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS = 1u << 0,
     62 
     63   // The instruction is always serial because one Def is tied to a Use.
     64   // e.g. AND32ri (alias via tied GR32)
     65   ALWAYS_SERIAL_TIED_REGS_ALIAS = 1u << 1,
     66 
     67   // The execution can be made serial by inserting a second instruction that
     68   // clobbers/reads memory.
     69   // e.g. MOV8rm
     70   SERIAL_VIA_MEMORY_INSTR = 1u << 2,
     71 
     72   // The execution can be made serial by picking one Def that aliases with one
     73   // Use.
     74   // e.g. VXORPSrr XMM1, XMM1, XMM2
     75   SERIAL_VIA_EXPLICIT_REGS = 1u << 3,
     76 
     77   // The execution can be made serial by inserting a second instruction that
     78   // uses one of the Defs and defs one of the Uses.
     79   // e.g.
     80   // 1st instruction: MMX_PMOVMSKBrr ECX, MM7
     81   // 2nd instruction: MMX_MOVD64rr MM7, ECX
     82   //  or instruction: MMX_MOVD64to64rr MM7, ECX
     83   //  or instruction: MMX_PINSRWrr MM7, MM7, ECX, 1
     84   SERIAL_VIA_NON_MEMORY_INSTR = 1u << 4,
     85 
     86   // The execution is always parallel because the instruction is missing Use or
     87   // Def operands.
     88   ALWAYS_PARALLEL_MISSING_USE_OR_DEF = 1u << 5,
     89 
     90   // The execution can be made parallel by repeating the same instruction but
     91   // making sure that Defs of one instruction do not alias with Uses of the
     92   // second one.
     93   PARALLEL_VIA_EXPLICIT_REGS = 1u << 6,
     94 
     95   LLVM_MARK_AS_BITMASK_ENUM(/*Largest*/ PARALLEL_VIA_EXPLICIT_REGS)
     96 };
     97 
     98 // Returns whether Execution is one of the values defined in the enum above.
     99 bool isEnumValue(ExecutionMode Execution);
    100 
    101 // Returns a human readable string for the enum.
    102 StringRef getName(ExecutionMode Execution);
    103 
    104 // Returns a sequence of increasing powers of two corresponding to all the
    105 // Execution flags.
    106 ArrayRef<ExecutionMode> getAllExecutionBits();
    107 
    108 // Decomposes Execution into individual set bits.
    109 SmallVector<ExecutionMode, 4> getExecutionModeBits(ExecutionMode);
    110 
    111 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
    112 
    113 // A CodeTemplate is a set of InstructionTemplates that may not be fully
    114 // specified (i.e. some variables are not yet set). This allows the
    115 // SnippetGenerator to instantiate it many times with specific values to study
    116 // their impact on instruction's performance.
    117 struct CodeTemplate {
    118   CodeTemplate() = default;
    119 
    120   CodeTemplate(CodeTemplate &&);            // default
    121   CodeTemplate &operator=(CodeTemplate &&); // default
    122   CodeTemplate(const CodeTemplate &) = delete;
    123   CodeTemplate &operator=(const CodeTemplate &) = delete;
    124 
    125   ExecutionMode Execution = ExecutionMode::UNKNOWN;
    126   // See InstructionBenchmarkKey.::Config.
    127   std::string Config;
    128   // Some information about how this template has been created.
    129   std::string Info;
    130   // The list of the instructions for this template.
    131   std::vector<InstructionTemplate> Instructions;
    132   // If the template uses the provided scratch memory, the register in which
    133   // the pointer to this memory is passed in to the function.
    134   unsigned ScratchSpacePointerInReg = 0;
    135 };
    136 
    137 } // namespace exegesis
    138 } // namespace llvm
    139 
    140 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H
    141