[InstCombine] Signed saturation patterns
[llvm-complete.git] / tools / llvm-exegesis / lib / SnippetRepetitor.cpp
blobba618ac3f97e34ac36d60b89d6a1f451f2b39bcb
1 //===-- SnippetRepetitor.cpp ------------------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include <array>
10 #include <string>
12 #include "SnippetRepetitor.h"
13 #include "Target.h"
14 #include "llvm/CodeGen/TargetInstrInfo.h"
15 #include "llvm/CodeGen/TargetSubtargetInfo.h"
17 namespace llvm {
18 namespace exegesis {
19 namespace {
21 class DuplicateSnippetRepetitor : public SnippetRepetitor {
22 public:
23 using SnippetRepetitor::SnippetRepetitor;
25 // Repeats the snippet until there are at least MinInstructions in the
26 // resulting code.
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()]);
38 Entry.addReturn();
42 BitVector getReservedRegs() const override {
43 // We're using no additional registers.
44 return State.getRATC().emptyRegisters();
48 class LoopSnippetRepetitor : public SnippetRepetitor {
49 public:
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) /
66 Instructions.size());
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, BranchProbability::getOne());
73 Loop.MBB->addSuccessor(Loop.MBB, 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, BranchProbability::getZero());
87 Exit.addReturn();
91 BitVector getReservedRegs() const override {
92 // We're using a single loop counter, but we have to reserve all aliasing
93 // registers.
94 return State.getRATC().getRegister(LoopCounter).aliasedBits();
97 private:
98 const unsigned LoopCounter;
101 } // namespace
103 SnippetRepetitor::~SnippetRepetitor() {}
105 std::unique_ptr<const SnippetRepetitor>
106 SnippetRepetitor::Create(InstructionBenchmark::RepetitionModeE Mode,
107 const LLVMState &State) {
108 switch (Mode) {
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
118 } // namespace llvm