mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-05 10:57:32 +00:00
[llvm-exegesis][NFC] Move random functions from CodeTemplate to SnippetGenerator.
Summary: Just moving methods around. Reviewers: courbet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D52720 llvm-svn: 343461
This commit is contained in:
parent
d5feb48889
commit
9743b1edae
@ -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());
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -70,6 +70,25 @@ private:
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user