//===- 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