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 //===----------------------------------------------------------------------===// 8 9 #include <array> 10 #include <string> 11 12 #include "SnippetRepetitor.h" 13 #include "Target.h" 14 #include "llvm/CodeGen/TargetInstrInfo.h" 15 #include "llvm/CodeGen/TargetSubtargetInfo.h" 16 17 namespace llvm { 18 namespace exegesis { 19 namespace { 20 21 class DuplicateSnippetRepetitor : public SnippetRepetitor { 22 public: 23 using SnippetRepetitor::SnippetRepetitor; 24 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()]); 36 } 37 } 38 Entry.addReturn(); 39 }; 40 } 41 42 BitVector getReservedRegs() const override { 43 // We're using no additional registers. 44 return State.getRATC().emptyRegisters(); 45 } 46 }; 47 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())) {} 54 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(); 63 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); 70 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()); 84 85 // Set up the exit basic block. 86 Loop.MBB->addSuccessor(Exit.MBB, BranchProbability::getZero()); 87 Exit.addReturn(); 88 }; 89 } 90 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(); 95 } 96 97 private: 98 const unsigned LoopCounter; 99 }; 100 101 } // namespace 102 103 SnippetRepetitor::~SnippetRepetitor() {} 104 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); 113 case InstructionBenchmark::AggregateMin: 114 break; 115 } 116 llvm_unreachable("Unknown RepetitionModeE enum"); 117 } 118 119 } // namespace exegesis 120 } // namespace llvm 121