1 //===- bolt/Passes/StokeInfo.h ----------------------------------*- 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 // Pass to get information for functions for the Stoke Optimization 10 // To use the Stoke optimization technique to optimize the HHVM. 11 // This Pass solves the two major problems to use the Stoke program without 12 // probing its code: 13 // 14 // 1. Stoke works on function level, but it is only limited to relative 15 // small functions which are loop-free, call-free, exception-free, etc. 16 // 17 // 2. Stoke requires much information being manually provided, such as the 18 // register usages and memory modification, etc. 19 // 20 // This Pass analyzes all functions and get the required information into 21 // .csv file. Next, we use python scripts to process the file, filter 22 // out functions for optimization and automatically generate configure files. 23 // Finally, these configure files are feed to the Stoke to do the job. 24 // 25 //===----------------------------------------------------------------------===// 26 27 #ifndef BOLT_PASSES_STOKEINFO_H 28 #define BOLT_PASSES_STOKEINFO_H 29 30 #include "bolt/Passes/BinaryPasses.h" 31 #include <fstream> 32 33 namespace llvm { 34 namespace bolt { 35 class DataflowInfoManager; 36 class RegAnalysis; 37 38 /// Structure to hold information needed by Stoke for a function 39 struct StokeFuncInfo { 40 std::string FuncName; 41 uint64_t Offset; 42 uint64_t Size; 43 uint64_t NumInstrs; 44 uint64_t NumBlocks; 45 bool IsLoopFree; 46 unsigned NumLoops; 47 unsigned MaxLoopDepth; 48 uint64_t HotSize; 49 uint64_t TotalSize; 50 uint64_t Score; 51 bool HasCall; 52 std::set<std::string> DefIn; 53 std::set<std::string> LiveOut; 54 bool HeapOut; 55 bool StackOut; 56 bool HasRipAddr; 57 bool Omitted; 58 StokeFuncInfoStokeFuncInfo59 StokeFuncInfo() { reset(); } 60 resetStokeFuncInfo61 void reset() { 62 FuncName = ""; 63 Offset = Size = NumInstrs = NumBlocks = 0; 64 NumLoops = MaxLoopDepth = 0; 65 HotSize = TotalSize = 0; 66 Score = 0; 67 IsLoopFree = HasCall = HeapOut = StackOut = HasRipAddr = Omitted = false; 68 DefIn.clear(); 69 LiveOut.clear(); 70 } 71 printCsvHeaderStokeFuncInfo72 void printCsvHeader(std::ofstream &Outfile) { 73 if (Outfile.is_open()) 74 Outfile << "FuncName,Offset,Size,NumInstrs,NumBlocks," 75 << "IsLoopFree,NumLoops,MaxLoopDepth," 76 << "HotSize,TotalSize," 77 << "Score," 78 << "HasCall," 79 << "DefIn,LiveOut,HeapOut,StackOut," 80 << "HasRipAddr," 81 << "Omitted\n"; 82 } 83 printDataStokeFuncInfo84 void printData(std::ofstream &Outfile) { 85 if (Outfile.is_open()) { 86 Outfile << FuncName << "," << Offset << "," << Size << "," << NumInstrs 87 << "," << NumBlocks << "," << IsLoopFree << "," << NumLoops << "," 88 << MaxLoopDepth << "," << HotSize << "," << TotalSize << "," 89 << Score << "," << HasCall << ",\"{ "; 90 for (const std::string &S : DefIn) 91 Outfile << "%" << S << " "; 92 Outfile << "}\",\"{ "; 93 for (const std::string &S : LiveOut) 94 Outfile << "%" << S << " "; 95 Outfile << "}\"," << HeapOut << "," << StackOut << "," << HasRipAddr 96 << "," << Omitted << "\n"; 97 } 98 } 99 }; 100 101 class StokeInfo : public BinaryFunctionPass { 102 103 private: 104 // stoke --def_in option default value, for X86: 105 // rax, rcx, rdx, rsi, rdi, r8, r9, xmm0-xmm7 106 BitVector DefaultDefInMask; 107 // --live_out option default value: rax, rdx, xmm0, xmm1 108 BitVector DefaultLiveOutMask; 109 110 uint16_t NumRegs; 111 112 public: StokeInfo(const cl::opt<bool> & PrintPass)113 StokeInfo(const cl::opt<bool> &PrintPass) : BinaryFunctionPass(PrintPass) {} 114 getName()115 const char *getName() const override { return "stoke-get-stat"; } 116 117 void checkInstr(const BinaryFunction &BF, StokeFuncInfo &FuncInfo); 118 119 /// Get all required information for the stoke optimization 120 bool checkFunction(BinaryFunction &BF, DataflowInfoManager &DInfo, 121 RegAnalysis &RA, StokeFuncInfo &FuncInfo); 122 123 Error runOnFunctions(BinaryContext &BC) override; 124 }; 125 126 } // namespace bolt 127 } // namespace llvm 128 129 #endif 130