diff options
author | Guillaume Chatelet <gchatelet@google.com> | 2018-06-13 13:24:41 +0000 |
---|---|---|
committer | Guillaume Chatelet <gchatelet@google.com> | 2018-06-13 13:24:41 +0000 |
commit | c9f727bb85bbff4bf6f112e9887595e9928f4261 (patch) | |
tree | f2ff4104a68abfac205ddb8862573459c7b92ed0 /llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp | |
parent | 3a7654c15dd204fe3454f477fc576924e3686d0d (diff) | |
download | bcm5719-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.cpp | 125 |
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, |