2018-05-17 12:52:18 +02:00
|
|
|
//===-- 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 {
|
|
|
|
|
2018-06-13 15:24:41 +02:00
|
|
|
// A variable represents the value associated to an Operand or a set of Operands
|
|
|
|
// if they are tied together.
|
2018-05-17 12:52:18 +02:00
|
|
|
struct Variable {
|
2018-10-09 10:59:10 +02:00
|
|
|
// Returns the index of this Variable inside Instruction's Variable.
|
|
|
|
unsigned getIndex() const;
|
|
|
|
|
|
|
|
// Returns the index of the Operand linked to this Variable.
|
|
|
|
unsigned getPrimaryOperandIndex() const;
|
|
|
|
|
|
|
|
// Returns whether this Variable has more than one Operand linked to it.
|
|
|
|
bool hasTiedOperands() const;
|
|
|
|
|
2018-06-20 10:52:30 +02:00
|
|
|
// The indices of the operands tied to this Variable.
|
|
|
|
llvm::SmallVector<unsigned, 2> TiedOperands;
|
2018-10-10 11:12:36 +02:00
|
|
|
|
2018-06-13 15:24:41 +02:00
|
|
|
// The index of this Variable in Instruction.Variables and its associated
|
2018-08-02 13:12:02 +02:00
|
|
|
// Value in InstructionBuilder.VariableValues.
|
2018-10-09 12:06:19 +02:00
|
|
|
int Index = -1;
|
2018-05-17 12:52:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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].
|
2018-06-13 15:24:41 +02:00
|
|
|
// - TiedToIndex: the index of the Operand holding the value or -1.
|
2018-05-17 12:52:18 +02:00
|
|
|
// - ImplicitReg: a pointer to the register value when Operand is Implicit,
|
|
|
|
// nullptr otherwise.
|
2018-06-13 15:24:41 +02:00
|
|
|
// - VariableIndex: the index of the Variable holding the value for this Operand
|
|
|
|
// or -1 if this operand is implicit.
|
2018-05-17 12:52:18 +02:00
|
|
|
struct Operand {
|
2018-10-09 10:59:10 +02:00
|
|
|
bool isExplicit() const;
|
|
|
|
bool isImplicit() const;
|
|
|
|
bool isImplicitReg() const;
|
|
|
|
bool isDef() const;
|
|
|
|
bool isUse() const;
|
|
|
|
bool isReg() const;
|
|
|
|
bool isTied() const;
|
|
|
|
bool isVariable() const;
|
|
|
|
bool isMemory() const;
|
|
|
|
bool isImmediate() const;
|
2018-10-09 16:51:29 +02:00
|
|
|
unsigned getIndex() const;
|
|
|
|
unsigned getTiedToIndex() const;
|
|
|
|
unsigned getVariableIndex() const;
|
2018-10-09 10:59:10 +02:00
|
|
|
unsigned getImplicitReg() const;
|
|
|
|
const RegisterAliasingTracker &getRegisterAliasing() const;
|
|
|
|
const llvm::MCOperandInfo &getExplicitOperandInfo() const;
|
|
|
|
|
|
|
|
// Please use the accessors above and not the following fields.
|
2018-06-13 15:24:41 +02:00
|
|
|
unsigned Index = 0;
|
2018-05-17 12:52:18 +02:00
|
|
|
bool IsDef = false;
|
|
|
|
const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
|
|
|
|
const llvm::MCOperandInfo *Info = nullptr; // Set for Explicit Op.
|
2018-06-25 13:12:30 +02:00
|
|
|
int TiedToIndex = -1; // Set for Reg&Explicit Op.
|
2018-05-17 12:52:18 +02:00
|
|
|
const llvm::MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op.
|
2018-06-25 13:12:30 +02:00
|
|
|
int VariableIndex = -1; // Set for Explicit Op.
|
2018-05-17 12:52:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// A view over an MCInstrDesc offering a convenient interface to compute
|
2018-06-13 15:24:41 +02:00
|
|
|
// Register aliasing.
|
2018-05-17 12:52:18 +02:00
|
|
|
struct Instruction {
|
|
|
|
Instruction(const llvm::MCInstrDesc &MCInstrDesc,
|
2018-06-13 15:24:41 +02:00
|
|
|
const RegisterAliasingTrackerCache &ATC);
|
2018-05-17 12:52:18 +02:00
|
|
|
|
2018-10-09 10:59:10 +02:00
|
|
|
// Returns the Operand linked to this Variable.
|
|
|
|
// In case the Variable is tied, the primary (i.e. Def) Operand is returned.
|
|
|
|
const Operand &getPrimaryOperand(const Variable &Var) const;
|
|
|
|
|
2018-10-10 11:12:36 +02:00
|
|
|
// Whether this instruction is self aliasing through its tied registers.
|
|
|
|
// Repeating this instruction is guaranteed to executes sequentially.
|
|
|
|
bool hasTiedRegisters() const;
|
2018-08-01 16:41:45 +02:00
|
|
|
|
2018-10-09 10:59:10 +02:00
|
|
|
// Whether this instruction is self aliasing through its implicit registers.
|
|
|
|
// Repeating this instruction is guaranteed to executes sequentially.
|
|
|
|
bool hasAliasingImplicitRegisters() const;
|
|
|
|
|
|
|
|
// Whether this instruction is self aliasing through some registers.
|
|
|
|
// Repeating this instruction may execute sequentially by picking aliasing
|
|
|
|
// Use and Def registers. It may also execute in parallel by picking non
|
|
|
|
// aliasing Use and Def registers.
|
|
|
|
bool hasAliasingRegisters() const;
|
|
|
|
|
2018-10-10 11:12:36 +02:00
|
|
|
// Whether this instruction's implicit registers alias with OtherInstr's
|
|
|
|
// implicit registers.
|
|
|
|
bool hasAliasingImplicitRegistersThrough(const Instruction &OtherInstr) const;
|
|
|
|
|
|
|
|
// Whether this instruction's registers alias with OtherInstr's registers.
|
|
|
|
bool hasAliasingRegistersThrough(const Instruction &OtherInstr) const;
|
|
|
|
|
|
|
|
// Returns whether this instruction has Memory Operands.
|
|
|
|
// Repeating this instruction executes sequentially with an instruction that
|
|
|
|
// reads or write the same memory region.
|
|
|
|
bool hasMemoryOperands() const;
|
|
|
|
|
2018-10-09 16:51:29 +02:00
|
|
|
// Convenient function to help with debugging.
|
2018-10-09 16:51:33 +02:00
|
|
|
void dump(const llvm::MCRegisterInfo &RegInfo,
|
2018-10-09 16:51:29 +02:00
|
|
|
llvm::raw_ostream &Stream) const;
|
|
|
|
|
2018-06-20 10:52:30 +02:00
|
|
|
const llvm::MCInstrDesc *Description; // Never nullptr.
|
2018-05-17 12:52:18 +02:00
|
|
|
llvm::SmallVector<Operand, 8> Operands;
|
2018-06-13 15:24:41 +02:00
|
|
|
llvm::SmallVector<Variable, 4> Variables;
|
2018-10-09 10:59:10 +02:00
|
|
|
llvm::BitVector ImplDefRegs; // The set of aliased implicit def registers.
|
|
|
|
llvm::BitVector ImplUseRegs; // The set of aliased implicit use registers.
|
|
|
|
llvm::BitVector AllDefRegs; // The set of all aliased def registers.
|
|
|
|
llvm::BitVector AllUseRegs; // The set of all aliased use registers.
|
2018-05-17 12:52:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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
|