|  | //===- subzero/src/IceRNG.cpp - PRNG implementation -----------------------===// | 
|  | // | 
|  | //                        The Subzero Code Generator | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | /// | 
|  | /// \file | 
|  | /// \brief Implements the random number generator. | 
|  | /// | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "IceRNG.h" | 
|  |  | 
|  | #include <climits> | 
|  | #include <ctime> | 
|  |  | 
|  | namespace Ice { | 
|  |  | 
|  | namespace { | 
|  | constexpr unsigned MAX = 2147483647; | 
|  | } // end of anonymous namespace | 
|  |  | 
|  | // TODO(wala,stichnot): Switch to RNG implementation from LLVM or C++11. | 
|  | // | 
|  | // TODO(wala,stichnot): Make it possible to replay the RNG sequence in a | 
|  | // subsequent run, for reproducing a bug. Print the seed in a comment in the | 
|  | // asm output. Embed the seed in the binary via metadata that an attacker can't | 
|  | // introspect. | 
|  | RandomNumberGenerator::RandomNumberGenerator(uint64_t Seed, llvm::StringRef) | 
|  | : State(Seed) {} | 
|  |  | 
|  | RandomNumberGenerator::RandomNumberGenerator( | 
|  | uint64_t Seed, RandomizationPassesEnum RandomizationPassID, uint64_t Salt) { | 
|  | constexpr unsigned NumBitsGlobalSeed = CHAR_BIT * sizeof(State); | 
|  | constexpr unsigned NumBitsPassID = 4; | 
|  | constexpr unsigned NumBitsSalt = 12; | 
|  | static_assert(RPE_num < (1 << NumBitsPassID), "NumBitsPassID too small"); | 
|  | State = Seed ^ ((uint64_t)RandomizationPassID | 
|  | << (NumBitsGlobalSeed - NumBitsPassID)) ^ | 
|  | (Salt << (NumBitsGlobalSeed - NumBitsPassID - NumBitsSalt)); | 
|  | } | 
|  | uint64_t RandomNumberGenerator::next(uint64_t Max) { | 
|  | // Lewis, Goodman, and Miller (1969) | 
|  | State = (16807 * State) % MAX; | 
|  | return State % Max; | 
|  | } | 
|  |  | 
|  | bool RandomNumberGeneratorWrapper::getTrueWithProbability(float Probability) { | 
|  | return RNG.next(MAX) < Probability * MAX; | 
|  | } | 
|  |  | 
|  | } // end of namespace Ice |