summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
diff options
context:
space:
mode:
authorGuillaume Chatelet <gchatelet@google.com>2018-06-13 13:24:41 +0000
committerGuillaume Chatelet <gchatelet@google.com>2018-06-13 13:24:41 +0000
commitc9f727bb85bbff4bf6f112e9887595e9928f4261 (patch)
treef2ff4104a68abfac205ddb8862573459c7b92ed0 /llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
parent3a7654c15dd204fe3454f477fc576924e3686d0d (diff)
downloadbcm5719-llvm-c9f727bb85bbff4bf6f112e9887595e9928f4261.tar.gz
bcm5719-llvm-c9f727bb85bbff4bf6f112e9887595e9928f4261.zip
[llvm-exegesis] Cleaner design without mutable data.
Summary: Previous design was relying on the 'mutate' keyword and was quite confusing. This version separate mutable from immutable data and makes it clearer what changes and what doesn't. Reviewers: courbet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D48020 llvm-svn: 334596
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp125
1 files changed, 61 insertions, 64 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 268136e9e6a..c57696979d5 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -17,14 +17,8 @@
namespace exegesis {
-static void tie(const Operand *FromOperand, llvm::Optional<Variable> &Var) {
- if (!Var)
- Var.emplace();
- Var->TiedOperands.push_back(FromOperand);
-}
-
Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
- RegisterAliasingTrackerCache &RATC)
+ const RegisterAliasingTrackerCache &RATC)
: Description(MCInstrDesc) {
unsigned OpIndex = 0;
for (; OpIndex < MCInstrDesc.getNumOperands(); ++OpIndex) {
@@ -36,6 +30,8 @@ Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
// TODO(gchatelet): Handle isLookupPtrRegClass.
if (OpInfo.RegClass >= 0)
Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass);
+ Operand.TiedToIndex =
+ MCInstrDesc.getOperandConstraint(OpIndex, llvm::MCOI::TIED_TO);
Operand.Info = &OpInfo;
Operands.push_back(Operand);
}
@@ -59,24 +55,23 @@ Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
Operand.ImplicitReg = MCPhysReg;
Operands.push_back(Operand);
}
- // Set TiedTo for operands.
- for (auto &Op : Operands) {
- if (Op.IsExplicit) {
- const int TiedTo =
- MCInstrDesc.getOperandConstraint(Op.Index, llvm::MCOI::TIED_TO);
- if (TiedTo >= 0) {
- Op.TiedTo = &Operands[TiedTo];
- tie(&Op, Operands[TiedTo].Var);
- } else {
- tie(&Op, Op.Var);
- }
- }
- }
- for (auto &Op : Operands) {
- if (Op.Var) {
- Variables.push_back(&*Op.Var);
+ // Assigning Variables to non tied explicit operands.
+ Variables.reserve(Operands.size()); // Variables.size() <= Operands.size()
+ for (auto &Op : Operands)
+ if (Op.IsExplicit && Op.TiedToIndex < 0) {
+ const size_t VariableIndex = Variables.size();
+ Op.VariableIndex = VariableIndex;
+ Variables.emplace_back();
+ Variables.back().Index = VariableIndex;
}
- }
+ // Assigning Variables to tied operands.
+ for (auto &Op : Operands)
+ if (Op.TiedToIndex >= 0)
+ Op.VariableIndex = Operands[Op.TiedToIndex].VariableIndex;
+ // Assigning Operands to Variables.
+ for (auto &Op : Operands)
+ if (Op.VariableIndex >= 0)
+ Variables[Op.VariableIndex].TiedOperands.push_back(&Op);
// Processing Aliasing.
DefRegisters = RATC.emptyRegisters();
UseRegisters = RATC.emptyRegisters();
@@ -88,6 +83,35 @@ Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
}
}
+InstructionInstance::InstructionInstance(const Instruction &Instr)
+ : Instr(Instr), VariableValues(Instr.Variables.size()) {}
+
+llvm::MCOperand &InstructionInstance::getValueFor(const Variable &Var) {
+ return VariableValues[Var.Index];
+}
+
+llvm::MCOperand &InstructionInstance::getValueFor(const Operand &Op) {
+ assert(Op.VariableIndex >= 0);
+ return getValueFor(Instr.Variables[Op.VariableIndex]);
+}
+
+// forward declaration.
+static void randomize(const Variable &Var, llvm::MCOperand &AssignedValue);
+
+llvm::MCInst InstructionInstance::randomizeUnsetVariablesAndBuild() {
+ for (const Variable &Var : Instr.Variables) {
+ llvm::MCOperand &AssignedValue = getValueFor(Var);
+ if (!AssignedValue.isValid())
+ randomize(Var, AssignedValue);
+ }
+ llvm::MCInst Result;
+ Result.setOpcode(Instr.Description.Opcode);
+ for (const auto &Op : Instr.Operands)
+ if (Op.IsExplicit)
+ Result.addOperand(getValueFor(Op));
+ return Result;
+}
+
bool RegisterOperandAssignment::
operator==(const RegisterOperandAssignment &Other) const {
return std::tie(Op, Reg) == std::tie(Other.Op, Other.Reg);
@@ -159,7 +183,7 @@ static auto randomElement(const C &Container) -> decltype(Container[0]) {
return Container[randomIndex(Container.size())];
}
-static void randomize(Variable &Var) {
+static void randomize(const Variable &Var, llvm::MCOperand &AssignedValue) {
assert(!Var.TiedOperands.empty());
assert(Var.TiedOperands.front() != nullptr);
const Operand &Op = *Var.TiedOperands.front();
@@ -168,12 +192,12 @@ static void randomize(Variable &Var) {
switch (OpInfo.OperandType) {
case llvm::MCOI::OperandType::OPERAND_IMMEDIATE:
// FIXME: explore immediate values too.
- Var.AssignedValue = llvm::MCOperand::createImm(1);
+ AssignedValue = llvm::MCOperand::createImm(1);
break;
case llvm::MCOI::OperandType::OPERAND_REGISTER: {
assert(Op.Tracker);
const auto &Registers = Op.Tracker->sourceBits();
- Var.AssignedValue = llvm::MCOperand::createReg(randomBit(Registers));
+ AssignedValue = llvm::MCOperand::createReg(randomBit(Registers));
break;
}
default:
@@ -181,15 +205,16 @@ static void randomize(Variable &Var) {
}
}
-static void setRegisterOperandValue(const RegisterOperandAssignment &ROV) {
- const Operand *Op = ROV.Op->TiedTo ? ROV.Op->TiedTo : ROV.Op;
- assert(Op->Var);
- auto &AssignedValue = Op->Var->AssignedValue;
+static void setRegisterOperandValue(const RegisterOperandAssignment &ROV,
+ InstructionInstance &II) {
+ assert(ROV.Op);
+ assert(ROV.Op->IsExplicit);
+ auto &AssignedValue = II.getValueFor(*ROV.Op);
if (AssignedValue.isValid()) {
assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg);
return;
}
- Op->Var->AssignedValue = llvm::MCOperand::createReg(ROV.Reg);
+ AssignedValue = llvm::MCOperand::createReg(ROV.Reg);
}
size_t randomBit(const llvm::BitVector &Vector) {
@@ -200,41 +225,13 @@ size_t randomBit(const llvm::BitVector &Vector) {
return *Itr;
}
-void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations) {
+void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
+ InstructionInstance &DefII, InstructionInstance &UseII) {
assert(!AliasingConfigurations.empty());
assert(!AliasingConfigurations.hasImplicitAliasing());
const auto &RandomConf = randomElement(AliasingConfigurations.Configurations);
- setRegisterOperandValue(randomElement(RandomConf.Defs));
- setRegisterOperandValue(randomElement(RandomConf.Uses));
-}
-
-void randomizeUnsetVariable(const Instruction &Instruction) {
- for (auto *Var : Instruction.Variables)
- if (!Var->AssignedValue.isValid())
- randomize(*Var);
-}
-
-void clearVariableAssignments(const Instruction &Instruction) {
- for (auto *Var : Instruction.Variables)
- Var->AssignedValue = llvm::MCOperand();
-}
-
-llvm::MCInst build(const Instruction &Instruction) {
- llvm::MCInst Result;
- Result.setOpcode(Instruction.Description.Opcode);
- for (const auto &Op : Instruction.Operands) {
- if (Op.IsExplicit) {
- auto &Var = Op.TiedTo ? Op.TiedTo->Var : Op.Var;
- assert(Var);
- Result.addOperand(Var->AssignedValue);
- }
- }
- return Result;
-}
-
-llvm::MCInst randomizeUnsetVariablesAndBuild(const Instruction &Instruction) {
- randomizeUnsetVariable(Instruction);
- return build(Instruction);
+ setRegisterOperandValue(randomElement(RandomConf.Defs), DefII);
+ setRegisterOperandValue(randomElement(RandomConf.Uses), UseII);
}
void DumpMCOperand(const llvm::MCRegisterInfo &MCRegisterInfo,
OpenPOWER on IntegriCloud