|
17 | 17 | /// prefetch instruction from any module. |
18 | 18 | //===----------------------------------------------------------------------===// |
19 | 19 |
|
| 20 | +#include "llvm/CodeGen/InsertCodePrefetch.h" |
| 21 | + |
20 | 22 | #include "llvm/ADT/SmallVector.h" |
21 | 23 | #include "llvm/ADT/StringExtras.h" |
22 | 24 | #include "llvm/ADT/StringRef.h" |
|
26 | 28 | #include "llvm/CodeGen/MachineFunction.h" |
27 | 29 | #include "llvm/CodeGen/MachineFunctionPass.h" |
28 | 30 | #include "llvm/CodeGen/Passes.h" |
| 31 | +#include "llvm/CodeGen/TargetInstrInfo.h" |
29 | 32 | #include "llvm/InitializePasses.h" |
30 | 33 |
|
31 | 34 | using namespace llvm; |
32 | 35 | #define DEBUG_TYPE "insert-code-prefetch" |
33 | 36 |
|
| 37 | +namespace llvm { |
| 38 | +SmallString<128> getPrefetchTargetSymbolName(StringRef FunctionName, const UniqueBBID &BBID, unsigned SubblockIndex) { |
| 39 | + SmallString<128> R("__llvm_prefetch_target_"); |
| 40 | + R += FunctionName; |
| 41 | + R += "_"; |
| 42 | + R += utostr(BBID.BaseID); |
| 43 | + R += "_"; |
| 44 | + R += utostr(SubblockIndex); |
| 45 | + return R; |
| 46 | +} |
| 47 | +} // namespace llvm |
| 48 | + |
34 | 49 | namespace { |
35 | 50 | class InsertCodePrefetch : public MachineFunctionPass { |
36 | 51 | public: |
@@ -82,7 +97,40 @@ bool InsertCodePrefetch::runOnMachineFunction(MachineFunction &MF) { |
82 | 97 | continue; |
83 | 98 | MBB.setPrefetchTargetSubblockIndexes(R->second); |
84 | 99 | } |
85 | | - return false; |
| 100 | + SmallVector<PrefetchHint> PrefetchHints = |
| 101 | + getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>() |
| 102 | + .getPrefetchHintsForFunction(MF.getName()); |
| 103 | + DenseMap<UniqueBBID, SmallVector<PrefetchHint>> |
| 104 | + PrefetchHintsBySiteBBID; |
| 105 | + for (const auto &H : PrefetchHints) |
| 106 | + PrefetchHintsBySiteBBID[H.SiteID.BBID].push_back(H); |
| 107 | + for (auto &[SiteBBID, H]: PrefetchHintsBySiteBBID) { |
| 108 | + llvm::sort(H, [](const PrefetchHint &H1, const PrefetchHint &H2) { |
| 109 | + return H1.SiteID.SubblockIndex < H2.SiteID.SubblockIndex; |
| 110 | + }); |
| 111 | + } |
| 112 | + auto PtrTy = PointerType::getUnqual(MF.getFunction().getParent()->getContext()); |
| 113 | + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); |
| 114 | + for (auto &BB : MF) { |
| 115 | + auto It = PrefetchHintsBySiteBBID.find(*BB.getBBID()); |
| 116 | + if (It == PrefetchHintsBySiteBBID.end()) |
| 117 | + continue; |
| 118 | + const auto &PrefetchHints = It->second; |
| 119 | + unsigned NumCallsInBB = 0; |
| 120 | + auto InstrIt = BB.begin(); |
| 121 | + for(auto HintIt = PrefetchHints.begin() ; HintIt != PrefetchHints.end();) { |
| 122 | + auto NextInstrIt = InstrIt == BB.end() ? BB.end() : std::next(InstrIt); |
| 123 | + while (NumCallsInBB >= HintIt->SiteID.SubblockIndex) { |
| 124 | + auto *GV = MF.getFunction().getParent()->getOrInsertGlobal(getPrefetchTargetSymbolName(HintIt->TargetFunction, HintIt->TargetID.BBID, HintIt->TargetID.SubblockIndex), PtrTy); |
| 125 | + TII->insertCodePrefetchInstr(BB, NextInstrIt, GV); |
| 126 | + ++HintIt; |
| 127 | + } |
| 128 | + if (InstrIt == BB.end()) break; |
| 129 | + if (InstrIt->isCall()) ++NumCallsInBB; |
| 130 | + InstrIt = NextInstrIt; |
| 131 | + } |
| 132 | + } |
| 133 | + return true; |
86 | 134 | } |
87 | 135 |
|
88 | 136 | void InsertCodePrefetch::getAnalysisUsage(AnalysisUsage &AU) const { |
|
0 commit comments