[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / tools / llvm-exegesis / lib / SnippetRepetitor.cpp
blob1851cb467433939b8664f8917eb7a73b111a2443
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/ADT/Sequence.h"
15 #include "llvm/CodeGen/TargetInstrInfo.h"
16 #include "llvm/CodeGen/TargetSubtargetInfo.h"
18 namespace llvm {
19 namespace exegesis {
20 namespace {
22 class DuplicateSnippetRepetitor : public SnippetRepetitor {
23 public:
24 using SnippetRepetitor::SnippetRepetitor;
26 // Repeats the snippet until there are at least MinInstructions in the
27 // resulting code.
28 FillFunction Repeat(ArrayRef<MCInst> Instructions, unsigned MinInstructions,
29 unsigned LoopBodySize) const override {
30 return [Instructions, MinInstructions](FunctionFiller &Filler) {
31 auto Entry = Filler.getEntry();
32 if (!Instructions.empty()) {
33 // Add the whole snippet at least once.
34 Entry.addInstructions(Instructions);
35 for (unsigned I = Instructions.size(); I < MinInstructions; ++I) {
36 Entry.addInstruction(Instructions[I % Instructions.size()]);
39 Entry.addReturn();
43 BitVector getReservedRegs() const override {
44 // We're using no additional registers.
45 return State.getRATC().emptyRegisters();
49 class LoopSnippetRepetitor : public SnippetRepetitor {
50 public:
51 explicit LoopSnippetRepetitor(const LLVMState &State)
52 : SnippetRepetitor(State),
53 LoopCounter(State.getExegesisTarget().getLoopCounterRegister(
54 State.getTargetMachine().getTargetTriple())) {}
56 // Loop over the snippet ceil(MinInstructions / Instructions.Size()) times.
57 FillFunction Repeat(ArrayRef<MCInst> Instructions, unsigned MinInstructions,
58 unsigned LoopBodySize) const override {
59 return [this, Instructions, MinInstructions,
60 LoopBodySize](FunctionFiller &Filler) {
61 const auto &ET = State.getExegesisTarget();
62 auto Entry = Filler.getEntry();
63 auto Loop = Filler.addBasicBlock();
64 auto Exit = Filler.addBasicBlock();
66 const unsigned LoopUnrollFactor =
67 LoopBodySize <= Instructions.size()
68 ? 1
69 : divideCeil(LoopBodySize, Instructions.size());
70 assert(LoopUnrollFactor >= 1 && "Should end up with at least 1 snippet.");
72 // Set loop counter to the right value:
73 const APInt LoopCount(
74 32,
75 divideCeil(MinInstructions, LoopUnrollFactor * Instructions.size()));
76 assert(LoopCount.uge(1) && "Trip count should be at least 1.");
77 for (const MCInst &Inst :
78 ET.setRegTo(State.getSubtargetInfo(), LoopCounter, LoopCount))
79 Entry.addInstruction(Inst);
81 // Set up the loop basic block.
82 Entry.MBB->addSuccessor(Loop.MBB, BranchProbability::getOne());
83 Loop.MBB->addSuccessor(Loop.MBB, BranchProbability::getOne());
84 // The live ins are: the loop counter, the registers that were setup by
85 // the entry block, and entry block live ins.
86 Loop.MBB->addLiveIn(LoopCounter);
87 for (unsigned Reg : Filler.getRegistersSetUp())
88 Loop.MBB->addLiveIn(Reg);
89 for (const auto &LiveIn : Entry.MBB->liveins())
90 Loop.MBB->addLiveIn(LiveIn);
91 for (auto _ : seq(0U, LoopUnrollFactor)) {
92 (void)_;
93 Loop.addInstructions(Instructions);
95 ET.decrementLoopCounterAndJump(*Loop.MBB, *Loop.MBB,
96 State.getInstrInfo());
98 // Set up the exit basic block.
99 Loop.MBB->addSuccessor(Exit.MBB, BranchProbability::getZero());
100 Exit.addReturn();
104 BitVector getReservedRegs() const override {
105 // We're using a single loop counter, but we have to reserve all aliasing
106 // registers.
107 return State.getRATC().getRegister(LoopCounter).aliasedBits();
110 private:
111 const unsigned LoopCounter;
114 } // namespace
116 SnippetRepetitor::~SnippetRepetitor() {}
118 std::unique_ptr<const SnippetRepetitor>
119 SnippetRepetitor::Create(InstructionBenchmark::RepetitionModeE Mode,
120 const LLVMState &State) {
121 switch (Mode) {
122 case InstructionBenchmark::Duplicate:
123 return std::make_unique<DuplicateSnippetRepetitor>(State);
124 case InstructionBenchmark::Loop:
125 return std::make_unique<LoopSnippetRepetitor>(State);
126 case InstructionBenchmark::AggregateMin:
127 break;
129 llvm_unreachable("Unknown RepetitionModeE enum");
132 } // namespace exegesis
133 } // namespace llvm