IROutliner.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. //===- IROutliner.h - Extract similar IR regions into functions ------------==//
  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. // \file
  10. // The interface file for the IROutliner which is used by the IROutliner Pass.
  11. //
  12. // The outliner uses the IRSimilarityIdentifier to identify the similar regions
  13. // of code. It evaluates each set of IRSimilarityCandidates with an estimate of
  14. // whether it will provide code size reduction. Each region is extracted using
  15. // the code extractor. These extracted functions are consolidated into a single
  16. // function and called from the extracted call site.
  17. //
  18. // For example:
  19. // \code
  20. // %1 = add i32 %a, %b
  21. // %2 = add i32 %b, %a
  22. // %3 = add i32 %b, %a
  23. // %4 = add i32 %a, %b
  24. // \endcode
  25. // would become function
  26. // \code
  27. // define internal void outlined_ir_function(i32 %0, i32 %1) {
  28. // %1 = add i32 %0, %1
  29. // %2 = add i32 %1, %0
  30. // ret void
  31. // }
  32. // \endcode
  33. // with calls:
  34. // \code
  35. // call void outlined_ir_function(i32 %a, i32 %b)
  36. // call void outlined_ir_function(i32 %b, i32 %a)
  37. // \endcode
  38. //
  39. //===----------------------------------------------------------------------===//
  40. #ifndef LLVM_TRANSFORMS_IPO_IROUTLINER_H
  41. #define LLVM_TRANSFORMS_IPO_IROUTLINER_H
  42. #include "llvm/Analysis/IRSimilarityIdentifier.h"
  43. #include "llvm/IR/PassManager.h"
  44. #include "llvm/IR/ValueMap.h"
  45. #include "llvm/Support/InstructionCost.h"
  46. #include "llvm/Transforms/Utils/CodeExtractor.h"
  47. #include <set>
  48. struct OutlinableGroup;
  49. namespace llvm {
  50. using namespace IRSimilarity;
  51. class Module;
  52. class TargetTransformInfo;
  53. class OptimizationRemarkEmitter;
  54. /// The OutlinableRegion holds all the information for a specific region, or
  55. /// sequence of instructions. This includes what values need to be hoisted to
  56. /// arguments from the extracted function, inputs and outputs to the region, and
  57. /// mapping from the extracted function arguments to overall function arguments.
  58. struct OutlinableRegion {
  59. /// Describes the region of code.
  60. IRSimilarityCandidate *Candidate;
  61. /// If this region is outlined, the front and back IRInstructionData could
  62. /// potentially become invalidated if the only new instruction is a call.
  63. /// This ensures that we replace in the instruction in the IRInstructionData.
  64. IRInstructionData *NewFront = nullptr;
  65. IRInstructionData *NewBack = nullptr;
  66. /// The number of extracted inputs from the CodeExtractor.
  67. unsigned NumExtractedInputs;
  68. /// The corresponding BasicBlock with the appropriate stores for this
  69. /// OutlinableRegion in the overall function.
  70. unsigned OutputBlockNum;
  71. /// Mapping the extracted argument number to the argument number in the
  72. /// overall function. Since there will be inputs, such as elevated constants
  73. /// that are not the same in each region in a SimilarityGroup, or values that
  74. /// cannot be sunk into the extracted section in every region, we must keep
  75. /// track of which extracted argument maps to which overall argument.
  76. DenseMap<unsigned, unsigned> ExtractedArgToAgg;
  77. DenseMap<unsigned, unsigned> AggArgToExtracted;
  78. /// Mapping of the argument number in the deduplicated function
  79. /// to a given constant, which is used when creating the arguments to the call
  80. /// to the newly created deduplicated function. This is handled separately
  81. /// since the CodeExtractor does not recognize constants.
  82. DenseMap<unsigned, Constant *> AggArgToConstant;
  83. /// The global value numbers that are used as outputs for this section. Once
  84. /// extracted, each output will be stored to an output register. This
  85. /// documents the global value numbers that are used in this pattern.
  86. SmallVector<unsigned, 4> GVNStores;
  87. /// Used to create an outlined function.
  88. CodeExtractor *CE = nullptr;
  89. /// The call site of the extracted region.
  90. CallInst *Call = nullptr;
  91. /// The function for the extracted region.
  92. Function *ExtractedFunction = nullptr;
  93. /// Flag for whether we have split out the IRSimilarityCanidate. That is,
  94. /// make the region contained the IRSimilarityCandidate its own BasicBlock.
  95. bool CandidateSplit = false;
  96. /// Flag for whether we should not consider this region for extraction.
  97. bool IgnoreRegion = false;
  98. /// The BasicBlock that is before the start of the region BasicBlock,
  99. /// only defined when the region has been split.
  100. BasicBlock *PrevBB = nullptr;
  101. /// The BasicBlock that contains the starting instruction of the region.
  102. BasicBlock *StartBB = nullptr;
  103. /// The BasicBlock that contains the ending instruction of the region.
  104. BasicBlock *EndBB = nullptr;
  105. /// The BasicBlock that is after the start of the region BasicBlock,
  106. /// only defined when the region has been split.
  107. BasicBlock *FollowBB = nullptr;
  108. /// The Outlinable Group that contains this region and structurally similar
  109. /// regions to this region.
  110. OutlinableGroup *Parent = nullptr;
  111. OutlinableRegion(IRSimilarityCandidate &C, OutlinableGroup &Group)
  112. : Candidate(&C), Parent(&Group) {
  113. StartBB = C.getStartBB();
  114. EndBB = C.getEndBB();
  115. }
  116. /// For the contained region, split the parent BasicBlock at the starting and
  117. /// ending instructions of the contained IRSimilarityCandidate.
  118. void splitCandidate();
  119. /// For the contained region, reattach the BasicBlock at the starting and
  120. /// ending instructions of the contained IRSimilarityCandidate, or if the
  121. /// function has been extracted, the start and end of the BasicBlock
  122. /// containing the called function.
  123. void reattachCandidate();
  124. /// Get the size of the code removed from the region.
  125. ///
  126. /// \param [in] TTI - The TargetTransformInfo for the parent function.
  127. /// \returns the code size of the region
  128. InstructionCost getBenefit(TargetTransformInfo &TTI);
  129. };
  130. /// This class is a pass that identifies similarity in a Module, extracts
  131. /// instances of the similarity, and then consolidating the similar regions
  132. /// in an effort to reduce code size. It uses the IRSimilarityIdentifier pass
  133. /// to identify the similar regions of code, and then extracts the similar
  134. /// sections into a single function. See the above for an example as to
  135. /// how code is extracted and consolidated into a single function.
  136. class IROutliner {
  137. public:
  138. IROutliner(function_ref<TargetTransformInfo &(Function &)> GTTI,
  139. function_ref<IRSimilarityIdentifier &(Module &)> GIRSI,
  140. function_ref<OptimizationRemarkEmitter &(Function &)> GORE)
  141. : getTTI(GTTI), getIRSI(GIRSI), getORE(GORE) {}
  142. bool run(Module &M);
  143. private:
  144. /// Find repeated similar code sequences in \p M and outline them into new
  145. /// Functions.
  146. ///
  147. /// \param [in] M - The module to outline from.
  148. /// \returns The number of Functions created.
  149. unsigned doOutline(Module &M);
  150. /// Remove all the IRSimilarityCandidates from \p CandidateVec that have
  151. /// instructions contained in a previously outlined region and put the
  152. /// remaining regions in \p CurrentGroup.
  153. ///
  154. /// \param [in] CandidateVec - List of similarity candidates for regions with
  155. /// the same similarity structure.
  156. /// \param [in,out] CurrentGroup - Contains the potential sections to
  157. /// be outlined.
  158. void
  159. pruneIncompatibleRegions(std::vector<IRSimilarityCandidate> &CandidateVec,
  160. OutlinableGroup &CurrentGroup);
  161. /// Create the function based on the overall types found in the current
  162. /// regions being outlined.
  163. ///
  164. /// \param M - The module to outline from.
  165. /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined.
  166. /// \param [in] FunctionNameSuffix - How many functions have we previously
  167. /// created.
  168. /// \returns the newly created function.
  169. Function *createFunction(Module &M, OutlinableGroup &CG,
  170. unsigned FunctionNameSuffix);
  171. /// Identify the needed extracted inputs in a section, and add to the overall
  172. /// function if needed.
  173. ///
  174. /// \param [in] M - The module to outline from.
  175. /// \param [in,out] Region - The region to be extracted.
  176. /// \param [in] NotSame - The global value numbers of the Values in the region
  177. /// that do not have the same Constant in each strucutrally similar region.
  178. void findAddInputsOutputs(Module &M, OutlinableRegion &Region,
  179. DenseSet<unsigned> &NotSame);
  180. /// Find the number of instructions that will be removed by extracting the
  181. /// OutlinableRegions in \p CurrentGroup.
  182. ///
  183. /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
  184. /// analyzed.
  185. /// \returns the number of outlined instructions across all regions.
  186. InstructionCost findBenefitFromAllRegions(OutlinableGroup &CurrentGroup);
  187. /// Find the number of instructions that will be added by reloading arguments.
  188. ///
  189. /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
  190. /// analyzed.
  191. /// \returns the number of added reload instructions across all regions.
  192. InstructionCost findCostOutputReloads(OutlinableGroup &CurrentGroup);
  193. /// Find the cost and the benefit of \p CurrentGroup and save it back to
  194. /// \p CurrentGroup.
  195. ///
  196. /// \param [in] M - The module being analyzed
  197. /// \param [in,out] CurrentGroup - The overall outlined section
  198. void findCostBenefit(Module &M, OutlinableGroup &CurrentGroup);
  199. /// Update the output mapping based on the load instruction, and the outputs
  200. /// of the extracted function.
  201. ///
  202. /// \param Region - The region extracted
  203. /// \param Outputs - The outputs from the extracted function.
  204. /// \param LI - The load instruction used to update the mapping.
  205. void updateOutputMapping(OutlinableRegion &Region,
  206. ArrayRef<Value *> Outputs, LoadInst *LI);
  207. /// Extract \p Region into its own function.
  208. ///
  209. /// \param [in] Region - The region to be extracted into its own function.
  210. /// \returns True if it was successfully outlined.
  211. bool extractSection(OutlinableRegion &Region);
  212. /// For the similarities found, and the extracted sections, create a single
  213. /// outlined function with appropriate output blocks as necessary.
  214. ///
  215. /// \param [in] M - The module to outline from
  216. /// \param [in] CurrentGroup - The set of extracted sections to consolidate.
  217. /// \param [in,out] FuncsToRemove - List of functions to remove from the
  218. /// module after outlining is completed.
  219. /// \param [in,out] OutlinedFunctionNum - the number of new outlined
  220. /// functions.
  221. void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup,
  222. std::vector<Function *> &FuncsToRemove,
  223. unsigned &OutlinedFunctionNum);
  224. /// If true, enables us to outline from functions that have LinkOnceFromODR
  225. /// linkages.
  226. bool OutlineFromLinkODRs = false;
  227. /// If false, we do not worry if the cost is greater than the benefit. This
  228. /// is for debugging and testing, so that we can test small cases to ensure
  229. /// that the outlining is being done correctly.
  230. bool CostModel = true;
  231. /// The set of outlined Instructions, identified by their location in the
  232. /// sequential ordering of instructions in a Module.
  233. DenseSet<unsigned> Outlined;
  234. /// TargetTransformInfo lambda for target specific information.
  235. function_ref<TargetTransformInfo &(Function &)> getTTI;
  236. /// A mapping from newly created reloaded output values to the original value.
  237. /// If an value is replace by an output from an outlined region, this maps
  238. /// that Value, back to its original Value.
  239. DenseMap<Value *, Value *> OutputMappings;
  240. /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier.
  241. function_ref<IRSimilarityIdentifier &(Module &)> getIRSI;
  242. /// The optimization remark emitter for the pass.
  243. function_ref<OptimizationRemarkEmitter &(Function &)> getORE;
  244. /// The memory allocator used to allocate the CodeExtractors.
  245. SpecificBumpPtrAllocator<CodeExtractor> ExtractorAllocator;
  246. /// The memory allocator used to allocate the OutlinableRegions.
  247. SpecificBumpPtrAllocator<OutlinableRegion> RegionAllocator;
  248. /// The memory allocator used to allocate new IRInstructionData.
  249. SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  250. /// Custom InstVisitor to classify different instructions for whether it can
  251. /// be analyzed for similarity. This is needed as there may be instruction we
  252. /// can identify as having similarity, but are more complicated to outline.
  253. struct InstructionAllowed : public InstVisitor<InstructionAllowed, bool> {
  254. InstructionAllowed() {}
  255. // TODO: Determine a scheme to resolve when the label is similar enough.
  256. bool visitBranchInst(BranchInst &BI) { return false; }
  257. // TODO: Determine a scheme to resolve when the labels are similar enough.
  258. bool visitPHINode(PHINode &PN) { return false; }
  259. // TODO: Handle allocas.
  260. bool visitAllocaInst(AllocaInst &AI) { return false; }
  261. // VAArg instructions are not allowed since this could cause difficulty when
  262. // differentiating between different sets of variable instructions in
  263. // the deduplicated outlined regions.
  264. bool visitVAArgInst(VAArgInst &VI) { return false; }
  265. // We exclude all exception handling cases since they are so context
  266. // dependent.
  267. bool visitLandingPadInst(LandingPadInst &LPI) { return false; }
  268. bool visitFuncletPadInst(FuncletPadInst &FPI) { return false; }
  269. // DebugInfo should be included in the regions, but should not be
  270. // analyzed for similarity as it has no bearing on the outcome of the
  271. // program.
  272. bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; }
  273. // TODO: Handle specific intrinsics individually from those that can be
  274. // handled.
  275. bool IntrinsicInst(IntrinsicInst &II) { return false; }
  276. // We only handle CallInsts that are not indirect, since we cannot guarantee
  277. // that they have a name in these cases.
  278. bool visitCallInst(CallInst &CI) {
  279. Function *F = CI.getCalledFunction();
  280. if (!F || CI.isIndirectCall() || !F->hasName())
  281. return false;
  282. return true;
  283. }
  284. // TODO: Handle FreezeInsts. Since a frozen value could be frozen inside
  285. // the outlined region, and then returned as an output, this will have to be
  286. // handled differently.
  287. bool visitFreezeInst(FreezeInst &CI) { return false; }
  288. // TODO: We do not current handle similarity that changes the control flow.
  289. bool visitInvokeInst(InvokeInst &II) { return false; }
  290. // TODO: We do not current handle similarity that changes the control flow.
  291. bool visitCallBrInst(CallBrInst &CBI) { return false; }
  292. // TODO: Handle interblock similarity.
  293. bool visitTerminator(Instruction &I) { return false; }
  294. bool visitInstruction(Instruction &I) { return true; }
  295. };
  296. /// A InstVisitor used to exclude certain instructions from being outlined.
  297. InstructionAllowed InstructionClassifier;
  298. };
  299. /// Pass to outline similar regions.
  300. class IROutlinerPass : public PassInfoMixin<IROutlinerPass> {
  301. public:
  302. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  303. };
  304. } // end namespace llvm
  305. #endif // LLVM_TRANSFORMS_IPO_IROUTLINER_H