blob: 966da2a8c41646047c67c417747b7ec1fcfc6581 [file] [log] [blame]
Clement Courbetd939f6d2018-09-13 07:40:53 +00001//===-- SnippetGenerator.h --------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Clement Courbetd939f6d2018-09-13 07:40:53 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Defines the abstract SnippetGenerator class for generating code that allows
11/// measuring a certain property of instructions (e.g. latency).
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H
16#define LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H
17
18#include "Assembler.h"
19#include "BenchmarkCode.h"
Guillaume Chatelet7f8d3102018-09-26 11:57:24 +000020#include "CodeTemplate.h"
Clement Courbetd939f6d2018-09-13 07:40:53 +000021#include "LlvmState.h"
22#include "MCInstrDescView.h"
23#include "RegisterAliasing.h"
24#include "llvm/MC/MCInst.h"
25#include "llvm/Support/Error.h"
26#include <cstdlib>
27#include <memory>
28#include <vector>
29
Fangrui Song32401af2018-10-22 17:10:47 +000030namespace llvm {
Clement Courbetd939f6d2018-09-13 07:40:53 +000031namespace exegesis {
32
Guillaume Chateletfcbb6f32018-10-17 11:37:28 +000033std::vector<CodeTemplate> getSingleton(CodeTemplate &&CT);
Guillaume Chatelet296a8622018-10-15 09:09:19 +000034
35// Generates code templates that has a self-dependency.
36llvm::Expected<std::vector<CodeTemplate>>
37generateSelfAliasingCodeTemplates(const Instruction &Instr);
38
39// Generates code templates without assignment constraints.
40llvm::Expected<std::vector<CodeTemplate>>
41generateUnconstrainedCodeTemplates(const Instruction &Instr,
42 llvm::StringRef Msg);
43
Clement Courbetd939f6d2018-09-13 07:40:53 +000044// A class representing failures that happened during Benchmark, they are used
45// to report informations to the user.
46class SnippetGeneratorFailure : public llvm::StringError {
47public:
48 SnippetGeneratorFailure(const llvm::Twine &S);
49};
50
51// Common code for all benchmark modes.
52class SnippetGenerator {
53public:
54 explicit SnippetGenerator(const LLVMState &State);
55
56 virtual ~SnippetGenerator();
57
58 // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
59 llvm::Expected<std::vector<BenchmarkCode>>
Guillaume Chatelet9b592382018-10-10 14:57:32 +000060 generateConfigurations(const Instruction &Instr) const;
Clement Courbetd939f6d2018-09-13 07:40:53 +000061
62 // Given a snippet, computes which registers the setup code needs to define.
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000063 std::vector<RegisterValue> computeRegisterInitialValues(
Guillaume Chatelet70ac0192018-09-27 09:23:04 +000064 const std::vector<InstructionTemplate> &Snippet) const;
Clement Courbetd939f6d2018-09-13 07:40:53 +000065
66protected:
67 const LLVMState &State;
Clement Courbetd939f6d2018-09-13 07:40:53 +000068
Clement Courbetd939f6d2018-09-13 07:40:53 +000069private:
70 // API to be implemented by subclasses.
Guillaume Chatelet296a8622018-10-15 09:09:19 +000071 virtual llvm::Expected<std::vector<CodeTemplate>>
Clement Courbet8ef97e12019-09-27 08:04:10 +000072 generateCodeTemplates(const Instruction &Instr,
73 const BitVector &ForbiddenRegisters) const = 0;
Clement Courbetd939f6d2018-09-13 07:40:53 +000074};
75
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000076// A global Random Number Generator to randomize configurations.
77// FIXME: Move random number generation into an object and make it seedable for
78// unit tests.
79std::mt19937 &randomGenerator();
80
Roman Lebedeva8223582019-04-08 10:11:00 +000081// Picks a random unsigned integer from 0 to Max (inclusive).
82size_t randomIndex(size_t Max);
83
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000084// Picks a random bit among the bits set in Vector and returns its index.
85// Precondition: Vector must have at least one bit set.
86size_t randomBit(const llvm::BitVector &Vector);
87
88// Picks a random configuration, then selects a random def and a random use from
89// it and finally set the selected values in the provided InstructionInstances.
90void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
91 InstructionTemplate &DefIB, InstructionTemplate &UseIB);
92
93// Assigns a Random Value to all Variables in IT that are still Invalid.
94// Do not use any of the registers in `ForbiddenRegs`.
Roman Lebedev404bdb12019-04-06 14:16:26 +000095void randomizeUnsetVariables(const ExegesisTarget &Target,
96 const llvm::BitVector &ForbiddenRegs,
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000097 InstructionTemplate &IT);
98
Clement Courbetd939f6d2018-09-13 07:40:53 +000099} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000100} // namespace llvm
Clement Courbetd939f6d2018-09-13 07:40:53 +0000101
102#endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H