annotate tools/llvm-exegesis/lib/Uops.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===-- Uops.cpp ------------------------------------------------*- C++ -*-===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include "Uops.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 #include "Assembler.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 #include "BenchmarkRunner.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 #include "MCInstrDescView.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #include "Target.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 // FIXME: Load constants into registers (e.g. with fld1) to not break
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 // instructions like x87.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 // Ideally we would like the only limitation on executing uops to be the issue
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 // ports. Maximizing port pressure increases the likelihood that the load is
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 // distributed evenly across possible ports.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 // To achieve that, one approach is to generate instructions that do not have
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 // data dependencies between them.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 // For some instructions, this is trivial:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 // mov rax, qword ptr [rsi]
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 // mov rax, qword ptr [rsi]
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 // mov rax, qword ptr [rsi]
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 // mov rax, qword ptr [rsi]
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 // For the above snippet, haswell just renames rax four times and executes the
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 // four instructions two at a time on P23 and P0126.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 // For some instructions, we just need to make sure that the source is
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 // different from the destination. For example, IDIV8r reads from GPR and
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 // writes to AX. We just need to ensure that the Var is assigned a
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 // register which is different from AX:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 // idiv bx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 // idiv bx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 // idiv bx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 // idiv bx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 // The above snippet will be able to fully saturate the ports, while the same
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 // with ax would issue one uop every `latency(IDIV8r)` cycles.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 // Some instructions make this harder because they both read and write from
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 // the same register:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 // inc rax
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 // inc rax
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 // inc rax
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 // inc rax
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 // This has a data dependency from each instruction to the next, limit the
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 // number of instructions that can be issued in parallel.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 // It turns out that this is not a big issue on recent Intel CPUs because they
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 // have heuristics to balance port pressure. In the snippet above, subsequent
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 // instructions will end up evenly distributed on {P0,P1,P5,P6}, but some CPUs
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 // might end up executing them all on P0 (just because they can), or try
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 // avoiding P5 because it's usually under high pressure from vector
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 // instructions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 // This issue is even more important for high-latency instructions because
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 // they increase the idle time of the CPU, e.g. :
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 // imul rax, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 // imul rax, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 // imul rax, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 // imul rax, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 // To avoid that, we do the renaming statically by generating as many
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 // independent exclusive assignments as possible (until all possible registers
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 // are exhausted) e.g.:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 // imul rax, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 // imul rcx, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 // imul rdx, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 // imul r8, rbx
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 // Some instruction even make the above static renaming impossible because
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 // they implicitly read and write from the same operand, e.g. ADC16rr reads
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 // and writes from EFLAGS.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 // In that case we just use a greedy register assignment and hope for the
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 // best.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 namespace llvm {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 namespace exegesis {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 static llvm::SmallVector<const Variable *, 8>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 getVariablesWithTiedOperands(const Instruction &Instr) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 llvm::SmallVector<const Variable *, 8> Result;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 for (const auto &Var : Instr.Variables)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 if (Var.hasTiedOperands())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 Result.push_back(&Var);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 return Result;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 static void remove(llvm::BitVector &a, const llvm::BitVector &b) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 assert(a.size() == b.size());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 for (auto I : b.set_bits())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 a.reset(I);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 UopsSnippetGenerator::~UopsSnippetGenerator() = default;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 void UopsSnippetGenerator::instantiateMemoryOperands(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 const unsigned ScratchSpacePointerInReg,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 std::vector<InstructionTemplate> &Instructions) const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 if (ScratchSpacePointerInReg == 0)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 return; // no memory operands.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 const auto &ET = State.getExegesisTarget();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 const unsigned MemStep = ET.getMaxMemoryAccessSize();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 const size_t OriginalInstructionsSize = Instructions.size();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 size_t I = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 for (InstructionTemplate &IT : Instructions) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 ET.fillMemoryOperands(IT, ScratchSpacePointerInReg, I * MemStep);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 ++I;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 while (Instructions.size() < kMinNumDifferentAddresses) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 InstructionTemplate IT = Instructions[I % OriginalInstructionsSize];
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 ET.fillMemoryOperands(IT, ScratchSpacePointerInReg, I * MemStep);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 ++I;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 Instructions.push_back(std::move(IT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 assert(I * MemStep < BenchmarkRunner::ScratchSpace::kSize &&
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 "not enough scratch space");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 static std::vector<InstructionTemplate> generateSnippetUsingStaticRenaming(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 const LLVMState &State, const InstructionTemplate &IT,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 const ArrayRef<const Variable *> TiedVariables,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 const BitVector *ScratchSpaceAliasedRegs) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 std::vector<InstructionTemplate> Instructions;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 // Assign registers to variables in a round-robin manner. This is simple but
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 // ensures that the most register-constrained variable does not get starved.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 std::vector<BitVector> PossibleRegsForVar;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 for (const Variable *Var : TiedVariables) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 assert(Var);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 const Operand &Op = IT.Instr.getPrimaryOperand(*Var);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 assert(Op.isReg());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 BitVector PossibleRegs = State.getRATC().emptyRegisters();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 if (ScratchSpaceAliasedRegs) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 PossibleRegs |= *ScratchSpaceAliasedRegs;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 PossibleRegs.flip();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 PossibleRegs &= Op.getRegisterAliasing().sourceBits();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 PossibleRegsForVar.push_back(std::move(PossibleRegs));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 SmallVector<int, 2> Iterators(TiedVariables.size(), 0);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 while (true) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 InstructionTemplate TmpIT = IT;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 // Find a possible register for each variable in turn, marking the
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 // register as taken.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 for (size_t VarId = 0; VarId < TiedVariables.size(); ++VarId) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 const int NextPossibleReg =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 PossibleRegsForVar[VarId].find_next(Iterators[VarId]);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 if (NextPossibleReg <= 0) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 return Instructions;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 TmpIT.getValueFor(*TiedVariables[VarId]) =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 llvm::MCOperand::createReg(NextPossibleReg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 // Bump iterator.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 Iterators[VarId] = NextPossibleReg;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 // Prevent other variables from using the register.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 for (BitVector &OtherPossibleRegs : PossibleRegsForVar) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 OtherPossibleRegs.reset(NextPossibleReg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 Instructions.push_back(std::move(TmpIT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 llvm::Expected<std::vector<CodeTemplate>>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 UopsSnippetGenerator::generateCodeTemplates(const Instruction &Instr) const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 CodeTemplate CT;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 if (Instr.hasMemoryOperands()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 const auto &ET = State.getExegesisTarget();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 CT.ScratchSpacePointerInReg =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 if (CT.ScratchSpacePointerInReg == 0)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 return llvm::make_error<BenchmarkFailure>(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 "Infeasible : target does not support memory instructions");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 ScratchSpaceAliasedRegs =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 &State.getRATC().getRegister(CT.ScratchSpacePointerInReg).aliasedBits();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 // If the instruction implicitly writes to ScratchSpacePointerInReg , abort.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 // FIXME: We could make a copy of the scratch register.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 for (const auto &Op : Instr.Operands) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 if (Op.isDef() && Op.isImplicitReg() &&
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 ScratchSpaceAliasedRegs->test(Op.getImplicitReg()))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 return llvm::make_error<BenchmarkFailure>(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 "Infeasible : memory instruction uses scratch memory register");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 const AliasingConfigurations SelfAliasing(Instr, Instr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 InstructionTemplate IT(Instr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 if (SelfAliasing.empty()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 CT.Info = "instruction is parallel, repeating a random one.";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 CT.Instructions.push_back(std::move(IT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 return getSingleton(std::move(CT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 if (SelfAliasing.hasImplicitAliasing()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 CT.Info = "instruction is serial, repeating a random one.";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 CT.Instructions.push_back(std::move(IT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 return getSingleton(std::move(CT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 const auto TiedVariables = getVariablesWithTiedOperands(Instr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 if (!TiedVariables.empty()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 CT.Info = "instruction has tied variables, using static renaming.";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 CT.Instructions = generateSnippetUsingStaticRenaming(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 State, IT, TiedVariables, ScratchSpaceAliasedRegs);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 return getSingleton(std::move(CT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 const auto &ReservedRegisters = State.getRATC().reservedRegisters();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 // No tied variables, we pick random values for defs.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 llvm::BitVector Defs(State.getRegInfo().getNumRegs());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 for (const auto &Op : Instr.Operands) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 if (Op.isReg() && Op.isExplicit() && Op.isDef() && !Op.isMemory()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 remove(PossibleRegisters, ReservedRegisters);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 // Do not use the scratch memory address register.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 if (ScratchSpaceAliasedRegs)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 assert(PossibleRegisters.any() && "No register left to choose from");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 const auto RandomReg = randomBit(PossibleRegisters);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 Defs.set(RandomReg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 IT.getValueFor(Op) = llvm::MCOperand::createReg(RandomReg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 // And pick random use values that are not reserved and don't alias with defs.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 const auto DefAliases = getAliasedBits(State.getRegInfo(), Defs);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 for (const auto &Op : Instr.Operands) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 if (Op.isReg() && Op.isExplicit() && Op.isUse() && !Op.isMemory()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 remove(PossibleRegisters, ReservedRegisters);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 // Do not use the scratch memory address register.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 if (ScratchSpaceAliasedRegs)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 remove(PossibleRegisters, DefAliases);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 assert(PossibleRegisters.any() && "No register left to choose from");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 const auto RandomReg = randomBit(PossibleRegisters);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 IT.getValueFor(Op) = llvm::MCOperand::createReg(RandomReg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 CT.Info =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 "instruction has no tied variables picking Uses different from defs";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 CT.Instructions.push_back(std::move(IT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 return getSingleton(std::move(CT));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 llvm::Expected<std::vector<BenchmarkMeasure>>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 UopsBenchmarkRunner::runMeasurements(const FunctionExecutor &Executor) const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 std::vector<BenchmarkMeasure> Result;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 const PfmCountersInfo &PCI = State.getPfmCounters();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 // Uops per port.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 for (const auto *IssueCounter = PCI.IssueCounters,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 *IssueCounterEnd = PCI.IssueCounters + PCI.NumIssueCounters;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 IssueCounter != IssueCounterEnd; ++IssueCounter) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 if (!IssueCounter->Counter)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 continue;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 auto ExpectedCounterValue = Executor.runAndMeasure(IssueCounter->Counter);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 if (!ExpectedCounterValue)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 return ExpectedCounterValue.takeError();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 Result.push_back(BenchmarkMeasure::Create(IssueCounter->ProcResName,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 *ExpectedCounterValue));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 // NumMicroOps.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 if (const char *const UopsCounter = PCI.UopsCounter) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 auto ExpectedCounterValue = Executor.runAndMeasure(UopsCounter);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 if (!ExpectedCounterValue)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 return ExpectedCounterValue.takeError();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 Result.push_back(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 BenchmarkMeasure::Create("NumMicroOps", *ExpectedCounterValue));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 return std::move(Result);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
279
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 constexpr const size_t UopsSnippetGenerator::kMinNumDifferentAddresses;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 } // namespace exegesis
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 } // namespace llvm