148 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// A set of structures and functions to craft instructions for the11/// SnippetGenerator.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H16#define LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H17 18#include "MCInstrDescView.h"19#include "llvm/ADT/BitmaskEnum.h"20 21namespace llvm {22namespace exegesis {23 24// A template for an Instruction holding values for each of its Variables.25struct InstructionTemplate {26 InstructionTemplate(const Instruction *Instr);27 28 InstructionTemplate(const InstructionTemplate &); // default29 InstructionTemplate &operator=(const InstructionTemplate &); // default30 InstructionTemplate(InstructionTemplate &&); // default31 InstructionTemplate &operator=(InstructionTemplate &&); // default32 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 operands48 // to the corresponding variable values. Precondition: All VariableValues must49 // be set.50 MCInst build() const;51 52private:53 const Instruction *Instr;54 SmallVector<MCOperand, 4> VariableValues;55};56 57enum 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 that68 // clobbers/reads memory.69 // e.g. MOV8rm70 SERIAL_VIA_MEMORY_INSTR = 1u << 2,71 72 // The execution can be made serial by picking one Def that aliases with one73 // Use.74 // e.g. VXORPSrr XMM1, XMM1, XMM275 SERIAL_VIA_EXPLICIT_REGS = 1u << 3,76 77 // The execution can be made serial by inserting a second instruction that78 // uses one of the Defs and defs one of the Uses.79 // e.g.80 // 1st instruction: MMX_PMOVMSKBrr ECX, MM781 // 2nd instruction: MMX_MOVD64rr MM7, ECX82 // or instruction: MMX_MOVD64to64rr MM7, ECX83 // or instruction: MMX_PINSRWrr MM7, MM7, ECX, 184 SERIAL_VIA_NON_MEMORY_INSTR = 1u << 4,85 86 // The execution is always parallel because the instruction is missing Use or87 // Def operands.88 ALWAYS_PARALLEL_MISSING_USE_OR_DEF = 1u << 5,89 90 // The execution can be made parallel by repeating the same instruction but91 // making sure that Defs of one instruction do not alias with Uses of the92 // 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.99bool isEnumValue(ExecutionMode Execution);100 101// Returns a human readable string for the enum.102StringRef getName(ExecutionMode Execution);103 104// Returns a sequence of increasing powers of two corresponding to all the105// Execution flags.106ArrayRef<ExecutionMode> getAllExecutionBits();107 108// Decomposes Execution into individual set bits.109SmallVector<ExecutionMode, 4> getExecutionModeBits(ExecutionMode);110 111LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();112 113// A CodeTemplate is a set of InstructionTemplates that may not be fully114// specified (i.e. some variables are not yet set). This allows the115// SnippetGenerator to instantiate it many times with specific values to study116// their impact on instruction's performance.117struct CodeTemplate {118 CodeTemplate() = default;119 120 CodeTemplate(CodeTemplate &&); // default121 CodeTemplate &operator=(CodeTemplate &&); // default122 123 CodeTemplate clone() const;124 125 ExecutionMode Execution = ExecutionMode::UNKNOWN;126 // See BenchmarkKey.::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 which133 // the pointer to this memory is passed in to the function.134 MCRegister ScratchSpacePointerInReg;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.138private:139#endif140 CodeTemplate(const CodeTemplate &); // default141 CodeTemplate &operator=(const CodeTemplate &); // default142};143 144} // namespace exegesis145} // namespace llvm146 147#endif // LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H148