xref: /openbsd-src/gnu/llvm/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- MCInstrDescView.h ---------------------------------------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick ///
909467b48Spatrick /// \file
1009467b48Spatrick /// Provide views around LLVM structures to represents an instruction instance,
1109467b48Spatrick /// as well as its implicit and explicit arguments in a uniform way.
1209467b48Spatrick /// Arguments that are explicit and independant (non tied) also have a Variable
1309467b48Spatrick /// associated to them so the instruction can be fully defined by reading its
1409467b48Spatrick /// Variables.
1509467b48Spatrick ///
1609467b48Spatrick //===----------------------------------------------------------------------===//
1709467b48Spatrick 
1809467b48Spatrick #ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
1909467b48Spatrick #define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
2009467b48Spatrick 
2109467b48Spatrick #include <memory>
2209467b48Spatrick #include <random>
2309467b48Spatrick #include <unordered_map>
2409467b48Spatrick 
2509467b48Spatrick #include "RegisterAliasing.h"
2609467b48Spatrick #include "llvm/ADT/ArrayRef.h"
2709467b48Spatrick #include "llvm/MC/MCInst.h"
2809467b48Spatrick #include "llvm/MC/MCInstrDesc.h"
2909467b48Spatrick #include "llvm/MC/MCInstrInfo.h"
3009467b48Spatrick 
3109467b48Spatrick namespace llvm {
3209467b48Spatrick namespace exegesis {
3309467b48Spatrick 
3409467b48Spatrick // A variable represents the value associated to an Operand or a set of Operands
3509467b48Spatrick // if they are tied together.
3609467b48Spatrick struct Variable {
3709467b48Spatrick   // Returns the index of this Variable inside Instruction's Variable.
3809467b48Spatrick   unsigned getIndex() const;
3909467b48Spatrick 
4009467b48Spatrick   // Returns the index of the Operand linked to this Variable.
4109467b48Spatrick   unsigned getPrimaryOperandIndex() const;
4209467b48Spatrick 
4309467b48Spatrick   // Returns whether this Variable has more than one Operand linked to it.
4409467b48Spatrick   bool hasTiedOperands() const;
4509467b48Spatrick 
4609467b48Spatrick   // The indices of the operands tied to this Variable.
4709467b48Spatrick   SmallVector<unsigned, 2> TiedOperands;
4809467b48Spatrick 
4909467b48Spatrick   // The index of this Variable in Instruction.Variables and its associated
5009467b48Spatrick   // Value in InstructionBuilder.VariableValues.
51*d415bd75Srobert   std::optional<uint8_t> Index;
5209467b48Spatrick };
5309467b48Spatrick 
5409467b48Spatrick // MCOperandInfo can only represents Explicit operands. This object gives a
5509467b48Spatrick // uniform view of Implicit and Explicit Operands.
5609467b48Spatrick // - Index: can be used to refer to MCInstrDesc::operands for Explicit operands.
5709467b48Spatrick // - Tracker: is set for Register Operands and is used to keep track of possible
5809467b48Spatrick // registers and the registers reachable from them (aliasing registers).
5909467b48Spatrick // - Info: a shortcut for MCInstrDesc::operands()[Index].
6009467b48Spatrick // - TiedToIndex: the index of the Operand holding the value or -1.
61*d415bd75Srobert // - ImplicitReg: the register value when Operand is Implicit, 0 otherwise.
6209467b48Spatrick // - VariableIndex: the index of the Variable holding the value for this Operand
6309467b48Spatrick // or -1 if this operand is implicit.
6409467b48Spatrick struct Operand {
6509467b48Spatrick   bool isExplicit() const;
6609467b48Spatrick   bool isImplicit() const;
6709467b48Spatrick   bool isImplicitReg() const;
6809467b48Spatrick   bool isDef() const;
6909467b48Spatrick   bool isUse() const;
7009467b48Spatrick   bool isReg() const;
7109467b48Spatrick   bool isTied() const;
7209467b48Spatrick   bool isVariable() const;
7309467b48Spatrick   bool isMemory() const;
7409467b48Spatrick   bool isImmediate() const;
7509467b48Spatrick   unsigned getIndex() const;
7609467b48Spatrick   unsigned getTiedToIndex() const;
7709467b48Spatrick   unsigned getVariableIndex() const;
7809467b48Spatrick   unsigned getImplicitReg() const;
7909467b48Spatrick   const RegisterAliasingTracker &getRegisterAliasing() const;
8009467b48Spatrick   const MCOperandInfo &getExplicitOperandInfo() const;
8109467b48Spatrick 
8209467b48Spatrick   // Please use the accessors above and not the following fields.
83*d415bd75Srobert   std::optional<uint8_t> Index;
8409467b48Spatrick   bool IsDef = false;
8509467b48Spatrick   const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
8609467b48Spatrick   const MCOperandInfo *Info = nullptr;              // Set for Explicit Op.
87*d415bd75Srobert   std::optional<uint8_t> TiedToIndex;               // Set for Reg&Explicit Op.
88*d415bd75Srobert   MCPhysReg ImplicitReg = 0;                        // Non-0 for Implicit Op.
89*d415bd75Srobert   std::optional<uint8_t> VariableIndex;             // Set for Explicit Op.
9009467b48Spatrick };
9109467b48Spatrick 
9209467b48Spatrick /// A cache of BitVector to reuse between Instructions.
9309467b48Spatrick /// The cache will only be exercised during Instruction initialization.
9409467b48Spatrick /// For X86, this is ~160 unique vectors for all of the ~15K Instructions.
9509467b48Spatrick struct BitVectorCache {
9609467b48Spatrick   // Finds or allocates the provided BitVector in the cache and retrieves it's
9709467b48Spatrick   // unique instance.
9809467b48Spatrick   const BitVector *getUnique(BitVector &&BV) const;
9909467b48Spatrick 
10009467b48Spatrick private:
10109467b48Spatrick   mutable std::vector<std::unique_ptr<BitVector>> Cache;
10209467b48Spatrick };
10309467b48Spatrick 
10409467b48Spatrick // A view over an MCInstrDesc offering a convenient interface to compute
10509467b48Spatrick // Register aliasing.
10609467b48Spatrick struct Instruction {
10709467b48Spatrick   // Create an instruction for a particular Opcode.
10809467b48Spatrick   static std::unique_ptr<Instruction>
10909467b48Spatrick   create(const MCInstrInfo &InstrInfo, const RegisterAliasingTrackerCache &RATC,
11009467b48Spatrick          const BitVectorCache &BVC, unsigned Opcode);
11109467b48Spatrick 
11209467b48Spatrick   // Prevent copy or move, instructions are allocated once and cached.
11309467b48Spatrick   Instruction(const Instruction &) = delete;
11409467b48Spatrick   Instruction(Instruction &&) = delete;
11509467b48Spatrick   Instruction &operator=(const Instruction &) = delete;
11609467b48Spatrick   Instruction &operator=(Instruction &&) = delete;
11709467b48Spatrick 
11809467b48Spatrick   // Returns the Operand linked to this Variable.
11909467b48Spatrick   // In case the Variable is tied, the primary (i.e. Def) Operand is returned.
12009467b48Spatrick   const Operand &getPrimaryOperand(const Variable &Var) const;
12109467b48Spatrick 
12209467b48Spatrick   // Whether this instruction is self aliasing through its tied registers.
12309467b48Spatrick   // Repeating this instruction is guaranteed to executes sequentially.
12409467b48Spatrick   bool hasTiedRegisters() const;
12509467b48Spatrick 
12609467b48Spatrick   // Whether this instruction is self aliasing through its implicit registers.
12709467b48Spatrick   // Repeating this instruction is guaranteed to executes sequentially.
12809467b48Spatrick   bool hasAliasingImplicitRegisters() const;
12909467b48Spatrick 
13009467b48Spatrick   // Whether this instruction is self aliasing through some registers.
13109467b48Spatrick   // Repeating this instruction may execute sequentially by picking aliasing
13209467b48Spatrick   // Use and Def registers. It may also execute in parallel by picking non
13309467b48Spatrick   // aliasing Use and Def registers.
13409467b48Spatrick   bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const;
13509467b48Spatrick 
13609467b48Spatrick   // Whether this instruction's registers alias with OtherInstr's registers.
13709467b48Spatrick   bool hasAliasingRegistersThrough(const Instruction &OtherInstr,
13809467b48Spatrick                                    const BitVector &ForbiddenRegisters) const;
13909467b48Spatrick 
14009467b48Spatrick   // Returns whether this instruction has Memory Operands.
14109467b48Spatrick   // Repeating this instruction executes sequentially with an instruction that
14209467b48Spatrick   // reads or write the same memory region.
14309467b48Spatrick   bool hasMemoryOperands() const;
14409467b48Spatrick 
14509467b48Spatrick   // Returns whether this instruction as at least one use or one def.
14609467b48Spatrick   // Repeating this instruction may execute sequentially by adding an
14709467b48Spatrick   // instruction that aliases one of these.
14809467b48Spatrick   bool hasOneUseOrOneDef() const;
14909467b48Spatrick 
15009467b48Spatrick   // Convenient function to help with debugging.
15109467b48Spatrick   void dump(const MCRegisterInfo &RegInfo,
15209467b48Spatrick             const RegisterAliasingTrackerCache &RATC,
15309467b48Spatrick             raw_ostream &Stream) const;
15409467b48Spatrick 
15509467b48Spatrick   const MCInstrDesc &Description;
15609467b48Spatrick   const StringRef Name; // The name of this instruction.
15709467b48Spatrick   const SmallVector<Operand, 8> Operands;
15809467b48Spatrick   const SmallVector<Variable, 4> Variables;
15909467b48Spatrick   const BitVector &ImplDefRegs; // The set of aliased implicit def registers.
16009467b48Spatrick   const BitVector &ImplUseRegs; // The set of aliased implicit use registers.
16109467b48Spatrick   const BitVector &AllDefRegs;  // The set of all aliased def registers.
16209467b48Spatrick   const BitVector &AllUseRegs;  // The set of all aliased use registers.
16309467b48Spatrick private:
16409467b48Spatrick   Instruction(const MCInstrDesc *Description, StringRef Name,
16509467b48Spatrick               SmallVector<Operand, 8> Operands,
16609467b48Spatrick               SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,
16709467b48Spatrick               const BitVector *ImplUseRegs, const BitVector *AllDefRegs,
16809467b48Spatrick               const BitVector *AllUseRegs);
16909467b48Spatrick };
17009467b48Spatrick 
17109467b48Spatrick // Instructions are expensive to instantiate. This class provides a cache of
17209467b48Spatrick // Instructions with lazy construction.
17309467b48Spatrick struct InstructionsCache {
17409467b48Spatrick   InstructionsCache(const MCInstrInfo &InstrInfo,
17509467b48Spatrick                     const RegisterAliasingTrackerCache &RATC);
17609467b48Spatrick 
17709467b48Spatrick   // Returns the Instruction object corresponding to this Opcode.
17809467b48Spatrick   const Instruction &getInstr(unsigned Opcode) const;
17909467b48Spatrick 
18009467b48Spatrick private:
18109467b48Spatrick   const MCInstrInfo &InstrInfo;
18209467b48Spatrick   const RegisterAliasingTrackerCache &RATC;
18309467b48Spatrick   mutable std::unordered_map<unsigned, std::unique_ptr<Instruction>>
18409467b48Spatrick       Instructions;
18509467b48Spatrick   const BitVectorCache BVC;
18609467b48Spatrick };
18709467b48Spatrick 
18809467b48Spatrick // Represents the assignment of a Register to an Operand.
18909467b48Spatrick struct RegisterOperandAssignment {
RegisterOperandAssignmentRegisterOperandAssignment19009467b48Spatrick   RegisterOperandAssignment(const Operand *Operand, MCPhysReg Reg)
19109467b48Spatrick       : Op(Operand), Reg(Reg) {}
19209467b48Spatrick 
19309467b48Spatrick   const Operand *Op; // Pointer to an Explicit Register Operand.
19409467b48Spatrick   MCPhysReg Reg;
19509467b48Spatrick 
19609467b48Spatrick   bool operator==(const RegisterOperandAssignment &other) const;
19709467b48Spatrick };
19809467b48Spatrick 
19909467b48Spatrick // Represents a set of Operands that would alias through the use of some
20009467b48Spatrick // Registers.
20109467b48Spatrick // There are two reasons why operands would alias:
20209467b48Spatrick // - The registers assigned to each of the operands are the same or alias each
20309467b48Spatrick //   other (e.g. AX/AL)
20409467b48Spatrick // - The operands are tied.
20509467b48Spatrick struct AliasingRegisterOperands {
20609467b48Spatrick   SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1.
20709467b48Spatrick   SmallVector<RegisterOperandAssignment, 2> Uses;
20809467b48Spatrick 
20909467b48Spatrick   // True is Defs and Use contain an Implicit Operand.
21009467b48Spatrick   bool hasImplicitAliasing() const;
21109467b48Spatrick 
21209467b48Spatrick   bool operator==(const AliasingRegisterOperands &other) const;
21309467b48Spatrick };
21409467b48Spatrick 
21509467b48Spatrick // Returns all possible configurations leading Def registers of DefInstruction
21609467b48Spatrick // to alias with Use registers of UseInstruction.
21709467b48Spatrick struct AliasingConfigurations {
21809467b48Spatrick   AliasingConfigurations(const Instruction &DefInstruction,
219*d415bd75Srobert                          const Instruction &UseInstruction,
220*d415bd75Srobert                          const BitVector &ForbiddenRegisters);
22109467b48Spatrick 
22209467b48Spatrick   bool empty() const; // True if no aliasing configuration is found.
22309467b48Spatrick   bool hasImplicitAliasing() const;
22409467b48Spatrick 
22509467b48Spatrick   SmallVector<AliasingRegisterOperands, 32> Configurations;
22609467b48Spatrick };
22709467b48Spatrick 
22809467b48Spatrick // Writes MCInst to OS.
22909467b48Spatrick // This is not assembly but the internal LLVM's name for instructions and
23009467b48Spatrick // registers.
23109467b48Spatrick void DumpMCInst(const MCRegisterInfo &MCRegisterInfo,
23209467b48Spatrick                 const MCInstrInfo &MCInstrInfo, const MCInst &MCInst,
23309467b48Spatrick                 raw_ostream &OS);
23409467b48Spatrick 
23509467b48Spatrick } // namespace exegesis
23609467b48Spatrick } // namespace llvm
23709467b48Spatrick 
23809467b48Spatrick #endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
239