diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/MCInstrDescView.h')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/MCInstrDescView.h | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h new file mode 100644 index 00000000000..386a32cebf4 --- /dev/null +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h @@ -0,0 +1,150 @@ +//===-- MCInstrDescView.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Provide views around LLVM structures to represents an instruction instance, +/// as well as its implicit and explicit arguments in a uniform way. +/// Arguments that are explicit and independant (non tied) also have a Variable +/// associated to them so the instruction can be fully defined by reading its +/// Variables. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H +#define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H + +#include <random> + +#include "RegisterAliasing.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace exegesis { + +struct Operand; // forward declaration. + +// A variable represents the value of an Operand or a set of Operands if they ar +// tied together. +struct Variable { + llvm::SmallVector<const Operand *, 2> TiedOperands; + llvm::MCOperand AssignedValue; +}; + +// MCOperandInfo can only represents Explicit operands. This object gives a +// uniform view of Implicit and Explicit Operands. +// +// - Index: can be used to refer to MCInstrDesc::operands for Explicit operands. +// - Tracker: is set for Register Operands and is used to keep track of possible +// registers and the registers reachable from them (aliasing registers). +// - Info: a shortcut for MCInstrDesc::operands()[Index]. +// - TiedTo: a pointer to the Operand holding the value or nullptr. +// - ImplicitReg: a pointer to the register value when Operand is Implicit, +// nullptr otherwise. +// - Variable: The value associated with this Operand. It is only set for +// explicit operands that are not TiedTo. +struct Operand { + uint8_t Index = 0; + bool IsDef = false; + bool IsExplicit = false; + const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op. + const llvm::MCOperandInfo *Info = nullptr; // Set for Explicit Op. + const Operand *TiedTo = nullptr; // Set for Reg/Explicit Op. + const llvm::MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op. + mutable llvm::Optional<Variable> Var; // Set for Explicit Op. +}; + +// A view over an MCInstrDesc offering a convenient interface to compute +// Register aliasing and assign values to Operands. +struct Instruction { + Instruction(const llvm::MCInstrDesc &MCInstrDesc, + RegisterAliasingTrackerCache &ATC); + + const llvm::MCInstrDesc &Description; + llvm::SmallVector<Operand, 8> Operands; + llvm::SmallVector<Variable *, 8> Variables; + llvm::BitVector DefRegisters; // The union of the aliased def registers. + llvm::BitVector UseRegisters; // The union of the aliased use registers. +}; + +// Represents the assignment of a Register to an Operand. +struct RegisterOperandAssignment { + RegisterOperandAssignment(const Operand *Operand, llvm::MCPhysReg Reg) + : Op(Operand), Reg(Reg) {} + + const Operand *Op; // Pointer to an Explicit Register Operand. + llvm::MCPhysReg Reg; + + bool operator==(const RegisterOperandAssignment &other) const; +}; + +// Represents a set of Operands that would alias through the use of some +// Registers. +// There are two reasons why operands would alias: +// - The registers assigned to each of the operands are the same or alias each +// other (e.g. AX/AL) +// - The operands are tied. +struct AliasingRegisterOperands { + llvm::SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1. + llvm::SmallVector<RegisterOperandAssignment, 2> Uses; + + // True is Defs and Use contain an Implicit Operand. + bool hasImplicitAliasing() const; + + bool operator==(const AliasingRegisterOperands &other) const; +}; + +// Returns all possible configurations leading Def registers of DefInstruction +// to alias with Use registers of UseInstruction. +struct AliasingConfigurations { + AliasingConfigurations(const Instruction &DefInstruction, + const Instruction &UseInstruction); + + bool empty() const; // True if no aliasing configuration is found. + bool hasImplicitAliasing() const; + void setExplicitAliasing() const; + + const Instruction &DefInstruction; + const Instruction &UseInstruction; + llvm::SmallVector<AliasingRegisterOperands, 32> Configurations; +}; + +// A global Random Number Generator to randomize configurations. +// FIXME: Move random number generation into an object and make it seedable for +// unit tests. +std::mt19937 &randomGenerator(); + +// Picks a random bit among the bits set in Vector and returns its index. +// Precondition: Vector must have at least one bit set. +size_t randomBit(const llvm::BitVector &Vector); + +// Picks a random configuration, then select a random def and a random use from +// it and set the target Variables to the selected values. +// FIXME: This function mutates some nested variables in a const object, please +// fix ASAP. +void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations); + +// Set all Instruction's Variables AssignedValue to Invalid. +void clearVariableAssignments(const Instruction &Instruction); + +// Assigns a Random Value to all Instruction's Variables that are still Invalid. +llvm::MCInst randomizeUnsetVariablesAndBuild(const Instruction &Instruction); + +// Writes MCInst to OS. +// This is not assembly but the internal LLVM's name for instructions and +// registers. +void DumpMCInst(const llvm::MCRegisterInfo &MCRegisterInfo, + const llvm::MCInstrInfo &MCInstrInfo, + const llvm::MCInst &MCInst, llvm::raw_ostream &OS); + +} // namespace exegesis + +#endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H |