diff options
| author | Clement Courbet <courbet@google.com> | 2019-02-26 10:54:45 +0000 |
|---|---|---|
| committer | Clement Courbet <courbet@google.com> | 2019-02-26 10:54:45 +0000 |
| commit | 0ddf81c43d6f1503c205dde9596d9291997c08c7 (patch) | |
| tree | 64bcaff81dd2b311c5e35c90f4906fa249c077b1 /llvm/tools/llvm-exegesis/lib/Uops.cpp | |
| parent | 4f7bc0eee7e6099b1abd57dac3c83529944ab23c (diff) | |
| download | bcm5719-llvm-0ddf81c43d6f1503c205dde9596d9291997c08c7.tar.gz bcm5719-llvm-0ddf81c43d6f1503c205dde9596d9291997c08c7.zip | |
[llvm-exegesis] Teach llvm-exegesis to handle instructions with multiple tied variables.
Reviewers: gchatelet
Subscribers: tschuett, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58285
llvm-svn: 354862
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/Uops.cpp')
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/Uops.cpp | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp index 055bcdf06a5..8fc8fd278d4 100644 --- a/llvm/tools/llvm-exegesis/lib/Uops.cpp +++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp @@ -123,6 +123,50 @@ void UopsSnippetGenerator::instantiateMemoryOperands( "not enough scratch space"); } +static std::vector<InstructionTemplate> generateSnippetUsingStaticRenaming( + const LLVMState &State, const InstructionTemplate &IT, + const ArrayRef<const Variable *> TiedVariables, + const BitVector *ScratchSpaceAliasedRegs) { + std::vector<InstructionTemplate> Instructions; + // Assign registers to variables in a round-robin manner. This is simple but + // ensures that the most register-constrained variable does not get starved. + std::vector<BitVector> PossibleRegsForVar; + for (const Variable *Var : TiedVariables) { + assert(Var); + const Operand &Op = IT.Instr.getPrimaryOperand(*Var); + assert(Op.isReg()); + BitVector PossibleRegs = State.getRATC().emptyRegisters(); + if (ScratchSpaceAliasedRegs) { + PossibleRegs |= *ScratchSpaceAliasedRegs; + } + PossibleRegs.flip(); + PossibleRegs &= Op.getRegisterAliasing().sourceBits(); + PossibleRegsForVar.push_back(std::move(PossibleRegs)); + } + SmallVector<int, 2> Iterators(TiedVariables.size(), 0); + while (true) { + InstructionTemplate TmpIT = IT; + // Find a possible register for each variable in turn, marking the + // register as taken. + for (size_t VarId = 0; VarId < TiedVariables.size(); ++VarId) { + const int NextPossibleReg = + PossibleRegsForVar[VarId].find_next(Iterators[VarId]); + if (NextPossibleReg <= 0) { + return Instructions; + } + TmpIT.getValueFor(*TiedVariables[VarId]) = + llvm::MCOperand::createReg(NextPossibleReg); + // Bump iterator. + Iterators[VarId] = NextPossibleReg; + // Prevent other variables from using the register. + for (BitVector &OtherPossibleRegs : PossibleRegsForVar) { + OtherPossibleRegs.reset(NextPossibleReg); + } + } + Instructions.push_back(std::move(TmpIT)); + } +} + llvm::Expected<std::vector<CodeTemplate>> UopsSnippetGenerator::generateCodeTemplates(const Instruction &Instr) const { CodeTemplate CT; @@ -162,23 +206,9 @@ UopsSnippetGenerator::generateCodeTemplates(const Instruction &Instr) const { } const auto TiedVariables = getVariablesWithTiedOperands(Instr); if (!TiedVariables.empty()) { - if (TiedVariables.size() > 1) - return llvm::make_error<llvm::StringError>( - "Infeasible : don't know how to handle several tied variables", - llvm::inconvertibleErrorCode()); - const Variable *Var = TiedVariables.front(); - assert(Var); - const Operand &Op = Instr.getPrimaryOperand(*Var); - assert(Op.isReg()); - CT.Info = "instruction has tied variables using static renaming."; - for (const llvm::MCPhysReg Reg : - Op.getRegisterAliasing().sourceBits().set_bits()) { - if (ScratchSpaceAliasedRegs && ScratchSpaceAliasedRegs->test(Reg)) - continue; // Do not use the scratch memory address register. - InstructionTemplate TmpIT = IT; - TmpIT.getValueFor(*Var) = llvm::MCOperand::createReg(Reg); - CT.Instructions.push_back(std::move(TmpIT)); - } + CT.Info = "instruction has tied variables, using static renaming."; + CT.Instructions = generateSnippetUsingStaticRenaming( + State, IT, TiedVariables, ScratchSpaceAliasedRegs); instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return getSingleton(std::move(CT)); } |

