mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
92ce5b3319
Summary: Currently, we only have nice exploration for LEA instruction, while for the rest, we rely on `randomizeUnsetVariables()` to sometimes generate something interesting. While that works, it isn't very reliable in coverage :) Here, i'm making an assumption that while we may want to explore multi-instruction configs, we are most interested in the characteristics of the main instruction we were asked about. Which we can do, by taking the existing `randomizeMCOperand()`, and turning it on it's head - instead of relying on it to randomly fill one of the interesting values, let's pregenerate all the possible interesting values for the variable, and then generate as much `InstructionTemplate` combinations of these possible values for variables as needed/possible. Of course, that requires invasive changes to no longer pass just the naked `Instruction`, but sometimes partially filled `InstructionTemplate`. As it can be seen from the test, this allows us to explore `X86::OperandType::OPERAND_COND_CODE` for instructions that take such an operand. I'm hoping this will greatly simplify exploration. Reviewers: courbet, gchatelet Reviewed By: gchatelet Subscribers: orodley, mgorny, sdardis, tschuett, jrtc27, atanasyan, mstojanovic, andreadb, RKSimon, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D74156
141 lines
5.1 KiB
C++
141 lines
5.1 KiB
C++
//===-- CodeTemplate.h ------------------------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
/// 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;
|
|
MCOperand &getValueFor(const Variable &Var);
|
|
const MCOperand &getValueFor(const Variable &Var) const;
|
|
MCOperand &getValueFor(const Operand &Op);
|
|
const MCOperand &getValueFor(const Operand &Op) const;
|
|
bool hasImmediateVariables() const;
|
|
const Instruction &getInstr() const { return *Instr; }
|
|
ArrayRef<MCOperand> getVariableValues() const { return VariableValues; }
|
|
void setVariableValues(ArrayRef<MCOperand> NewVariableValues) {
|
|
assert(VariableValues.size() == NewVariableValues.size() &&
|
|
"Value count mismatch");
|
|
VariableValues.assign(NewVariableValues.begin(), NewVariableValues.end());
|
|
}
|
|
|
|
// Builds an MCInst from this InstructionTemplate setting its operands
|
|
// to the corresponding variable values. Precondition: All VariableValues must
|
|
// be set.
|
|
MCInst build() const;
|
|
|
|
private:
|
|
const Instruction *Instr;
|
|
SmallVector<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.
|
|
StringRef getName(ExecutionMode Execution);
|
|
|
|
// Returns a sequence of increasing powers of two corresponding to all the
|
|
// Execution flags.
|
|
ArrayRef<ExecutionMode> getAllExecutionBits();
|
|
|
|
// Decomposes Execution into individual set bits.
|
|
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;
|
|
// See InstructionBenchmarkKey.::Config.
|
|
std::string Config;
|
|
// 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
|