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; getInstrInstructionTemplate39 const Instruction &getInstr() const { return *Instr; } getVariableValuesInstructionTemplate40 ArrayRef<MCOperand> getVariableValues() const { return VariableValues; } setVariableValuesInstructionTemplate41 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 123 CodeTemplate clone() const; 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 #if defined(__GNUC__) && (defined(__clang__) || LLVM_GNUC_PREREQ(8, 0, 0)) 137 // FIXME: GCC7 bug workaround. Drop #if after GCC7 no longer supported. 138 private: 139 #endif 140 CodeTemplate(const CodeTemplate &); // default 141 CodeTemplate &operator=(const CodeTemplate &); // default 142 }; 143 144 } // namespace exegesis 145 } // namespace llvm 146 147 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H 148