xref: /aosp_15_r20/external/llvm/lib/Support/RandomNumberGenerator.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements deterministic random number generation (RNG).
11*9880d681SAndroid Build Coastguard Worker // The current implementation is NOT cryptographically secure as it uses
12*9880d681SAndroid Build Coastguard Worker // the C++11 <random> facilities.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/RandomNumberGenerator.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "rng"
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker // Tracking BUG: 19665
26*9880d681SAndroid Build Coastguard Worker // http://llvm.org/bugs/show_bug.cgi?id=19665
27*9880d681SAndroid Build Coastguard Worker //
28*9880d681SAndroid Build Coastguard Worker // Do not change to cl::opt<uint64_t> since this silently breaks argument parsing.
29*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned long long>
30*9880d681SAndroid Build Coastguard Worker Seed("rng-seed", cl::value_desc("seed"),
31*9880d681SAndroid Build Coastguard Worker      cl::desc("Seed for the random number generator"), cl::init(0));
32*9880d681SAndroid Build Coastguard Worker 
RandomNumberGenerator(StringRef Salt)33*9880d681SAndroid Build Coastguard Worker RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
34*9880d681SAndroid Build Coastguard Worker   DEBUG(
35*9880d681SAndroid Build Coastguard Worker     if (Seed == 0)
36*9880d681SAndroid Build Coastguard Worker       dbgs() << "Warning! Using unseeded random number generator.\n"
37*9880d681SAndroid Build Coastguard Worker   );
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker   // Combine seed and salts using std::seed_seq.
40*9880d681SAndroid Build Coastguard Worker   // Data: Seed-low, Seed-high, Salt
41*9880d681SAndroid Build Coastguard Worker   // Note: std::seed_seq can only store 32-bit values, even though we
42*9880d681SAndroid Build Coastguard Worker   // are using a 64-bit RNG. This isn't a problem since the Mersenne
43*9880d681SAndroid Build Coastguard Worker   // twister constructor copies these correctly into its initial state.
44*9880d681SAndroid Build Coastguard Worker   std::vector<uint32_t> Data;
45*9880d681SAndroid Build Coastguard Worker   Data.reserve(2 + Salt.size());
46*9880d681SAndroid Build Coastguard Worker   Data.push_back(Seed);
47*9880d681SAndroid Build Coastguard Worker   Data.push_back(Seed >> 32);
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   std::copy(Salt.begin(), Salt.end(), Data.end());
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   std::seed_seq SeedSeq(Data.begin(), Data.end());
52*9880d681SAndroid Build Coastguard Worker   Generator.seed(SeedSeq);
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker 
operator ()()55*9880d681SAndroid Build Coastguard Worker uint_fast64_t RandomNumberGenerator::operator()() {
56*9880d681SAndroid Build Coastguard Worker   return Generator();
57*9880d681SAndroid Build Coastguard Worker }
58