blob: 386a32cebf4d433fdcf5ceac8ae9cd5631a35500 [file] [log] [blame]
Clement Courbet0e69e2d2018-05-17 10:52:18 +00001//===-- MCInstrDescView.h ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// Provide views around LLVM structures to represents an instruction instance,
12/// as well as its implicit and explicit arguments in a uniform way.
13/// Arguments that are explicit and independant (non tied) also have a Variable
14/// associated to them so the instruction can be fully defined by reading its
15/// Variables.
16///
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
20#define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
21
22#include <random>
23
24#include "RegisterAliasing.h"
25#include "llvm/ADT/ArrayRef.h"
26#include "llvm/ADT/Optional.h"
27#include "llvm/MC/MCInst.h"
28#include "llvm/MC/MCInstrDesc.h"
29#include "llvm/MC/MCInstrInfo.h"
30
31namespace exegesis {
32
33struct Operand; // forward declaration.
34
35// A variable represents the value of an Operand or a set of Operands if they ar
36// tied together.
37struct Variable {
38 llvm::SmallVector<const Operand *, 2> TiedOperands;
39 llvm::MCOperand AssignedValue;
40};
41
42// MCOperandInfo can only represents Explicit operands. This object gives a
43// uniform view of Implicit and Explicit Operands.
44//
45// - Index: can be used to refer to MCInstrDesc::operands for Explicit operands.
46// - Tracker: is set for Register Operands and is used to keep track of possible
47// registers and the registers reachable from them (aliasing registers).
48// - Info: a shortcut for MCInstrDesc::operands()[Index].
49// - TiedTo: a pointer to the Operand holding the value or nullptr.
50// - ImplicitReg: a pointer to the register value when Operand is Implicit,
51// nullptr otherwise.
52// - Variable: The value associated with this Operand. It is only set for
53// explicit operands that are not TiedTo.
54struct Operand {
55 uint8_t Index = 0;
56 bool IsDef = false;
57 bool IsExplicit = false;
58 const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
59 const llvm::MCOperandInfo *Info = nullptr; // Set for Explicit Op.
60 const Operand *TiedTo = nullptr; // Set for Reg/Explicit Op.
61 const llvm::MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op.
62 mutable llvm::Optional<Variable> Var; // Set for Explicit Op.
63};
64
65// A view over an MCInstrDesc offering a convenient interface to compute
66// Register aliasing and assign values to Operands.
67struct Instruction {
68 Instruction(const llvm::MCInstrDesc &MCInstrDesc,
69 RegisterAliasingTrackerCache &ATC);
70
71 const llvm::MCInstrDesc &Description;
72 llvm::SmallVector<Operand, 8> Operands;
73 llvm::SmallVector<Variable *, 8> Variables;
74 llvm::BitVector DefRegisters; // The union of the aliased def registers.
75 llvm::BitVector UseRegisters; // The union of the aliased use registers.
76};
77
78// Represents the assignment of a Register to an Operand.
79struct RegisterOperandAssignment {
80 RegisterOperandAssignment(const Operand *Operand, llvm::MCPhysReg Reg)
81 : Op(Operand), Reg(Reg) {}
82
83 const Operand *Op; // Pointer to an Explicit Register Operand.
84 llvm::MCPhysReg Reg;
85
86 bool operator==(const RegisterOperandAssignment &other) const;
87};
88
89// Represents a set of Operands that would alias through the use of some
90// Registers.
91// There are two reasons why operands would alias:
92// - The registers assigned to each of the operands are the same or alias each
93// other (e.g. AX/AL)
94// - The operands are tied.
95struct AliasingRegisterOperands {
96 llvm::SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1.
97 llvm::SmallVector<RegisterOperandAssignment, 2> Uses;
98
99 // True is Defs and Use contain an Implicit Operand.
100 bool hasImplicitAliasing() const;
101
102 bool operator==(const AliasingRegisterOperands &other) const;
103};
104
105// Returns all possible configurations leading Def registers of DefInstruction
106// to alias with Use registers of UseInstruction.
107struct AliasingConfigurations {
108 AliasingConfigurations(const Instruction &DefInstruction,
109 const Instruction &UseInstruction);
110
111 bool empty() const; // True if no aliasing configuration is found.
112 bool hasImplicitAliasing() const;
113 void setExplicitAliasing() const;
114
115 const Instruction &DefInstruction;
116 const Instruction &UseInstruction;
117 llvm::SmallVector<AliasingRegisterOperands, 32> Configurations;
118};
119
120// A global Random Number Generator to randomize configurations.
121// FIXME: Move random number generation into an object and make it seedable for
122// unit tests.
123std::mt19937 &randomGenerator();
124
125// Picks a random bit among the bits set in Vector and returns its index.
126// Precondition: Vector must have at least one bit set.
127size_t randomBit(const llvm::BitVector &Vector);
128
129// Picks a random configuration, then select a random def and a random use from
130// it and set the target Variables to the selected values.
131// FIXME: This function mutates some nested variables in a const object, please
132// fix ASAP.
133void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations);
134
135// Set all Instruction's Variables AssignedValue to Invalid.
136void clearVariableAssignments(const Instruction &Instruction);
137
138// Assigns a Random Value to all Instruction's Variables that are still Invalid.
139llvm::MCInst randomizeUnsetVariablesAndBuild(const Instruction &Instruction);
140
141// Writes MCInst to OS.
142// This is not assembly but the internal LLVM's name for instructions and
143// registers.
144void DumpMCInst(const llvm::MCRegisterInfo &MCRegisterInfo,
145 const llvm::MCInstrInfo &MCInstrInfo,
146 const llvm::MCInst &MCInst, llvm::raw_ostream &OS);
147
148} // namespace exegesis
149
150#endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H