1274955Ssvnmir//===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===// 2274955Ssvnmir// 3274955Ssvnmir// The LLVM Compiler Infrastructure 4274955Ssvnmir// 5274955Ssvnmir// This file is distributed under the University of Illinois Open Source 6274955Ssvnmir// License. See LICENSE.TXT for details. 7274955Ssvnmir// 8274955Ssvnmir//===----------------------------------------------------------------------===// 9274955Ssvnmir// 10280031Sdim// This file implements deterministic random number generation (RNG). 11274955Ssvnmir// The current implementation is NOT cryptographically secure as it uses 12274955Ssvnmir// the C++11 <random> facilities. 13274955Ssvnmir// 14274955Ssvnmir//===----------------------------------------------------------------------===// 15274955Ssvnmir 16288943Sdim#include "llvm/Support/RandomNumberGenerator.h" 17274955Ssvnmir#include "llvm/Support/CommandLine.h" 18274955Ssvnmir#include "llvm/Support/Debug.h" 19288943Sdim#include "llvm/Support/raw_ostream.h" 20274955Ssvnmir 21274955Ssvnmirusing namespace llvm; 22274955Ssvnmir 23288943Sdim#define DEBUG_TYPE "rng" 24288943Sdim 25274955Ssvnmir// Tracking BUG: 19665 26274955Ssvnmir// http://llvm.org/bugs/show_bug.cgi?id=19665 27274955Ssvnmir// 28274955Ssvnmir// Do not change to cl::opt<uint64_t> since this silently breaks argument parsing. 29274955Ssvnmirstatic cl::opt<unsigned long long> 30274955SsvnmirSeed("rng-seed", cl::value_desc("seed"), 31274955Ssvnmir cl::desc("Seed for the random number generator"), cl::init(0)); 32274955Ssvnmir 33274955SsvnmirRandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { 34274955Ssvnmir DEBUG( 35274955Ssvnmir if (Seed == 0) 36280031Sdim dbgs() << "Warning! Using unseeded random number generator.\n" 37274955Ssvnmir ); 38274955Ssvnmir 39280031Sdim // Combine seed and salts using std::seed_seq. 40280031Sdim // Data: Seed-low, Seed-high, Salt 41280031Sdim // Note: std::seed_seq can only store 32-bit values, even though we 42280031Sdim // are using a 64-bit RNG. This isn't a problem since the Mersenne 43280031Sdim // twister constructor copies these correctly into its initial state. 44274955Ssvnmir std::vector<uint32_t> Data; 45280031Sdim Data.reserve(2 + Salt.size()); 46274955Ssvnmir Data.push_back(Seed); 47274955Ssvnmir Data.push_back(Seed >> 32); 48274955Ssvnmir 49280031Sdim std::copy(Salt.begin(), Salt.end(), Data.end()); 50274955Ssvnmir 51274955Ssvnmir std::seed_seq SeedSeq(Data.begin(), Data.end()); 52274955Ssvnmir Generator.seed(SeedSeq); 53274955Ssvnmir} 54274955Ssvnmir 55280031Sdimuint_fast64_t RandomNumberGenerator::operator()() { 56280031Sdim return Generator(); 57274955Ssvnmir} 58