Skip to content

Commit

Permalink
[llvm-exegesis][NFC] Move random functions from CodeTemplate to Snipp…
Browse files Browse the repository at this point in the history
…etGenerator.

Summary: Just moving methods around.

Reviewers: courbet

Subscribers: tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D52720

llvm-svn: 343461
  • Loading branch information
gchatelet committed Oct 1, 2018
1 parent 79c995c commit 415b2fb
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 109 deletions.
90 changes: 0 additions & 90 deletions llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ InstructionTemplate::getValueFor(const Operand &Op) const {
return getValueFor(Instr.Variables[Op.VariableIndex]);
}

// forward declaration.
static void randomize(const Instruction &Instr, const Variable &Var,
llvm::MCOperand &AssignedValue,
const llvm::BitVector &ForbiddenRegs);

bool InstructionTemplate::hasImmediateVariables() const {
return llvm::any_of(Instr.Variables, [this](const Variable &Var) {
assert(!Var.TiedOperands.empty());
Expand All @@ -76,89 +71,4 @@ llvm::MCInst InstructionTemplate::build() const {
return Result;
}

std::mt19937 &randomGenerator() {
static std::random_device RandomDevice;
static std::mt19937 RandomGenerator(RandomDevice());
return RandomGenerator;
}

static size_t randomIndex(size_t Size) {
assert(Size > 0);
std::uniform_int_distribution<> Distribution(0, Size - 1);
return Distribution(randomGenerator());
}

template <typename C>
static auto randomElement(const C &Container) -> decltype(Container[0]) {
return Container[randomIndex(Container.size())];
}

static void randomize(const Instruction &Instr, const Variable &Var,
llvm::MCOperand &AssignedValue,
const llvm::BitVector &ForbiddenRegs) {
assert(!Var.TiedOperands.empty());
const Operand &Op = Instr.Operands[Var.TiedOperands.front()];
assert(Op.Info != nullptr);
const auto &OpInfo = *Op.Info;
switch (OpInfo.OperandType) {
case llvm::MCOI::OperandType::OPERAND_IMMEDIATE:
// FIXME: explore immediate values too.
AssignedValue = llvm::MCOperand::createImm(1);
break;
case llvm::MCOI::OperandType::OPERAND_REGISTER: {
assert(Op.Tracker);
auto AllowedRegs = Op.Tracker->sourceBits();
assert(AllowedRegs.size() == ForbiddenRegs.size());
for (auto I : ForbiddenRegs.set_bits())
AllowedRegs.reset(I);
AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs));
break;
}
default:
break;
}
}

static void setRegisterOperandValue(const RegisterOperandAssignment &ROV,
InstructionTemplate &IB) {
assert(ROV.Op);
if (ROV.Op->IsExplicit) {
auto &AssignedValue = IB.getValueFor(*ROV.Op);
if (AssignedValue.isValid()) {
assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg);
return;
}
AssignedValue = llvm::MCOperand::createReg(ROV.Reg);
} else {
assert(ROV.Op->ImplicitReg != nullptr);
assert(ROV.Reg == *ROV.Op->ImplicitReg);
}
}

size_t randomBit(const llvm::BitVector &Vector) {
assert(Vector.any());
auto Itr = Vector.set_bits_begin();
for (size_t I = randomIndex(Vector.count()); I != 0; --I)
++Itr;
return *Itr;
}

void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
InstructionTemplate &DefIB, InstructionTemplate &UseIB) {
assert(!AliasingConfigurations.empty());
assert(!AliasingConfigurations.hasImplicitAliasing());
const auto &RandomConf = randomElement(AliasingConfigurations.Configurations);
setRegisterOperandValue(randomElement(RandomConf.Defs), DefIB);
setRegisterOperandValue(randomElement(RandomConf.Uses), UseIB);
}

void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
InstructionTemplate &IT) {
for (const Variable &Var : IT.Instr.Variables) {
llvm::MCOperand &AssignedValue = IT.getValueFor(Var);
if (!AssignedValue.isValid())
randomize(IT.Instr, Var, AssignedValue, ForbiddenRegs);
}
}

} // namespace exegesis
19 changes: 0 additions & 19 deletions llvm/tools/llvm-exegesis/lib/CodeTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,6 @@ struct CodeTemplate {
unsigned ScratchSpacePointerInReg = 0;
};

// A global Random Number Generator to randomize configurations.
// FIXME: Move random number generation into an object and make it seedable for
// unit tests.
std::mt19937 &randomGenerator();

// Picks a random bit among the bits set in Vector and returns its index.
// Precondition: Vector must have at least one bit set.
size_t randomBit(const llvm::BitVector &Vector);

