1274955Ssvnmir//==- llvm/Support/RandomNumberGenerator.h - RNG for diversity ---*- C++ -*-==//
2274955Ssvnmir//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6274955Ssvnmir//
7274955Ssvnmir//===----------------------------------------------------------------------===//
8274955Ssvnmir//
9280031Sdim// This file defines an abstraction for deterministic random number
10280031Sdim// generation (RNG).  Note that the current implementation is not
11280031Sdim// cryptographically secure as it uses the C++11 <random> facilities.
12274955Ssvnmir//
13274955Ssvnmir//===----------------------------------------------------------------------===//
14274955Ssvnmir
15274955Ssvnmir#ifndef LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
16274955Ssvnmir#define LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
17274955Ssvnmir
18274955Ssvnmir#include "llvm/Support/Compiler.h"
19274955Ssvnmir#include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows.
20274955Ssvnmir#include <random>
21314564Sdim#include <system_error>
22274955Ssvnmir
23274955Ssvnmirnamespace llvm {
24309124Sdimclass StringRef;
25274955Ssvnmir
26274955Ssvnmir/// A random number generator.
27280031Sdim///
28280031Sdim/// Instances of this class should not be shared across threads. The
29280031Sdim/// seed should be set by passing the -rng-seed=<uint64> option. Use
30280031Sdim/// Module::createRNG to create a new RNG instance for use with that
31280031Sdim/// module.
32274955Ssvnmirclass RandomNumberGenerator {
33314564Sdim
34314564Sdim  // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
35314564Sdim  // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
36314564Sdim  // This RNG is deterministically portable across C++11
37314564Sdim  // implementations.
38314564Sdim  using generator_type = std::mt19937_64;
39314564Sdim
40274955Ssvnmirpublic:
41314564Sdim  using result_type = generator_type::result_type;
42314564Sdim
43274955Ssvnmir  /// Returns a random number in the range [0, Max).
44314564Sdim  result_type operator()();
45274955Ssvnmir
46314564Sdim  static constexpr result_type min() { return generator_type::min(); }
47314564Sdim  static constexpr result_type max() { return generator_type::max(); }
48314564Sdim
49274955Ssvnmirprivate:
50280031Sdim  /// Seeds and salts the underlying RNG engine.
51280031Sdim  ///
52280031Sdim  /// This constructor should not be used directly. Instead use
53280031Sdim  /// Module::createRNG to create a new RNG salted with the Module ID.
54280031Sdim  RandomNumberGenerator(StringRef Salt);
55280031Sdim
56314564Sdim  generator_type Generator;
57274955Ssvnmir
58274955Ssvnmir  // Noncopyable.
59288943Sdim  RandomNumberGenerator(const RandomNumberGenerator &other) = delete;
60288943Sdim  RandomNumberGenerator &operator=(const RandomNumberGenerator &other) = delete;
61280031Sdim
62280031Sdim  friend class Module;
63274955Ssvnmir};
64314564Sdim
65314564Sdim// Get random vector of specified size
66314564Sdimstd::error_code getRandomBytes(void *Buffer, size_t Size);
67274955Ssvnmir}
68274955Ssvnmir
69274955Ssvnmir#endif
70