1 //===-- SnippetRepetitor.cpp ------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 #include "SnippetRepetitor.h"
14 #include "llvm/CodeGen/TargetInstrInfo.h"
15 #include "llvm/CodeGen/TargetSubtargetInfo.h"
21 class DuplicateSnippetRepetitor
: public SnippetRepetitor
{
23 using SnippetRepetitor::SnippetRepetitor
;
25 // Repeats the snippet until there are at least MinInstructions in the
27 FillFunction
Repeat(ArrayRef
<MCInst
> Instructions
,
28 unsigned MinInstructions
) const override
{
29 return [Instructions
, MinInstructions
](FunctionFiller
&Filler
) {
30 auto Entry
= Filler
.getEntry();
31 if (!Instructions
.empty()) {
32 // Add the whole snippet at least once.
33 Entry
.addInstructions(Instructions
);
34 for (unsigned I
= Instructions
.size(); I
< MinInstructions
; ++I
) {
35 Entry
.addInstruction(Instructions
[I
% Instructions
.size()]);
42 BitVector
getReservedRegs() const override
{
43 // We're using no additional registers.
44 return State
.getRATC().emptyRegisters();
48 class LoopSnippetRepetitor
: public SnippetRepetitor
{
50 explicit LoopSnippetRepetitor(const LLVMState
&State
)
51 : SnippetRepetitor(State
),
52 LoopCounter(State
.getExegesisTarget().getLoopCounterRegister(
53 State
.getTargetMachine().getTargetTriple())) {}
55 // Loop over the snippet ceil(MinInstructions / Instructions.Size()) times.
56 FillFunction
Repeat(ArrayRef
<MCInst
> Instructions
,
57 unsigned MinInstructions
) const override
{
58 return [this, Instructions
, MinInstructions
](FunctionFiller
&Filler
) {
59 const auto &ET
= State
.getExegesisTarget();
60 auto Entry
= Filler
.getEntry();
61 auto Loop
= Filler
.addBasicBlock();
62 auto Exit
= Filler
.addBasicBlock();
64 // Set loop counter to the right value:
65 const APInt
LoopCount(32, (MinInstructions
+ Instructions
.size() - 1) /
67 for (const MCInst
&Inst
:
68 ET
.setRegTo(State
.getSubtargetInfo(), LoopCounter
, LoopCount
))
69 Entry
.addInstruction(Inst
);
71 // Set up the loop basic block.
72 Entry
.MBB
->addSuccessor(Loop
.MBB
, llvm::BranchProbability::getOne());
73 Loop
.MBB
->addSuccessor(Loop
.MBB
, llvm::BranchProbability::getOne());
74 // The live ins are: the loop counter, the registers that were setup by
75 // the entry block, and entry block live ins.
76 Loop
.MBB
->addLiveIn(LoopCounter
);
77 for (unsigned Reg
: Filler
.getRegistersSetUp())
78 Loop
.MBB
->addLiveIn(Reg
);
79 for (const auto &LiveIn
: Entry
.MBB
->liveins())
80 Loop
.MBB
->addLiveIn(LiveIn
);
81 Loop
.addInstructions(Instructions
);
82 ET
.decrementLoopCounterAndJump(*Loop
.MBB
, *Loop
.MBB
,
83 State
.getInstrInfo());
85 // Set up the exit basic block.
86 Loop
.MBB
->addSuccessor(Exit
.MBB
, llvm::BranchProbability::getZero());
91 BitVector
getReservedRegs() const override
{
92 // We're using a single loop counter, but we have to reserve all aliasing
94 return State
.getRATC().getRegister(LoopCounter
).aliasedBits();
98 const unsigned LoopCounter
;
103 SnippetRepetitor::~SnippetRepetitor() {}
105 std::unique_ptr
<const SnippetRepetitor
>
106 SnippetRepetitor::Create(InstructionBenchmark::RepetitionModeE Mode
,
107 const LLVMState
&State
) {
109 case InstructionBenchmark::Duplicate
:
110 return std::make_unique
<DuplicateSnippetRepetitor
>(State
);
111 case InstructionBenchmark::Loop
:
112 return std::make_unique
<LoopSnippetRepetitor
>(State
);
114 llvm_unreachable("Unknown RepetitionModeE enum");
117 } // namespace exegesis