// Picks a random configuration, then selects a random def and a random use from
// it and finally set the selected values in the provided InstructionInstances.
void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
InstructionTemplate &DefIB, InstructionTemplate &UseIB);

// Assigns a Random Value to all Variables in IT that are still Invalid.
// Do not use any of the registers in `ForbiddenRegs`.
void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
InstructionTemplate &IT);

} // namespace exegesis

#endif // LLVM_TOOLS_LLVM_EXEGESIS_CODETEMPLATE_H
85 changes: 85 additions & 0 deletions llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,89 @@ SnippetGenerator::generateUnconstrainedCodeTemplate(const Instruction &Instr,
return std::move(CT);
}

std::mt19937 &randomGenerator() {
static std::random_device RandomDevice;
static std::mt19937 RandomGenerator(RandomDevice());
return RandomGenerator;
}

static size_t randomIndex(size_t Size) {
assert(Size > 0);
std::uniform_int_distribution<> Distribution(0, Size - 1);
return Distribution(randomGenerator());
}

template <typename C>
static auto randomElement(const C &Container) -> decltype(Container[0]) {
return Container[randomIndex(Container.size())];
}

static void randomize(const Instruction &Instr, const Variable &Var,
llvm::MCOperand &AssignedValue,
const llvm::BitVector &ForbiddenRegs) {
assert(!Var.TiedOperands.empty());
const Operand &Op = Instr.Operands[Var.TiedOperands.front()];
assert(Op.Info != nullptr);
const auto &OpInfo = *Op.Info;
switch (OpInfo.OperandType) {
case llvm::MCOI::OperandType::OPERAND_IMMEDIATE:
// FIXME: explore immediate values too.
AssignedValue = llvm::MCOperand::createImm(1);
break;
case llvm::MCOI::OperandType::OPERAND_REGISTER: {
assert(Op.Tracker);
auto AllowedRegs = Op.Tracker->sourceBits();
assert(AllowedRegs.size() == ForbiddenRegs.size());
for (auto I : ForbiddenRegs.set_bits())
AllowedRegs.reset(I);
AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs));
break;
}
default:
break;
}
}

static void setRegisterOperandValue(const RegisterOperandAssignment &ROV,
InstructionTemplate &IB) {
assert(ROV.Op);
if (ROV.Op->IsExplicit) {
auto &AssignedValue = IB.getValueFor(*ROV.Op);
if (AssignedValue.isValid()) {
assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg);
return;
}
AssignedValue = llvm::MCOperand::createReg(ROV.Reg);
} else {
assert(ROV.Op->ImplicitReg != nullptr);
assert(ROV.Reg == *ROV.Op->ImplicitReg);
}
}

size_t randomBit(const llvm::BitVector &Vector) {
assert(Vector.any());
auto Itr = Vector.set_bits_begin();
for (size_t I = randomIndex(Vector.count()); I != 0; --I)
++Itr;
return *Itr;
}

void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
InstructionTemplate &DefIB, InstructionTemplate &UseIB) {
assert(!AliasingConfigurations.empty());
assert(!AliasingConfigurations.hasImplicitAliasing());
const auto &RandomConf = randomElement(AliasingConfigurations.Configurations);
setRegisterOperandValue(randomElement(RandomConf.Defs), DefIB);
setRegisterOperandValue(randomElement(RandomConf.Uses), UseIB);
}

void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
InstructionTemplate &IT) {
for (const Variable &Var : IT.Instr.Variables) {
llvm::MCOperand &AssignedValue = IT.getValueFor(Var);
if (!AssignedValue.isValid())
randomize(IT.Instr, Var, AssignedValue, ForbiddenRegs);
}
}

} // namespace exegesis
19 changes: 19 additions & 0 deletions llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ class SnippetGenerator {
generateCodeTemplate(unsigned Opcode) const = 0;
};

// A global Random Number Generator to randomize configurations.
// FIXME: Move random number generation into an object and make it seedable for
// unit tests.
std::mt19937 &randomGenerator();

// Picks a random bit among the bits set in Vector and returns its index.
// Precondition: Vector must have at least one bit set.
size_t randomBit(const llvm::BitVector &Vector);

// Picks a random configuration, then selects a random def and a random use from
// it and finally set the selected values in the provided InstructionInstances.
void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
InstructionTemplate &DefIB, InstructionTemplate &UseIB);

// Assigns a Random Value to all Variables in IT that are still Invalid.
// Do not use any of the registers in `ForbiddenRegs`.
void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
InstructionTemplate &IT);

} // namespace exegesis

#endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H

0 comments on commit 415b2fb

Please sign in to comment.