blob: 7e7f6e487e18d03f55e1eb2cd5ed6bd1af9de440 [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.
Clement Courbet50cdd562019-10-09 11:58:42 +000036Expected<std::vector<CodeTemplate>>
Guillaume Chatelet296a8622018-10-15 09:09:19 +000037generateSelfAliasingCodeTemplates(const Instruction &Instr);
38
39// Generates code templates without assignment constraints.
Clement Courbet50cdd562019-10-09 11:58:42 +000040Expected<std::vector<CodeTemplate>>
41generateUnconstrainedCodeTemplates(const Instruction &Instr, StringRef Msg);
Guillaume Chatelet296a8622018-10-15 09:09:19 +000042
Clement Courbetd939f6d2018-09-13 07:40:53 +000043// A class representing failures that happened during Benchmark, they are used
44// to report informations to the user.
Clement Courbet50cdd562019-10-09 11:58:42 +000045class SnippetGeneratorFailure : public StringError {
Clement Courbetd939f6d2018-09-13 07:40:53 +000046public:
Clement Courbet50cdd562019-10-09 11:58:42 +000047 SnippetGeneratorFailure(const Twine &S);
Clement Courbetd939f6d2018-09-13 07:40:53 +000048};
49
50// Common code for all benchmark modes.
51class SnippetGenerator {
52public:
Clement Courbet2cd0f282019-10-08 14:30:24 +000053 struct Options {
54 unsigned MaxConfigsPerOpcode = 1;
55 };
56
57 explicit SnippetGenerator(const LLVMState &State, const Options &Opts);
Clement Courbetd939f6d2018-09-13 07:40:53 +000058
59 virtual ~SnippetGenerator();
60
61 // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
Clement Courbet50cdd562019-10-09 11:58:42 +000062 Expected<std::vector<BenchmarkCode>>
Clement Courbet9431b722019-09-27 12:56:24 +000063 generateConfigurations(const Instruction &Instr,
Clement Courbet50cdd562019-10-09 11:58:42 +000064 const BitVector &ExtraForbiddenRegs) const;
Clement Courbetd939f6d2018-09-13 07:40:53 +000065
66 // Given a snippet, computes which registers the setup code needs to define.
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000067 std::vector<RegisterValue> computeRegisterInitialValues(
Guillaume Chatelet70ac0192018-09-27 09:23:04 +000068 const std::vector<InstructionTemplate> &Snippet) const;
Clement Courbetd939f6d2018-09-13 07:40:53 +000069
70protected:
71 const LLVMState &State;
Clement Courbet2cd0f282019-10-08 14:30:24 +000072 const Options Opts;
Clement Courbetd939f6d2018-09-13 07:40:53 +000073
Clement Courbetd939f6d2018-09-13 07:40:53 +000074private:
75 // API to be implemented by subclasses.
Clement Courbet50cdd562019-10-09 11:58:42 +000076 virtual Expected<std::vector<CodeTemplate>>
Clement Courbet8ef97e12019-09-27 08:04:10 +000077 generateCodeTemplates(const Instruction &Instr,
78 const BitVector &ForbiddenRegisters) const = 0;
Clement Courbetd939f6d2018-09-13 07:40:53 +000079};
80
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000081// A global Random Number Generator to randomize configurations.
82// FIXME: Move random number generation into an object and make it seedable for
83// unit tests.
84std::mt19937 &randomGenerator();
85
Roman Lebedeva8223582019-04-08 10:11:00 +000086// Picks a random unsigned integer from 0 to Max (inclusive).
87size_t randomIndex(size_t Max);
88
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000089// Picks a random bit among the bits set in Vector and returns its index.
90// Precondition: Vector must have at least one bit set.
Clement Courbet50cdd562019-10-09 11:58:42 +000091size_t randomBit(const BitVector &Vector);
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +000092
93// Picks a random configuration, then selects a random def and a random use from
94// it and finally set the selected values in the provided InstructionInstances.
95void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
96 InstructionTemplate &DefIB, InstructionTemplate &UseIB);
97
98// Assigns a Random Value to all Variables in IT that are still Invalid.
99// Do not use any of the registers in `ForbiddenRegs`.
Clement Courbet04fd2042020-01-22 15:49:10 +0100100Error randomizeUnsetVariables(const LLVMState &State,
101 const BitVector &ForbiddenRegs,
102 InstructionTemplate &IT);
Guillaume Chatelet415b2fb2018-10-01 12:19:10 +0000103
Clement Courbetd939f6d2018-09-13 07:40:53 +0000104} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000105} // namespace llvm
Clement Courbetd939f6d2018-09-13 07:40:53 +0000106
107#endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H