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