summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h')
-rw-r--r--llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h
new file mode 100644
index 00000000000..be21f8725ad
--- /dev/null
+++ b/llvm/tools/llvm-exegesis/lib/InstructionSnippetGenerator.h
@@ -0,0 +1,119 @@
+//===-- InstructionSnippetGenerator.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines helper classes to generate code snippets, in particular register
+/// assignment.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_EXEGESIS_INSTRUCTIONSNIPPETGENERATOR_H
+#define LLVM_TOOLS_LLVM_EXEGESIS_INSTRUCTIONSNIPPETGENERATOR_H
+
+#include "OperandGraph.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include <vector>
+
+namespace exegesis {
+
+// A Variable represents a set of possible values that we need to choose from.
+// It may represent one or more explicit operands that are tied together, or one
+// implicit operand.
+class Variable final {
+public:
+ bool IsUse = false;
+ bool IsDef = false;
+ bool IsReg = false;
+
+ // Lists all the explicit operand indices that are tied to this variable.
+ // Empty if Variable represents an implicit operand.
+ llvm::SmallVector<size_t, 8> ExplicitOperands;
+
+ // - In case of explicit operands, PossibleRegisters is the expansion of the
+ // operands's RegClass registers. Please note that tied together explicit
+ // operands share the same RegClass.
+ // - In case of implicit operands, PossibleRegisters is a singleton MCPhysReg.
+ llvm::SmallSetVector<llvm::MCPhysReg, 16> PossibleRegisters;
+
+ // If RegInfo is null, register names won't get resolved.
+ void print(llvm::raw_ostream &OS, const llvm::MCRegisterInfo *RegInfo) const;
+};
+
+// Builds a model of implicit and explicit operands for InstrDesc into
+// Variables.
+llvm::SmallVector<Variable, 8>
+getVariables(const llvm::MCRegisterInfo &RegInfo,
+ const llvm::MCInstrDesc &InstrDesc,
+ const llvm::BitVector &ReservedRegs);
+
+// A simple object to represent a Variable assignement.
+struct VariableAssignment {
+ VariableAssignment(size_t VarIdx, llvm::MCPhysReg AssignedReg);
+
+ size_t VarIdx;
+ llvm::MCPhysReg AssignedReg;
+
+ bool operator==(const VariableAssignment &) const;
+ bool operator<(const VariableAssignment &) const;
+};
+
+// An AssignmentChain is a set of assignement realizing a dependency chain.
+// We inherit from std::set to leverage uniqueness of elements.
+using AssignmentChain = std::set<VariableAssignment>;
+
+// Debug function to print an assignment chain.
+void dumpAssignmentChain(const llvm::MCRegisterInfo &RegInfo,
+ const AssignmentChain &Chain);
+
+// Inserts Variables into a graph representing register aliasing and finds all
+// the possible dependency chains for this instruction, i.e. all the possible
+// assignement of operands that would make execution of the instruction
+// sequential.
+std::vector<AssignmentChain>
+computeSequentialAssignmentChains(const llvm::MCRegisterInfo &RegInfo,
+ llvm::ArrayRef<Variable> Vars);
+
+// Selects a random configuration leading to a dependency chain.
+// The result is a vector of the same size as `Vars`.
+// `random_index_for_size` is a functor giving a random value in [0, arg[.
+std::vector<llvm::MCPhysReg>
+getRandomAssignment(llvm::ArrayRef<Variable> Vars,
+ llvm::ArrayRef<AssignmentChain> Chains,
+ const std::function<size_t(size_t)> &RandomIndexForSize);
+
+// Finds an assignment of registers to variables such that no two variables are
+// assigned the same register.
+// The result is a vector of the same size as `Vars`, or `{}` if the
+// assignment is not feasible.
+std::vector<llvm::MCPhysReg>
+getExclusiveAssignment(llvm::ArrayRef<Variable> Vars);
+
+// Finds a greedy assignment of registers to variables. Each variable gets
+// assigned the first possible register that is not already assigned to a
+// previous variable. If there is no such register, the variable gets assigned
+// the first possible register.
+// The result is a vector of the same size as `Vars`, or `{}` if the
+// assignment is not feasible.
+std::vector<llvm::MCPhysReg>
+getGreedyAssignment(llvm::ArrayRef<Variable> Vars);
+
+// Generates an LLVM MCInst with the previously computed variables.
+// Immediate values are set to 1.
+llvm::MCInst generateMCInst(const llvm::MCInstrDesc &InstrDesc,
+ llvm::ArrayRef<Variable> Vars,
+ llvm::ArrayRef<llvm::MCPhysReg> VarRegs);
+
+} // namespace exegesis
+
+#endif // LLVM_TOOLS_LLVM_EXEGESIS_INSTRUCTIONSNIPPETGENERATOR_H
OpenPOWER on IntegriCloud