1 //===-- MCInstrDescView.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
17 //===----------------------------------------------------------------------===//
19 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
20 #define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
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"
33 struct Operand
; // forward declaration.
35 // A variable represents the value associated to an Operand or a set of Operands
36 // if they are tied together.
38 // The indices of the operands tied to this Variable.
39 llvm::SmallVector
<unsigned, 2> TiedOperands
;
40 llvm::MCOperand AssignedValue
;
41 // The index of this Variable in Instruction.Variables and its associated
42 // Value in InstructionInstance.VariableValues.
46 // MCOperandInfo can only represents Explicit operands. This object gives a
47 // uniform view of Implicit and Explicit Operands.
49 // - Index: can be used to refer to MCInstrDesc::operands for Explicit operands.
50 // - Tracker: is set for Register Operands and is used to keep track of possible
51 // registers and the registers reachable from them (aliasing registers).
52 // - Info: a shortcut for MCInstrDesc::operands()[Index].
53 // - TiedToIndex: the index of the Operand holding the value or -1.
54 // - ImplicitReg: a pointer to the register value when Operand is Implicit,
56 // - VariableIndex: the index of the Variable holding the value for this Operand
57 // or -1 if this operand is implicit.
62 bool IsExplicit
= false;
63 const RegisterAliasingTracker
*Tracker
= nullptr; // Set for Register Op.
64 const llvm::MCOperandInfo
*Info
= nullptr; // Set for Explicit Op.
65 int TiedToIndex
= -1; // Set for Reg&Explicit Op.
66 const llvm::MCPhysReg
*ImplicitReg
= nullptr; // Set for Implicit Op.
67 int VariableIndex
= -1; // Set for Explicit Op.
70 // A view over an MCInstrDesc offering a convenient interface to compute
73 Instruction(const llvm::MCInstrDesc
&MCInstrDesc
,
74 const RegisterAliasingTrackerCache
&ATC
);
76 bool hasMemoryOperands() const;
78 const llvm::MCInstrDesc
*Description
; // Never nullptr.
79 llvm::SmallVector
<Operand
, 8> Operands
;
80 llvm::SmallVector
<Variable
, 4> Variables
;
81 llvm::BitVector DefRegisters
; // The union of the aliased def registers.
82 llvm::BitVector UseRegisters
; // The union of the aliased use registers.
85 // An instance of an Instruction holding values for each of its Variables.
86 struct InstructionInstance
{
87 InstructionInstance(const Instruction
&Instr
);
89 InstructionInstance(const InstructionInstance
&);
90 InstructionInstance
&operator=(const InstructionInstance
&);
91 InstructionInstance(InstructionInstance
&&);
92 InstructionInstance
&operator=(InstructionInstance
&&);
94 unsigned getOpcode() const;
95 llvm::MCOperand
&getValueFor(const Variable
&Var
);
96 const llvm::MCOperand
&getValueFor(const Variable
&Var
) const;
97 llvm::MCOperand
&getValueFor(const Operand
&Op
);
98 const llvm::MCOperand
&getValueFor(const Operand
&Op
) const;
99 bool hasImmediateVariables() const;
101 // Assigns a Random Value to all Variables that are still Invalid.
102 // Do not use any of the registers in `ForbiddenRegs`.
103 void randomizeUnsetVariables(const llvm::BitVector
&ForbiddenRegs
);
105 // Returns the instance as an llvm::MCInst. The InstructionInstance must be
106 // fully allocated (no invalid variables).
107 llvm::MCInst
build() const;
110 llvm::SmallVector
<llvm::MCOperand
, 4> VariableValues
;
113 // A prototype is a set of InstructionInstances with an explanation of how
114 // it's been built. The prototype can then be randomized to exercice several
115 // immediate values. It is also used to gather the used registers and define
116 // their initial values.
117 struct SnippetPrototype
{
118 SnippetPrototype() = default;
121 SnippetPrototype(const SnippetPrototype
&) = delete;
122 SnippetPrototype
&operator=(const SnippetPrototype
&) = delete;
125 SnippetPrototype(SnippetPrototype
&&);
126 SnippetPrototype
&operator=(SnippetPrototype
&&);
128 std::string Explanation
;
129 // If the prototype uses the provided scratch memory, the register in which
130 // the pointer to this memory is passed in to the function.
131 unsigned ScratchSpaceReg
= 0;
132 std::vector
<InstructionInstance
> Snippet
;
135 // Represents the assignment of a Register to an Operand.
136 struct RegisterOperandAssignment
{
137 RegisterOperandAssignment(const Operand
*Operand
, llvm::MCPhysReg Reg
)
138 : Op(Operand
), Reg(Reg
) {}
140 const Operand
*Op
; // Pointer to an Explicit Register Operand.
143 bool operator==(const RegisterOperandAssignment
&other
) const;
146 // Represents a set of Operands that would alias through the use of some
148 // There are two reasons why operands would alias:
149 // - The registers assigned to each of the operands are the same or alias each
150 // other (e.g. AX/AL)
151 // - The operands are tied.
152 struct AliasingRegisterOperands
{
153 llvm::SmallVector
<RegisterOperandAssignment
, 1> Defs
; // Unlikely size() > 1.
154 llvm::SmallVector
<RegisterOperandAssignment
, 2> Uses
;
156 // True is Defs and Use contain an Implicit Operand.
157 bool hasImplicitAliasing() const;
159 bool operator==(const AliasingRegisterOperands
&other
) const;
162 // Returns all possible configurations leading Def registers of DefInstruction
163 // to alias with Use registers of UseInstruction.
164 struct AliasingConfigurations
{
165 AliasingConfigurations(const Instruction
&DefInstruction
,
166 const Instruction
&UseInstruction
);
168 bool empty() const; // True if no aliasing configuration is found.
169 bool hasImplicitAliasing() const;
170 void setExplicitAliasing() const;
172 const Instruction
&DefInstruction
;
173 const Instruction
&UseInstruction
;
174 llvm::SmallVector
<AliasingRegisterOperands
, 32> Configurations
;
177 // A global Random Number Generator to randomize configurations.
178 // FIXME: Move random number generation into an object and make it seedable for
180 std::mt19937
&randomGenerator();
182 // Picks a random bit among the bits set in Vector and returns its index.
183 // Precondition: Vector must have at least one bit set.
184 size_t randomBit(const llvm::BitVector
&Vector
);
186 // Picks a random configuration, then selects a random def and a random use from
187 // it and finally set the selected values in the provided InstructionInstances.
188 void setRandomAliasing(const AliasingConfigurations
&AliasingConfigurations
,
189 InstructionInstance
&DefII
, InstructionInstance
&UseII
);
191 // Writes MCInst to OS.
192 // This is not assembly but the internal LLVM's name for instructions and
194 void DumpMCInst(const llvm::MCRegisterInfo
&MCRegisterInfo
,
195 const llvm::MCInstrInfo
&MCInstrInfo
,
196 const llvm::MCInst
&MCInst
, llvm::raw_ostream
&OS
);
198 } // namespace exegesis
200 #endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H