IROutliner.cpp 127 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101
  1. //===- IROutliner.cpp -- Outline Similar Regions ----------------*- 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. /// \file
  10. // Implementation for the IROutliner which is used by the IROutliner Pass.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/Transforms/IPO/IROutliner.h"
  14. #include "llvm/Analysis/IRSimilarityIdentifier.h"
  15. #include "llvm/Analysis/OptimizationRemarkEmitter.h"
  16. #include "llvm/Analysis/TargetTransformInfo.h"
  17. #include "llvm/IR/Attributes.h"
  18. #include "llvm/IR/DIBuilder.h"
  19. #include "llvm/IR/DebugInfo.h"
  20. #include "llvm/IR/DebugInfoMetadata.h"
  21. #include "llvm/IR/Dominators.h"
  22. #include "llvm/IR/Mangler.h"
  23. #include "llvm/IR/PassManager.h"
  24. #include "llvm/InitializePasses.h"
  25. #include "llvm/Pass.h"
  26. #include "llvm/Support/CommandLine.h"
  27. #include "llvm/Transforms/IPO.h"
  28. #include <optional>
  29. #include <vector>
  30. #define DEBUG_TYPE "iroutliner"
  31. using namespace llvm;
  32. using namespace IRSimilarity;
  33. // A command flag to be used for debugging to exclude branches from similarity
  34. // matching and outlining.
  35. namespace llvm {
  36. extern cl::opt<bool> DisableBranches;
  37. // A command flag to be used for debugging to indirect calls from similarity
  38. // matching and outlining.
  39. extern cl::opt<bool> DisableIndirectCalls;
  40. // A command flag to be used for debugging to exclude intrinsics from similarity
  41. // matching and outlining.
  42. extern cl::opt<bool> DisableIntrinsics;
  43. } // namespace llvm
  44. // Set to true if the user wants the ir outliner to run on linkonceodr linkage
  45. // functions. This is false by default because the linker can dedupe linkonceodr
  46. // functions. Since the outliner is confined to a single module (modulo LTO),
  47. // this is off by default. It should, however, be the default behavior in
  48. // LTO.
  49. static cl::opt<bool> EnableLinkOnceODRIROutlining(
  50. "enable-linkonceodr-ir-outlining", cl::Hidden,
  51. cl::desc("Enable the IR outliner on linkonceodr functions"),
  52. cl::init(false));
  53. // This is a debug option to test small pieces of code to ensure that outlining
  54. // works correctly.
  55. static cl::opt<bool> NoCostModel(
  56. "ir-outlining-no-cost", cl::init(false), cl::ReallyHidden,
  57. cl::desc("Debug option to outline greedily, without restriction that "
  58. "calculated benefit outweighs cost"));
  59. /// The OutlinableGroup holds all the overarching information for outlining
  60. /// a set of regions that are structurally similar to one another, such as the
  61. /// types of the overall function, the output blocks, the sets of stores needed
  62. /// and a list of the different regions. This information is used in the
  63. /// deduplication of extracted regions with the same structure.
  64. struct OutlinableGroup {
  65. /// The sections that could be outlined
  66. std::vector<OutlinableRegion *> Regions;
  67. /// The argument types for the function created as the overall function to
  68. /// replace the extracted function for each region.
  69. std::vector<Type *> ArgumentTypes;
  70. /// The FunctionType for the overall function.
  71. FunctionType *OutlinedFunctionType = nullptr;
  72. /// The Function for the collective overall function.
  73. Function *OutlinedFunction = nullptr;
  74. /// Flag for whether we should not consider this group of OutlinableRegions
  75. /// for extraction.
  76. bool IgnoreGroup = false;
  77. /// The return blocks for the overall function.
  78. DenseMap<Value *, BasicBlock *> EndBBs;
  79. /// The PHIBlocks with their corresponding return block based on the return
  80. /// value as the key.
  81. DenseMap<Value *, BasicBlock *> PHIBlocks;
  82. /// A set containing the different GVN store sets needed. Each array contains
  83. /// a sorted list of the different values that need to be stored into output
  84. /// registers.
  85. DenseSet<ArrayRef<unsigned>> OutputGVNCombinations;
  86. /// Flag for whether the \ref ArgumentTypes have been defined after the
  87. /// extraction of the first region.
  88. bool InputTypesSet = false;
  89. /// The number of input values in \ref ArgumentTypes. Anything after this
  90. /// index in ArgumentTypes is an output argument.
  91. unsigned NumAggregateInputs = 0;
  92. /// The mapping of the canonical numbering of the values in outlined sections
  93. /// to specific arguments.
  94. DenseMap<unsigned, unsigned> CanonicalNumberToAggArg;
  95. /// The number of branches in the region target a basic block that is outside
  96. /// of the region.
  97. unsigned BranchesToOutside = 0;
  98. /// Tracker counting backwards from the highest unsigned value possible to
  99. /// avoid conflicting with the GVNs of assigned values. We start at -3 since
  100. /// -2 and -1 are assigned by the DenseMap.
  101. unsigned PHINodeGVNTracker = -3;
  102. DenseMap<unsigned,
  103. std::pair<std::pair<unsigned, unsigned>, SmallVector<unsigned, 2>>>
  104. PHINodeGVNToGVNs;
  105. DenseMap<hash_code, unsigned> GVNsToPHINodeGVN;
  106. /// The number of instructions that will be outlined by extracting \ref
  107. /// Regions.
  108. InstructionCost Benefit = 0;
  109. /// The number of added instructions needed for the outlining of the \ref
  110. /// Regions.
  111. InstructionCost Cost = 0;
  112. /// The argument that needs to be marked with the swifterr attribute. If not
  113. /// needed, there is no value.
  114. std::optional<unsigned> SwiftErrorArgument;
  115. /// For the \ref Regions, we look at every Value. If it is a constant,
  116. /// we check whether it is the same in Region.
  117. ///
  118. /// \param [in,out] NotSame contains the global value numbers where the
  119. /// constant is not always the same, and must be passed in as an argument.
  120. void findSameConstants(DenseSet<unsigned> &NotSame);
  121. /// For the regions, look at each set of GVN stores needed and account for
  122. /// each combination. Add an argument to the argument types if there is
  123. /// more than one combination.
  124. ///
  125. /// \param [in] M - The module we are outlining from.
  126. void collectGVNStoreSets(Module &M);
  127. };
  128. /// Move the contents of \p SourceBB to before the last instruction of \p
  129. /// TargetBB.
  130. /// \param SourceBB - the BasicBlock to pull Instructions from.
  131. /// \param TargetBB - the BasicBlock to put Instruction into.
  132. static void moveBBContents(BasicBlock &SourceBB, BasicBlock &TargetBB) {
  133. for (Instruction &I : llvm::make_early_inc_range(SourceBB))
  134. I.moveBefore(TargetBB, TargetBB.end());
  135. }
  136. /// A function to sort the keys of \p Map, which must be a mapping of constant
  137. /// values to basic blocks and return it in \p SortedKeys
  138. ///
  139. /// \param SortedKeys - The vector the keys will be return in and sorted.
  140. /// \param Map - The DenseMap containing keys to sort.
  141. static void getSortedConstantKeys(std::vector<Value *> &SortedKeys,
  142. DenseMap<Value *, BasicBlock *> &Map) {
  143. for (auto &VtoBB : Map)
  144. SortedKeys.push_back(VtoBB.first);
  145. // Here we expect to have either 1 value that is void (nullptr) or multiple
  146. // values that are all constant integers.
  147. if (SortedKeys.size() == 1) {
  148. assert(!SortedKeys[0] && "Expected a single void value.");
  149. return;
  150. }
  151. stable_sort(SortedKeys, [](const Value *LHS, const Value *RHS) {
  152. assert(LHS && RHS && "Expected non void values.");
  153. const ConstantInt *LHSC = dyn_cast<ConstantInt>(LHS);
  154. const ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS);
  155. assert(RHSC && "Not a constant integer in return value?");
  156. assert(LHSC && "Not a constant integer in return value?");
  157. return LHSC->getLimitedValue() < RHSC->getLimitedValue();
  158. });
  159. }
  160. Value *OutlinableRegion::findCorrespondingValueIn(const OutlinableRegion &Other,
  161. Value *V) {
  162. std::optional<unsigned> GVN = Candidate->getGVN(V);
  163. assert(GVN && "No GVN for incoming value");
  164. std::optional<unsigned> CanonNum = Candidate->getCanonicalNum(*GVN);
  165. std::optional<unsigned> FirstGVN =
  166. Other.Candidate->fromCanonicalNum(*CanonNum);
  167. std::optional<Value *> FoundValueOpt = Other.Candidate->fromGVN(*FirstGVN);
  168. return FoundValueOpt.value_or(nullptr);
  169. }
  170. BasicBlock *
  171. OutlinableRegion::findCorrespondingBlockIn(const OutlinableRegion &Other,
  172. BasicBlock *BB) {
  173. Instruction *FirstNonPHI = BB->getFirstNonPHI();
  174. assert(FirstNonPHI && "block is empty?");
  175. Value *CorrespondingVal = findCorrespondingValueIn(Other, FirstNonPHI);
  176. if (!CorrespondingVal)
  177. return nullptr;
  178. BasicBlock *CorrespondingBlock =
  179. cast<Instruction>(CorrespondingVal)->getParent();
  180. return CorrespondingBlock;
  181. }
  182. /// Rewrite the BranchInsts in the incoming blocks to \p PHIBlock that are found
  183. /// in \p Included to branch to BasicBlock \p Replace if they currently branch
  184. /// to the BasicBlock \p Find. This is used to fix up the incoming basic blocks
  185. /// when PHINodes are included in outlined regions.
  186. ///
  187. /// \param PHIBlock - The BasicBlock containing the PHINodes that need to be
  188. /// checked.
  189. /// \param Find - The successor block to be replaced.
  190. /// \param Replace - The new succesor block to branch to.
  191. /// \param Included - The set of blocks about to be outlined.
  192. static void replaceTargetsFromPHINode(BasicBlock *PHIBlock, BasicBlock *Find,
  193. BasicBlock *Replace,
  194. DenseSet<BasicBlock *> &Included) {
  195. for (PHINode &PN : PHIBlock->phis()) {
  196. for (unsigned Idx = 0, PNEnd = PN.getNumIncomingValues(); Idx != PNEnd;
  197. ++Idx) {
  198. // Check if the incoming block is included in the set of blocks being
  199. // outlined.
  200. BasicBlock *Incoming = PN.getIncomingBlock(Idx);
  201. if (!Included.contains(Incoming))
  202. continue;
  203. BranchInst *BI = dyn_cast<BranchInst>(Incoming->getTerminator());
  204. assert(BI && "Not a branch instruction?");
  205. // Look over the branching instructions into this block to see if we
  206. // used to branch to Find in this outlined block.
  207. for (unsigned Succ = 0, End = BI->getNumSuccessors(); Succ != End;
  208. Succ++) {
  209. // If we have found the block to replace, we do so here.
  210. if (BI->getSuccessor(Succ) != Find)
  211. continue;
  212. BI->setSuccessor(Succ, Replace);
  213. }
  214. }
  215. }
  216. }
  217. void OutlinableRegion::splitCandidate() {
  218. assert(!CandidateSplit && "Candidate already split!");
  219. Instruction *BackInst = Candidate->backInstruction();
  220. Instruction *EndInst = nullptr;
  221. // Check whether the last instruction is a terminator, if it is, we do
  222. // not split on the following instruction. We leave the block as it is. We
  223. // also check that this is not the last instruction in the Module, otherwise
  224. // the check for whether the current following instruction matches the
  225. // previously recorded instruction will be incorrect.
  226. if (!BackInst->isTerminator() ||
  227. BackInst->getParent() != &BackInst->getFunction()->back()) {
  228. EndInst = Candidate->end()->Inst;
  229. assert(EndInst && "Expected an end instruction?");
  230. }
  231. // We check if the current instruction following the last instruction in the
  232. // region is the same as the recorded instruction following the last
  233. // instruction. If they do not match, there could be problems in rewriting
  234. // the program after outlining, so we ignore it.
  235. if (!BackInst->isTerminator() &&
  236. EndInst != BackInst->getNextNonDebugInstruction())
  237. return;
  238. Instruction *StartInst = (*Candidate->begin()).Inst;
  239. assert(StartInst && "Expected a start instruction?");
  240. StartBB = StartInst->getParent();
  241. PrevBB = StartBB;
  242. DenseSet<BasicBlock *> BBSet;
  243. Candidate->getBasicBlocks(BBSet);
  244. // We iterate over the instructions in the region, if we find a PHINode, we
  245. // check if there are predecessors outside of the region, if there are,
  246. // we ignore this region since we are unable to handle the severing of the
  247. // phi node right now.
  248. // TODO: Handle extraneous inputs for PHINodes through variable number of
  249. // inputs, similar to how outputs are handled.
  250. BasicBlock::iterator It = StartInst->getIterator();
  251. EndBB = BackInst->getParent();
  252. BasicBlock *IBlock;
  253. BasicBlock *PHIPredBlock = nullptr;
  254. bool EndBBTermAndBackInstDifferent = EndBB->getTerminator() != BackInst;
  255. while (PHINode *PN = dyn_cast<PHINode>(&*It)) {
  256. unsigned NumPredsOutsideRegion = 0;
  257. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
  258. if (!BBSet.contains(PN->getIncomingBlock(i))) {
  259. PHIPredBlock = PN->getIncomingBlock(i);
  260. ++NumPredsOutsideRegion;
  261. continue;
  262. }
  263. // We must consider the case there the incoming block to the PHINode is
  264. // the same as the final block of the OutlinableRegion. If this is the
  265. // case, the branch from this block must also be outlined to be valid.
  266. IBlock = PN->getIncomingBlock(i);
  267. if (IBlock == EndBB && EndBBTermAndBackInstDifferent) {
  268. PHIPredBlock = PN->getIncomingBlock(i);
  269. ++NumPredsOutsideRegion;
  270. }
  271. }
  272. if (NumPredsOutsideRegion > 1)
  273. return;
  274. It++;
  275. }
  276. // If the region starts with a PHINode, but is not the initial instruction of
  277. // the BasicBlock, we ignore this region for now.
  278. if (isa<PHINode>(StartInst) && StartInst != &*StartBB->begin())
  279. return;
  280. // If the region ends with a PHINode, but does not contain all of the phi node
  281. // instructions of the region, we ignore it for now.
  282. if (isa<PHINode>(BackInst) &&
  283. BackInst != &*std::prev(EndBB->getFirstInsertionPt()))
  284. return;
  285. // The basic block gets split like so:
  286. // block: block:
  287. // inst1 inst1
  288. // inst2 inst2
  289. // region1 br block_to_outline
  290. // region2 block_to_outline:
  291. // region3 -> region1
  292. // region4 region2
  293. // inst3 region3
  294. // inst4 region4
  295. // br block_after_outline
  296. // block_after_outline:
  297. // inst3
  298. // inst4
  299. std::string OriginalName = PrevBB->getName().str();
  300. StartBB = PrevBB->splitBasicBlock(StartInst, OriginalName + "_to_outline");
  301. PrevBB->replaceSuccessorsPhiUsesWith(PrevBB, StartBB);
  302. // If there was a PHINode with an incoming block outside the region,
  303. // make sure is correctly updated in the newly split block.
  304. if (PHIPredBlock)
  305. PrevBB->replaceSuccessorsPhiUsesWith(PHIPredBlock, PrevBB);
  306. CandidateSplit = true;
  307. if (!BackInst->isTerminator()) {
  308. EndBB = EndInst->getParent();
  309. FollowBB = EndBB->splitBasicBlock(EndInst, OriginalName + "_after_outline");
  310. EndBB->replaceSuccessorsPhiUsesWith(EndBB, FollowBB);
  311. FollowBB->replaceSuccessorsPhiUsesWith(PrevBB, FollowBB);
  312. } else {
  313. EndBB = BackInst->getParent();
  314. EndsInBranch = true;
  315. FollowBB = nullptr;
  316. }
  317. // Refind the basic block set.
  318. BBSet.clear();
  319. Candidate->getBasicBlocks(BBSet);
  320. // For the phi nodes in the new starting basic block of the region, we
  321. // reassign the targets of the basic blocks branching instructions.
  322. replaceTargetsFromPHINode(StartBB, PrevBB, StartBB, BBSet);
  323. if (FollowBB)
  324. replaceTargetsFromPHINode(FollowBB, EndBB, FollowBB, BBSet);
  325. }
  326. void OutlinableRegion::reattachCandidate() {
  327. assert(CandidateSplit && "Candidate is not split!");
  328. // The basic block gets reattached like so:
  329. // block: block:
  330. // inst1 inst1
  331. // inst2 inst2
  332. // br block_to_outline region1
  333. // block_to_outline: -> region2
  334. // region1 region3
  335. // region2 region4
  336. // region3 inst3
  337. // region4 inst4
  338. // br block_after_outline
  339. // block_after_outline:
  340. // inst3
  341. // inst4
  342. assert(StartBB != nullptr && "StartBB for Candidate is not defined!");
  343. assert(PrevBB->getTerminator() && "Terminator removed from PrevBB!");
  344. // Make sure PHINode references to the block we are merging into are
  345. // updated to be incoming blocks from the predecessor to the current block.
  346. // NOTE: If this is updated such that the outlined block can have more than
  347. // one incoming block to a PHINode, this logic will have to updated
  348. // to handle multiple precessors instead.
  349. // We only need to update this if the outlined section contains a PHINode, if
  350. // it does not, then the incoming block was never changed in the first place.
  351. // On the other hand, if PrevBB has no predecessors, it means that all
  352. // incoming blocks to the first block are contained in the region, and there
  353. // will be nothing to update.
  354. Instruction *StartInst = (*Candidate->begin()).Inst;
  355. if (isa<PHINode>(StartInst) && !PrevBB->hasNPredecessors(0)) {
  356. assert(!PrevBB->hasNPredecessorsOrMore(2) &&
  357. "PrevBB has more than one predecessor. Should be 0 or 1.");
  358. BasicBlock *BeforePrevBB = PrevBB->getSinglePredecessor();
  359. PrevBB->replaceSuccessorsPhiUsesWith(PrevBB, BeforePrevBB);
  360. }
  361. PrevBB->getTerminator()->eraseFromParent();
  362. // If we reattaching after outlining, we iterate over the phi nodes to
  363. // the initial block, and reassign the branch instructions of the incoming
  364. // blocks to the block we are remerging into.
  365. if (!ExtractedFunction) {
  366. DenseSet<BasicBlock *> BBSet;
  367. Candidate->getBasicBlocks(BBSet);
  368. replaceTargetsFromPHINode(StartBB, StartBB, PrevBB, BBSet);
  369. if (!EndsInBranch)
  370. replaceTargetsFromPHINode(FollowBB, FollowBB, EndBB, BBSet);
  371. }
  372. moveBBContents(*StartBB, *PrevBB);
  373. BasicBlock *PlacementBB = PrevBB;
  374. if (StartBB != EndBB)
  375. PlacementBB = EndBB;
  376. if (!EndsInBranch && PlacementBB->getUniqueSuccessor() != nullptr) {
  377. assert(FollowBB != nullptr && "FollowBB for Candidate is not defined!");
  378. assert(PlacementBB->getTerminator() && "Terminator removed from EndBB!");
  379. PlacementBB->getTerminator()->eraseFromParent();
  380. moveBBContents(*FollowBB, *PlacementBB);
  381. PlacementBB->replaceSuccessorsPhiUsesWith(FollowBB, PlacementBB);
  382. FollowBB->eraseFromParent();
  383. }
  384. PrevBB->replaceSuccessorsPhiUsesWith(StartBB, PrevBB);
  385. StartBB->eraseFromParent();
  386. // Make sure to save changes back to the StartBB.
  387. StartBB = PrevBB;
  388. EndBB = nullptr;
  389. PrevBB = nullptr;
  390. FollowBB = nullptr;
  391. CandidateSplit = false;
  392. }
  393. /// Find whether \p V matches the Constants previously found for the \p GVN.
  394. ///
  395. /// \param V - The value to check for consistency.
  396. /// \param GVN - The global value number assigned to \p V.
  397. /// \param GVNToConstant - The mapping of global value number to Constants.
  398. /// \returns true if the Value matches the Constant mapped to by V and false if
  399. /// it \p V is a Constant but does not match.
  400. /// \returns std::nullopt if \p V is not a Constant.
  401. static std::optional<bool>
  402. constantMatches(Value *V, unsigned GVN,
  403. DenseMap<unsigned, Constant *> &GVNToConstant) {
  404. // See if we have a constants
  405. Constant *CST = dyn_cast<Constant>(V);
  406. if (!CST)
  407. return std::nullopt;
  408. // Holds a mapping from a global value number to a Constant.
  409. DenseMap<unsigned, Constant *>::iterator GVNToConstantIt;
  410. bool Inserted;
  411. // If we have a constant, try to make a new entry in the GVNToConstant.
  412. std::tie(GVNToConstantIt, Inserted) =
  413. GVNToConstant.insert(std::make_pair(GVN, CST));
  414. // If it was found and is not equal, it is not the same. We do not
  415. // handle this case yet, and exit early.
  416. if (Inserted || (GVNToConstantIt->second == CST))
  417. return true;
  418. return false;
  419. }
  420. InstructionCost OutlinableRegion::getBenefit(TargetTransformInfo &TTI) {
  421. InstructionCost Benefit = 0;
  422. // Estimate the benefit of outlining a specific sections of the program. We
  423. // delegate mostly this task to the TargetTransformInfo so that if the target
  424. // has specific changes, we can have a more accurate estimate.
  425. // However, getInstructionCost delegates the code size calculation for
  426. // arithmetic instructions to getArithmeticInstrCost in
  427. // include/Analysis/TargetTransformImpl.h, where it always estimates that the
  428. // code size for a division and remainder instruction to be equal to 4, and
  429. // everything else to 1. This is not an accurate representation of the
  430. // division instruction for targets that have a native division instruction.
  431. // To be overly conservative, we only add 1 to the number of instructions for
  432. // each division instruction.
  433. for (IRInstructionData &ID : *Candidate) {
  434. Instruction *I = ID.Inst;
  435. switch (I->getOpcode()) {
  436. case Instruction::FDiv:
  437. case Instruction::FRem:
  438. case Instruction::SDiv:
  439. case Instruction::SRem:
  440. case Instruction::UDiv:
  441. case Instruction::URem:
  442. Benefit += 1;
  443. break;
  444. default:
  445. Benefit += TTI.getInstructionCost(I, TargetTransformInfo::TCK_CodeSize);
  446. break;
  447. }
  448. }
  449. return Benefit;
  450. }
  451. /// Check the \p OutputMappings structure for value \p Input, if it exists
  452. /// it has been used as an output for outlining, and has been renamed, and we
  453. /// return the new value, otherwise, we return the same value.
  454. ///
  455. /// \param OutputMappings [in] - The mapping of values to their renamed value
  456. /// after being used as an output for an outlined region.
  457. /// \param Input [in] - The value to find the remapped value of, if it exists.
  458. /// \return The remapped value if it has been renamed, and the same value if has
  459. /// not.
  460. static Value *findOutputMapping(const DenseMap<Value *, Value *> OutputMappings,
  461. Value *Input) {
  462. DenseMap<Value *, Value *>::const_iterator OutputMapping =
  463. OutputMappings.find(Input);
  464. if (OutputMapping != OutputMappings.end())
  465. return OutputMapping->second;
  466. return Input;
  467. }
  468. /// Find whether \p Region matches the global value numbering to Constant
  469. /// mapping found so far.
  470. ///
  471. /// \param Region - The OutlinableRegion we are checking for constants
  472. /// \param GVNToConstant - The mapping of global value number to Constants.
  473. /// \param NotSame - The set of global value numbers that do not have the same
  474. /// constant in each region.
  475. /// \returns true if all Constants are the same in every use of a Constant in \p
  476. /// Region and false if not
  477. static bool
  478. collectRegionsConstants(OutlinableRegion &Region,
  479. DenseMap<unsigned, Constant *> &GVNToConstant,
  480. DenseSet<unsigned> &NotSame) {
  481. bool ConstantsTheSame = true;
  482. IRSimilarityCandidate &C = *Region.Candidate;
  483. for (IRInstructionData &ID : C) {
  484. // Iterate over the operands in an instruction. If the global value number,
  485. // assigned by the IRSimilarityCandidate, has been seen before, we check if
  486. // the the number has been found to be not the same value in each instance.
  487. for (Value *V : ID.OperVals) {
  488. std::optional<unsigned> GVNOpt = C.getGVN(V);
  489. assert(GVNOpt && "Expected a GVN for operand?");
  490. unsigned GVN = *GVNOpt;
  491. // Check if this global value has been found to not be the same already.
  492. if (NotSame.contains(GVN)) {
  493. if (isa<Constant>(V))
  494. ConstantsTheSame = false;
  495. continue;
  496. }
  497. // If it has been the same so far, we check the value for if the
  498. // associated Constant value match the previous instances of the same
  499. // global value number. If the global value does not map to a Constant,
  500. // it is considered to not be the same value.
  501. std::optional<bool> ConstantMatches =
  502. constantMatches(V, GVN, GVNToConstant);
  503. if (ConstantMatches) {
  504. if (*ConstantMatches)
  505. continue;
  506. else
  507. ConstantsTheSame = false;
  508. }
  509. // While this value is a register, it might not have been previously,
  510. // make sure we don't already have a constant mapped to this global value
  511. // number.
  512. if (GVNToConstant.find(GVN) != GVNToConstant.end())
  513. ConstantsTheSame = false;
  514. NotSame.insert(GVN);
  515. }
  516. }
  517. return ConstantsTheSame;
  518. }
  519. void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
  520. DenseMap<unsigned, Constant *> GVNToConstant;
  521. for (OutlinableRegion *Region : Regions)
  522. collectRegionsConstants(*Region, GVNToConstant, NotSame);
  523. }
  524. void OutlinableGroup::collectGVNStoreSets(Module &M) {
  525. for (OutlinableRegion *OS : Regions)
  526. OutputGVNCombinations.insert(OS->GVNStores);
  527. // We are adding an extracted argument to decide between which output path
  528. // to use in the basic block. It is used in a switch statement and only
  529. // needs to be an integer.
  530. if (OutputGVNCombinations.size() > 1)
  531. ArgumentTypes.push_back(Type::getInt32Ty(M.getContext()));
  532. }
  533. /// Get the subprogram if it exists for one of the outlined regions.
  534. ///
  535. /// \param [in] Group - The set of regions to find a subprogram for.
  536. /// \returns the subprogram if it exists, or nullptr.
  537. static DISubprogram *getSubprogramOrNull(OutlinableGroup &Group) {
  538. for (OutlinableRegion *OS : Group.Regions)
  539. if (Function *F = OS->Call->getFunction())
  540. if (DISubprogram *SP = F->getSubprogram())
  541. return SP;
  542. return nullptr;
  543. }
  544. Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
  545. unsigned FunctionNameSuffix) {
  546. assert(!Group.OutlinedFunction && "Function is already defined!");
  547. Type *RetTy = Type::getVoidTy(M.getContext());
  548. // All extracted functions _should_ have the same return type at this point
  549. // since the similarity identifier ensures that all branches outside of the
  550. // region occur in the same place.
  551. // NOTE: Should we ever move to the model that uses a switch at every point
  552. // needed, meaning that we could branch within the region or out, it is
  553. // possible that we will need to switch to using the most general case all of
  554. // the time.
  555. for (OutlinableRegion *R : Group.Regions) {
  556. Type *ExtractedFuncType = R->ExtractedFunction->getReturnType();
  557. if ((RetTy->isVoidTy() && !ExtractedFuncType->isVoidTy()) ||
  558. (RetTy->isIntegerTy(1) && ExtractedFuncType->isIntegerTy(16)))
  559. RetTy = ExtractedFuncType;
  560. }
  561. Group.OutlinedFunctionType = FunctionType::get(
  562. RetTy, Group.ArgumentTypes, false);
  563. // These functions will only be called from within the same module, so
  564. // we can set an internal linkage.
  565. Group.OutlinedFunction = Function::Create(
  566. Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
  567. "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);
  568. // Transfer the swifterr attribute to the correct function parameter.
  569. if (Group.SwiftErrorArgument)
  570. Group.OutlinedFunction->addParamAttr(*Group.SwiftErrorArgument,
  571. Attribute::SwiftError);
  572. Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
  573. Group.OutlinedFunction->addFnAttr(Attribute::MinSize);
  574. // If there's a DISubprogram associated with this outlined function, then
  575. // emit debug info for the outlined function.
  576. if (DISubprogram *SP = getSubprogramOrNull(Group)) {
  577. Function *F = Group.OutlinedFunction;
  578. // We have a DISubprogram. Get its DICompileUnit.
  579. DICompileUnit *CU = SP->getUnit();
  580. DIBuilder DB(M, true, CU);
  581. DIFile *Unit = SP->getFile();
  582. Mangler Mg;
  583. // Get the mangled name of the function for the linkage name.
  584. std::string Dummy;
  585. llvm::raw_string_ostream MangledNameStream(Dummy);
  586. Mg.getNameWithPrefix(MangledNameStream, F, false);
  587. DISubprogram *OutlinedSP = DB.createFunction(
  588. Unit /* Context */, F->getName(), MangledNameStream.str(),
  589. Unit /* File */,
  590. 0 /* Line 0 is reserved for compiler-generated code. */,
  591. DB.createSubroutineType(
  592. DB.getOrCreateTypeArray(std::nullopt)), /* void type */
  593. 0, /* Line 0 is reserved for compiler-generated code. */
  594. DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
  595. /* Outlined code is optimized code by definition. */
  596. DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
  597. // Don't add any new variables to the subprogram.
  598. DB.finalizeSubprogram(OutlinedSP);
  599. // Attach subprogram to the function.
  600. F->setSubprogram(OutlinedSP);
  601. // We're done with the DIBuilder.
  602. DB.finalize();
  603. }
  604. return Group.OutlinedFunction;
  605. }
  606. /// Move each BasicBlock in \p Old to \p New.
  607. ///
  608. /// \param [in] Old - The function to move the basic blocks from.
  609. /// \param [in] New - The function to move the basic blocks to.
  610. /// \param [out] NewEnds - The return blocks of the new overall function.
  611. static void moveFunctionData(Function &Old, Function &New,
  612. DenseMap<Value *, BasicBlock *> &NewEnds) {
  613. for (BasicBlock &CurrBB : llvm::make_early_inc_range(Old)) {
  614. CurrBB.removeFromParent();
  615. CurrBB.insertInto(&New);
  616. Instruction *I = CurrBB.getTerminator();
  617. // For each block we find a return instruction is, it is a potential exit
  618. // path for the function. We keep track of each block based on the return
  619. // value here.
  620. if (ReturnInst *RI = dyn_cast<ReturnInst>(I))
  621. NewEnds.insert(std::make_pair(RI->getReturnValue(), &CurrBB));
  622. std::vector<Instruction *> DebugInsts;
  623. for (Instruction &Val : CurrBB) {
  624. // We must handle the scoping of called functions differently than
  625. // other outlined instructions.
  626. if (!isa<CallInst>(&Val)) {
  627. // Remove the debug information for outlined functions.
  628. Val.setDebugLoc(DebugLoc());
  629. // Loop info metadata may contain line locations. Update them to have no
  630. // value in the new subprogram since the outlined code could be from
  631. // several locations.
  632. auto updateLoopInfoLoc = [&New](Metadata *MD) -> Metadata * {
  633. if (DISubprogram *SP = New.getSubprogram())
  634. if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
  635. return DILocation::get(New.getContext(), Loc->getLine(),
  636. Loc->getColumn(), SP, nullptr);
  637. return MD;
  638. };
  639. updateLoopMetadataDebugLocations(Val, updateLoopInfoLoc);
  640. continue;
  641. }
  642. // From this point we are only handling call instructions.
  643. CallInst *CI = cast<CallInst>(&Val);
  644. // We add any debug statements here, to be removed after. Since the
  645. // instructions originate from many different locations in the program,
  646. // it will cause incorrect reporting from a debugger if we keep the
  647. // same debug instructions.
  648. if (isa<DbgInfoIntrinsic>(CI)) {
  649. DebugInsts.push_back(&Val);
  650. continue;
  651. }
  652. // Edit the scope of called functions inside of outlined functions.
  653. if (DISubprogram *SP = New.getSubprogram()) {
  654. DILocation *DI = DILocation::get(New.getContext(), 0, 0, SP);
  655. Val.setDebugLoc(DI);
  656. }
  657. }
  658. for (Instruction *I : DebugInsts)
  659. I->eraseFromParent();
  660. }
  661. }
  662. /// Find the the constants that will need to be lifted into arguments
  663. /// as they are not the same in each instance of the region.
  664. ///
  665. /// \param [in] C - The IRSimilarityCandidate containing the region we are
  666. /// analyzing.
  667. /// \param [in] NotSame - The set of global value numbers that do not have a
  668. /// single Constant across all OutlinableRegions similar to \p C.
  669. /// \param [out] Inputs - The list containing the global value numbers of the
  670. /// arguments needed for the region of code.
  671. static void findConstants(IRSimilarityCandidate &C, DenseSet<unsigned> &NotSame,
  672. std::vector<unsigned> &Inputs) {
  673. DenseSet<unsigned> Seen;
  674. // Iterate over the instructions, and find what constants will need to be
  675. // extracted into arguments.
  676. for (IRInstructionDataList::iterator IDIt = C.begin(), EndIDIt = C.end();
  677. IDIt != EndIDIt; IDIt++) {
  678. for (Value *V : (*IDIt).OperVals) {
  679. // Since these are stored before any outlining, they will be in the
  680. // global value numbering.
  681. unsigned GVN = *C.getGVN(V);
  682. if (isa<Constant>(V))
  683. if (NotSame.contains(GVN) && !Seen.contains(GVN)) {
  684. Inputs.push_back(GVN);
  685. Seen.insert(GVN);
  686. }
  687. }
  688. }
  689. }
  690. /// Find the GVN for the inputs that have been found by the CodeExtractor.
  691. ///
  692. /// \param [in] C - The IRSimilarityCandidate containing the region we are
  693. /// analyzing.
  694. /// \param [in] CurrentInputs - The set of inputs found by the
  695. /// CodeExtractor.
  696. /// \param [in] OutputMappings - The mapping of values that have been replaced
  697. /// by a new output value.
  698. /// \param [out] EndInputNumbers - The global value numbers for the extracted
  699. /// arguments.
  700. static void mapInputsToGVNs(IRSimilarityCandidate &C,
  701. SetVector<Value *> &CurrentInputs,
  702. const DenseMap<Value *, Value *> &OutputMappings,
  703. std::vector<unsigned> &EndInputNumbers) {
  704. // Get the Global Value Number for each input. We check if the Value has been
  705. // replaced by a different value at output, and use the original value before
  706. // replacement.
  707. for (Value *Input : CurrentInputs) {
  708. assert(Input && "Have a nullptr as an input");
  709. if (OutputMappings.find(Input) != OutputMappings.end())
  710. Input = OutputMappings.find(Input)->second;
  711. assert(C.getGVN(Input) && "Could not find a numbering for the given input");
  712. EndInputNumbers.push_back(*C.getGVN(Input));
  713. }
  714. }
  715. /// Find the original value for the \p ArgInput values if any one of them was
  716. /// replaced during a previous extraction.
  717. ///
  718. /// \param [in] ArgInputs - The inputs to be extracted by the code extractor.
  719. /// \param [in] OutputMappings - The mapping of values that have been replaced
  720. /// by a new output value.
  721. /// \param [out] RemappedArgInputs - The remapped values according to
  722. /// \p OutputMappings that will be extracted.
  723. static void
  724. remapExtractedInputs(const ArrayRef<Value *> ArgInputs,
  725. const DenseMap<Value *, Value *> &OutputMappings,
  726. SetVector<Value *> &RemappedArgInputs) {
  727. // Get the global value number for each input that will be extracted as an
  728. // argument by the code extractor, remapping if needed for reloaded values.
  729. for (Value *Input : ArgInputs) {
  730. if (OutputMappings.find(Input) != OutputMappings.end())
  731. Input = OutputMappings.find(Input)->second;
  732. RemappedArgInputs.insert(Input);
  733. }
  734. }
  735. /// Find the input GVNs and the output values for a region of Instructions.
  736. /// Using the code extractor, we collect the inputs to the extracted function.
  737. ///
  738. /// The \p Region can be identified as needing to be ignored in this function.
  739. /// It should be checked whether it should be ignored after a call to this
  740. /// function.
  741. ///
  742. /// \param [in,out] Region - The region of code to be analyzed.
  743. /// \param [out] InputGVNs - The global value numbers for the extracted
  744. /// arguments.
  745. /// \param [in] NotSame - The global value numbers in the region that do not
  746. /// have the same constant value in the regions structurally similar to
  747. /// \p Region.
  748. /// \param [in] OutputMappings - The mapping of values that have been replaced
  749. /// by a new output value after extraction.
  750. /// \param [out] ArgInputs - The values of the inputs to the extracted function.
  751. /// \param [out] Outputs - The set of values extracted by the CodeExtractor
  752. /// as outputs.
  753. static void getCodeExtractorArguments(
  754. OutlinableRegion &Region, std::vector<unsigned> &InputGVNs,
  755. DenseSet<unsigned> &NotSame, DenseMap<Value *, Value *> &OutputMappings,
  756. SetVector<Value *> &ArgInputs, SetVector<Value *> &Outputs) {
  757. IRSimilarityCandidate &C = *Region.Candidate;
  758. // OverallInputs are the inputs to the region found by the CodeExtractor,
  759. // SinkCands and HoistCands are used by the CodeExtractor to find sunken
  760. // allocas of values whose lifetimes are contained completely within the
  761. // outlined region. PremappedInputs are the arguments found by the
  762. // CodeExtractor, removing conditions such as sunken allocas, but that
  763. // may need to be remapped due to the extracted output values replacing
  764. // the original values. We use DummyOutputs for this first run of finding
  765. // inputs and outputs since the outputs could change during findAllocas,
  766. // the correct set of extracted outputs will be in the final Outputs ValueSet.
  767. SetVector<Value *> OverallInputs, PremappedInputs, SinkCands, HoistCands,
  768. DummyOutputs;
  769. // Use the code extractor to get the inputs and outputs, without sunken
  770. // allocas or removing llvm.assumes.
  771. CodeExtractor *CE = Region.CE;
  772. CE->findInputsOutputs(OverallInputs, DummyOutputs, SinkCands);
  773. assert(Region.StartBB && "Region must have a start BasicBlock!");
  774. Function *OrigF = Region.StartBB->getParent();
  775. CodeExtractorAnalysisCache CEAC(*OrigF);
  776. BasicBlock *Dummy = nullptr;
  777. // The region may be ineligible due to VarArgs in the parent function. In this
  778. // case we ignore the region.
  779. if (!CE->isEligible()) {
  780. Region.IgnoreRegion = true;
  781. return;
  782. }
  783. // Find if any values are going to be sunk into the function when extracted
  784. CE->findAllocas(CEAC, SinkCands, HoistCands, Dummy);
  785. CE->findInputsOutputs(PremappedInputs, Outputs, SinkCands);
  786. // TODO: Support regions with sunken allocas: values whose lifetimes are
  787. // contained completely within the outlined region. These are not guaranteed
  788. // to be the same in every region, so we must elevate them all to arguments
  789. // when they appear. If these values are not equal, it means there is some
  790. // Input in OverallInputs that was removed for ArgInputs.
  791. if (OverallInputs.size() != PremappedInputs.size()) {
  792. Region.IgnoreRegion = true;
  793. return;
  794. }
  795. findConstants(C, NotSame, InputGVNs);
  796. mapInputsToGVNs(C, OverallInputs, OutputMappings, InputGVNs);
  797. remapExtractedInputs(PremappedInputs.getArrayRef(), OutputMappings,
  798. ArgInputs);
  799. // Sort the GVNs, since we now have constants included in the \ref InputGVNs
  800. // we need to make sure they are in a deterministic order.
  801. stable_sort(InputGVNs);
  802. }
  803. /// Look over the inputs and map each input argument to an argument in the
  804. /// overall function for the OutlinableRegions. This creates a way to replace
  805. /// the arguments of the extracted function with the arguments of the new
  806. /// overall function.
  807. ///
  808. /// \param [in,out] Region - The region of code to be analyzed.
  809. /// \param [in] InputGVNs - The global value numbering of the input values
  810. /// collected.
  811. /// \param [in] ArgInputs - The values of the arguments to the extracted
  812. /// function.
  813. static void
  814. findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
  815. std::vector<unsigned> &InputGVNs,
  816. SetVector<Value *> &ArgInputs) {
  817. IRSimilarityCandidate &C = *Region.Candidate;
  818. OutlinableGroup &Group = *Region.Parent;
  819. // This counts the argument number in the overall function.
  820. unsigned TypeIndex = 0;
  821. // This counts the argument number in the extracted function.
  822. unsigned OriginalIndex = 0;
  823. // Find the mapping of the extracted arguments to the arguments for the
  824. // overall function. Since there may be extra arguments in the overall
  825. // function to account for the extracted constants, we have two different
  826. // counters as we find extracted arguments, and as we come across overall
  827. // arguments.
  828. // Additionally, in our first pass, for the first extracted function,
  829. // we find argument locations for the canonical value numbering. This
  830. // numbering overrides any discovered location for the extracted code.
  831. for (unsigned InputVal : InputGVNs) {
  832. std::optional<unsigned> CanonicalNumberOpt = C.getCanonicalNum(InputVal);
  833. assert(CanonicalNumberOpt && "Canonical number not found?");
  834. unsigned CanonicalNumber = *CanonicalNumberOpt;
  835. std::optional<Value *> InputOpt = C.fromGVN(InputVal);
  836. assert(InputOpt && "Global value number not found?");
  837. Value *Input = *InputOpt;
  838. DenseMap<unsigned, unsigned>::iterator AggArgIt =
  839. Group.CanonicalNumberToAggArg.find(CanonicalNumber);
  840. if (!Group.InputTypesSet) {
  841. Group.ArgumentTypes.push_back(Input->getType());
  842. // If the input value has a swifterr attribute, make sure to mark the
  843. // argument in the overall function.
  844. if (Input->isSwiftError()) {
  845. assert(
  846. !Group.SwiftErrorArgument &&
  847. "Argument already marked with swifterr for this OutlinableGroup!");
  848. Group.SwiftErrorArgument = TypeIndex;
  849. }
  850. }
  851. // Check if we have a constant. If we do add it to the overall argument
  852. // number to Constant map for the region, and continue to the next input.
  853. if (Constant *CST = dyn_cast<Constant>(Input)) {
  854. if (AggArgIt != Group.CanonicalNumberToAggArg.end())
  855. Region.AggArgToConstant.insert(std::make_pair(AggArgIt->second, CST));
  856. else {
  857. Group.CanonicalNumberToAggArg.insert(
  858. std::make_pair(CanonicalNumber, TypeIndex));
  859. Region.AggArgToConstant.insert(std::make_pair(TypeIndex, CST));
  860. }
  861. TypeIndex++;
  862. continue;
  863. }
  864. // It is not a constant, we create the mapping from extracted argument list
  865. // to the overall argument list, using the canonical location, if it exists.
  866. assert(ArgInputs.count(Input) && "Input cannot be found!");
  867. if (AggArgIt != Group.CanonicalNumberToAggArg.end()) {
  868. if (OriginalIndex != AggArgIt->second)
  869. Region.ChangedArgOrder = true;
  870. Region.ExtractedArgToAgg.insert(
  871. std::make_pair(OriginalIndex, AggArgIt->second));
  872. Region.AggArgToExtracted.insert(
  873. std::make_pair(AggArgIt->second, OriginalIndex));
  874. } else {
  875. Group.CanonicalNumberToAggArg.insert(
  876. std::make_pair(CanonicalNumber, TypeIndex));
  877. Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, TypeIndex));
  878. Region.AggArgToExtracted.insert(std::make_pair(TypeIndex, OriginalIndex));
  879. }
  880. OriginalIndex++;
  881. TypeIndex++;
  882. }
  883. // If the function type definitions for the OutlinableGroup holding the region
  884. // have not been set, set the length of the inputs here. We should have the
  885. // same inputs for all of the different regions contained in the
  886. // OutlinableGroup since they are all structurally similar to one another.
  887. if (!Group.InputTypesSet) {
  888. Group.NumAggregateInputs = TypeIndex;
  889. Group.InputTypesSet = true;
  890. }
  891. Region.NumExtractedInputs = OriginalIndex;
  892. }
  893. /// Check if the \p V has any uses outside of the region other than \p PN.
  894. ///
  895. /// \param V [in] - The value to check.
  896. /// \param PHILoc [in] - The location in the PHINode of \p V.
  897. /// \param PN [in] - The PHINode using \p V.
  898. /// \param Exits [in] - The potential blocks we exit to from the outlined
  899. /// region.
  900. /// \param BlocksInRegion [in] - The basic blocks contained in the region.
  901. /// \returns true if \p V has any use soutside its region other than \p PN.
  902. static bool outputHasNonPHI(Value *V, unsigned PHILoc, PHINode &PN,
  903. SmallPtrSet<BasicBlock *, 1> &Exits,
  904. DenseSet<BasicBlock *> &BlocksInRegion) {
  905. // We check to see if the value is used by the PHINode from some other
  906. // predecessor not included in the region. If it is, we make sure
  907. // to keep it as an output.
  908. if (any_of(llvm::seq<unsigned>(0, PN.getNumIncomingValues()),
  909. [PHILoc, &PN, V, &BlocksInRegion](unsigned Idx) {
  910. return (Idx != PHILoc && V == PN.getIncomingValue(Idx) &&
  911. !BlocksInRegion.contains(PN.getIncomingBlock(Idx)));
  912. }))
  913. return true;
  914. // Check if the value is used by any other instructions outside the region.
  915. return any_of(V->users(), [&Exits, &BlocksInRegion](User *U) {
  916. Instruction *I = dyn_cast<Instruction>(U);
  917. if (!I)
  918. return false;
  919. // If the use of the item is inside the region, we skip it. Uses
  920. // inside the region give us useful information about how the item could be
  921. // used as an output.
  922. BasicBlock *Parent = I->getParent();
  923. if (BlocksInRegion.contains(Parent))
  924. return false;
  925. // If it's not a PHINode then we definitely know the use matters. This
  926. // output value will not completely combined with another item in a PHINode
  927. // as it is directly reference by another non-phi instruction
  928. if (!isa<PHINode>(I))
  929. return true;
  930. // If we have a PHINode outside one of the exit locations, then it
  931. // can be considered an outside use as well. If there is a PHINode
  932. // contained in the Exit where this values use matters, it will be
  933. // caught when we analyze that PHINode.
  934. if (!Exits.contains(Parent))
  935. return true;
  936. return false;
  937. });
  938. }
  939. /// Test whether \p CurrentExitFromRegion contains any PhiNodes that should be
  940. /// considered outputs. A PHINodes is an output when more than one incoming
  941. /// value has been marked by the CodeExtractor as an output.
  942. ///
  943. /// \param CurrentExitFromRegion [in] - The block to analyze.
  944. /// \param PotentialExitsFromRegion [in] - The potential exit blocks from the
  945. /// region.
  946. /// \param RegionBlocks [in] - The basic blocks in the region.
  947. /// \param Outputs [in, out] - The existing outputs for the region, we may add
  948. /// PHINodes to this as we find that they replace output values.
  949. /// \param OutputsReplacedByPHINode [out] - A set containing outputs that are
  950. /// totally replaced by a PHINode.
  951. /// \param OutputsWithNonPhiUses [out] - A set containing outputs that are used
  952. /// in PHINodes, but have other uses, and should still be considered outputs.
  953. static void analyzeExitPHIsForOutputUses(
  954. BasicBlock *CurrentExitFromRegion,
  955. SmallPtrSet<BasicBlock *, 1> &PotentialExitsFromRegion,
  956. DenseSet<BasicBlock *> &RegionBlocks, SetVector<Value *> &Outputs,
  957. DenseSet<Value *> &OutputsReplacedByPHINode,
  958. DenseSet<Value *> &OutputsWithNonPhiUses) {
  959. for (PHINode &PN : CurrentExitFromRegion->phis()) {
  960. // Find all incoming values from the outlining region.
  961. SmallVector<unsigned, 2> IncomingVals;
  962. for (unsigned I = 0, E = PN.getNumIncomingValues(); I < E; ++I)
  963. if (RegionBlocks.contains(PN.getIncomingBlock(I)))
  964. IncomingVals.push_back(I);
  965. // Do not process PHI if there are no predecessors from region.
  966. unsigned NumIncomingVals = IncomingVals.size();
  967. if (NumIncomingVals == 0)
  968. continue;
  969. // If there is one predecessor, we mark it as a value that needs to be kept
  970. // as an output.
  971. if (NumIncomingVals == 1) {
  972. Value *V = PN.getIncomingValue(*IncomingVals.begin());
  973. OutputsWithNonPhiUses.insert(V);
  974. OutputsReplacedByPHINode.erase(V);
  975. continue;
  976. }
  977. // This PHINode will be used as an output value, so we add it to our list.
  978. Outputs.insert(&PN);
  979. // Not all of the incoming values should be ignored as other inputs and
  980. // outputs may have uses in outlined region. If they have other uses
  981. // outside of the single PHINode we should not skip over it.
  982. for (unsigned Idx : IncomingVals) {
  983. Value *V = PN.getIncomingValue(Idx);
  984. if (outputHasNonPHI(V, Idx, PN, PotentialExitsFromRegion, RegionBlocks)) {
  985. OutputsWithNonPhiUses.insert(V);
  986. OutputsReplacedByPHINode.erase(V);
  987. continue;
  988. }
  989. if (!OutputsWithNonPhiUses.contains(V))
  990. OutputsReplacedByPHINode.insert(V);
  991. }
  992. }
  993. }
  994. // Represents the type for the unsigned number denoting the output number for
  995. // phi node, along with the canonical number for the exit block.
  996. using ArgLocWithBBCanon = std::pair<unsigned, unsigned>;
  997. // The list of canonical numbers for the incoming values to a PHINode.
  998. using CanonList = SmallVector<unsigned, 2>;
  999. // The pair type representing the set of canonical values being combined in the
  1000. // PHINode, along with the location data for the PHINode.
  1001. using PHINodeData = std::pair<ArgLocWithBBCanon, CanonList>;
  1002. /// Encode \p PND as an integer for easy lookup based on the argument location,
  1003. /// the parent BasicBlock canonical numbering, and the canonical numbering of
  1004. /// the values stored in the PHINode.
  1005. ///
  1006. /// \param PND - The data to hash.
  1007. /// \returns The hash code of \p PND.
  1008. static hash_code encodePHINodeData(PHINodeData &PND) {
  1009. return llvm::hash_combine(
  1010. llvm::hash_value(PND.first.first), llvm::hash_value(PND.first.second),
  1011. llvm::hash_combine_range(PND.second.begin(), PND.second.end()));
  1012. }
  1013. /// Create a special GVN for PHINodes that will be used outside of
  1014. /// the region. We create a hash code based on the Canonical number of the
  1015. /// parent BasicBlock, the canonical numbering of the values stored in the
  1016. /// PHINode and the aggregate argument location. This is used to find whether
  1017. /// this PHINode type has been given a canonical numbering already. If not, we
  1018. /// assign it a value and store it for later use. The value is returned to
  1019. /// identify different output schemes for the set of regions.
  1020. ///
  1021. /// \param Region - The region that \p PN is an output for.
  1022. /// \param PN - The PHINode we are analyzing.
  1023. /// \param Blocks - The blocks for the region we are analyzing.
  1024. /// \param AggArgIdx - The argument \p PN will be stored into.
  1025. /// \returns An optional holding the assigned canonical number, or std::nullopt
  1026. /// if there is some attribute of the PHINode blocking it from being used.
  1027. static std::optional<unsigned> getGVNForPHINode(OutlinableRegion &Region,
  1028. PHINode *PN,
  1029. DenseSet<BasicBlock *> &Blocks,
  1030. unsigned AggArgIdx) {
  1031. OutlinableGroup &Group = *Region.Parent;
  1032. IRSimilarityCandidate &Cand = *Region.Candidate;
  1033. BasicBlock *PHIBB = PN->getParent();
  1034. CanonList PHIGVNs;
  1035. Value *Incoming;
  1036. BasicBlock *IncomingBlock;
  1037. for (unsigned Idx = 0, EIdx = PN->getNumIncomingValues(); Idx < EIdx; Idx++) {
  1038. Incoming = PN->getIncomingValue(Idx);
  1039. IncomingBlock = PN->getIncomingBlock(Idx);
  1040. // If we cannot find a GVN, and the incoming block is included in the region
  1041. // this means that the input to the PHINode is not included in the region we
  1042. // are trying to analyze, meaning, that if it was outlined, we would be
  1043. // adding an extra input. We ignore this case for now, and so ignore the
  1044. // region.
  1045. std::optional<unsigned> OGVN = Cand.getGVN(Incoming);
  1046. if (!OGVN && Blocks.contains(IncomingBlock)) {
  1047. Region.IgnoreRegion = true;
  1048. return std::nullopt;
  1049. }
  1050. // If the incoming block isn't in the region, we don't have to worry about
  1051. // this incoming value.
  1052. if (!Blocks.contains(IncomingBlock))
  1053. continue;
  1054. // Collect the canonical numbers of the values in the PHINode.
  1055. unsigned GVN = *OGVN;
  1056. OGVN = Cand.getCanonicalNum(GVN);
  1057. assert(OGVN && "No GVN found for incoming value?");
  1058. PHIGVNs.push_back(*OGVN);
  1059. // Find the incoming block and use the canonical numbering as well to define
  1060. // the hash for the PHINode.
  1061. OGVN = Cand.getGVN(IncomingBlock);
  1062. // If there is no number for the incoming block, it is because we have
  1063. // split the candidate basic blocks. So we use the previous block that it
  1064. // was split from to find the valid global value numbering for the PHINode.
  1065. if (!OGVN) {
  1066. assert(Cand.getStartBB() == IncomingBlock &&
  1067. "Unknown basic block used in exit path PHINode.");
  1068. BasicBlock *PrevBlock = nullptr;
  1069. // Iterate over the predecessors to the incoming block of the
  1070. // PHINode, when we find a block that is not contained in the region
  1071. // we know that this is the first block that we split from, and should
  1072. // have a valid global value numbering.
  1073. for (BasicBlock *Pred : predecessors(IncomingBlock))
  1074. if (!Blocks.contains(Pred)) {
  1075. PrevBlock = Pred;
  1076. break;
  1077. }
  1078. assert(PrevBlock && "Expected a predecessor not in the reigon!");
  1079. OGVN = Cand.getGVN(PrevBlock);
  1080. }
  1081. GVN = *OGVN;
  1082. OGVN = Cand.getCanonicalNum(GVN);
  1083. assert(OGVN && "No GVN found for incoming block?");
  1084. PHIGVNs.push_back(*OGVN);
  1085. }
  1086. // Now that we have the GVNs for the incoming values, we are going to combine
  1087. // them with the GVN of the incoming bock, and the output location of the
  1088. // PHINode to generate a hash value representing this instance of the PHINode.
  1089. DenseMap<hash_code, unsigned>::iterator GVNToPHIIt;
  1090. DenseMap<unsigned, PHINodeData>::iterator PHIToGVNIt;
  1091. std::optional<unsigned> BBGVN = Cand.getGVN(PHIBB);
  1092. assert(BBGVN && "Could not find GVN for the incoming block!");
  1093. BBGVN = Cand.getCanonicalNum(*BBGVN);
  1094. assert(BBGVN && "Could not find canonical number for the incoming block!");
  1095. // Create a pair of the exit block canonical value, and the aggregate
  1096. // argument location, connected to the canonical numbers stored in the
  1097. // PHINode.
  1098. PHINodeData TemporaryPair =
  1099. std::make_pair(std::make_pair(*BBGVN, AggArgIdx), PHIGVNs);
  1100. hash_code PHINodeDataHash = encodePHINodeData(TemporaryPair);
  1101. // Look for and create a new entry in our connection between canonical
  1102. // numbers for PHINodes, and the set of objects we just created.
  1103. GVNToPHIIt = Group.GVNsToPHINodeGVN.find(PHINodeDataHash);
  1104. if (GVNToPHIIt == Group.GVNsToPHINodeGVN.end()) {
  1105. bool Inserted = false;
  1106. std::tie(PHIToGVNIt, Inserted) = Group.PHINodeGVNToGVNs.insert(
  1107. std::make_pair(Group.PHINodeGVNTracker, TemporaryPair));
  1108. std::tie(GVNToPHIIt, Inserted) = Group.GVNsToPHINodeGVN.insert(
  1109. std::make_pair(PHINodeDataHash, Group.PHINodeGVNTracker--));
  1110. }
  1111. return GVNToPHIIt->second;
  1112. }
  1113. /// Create a mapping of the output arguments for the \p Region to the output
  1114. /// arguments of the overall outlined function.
  1115. ///
  1116. /// \param [in,out] Region - The region of code to be analyzed.
  1117. /// \param [in] Outputs - The values found by the code extractor.
  1118. static void
  1119. findExtractedOutputToOverallOutputMapping(Module &M, OutlinableRegion &Region,
  1120. SetVector<Value *> &Outputs) {
  1121. OutlinableGroup &Group = *Region.Parent;
  1122. IRSimilarityCandidate &C = *Region.Candidate;
  1123. SmallVector<BasicBlock *> BE;
  1124. DenseSet<BasicBlock *> BlocksInRegion;
  1125. C.getBasicBlocks(BlocksInRegion, BE);
  1126. // Find the exits to the region.
  1127. SmallPtrSet<BasicBlock *, 1> Exits;
  1128. for (BasicBlock *Block : BE)
  1129. for (BasicBlock *Succ : successors(Block))
  1130. if (!BlocksInRegion.contains(Succ))
  1131. Exits.insert(Succ);
  1132. // After determining which blocks exit to PHINodes, we add these PHINodes to
  1133. // the set of outputs to be processed. We also check the incoming values of
  1134. // the PHINodes for whether they should no longer be considered outputs.
  1135. DenseSet<Value *> OutputsReplacedByPHINode;
  1136. DenseSet<Value *> OutputsWithNonPhiUses;
  1137. for (BasicBlock *ExitBB : Exits)
  1138. analyzeExitPHIsForOutputUses(ExitBB, Exits, BlocksInRegion, Outputs,
  1139. OutputsReplacedByPHINode,
  1140. OutputsWithNonPhiUses);
  1141. // This counts the argument number in the extracted function.
  1142. unsigned OriginalIndex = Region.NumExtractedInputs;
  1143. // This counts the argument number in the overall function.
  1144. unsigned TypeIndex = Group.NumAggregateInputs;
  1145. bool TypeFound;
  1146. DenseSet<unsigned> AggArgsUsed;
  1147. // Iterate over the output types and identify if there is an aggregate pointer
  1148. // type whose base type matches the current output type. If there is, we mark
  1149. // that we will use this output register for this value. If not we add another
  1150. // type to the overall argument type list. We also store the GVNs used for
  1151. // stores to identify which values will need to be moved into an special
  1152. // block that holds the stores to the output registers.
  1153. for (Value *Output : Outputs) {
  1154. TypeFound = false;
  1155. // We can do this since it is a result value, and will have a number
  1156. // that is necessarily the same. BUT if in the future, the instructions
  1157. // do not have to be in same order, but are functionally the same, we will
  1158. // have to use a different scheme, as one-to-one correspondence is not
  1159. // guaranteed.
  1160. unsigned ArgumentSize = Group.ArgumentTypes.size();
  1161. // If the output is combined in a PHINode, we make sure to skip over it.
  1162. if (OutputsReplacedByPHINode.contains(Output))
  1163. continue;
  1164. unsigned AggArgIdx = 0;
  1165. for (unsigned Jdx = TypeIndex; Jdx < ArgumentSize; Jdx++) {
  1166. if (Group.ArgumentTypes[Jdx] != PointerType::getUnqual(Output->getType()))
  1167. continue;
  1168. if (AggArgsUsed.contains(Jdx))
  1169. continue;
  1170. TypeFound = true;
  1171. AggArgsUsed.insert(Jdx);
  1172. Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, Jdx));
  1173. Region.AggArgToExtracted.insert(std::make_pair(Jdx, OriginalIndex));
  1174. AggArgIdx = Jdx;
  1175. break;
  1176. }
  1177. // We were unable to find an unused type in the output type set that matches
  1178. // the output, so we add a pointer type to the argument types of the overall
  1179. // function to handle this output and create a mapping to it.
  1180. if (!TypeFound) {
  1181. Group.ArgumentTypes.push_back(Output->getType()->getPointerTo(
  1182. M.getDataLayout().getAllocaAddrSpace()));
  1183. // Mark the new pointer type as the last value in the aggregate argument
  1184. // list.
  1185. unsigned ArgTypeIdx = Group.ArgumentTypes.size() - 1;
  1186. AggArgsUsed.insert(ArgTypeIdx);
  1187. Region.ExtractedArgToAgg.insert(
  1188. std::make_pair(OriginalIndex, ArgTypeIdx));
  1189. Region.AggArgToExtracted.insert(
  1190. std::make_pair(ArgTypeIdx, OriginalIndex));
  1191. AggArgIdx = ArgTypeIdx;
  1192. }
  1193. // TODO: Adapt to the extra input from the PHINode.
  1194. PHINode *PN = dyn_cast<PHINode>(Output);
  1195. std::optional<unsigned> GVN;
  1196. if (PN && !BlocksInRegion.contains(PN->getParent())) {
  1197. // Values outside the region can be combined into PHINode when we
  1198. // have multiple exits. We collect both of these into a list to identify
  1199. // which values are being used in the PHINode. Each list identifies a
  1200. // different PHINode, and a different output. We store the PHINode as it's
  1201. // own canonical value. These canonical values are also dependent on the
  1202. // output argument it is saved to.
  1203. // If two PHINodes have the same canonical values, but different aggregate
  1204. // argument locations, then they will have distinct Canonical Values.
  1205. GVN = getGVNForPHINode(Region, PN, BlocksInRegion, AggArgIdx);
  1206. if (!GVN)
  1207. return;
  1208. } else {
  1209. // If we do not have a PHINode we use the global value numbering for the
  1210. // output value, to find the canonical number to add to the set of stored
  1211. // values.
  1212. GVN = C.getGVN(Output);
  1213. GVN = C.getCanonicalNum(*GVN);
  1214. }
  1215. // Each region has a potentially unique set of outputs. We save which
  1216. // values are output in a list of canonical values so we can differentiate
  1217. // among the different store schemes.
  1218. Region.GVNStores.push_back(*GVN);
  1219. OriginalIndex++;
  1220. TypeIndex++;
  1221. }
  1222. // We sort the stored values to make sure that we are not affected by analysis
  1223. // order when determining what combination of items were stored.
  1224. stable_sort(Region.GVNStores);
  1225. }
  1226. void IROutliner::findAddInputsOutputs(Module &M, OutlinableRegion &Region,
  1227. DenseSet<unsigned> &NotSame) {
  1228. std::vector<unsigned> Inputs;
  1229. SetVector<Value *> ArgInputs, Outputs;
  1230. getCodeExtractorArguments(Region, Inputs, NotSame, OutputMappings, ArgInputs,
  1231. Outputs);
  1232. if (Region.IgnoreRegion)
  1233. return;
  1234. // Map the inputs found by the CodeExtractor to the arguments found for
  1235. // the overall function.
  1236. findExtractedInputToOverallInputMapping(Region, Inputs, ArgInputs);
  1237. // Map the outputs found by the CodeExtractor to the arguments found for
  1238. // the overall function.
  1239. findExtractedOutputToOverallOutputMapping(M, Region, Outputs);
  1240. }
  1241. /// Replace the extracted function in the Region with a call to the overall
  1242. /// function constructed from the deduplicated similar regions, replacing and
  1243. /// remapping the values passed to the extracted function as arguments to the
  1244. /// new arguments of the overall function.
  1245. ///
  1246. /// \param [in] M - The module to outline from.
  1247. /// \param [in] Region - The regions of extracted code to be replaced with a new
  1248. /// function.
  1249. /// \returns a call instruction with the replaced function.
  1250. CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
  1251. std::vector<Value *> NewCallArgs;
  1252. DenseMap<unsigned, unsigned>::iterator ArgPair;
  1253. OutlinableGroup &Group = *Region.Parent;
  1254. CallInst *Call = Region.Call;
  1255. assert(Call && "Call to replace is nullptr?");
  1256. Function *AggFunc = Group.OutlinedFunction;
  1257. assert(AggFunc && "Function to replace with is nullptr?");
  1258. // If the arguments are the same size, there are not values that need to be
  1259. // made into an argument, the argument ordering has not been change, or
  1260. // different output registers to handle. We can simply replace the called
  1261. // function in this case.
  1262. if (!Region.ChangedArgOrder && AggFunc->arg_size() == Call->arg_size()) {
  1263. LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
  1264. << *AggFunc << " with same number of arguments\n");
  1265. Call->setCalledFunction(AggFunc);
  1266. return Call;
  1267. }
  1268. // We have a different number of arguments than the new function, so
  1269. // we need to use our previously mappings off extracted argument to overall
  1270. // function argument, and constants to overall function argument to create the
  1271. // new argument list.
  1272. for (unsigned AggArgIdx = 0; AggArgIdx < AggFunc->arg_size(); AggArgIdx++) {
  1273. if (AggArgIdx == AggFunc->arg_size() - 1 &&
  1274. Group.OutputGVNCombinations.size() > 1) {
  1275. // If we are on the last argument, and we need to differentiate between
  1276. // output blocks, add an integer to the argument list to determine
  1277. // what block to take
  1278. LLVM_DEBUG(dbgs() << "Set switch block argument to "
  1279. << Region.OutputBlockNum << "\n");
  1280. NewCallArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()),
  1281. Region.OutputBlockNum));
  1282. continue;
  1283. }
  1284. ArgPair = Region.AggArgToExtracted.find(AggArgIdx);
  1285. if (ArgPair != Region.AggArgToExtracted.end()) {
  1286. Value *ArgumentValue = Call->getArgOperand(ArgPair->second);
  1287. // If we found the mapping from the extracted function to the overall
  1288. // function, we simply add it to the argument list. We use the same
  1289. // value, it just needs to honor the new order of arguments.
  1290. LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
  1291. << *ArgumentValue << "\n");
  1292. NewCallArgs.push_back(ArgumentValue);
  1293. continue;
  1294. }
  1295. // If it is a constant, we simply add it to the argument list as a value.
  1296. if (Region.AggArgToConstant.find(AggArgIdx) !=
  1297. Region.AggArgToConstant.end()) {
  1298. Constant *CST = Region.AggArgToConstant.find(AggArgIdx)->second;
  1299. LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
  1300. << *CST << "\n");
  1301. NewCallArgs.push_back(CST);
  1302. continue;
  1303. }
  1304. // Add a nullptr value if the argument is not found in the extracted
  1305. // function. If we cannot find a value, it means it is not in use
  1306. // for the region, so we should not pass anything to it.
  1307. LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to nullptr\n");
  1308. NewCallArgs.push_back(ConstantPointerNull::get(
  1309. static_cast<PointerType *>(AggFunc->getArg(AggArgIdx)->getType())));
  1310. }
  1311. LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
  1312. << *AggFunc << " with new set of arguments\n");
  1313. // Create the new call instruction and erase the old one.
  1314. Call = CallInst::Create(AggFunc->getFunctionType(), AggFunc, NewCallArgs, "",
  1315. Call);
  1316. // It is possible that the call to the outlined function is either the first
  1317. // instruction is in the new block, the last instruction, or both. If either
  1318. // of these is the case, we need to make sure that we replace the instruction
  1319. // in the IRInstructionData struct with the new call.
  1320. CallInst *OldCall = Region.Call;
  1321. if (Region.NewFront->Inst == OldCall)
  1322. Region.NewFront->Inst = Call;
  1323. if (Region.NewBack->Inst == OldCall)
  1324. Region.NewBack->Inst = Call;
  1325. // Transfer any debug information.
  1326. Call->setDebugLoc(Region.Call->getDebugLoc());
  1327. // Since our output may determine which branch we go to, we make sure to
  1328. // propogate this new call value through the module.
  1329. OldCall->replaceAllUsesWith(Call);
  1330. // Remove the old instruction.
  1331. OldCall->eraseFromParent();
  1332. Region.Call = Call;
  1333. // Make sure that the argument in the new function has the SwiftError
  1334. // argument.
  1335. if (Group.SwiftErrorArgument)
  1336. Call->addParamAttr(*Group.SwiftErrorArgument, Attribute::SwiftError);
  1337. return Call;
  1338. }
  1339. /// Find or create a BasicBlock in the outlined function containing PhiBlocks
  1340. /// for \p RetVal.
  1341. ///
  1342. /// \param Group - The OutlinableGroup containing the information about the
  1343. /// overall outlined function.
  1344. /// \param RetVal - The return value or exit option that we are currently
  1345. /// evaluating.
  1346. /// \returns The found or newly created BasicBlock to contain the needed
  1347. /// PHINodes to be used as outputs.
  1348. static BasicBlock *findOrCreatePHIBlock(OutlinableGroup &Group, Value *RetVal) {
  1349. DenseMap<Value *, BasicBlock *>::iterator PhiBlockForRetVal,
  1350. ReturnBlockForRetVal;
  1351. PhiBlockForRetVal = Group.PHIBlocks.find(RetVal);
  1352. ReturnBlockForRetVal = Group.EndBBs.find(RetVal);
  1353. assert(ReturnBlockForRetVal != Group.EndBBs.end() &&
  1354. "Could not find output value!");
  1355. BasicBlock *ReturnBB = ReturnBlockForRetVal->second;
  1356. // Find if a PHIBlock exists for this return value already. If it is
  1357. // the first time we are analyzing this, we will not, so we record it.
  1358. PhiBlockForRetVal = Group.PHIBlocks.find(RetVal);
  1359. if (PhiBlockForRetVal != Group.PHIBlocks.end())
  1360. return PhiBlockForRetVal->second;
  1361. // If we did not find a block, we create one, and insert it into the
  1362. // overall function and record it.
  1363. bool Inserted = false;
  1364. BasicBlock *PHIBlock = BasicBlock::Create(ReturnBB->getContext(), "phi_block",
  1365. ReturnBB->getParent());
  1366. std::tie(PhiBlockForRetVal, Inserted) =
  1367. Group.PHIBlocks.insert(std::make_pair(RetVal, PHIBlock));
  1368. // We find the predecessors of the return block in the newly created outlined
  1369. // function in order to point them to the new PHIBlock rather than the already
  1370. // existing return block.
  1371. SmallVector<BranchInst *, 2> BranchesToChange;
  1372. for (BasicBlock *Pred : predecessors(ReturnBB))
  1373. BranchesToChange.push_back(cast<BranchInst>(Pred->getTerminator()));
  1374. // Now we mark the branch instructions found, and change the references of the
  1375. // return block to the newly created PHIBlock.
  1376. for (BranchInst *BI : BranchesToChange)
  1377. for (unsigned Succ = 0, End = BI->getNumSuccessors(); Succ < End; Succ++) {
  1378. if (BI->getSuccessor(Succ) != ReturnBB)
  1379. continue;
  1380. BI->setSuccessor(Succ, PHIBlock);
  1381. }
  1382. BranchInst::Create(ReturnBB, PHIBlock);
  1383. return PhiBlockForRetVal->second;
  1384. }
  1385. /// For the function call now representing the \p Region, find the passed value
  1386. /// to that call that represents Argument \p A at the call location if the
  1387. /// call has already been replaced with a call to the overall, aggregate
  1388. /// function.
  1389. ///
  1390. /// \param A - The Argument to get the passed value for.
  1391. /// \param Region - The extracted Region corresponding to the outlined function.
  1392. /// \returns The Value representing \p A at the call site.
  1393. static Value *
  1394. getPassedArgumentInAlreadyOutlinedFunction(const Argument *A,
  1395. const OutlinableRegion &Region) {
  1396. // If we don't need to adjust the argument number at all (since the call
  1397. // has already been replaced by a call to the overall outlined function)
  1398. // we can just get the specified argument.
  1399. return Region.Call->getArgOperand(A->getArgNo());
  1400. }
  1401. /// For the function call now representing the \p Region, find the passed value
  1402. /// to that call that represents Argument \p A at the call location if the
  1403. /// call has only been replaced by the call to the aggregate function.
  1404. ///
  1405. /// \param A - The Argument to get the passed value for.
  1406. /// \param Region - The extracted Region corresponding to the outlined function.
  1407. /// \returns The Value representing \p A at the call site.
  1408. static Value *
  1409. getPassedArgumentAndAdjustArgumentLocation(const Argument *A,
  1410. const OutlinableRegion &Region) {
  1411. unsigned ArgNum = A->getArgNo();
  1412. // If it is a constant, we can look at our mapping from when we created
  1413. // the outputs to figure out what the constant value is.
  1414. if (Region.AggArgToConstant.count(ArgNum))
  1415. return Region.AggArgToConstant.find(ArgNum)->second;
  1416. // If it is not a constant, and we are not looking at the overall function, we
  1417. // need to adjust which argument we are looking at.
  1418. ArgNum = Region.AggArgToExtracted.find(ArgNum)->second;
  1419. return Region.Call->getArgOperand(ArgNum);
  1420. }
  1421. /// Find the canonical numbering for the incoming Values into the PHINode \p PN.
  1422. ///
  1423. /// \param PN [in] - The PHINode that we are finding the canonical numbers for.
  1424. /// \param Region [in] - The OutlinableRegion containing \p PN.
  1425. /// \param OutputMappings [in] - The mapping of output values from outlined
  1426. /// region to their original values.
  1427. /// \param CanonNums [out] - The canonical numbering for the incoming values to
  1428. /// \p PN paired with their incoming block.
  1429. /// \param ReplacedWithOutlinedCall - A flag to use the extracted function call
  1430. /// of \p Region rather than the overall function's call.
  1431. static void findCanonNumsForPHI(
  1432. PHINode *PN, OutlinableRegion &Region,
  1433. const DenseMap<Value *, Value *> &OutputMappings,
  1434. SmallVector<std::pair<unsigned, BasicBlock *>> &CanonNums,
  1435. bool ReplacedWithOutlinedCall = true) {
  1436. // Iterate over the incoming values.
  1437. for (unsigned Idx = 0, EIdx = PN->getNumIncomingValues(); Idx < EIdx; Idx++) {
  1438. Value *IVal = PN->getIncomingValue(Idx);
  1439. BasicBlock *IBlock = PN->getIncomingBlock(Idx);
  1440. // If we have an argument as incoming value, we need to grab the passed
  1441. // value from the call itself.
  1442. if (Argument *A = dyn_cast<Argument>(IVal)) {
  1443. if (ReplacedWithOutlinedCall)
  1444. IVal = getPassedArgumentInAlreadyOutlinedFunction(A, Region);
  1445. else
  1446. IVal = getPassedArgumentAndAdjustArgumentLocation(A, Region);
  1447. }
  1448. // Get the original value if it has been replaced by an output value.
  1449. IVal = findOutputMapping(OutputMappings, IVal);
  1450. // Find and add the canonical number for the incoming value.
  1451. std::optional<unsigned> GVN = Region.Candidate->getGVN(IVal);
  1452. assert(GVN && "No GVN for incoming value");
  1453. std::optional<unsigned> CanonNum = Region.Candidate->getCanonicalNum(*GVN);
  1454. assert(CanonNum && "No Canonical Number for GVN");
  1455. CanonNums.push_back(std::make_pair(*CanonNum, IBlock));
  1456. }
  1457. }
  1458. /// Find, or add PHINode \p PN to the combined PHINode Block \p OverallPHIBlock
  1459. /// in order to condense the number of instructions added to the outlined
  1460. /// function.
  1461. ///
  1462. /// \param PN [in] - The PHINode that we are finding the canonical numbers for.
  1463. /// \param Region [in] - The OutlinableRegion containing \p PN.
  1464. /// \param OverallPhiBlock [in] - The overall PHIBlock we are trying to find
  1465. /// \p PN in.
  1466. /// \param OutputMappings [in] - The mapping of output values from outlined
  1467. /// region to their original values.
  1468. /// \param UsedPHIs [in, out] - The PHINodes in the block that have already been
  1469. /// matched.
  1470. /// \return the newly found or created PHINode in \p OverallPhiBlock.
  1471. static PHINode*
  1472. findOrCreatePHIInBlock(PHINode &PN, OutlinableRegion &Region,
  1473. BasicBlock *OverallPhiBlock,
  1474. const DenseMap<Value *, Value *> &OutputMappings,
  1475. DenseSet<PHINode *> &UsedPHIs) {
  1476. OutlinableGroup &Group = *Region.Parent;
  1477. // A list of the canonical numbering assigned to each incoming value, paired
  1478. // with the incoming block for the PHINode passed into this function.
  1479. SmallVector<std::pair<unsigned, BasicBlock *>> PNCanonNums;
  1480. // We have to use the extracted function since we have merged this region into
  1481. // the overall function yet. We make sure to reassign the argument numbering
  1482. // since it is possible that the argument ordering is different between the
  1483. // functions.
  1484. findCanonNumsForPHI(&PN, Region, OutputMappings, PNCanonNums,
  1485. /* ReplacedWithOutlinedCall = */ false);
  1486. OutlinableRegion *FirstRegion = Group.Regions[0];
  1487. // A list of the canonical numbering assigned to each incoming value, paired
  1488. // with the incoming block for the PHINode that we are currently comparing
  1489. // the passed PHINode to.
  1490. SmallVector<std::pair<unsigned, BasicBlock *>> CurrentCanonNums;
  1491. // Find the Canonical Numbering for each PHINode, if it matches, we replace
  1492. // the uses of the PHINode we are searching for, with the found PHINode.
  1493. for (PHINode &CurrPN : OverallPhiBlock->phis()) {
  1494. // If this PHINode has already been matched to another PHINode to be merged,
  1495. // we skip it.
  1496. if (UsedPHIs.contains(&CurrPN))
  1497. continue;
  1498. CurrentCanonNums.clear();
  1499. findCanonNumsForPHI(&CurrPN, *FirstRegion, OutputMappings, CurrentCanonNums,
  1500. /* ReplacedWithOutlinedCall = */ true);
  1501. // If the list of incoming values is not the same length, then they cannot
  1502. // match since there is not an analogue for each incoming value.
  1503. if (PNCanonNums.size() != CurrentCanonNums.size())
  1504. continue;
  1505. bool FoundMatch = true;
  1506. // We compare the canonical value for each incoming value in the passed
  1507. // in PHINode to one already present in the outlined region. If the
  1508. // incoming values do not match, then the PHINodes do not match.
  1509. // We also check to make sure that the incoming block matches as well by
  1510. // finding the corresponding incoming block in the combined outlined region
  1511. // for the current outlined region.
  1512. for (unsigned Idx = 0, Edx = PNCanonNums.size(); Idx < Edx; ++Idx) {
  1513. std::pair<unsigned, BasicBlock *> ToCompareTo = CurrentCanonNums[Idx];
  1514. std::pair<unsigned, BasicBlock *> ToAdd = PNCanonNums[Idx];
  1515. if (ToCompareTo.first != ToAdd.first) {
  1516. FoundMatch = false;
  1517. break;
  1518. }
  1519. BasicBlock *CorrespondingBlock =
  1520. Region.findCorrespondingBlockIn(*FirstRegion, ToAdd.second);
  1521. assert(CorrespondingBlock && "Found block is nullptr");
  1522. if (CorrespondingBlock != ToCompareTo.second) {
  1523. FoundMatch = false;
  1524. break;
  1525. }
  1526. }
  1527. // If all incoming values and branches matched, then we can merge
  1528. // into the found PHINode.
  1529. if (FoundMatch) {
  1530. UsedPHIs.insert(&CurrPN);
  1531. return &CurrPN;
  1532. }
  1533. }
  1534. // If we've made it here, it means we weren't able to replace the PHINode, so
  1535. // we must insert it ourselves.
  1536. PHINode *NewPN = cast<PHINode>(PN.clone());
  1537. NewPN->insertBefore(&*OverallPhiBlock->begin());
  1538. for (unsigned Idx = 0, Edx = NewPN->getNumIncomingValues(); Idx < Edx;
  1539. Idx++) {
  1540. Value *IncomingVal = NewPN->getIncomingValue(Idx);
  1541. BasicBlock *IncomingBlock = NewPN->getIncomingBlock(Idx);
  1542. // Find corresponding basic block in the overall function for the incoming
  1543. // block.
  1544. BasicBlock *BlockToUse =
  1545. Region.findCorrespondingBlockIn(*FirstRegion, IncomingBlock);
  1546. NewPN->setIncomingBlock(Idx, BlockToUse);
  1547. // If we have an argument we make sure we replace using the argument from
  1548. // the correct function.
  1549. if (Argument *A = dyn_cast<Argument>(IncomingVal)) {
  1550. Value *Val = Group.OutlinedFunction->getArg(A->getArgNo());
  1551. NewPN->setIncomingValue(Idx, Val);
  1552. continue;
  1553. }
  1554. // Find the corresponding value in the overall function.
  1555. IncomingVal = findOutputMapping(OutputMappings, IncomingVal);
  1556. Value *Val = Region.findCorrespondingValueIn(*FirstRegion, IncomingVal);
  1557. assert(Val && "Value is nullptr?");
  1558. DenseMap<Value *, Value *>::iterator RemappedIt =
  1559. FirstRegion->RemappedArguments.find(Val);
  1560. if (RemappedIt != FirstRegion->RemappedArguments.end())
  1561. Val = RemappedIt->second;
  1562. NewPN->setIncomingValue(Idx, Val);
  1563. }
  1564. return NewPN;
  1565. }
  1566. // Within an extracted function, replace the argument uses of the extracted
  1567. // region with the arguments of the function for an OutlinableGroup.
  1568. //
  1569. /// \param [in] Region - The region of extracted code to be changed.
  1570. /// \param [in,out] OutputBBs - The BasicBlock for the output stores for this
  1571. /// region.
  1572. /// \param [in] FirstFunction - A flag to indicate whether we are using this
  1573. /// function to define the overall outlined function for all the regions, or
  1574. /// if we are operating on one of the following regions.
  1575. static void
  1576. replaceArgumentUses(OutlinableRegion &Region,
  1577. DenseMap<Value *, BasicBlock *> &OutputBBs,
  1578. const DenseMap<Value *, Value *> &OutputMappings,
  1579. bool FirstFunction = false) {
  1580. OutlinableGroup &Group = *Region.Parent;
  1581. assert(Region.ExtractedFunction && "Region has no extracted function?");
  1582. Function *DominatingFunction = Region.ExtractedFunction;
  1583. if (FirstFunction)
  1584. DominatingFunction = Group.OutlinedFunction;
  1585. DominatorTree DT(*DominatingFunction);
  1586. DenseSet<PHINode *> UsedPHIs;
  1587. for (unsigned ArgIdx = 0; ArgIdx < Region.ExtractedFunction->arg_size();
  1588. ArgIdx++) {
  1589. assert(Region.ExtractedArgToAgg.find(ArgIdx) !=
  1590. Region.ExtractedArgToAgg.end() &&
  1591. "No mapping from extracted to outlined?");
  1592. unsigned AggArgIdx = Region.ExtractedArgToAgg.find(ArgIdx)->second;
  1593. Argument *AggArg = Group.OutlinedFunction->getArg(AggArgIdx);
  1594. Argument *Arg = Region.ExtractedFunction->getArg(ArgIdx);
  1595. // The argument is an input, so we can simply replace it with the overall
  1596. // argument value
  1597. if (ArgIdx < Region.NumExtractedInputs) {
  1598. LLVM_DEBUG(dbgs() << "Replacing uses of input " << *Arg << " in function "
  1599. << *Region.ExtractedFunction << " with " << *AggArg
  1600. << " in function " << *Group.OutlinedFunction << "\n");
  1601. Arg->replaceAllUsesWith(AggArg);
  1602. Value *V = Region.Call->getArgOperand(ArgIdx);
  1603. Region.RemappedArguments.insert(std::make_pair(V, AggArg));
  1604. continue;
  1605. }
  1606. // If we are replacing an output, we place the store value in its own
  1607. // block inside the overall function before replacing the use of the output
  1608. // in the function.
  1609. assert(Arg->hasOneUse() && "Output argument can only have one use");
  1610. User *InstAsUser = Arg->user_back();
  1611. assert(InstAsUser && "User is nullptr!");
  1612. Instruction *I = cast<Instruction>(InstAsUser);
  1613. BasicBlock *BB = I->getParent();
  1614. SmallVector<BasicBlock *, 4> Descendants;
  1615. DT.getDescendants(BB, Descendants);
  1616. bool EdgeAdded = false;
  1617. if (Descendants.size() == 0) {
  1618. EdgeAdded = true;
  1619. DT.insertEdge(&DominatingFunction->getEntryBlock(), BB);
  1620. DT.getDescendants(BB, Descendants);
  1621. }
  1622. // Iterate over the following blocks, looking for return instructions,
  1623. // if we find one, find the corresponding output block for the return value
  1624. // and move our store instruction there.
  1625. for (BasicBlock *DescendBB : Descendants) {
  1626. ReturnInst *RI = dyn_cast<ReturnInst>(DescendBB->getTerminator());
  1627. if (!RI)
  1628. continue;
  1629. Value *RetVal = RI->getReturnValue();
  1630. auto VBBIt = OutputBBs.find(RetVal);
  1631. assert(VBBIt != OutputBBs.end() && "Could not find output value!");
  1632. // If this is storing a PHINode, we must make sure it is included in the
  1633. // overall function.
  1634. StoreInst *SI = cast<StoreInst>(I);
  1635. Value *ValueOperand = SI->getValueOperand();
  1636. StoreInst *NewI = cast<StoreInst>(I->clone());
  1637. NewI->setDebugLoc(DebugLoc());
  1638. BasicBlock *OutputBB = VBBIt->second;
  1639. NewI->insertInto(OutputBB, OutputBB->end());
  1640. LLVM_DEBUG(dbgs() << "Move store for instruction " << *I << " to "
  1641. << *OutputBB << "\n");
  1642. // If this is storing a PHINode, we must make sure it is included in the
  1643. // overall function.
  1644. if (!isa<PHINode>(ValueOperand) ||
  1645. Region.Candidate->getGVN(ValueOperand).has_value()) {
  1646. if (FirstFunction)
  1647. continue;
  1648. Value *CorrVal =
  1649. Region.findCorrespondingValueIn(*Group.Regions[0], ValueOperand);
  1650. assert(CorrVal && "Value is nullptr?");
  1651. NewI->setOperand(0, CorrVal);
  1652. continue;
  1653. }
  1654. PHINode *PN = cast<PHINode>(SI->getValueOperand());
  1655. // If it has a value, it was not split by the code extractor, which
  1656. // is what we are looking for.
  1657. if (Region.Candidate->getGVN(PN))
  1658. continue;
  1659. // We record the parent block for the PHINode in the Region so that
  1660. // we can exclude it from checks later on.
  1661. Region.PHIBlocks.insert(std::make_pair(RetVal, PN->getParent()));
  1662. // If this is the first function, we do not need to worry about mergiing
  1663. // this with any other block in the overall outlined function, so we can
  1664. // just continue.
  1665. if (FirstFunction) {
  1666. BasicBlock *PHIBlock = PN->getParent();
  1667. Group.PHIBlocks.insert(std::make_pair(RetVal, PHIBlock));
  1668. continue;
  1669. }
  1670. // We look for the aggregate block that contains the PHINodes leading into
  1671. // this exit path. If we can't find one, we create one.
  1672. BasicBlock *OverallPhiBlock = findOrCreatePHIBlock(Group, RetVal);
  1673. // For our PHINode, we find the combined canonical numbering, and
  1674. // attempt to find a matching PHINode in the overall PHIBlock. If we
  1675. // cannot, we copy the PHINode and move it into this new block.
  1676. PHINode *NewPN = findOrCreatePHIInBlock(*PN, Region, OverallPhiBlock,
  1677. OutputMappings, UsedPHIs);
  1678. NewI->setOperand(0, NewPN);
  1679. }
  1680. // If we added an edge for basic blocks without a predecessor, we remove it
  1681. // here.
  1682. if (EdgeAdded)
  1683. DT.deleteEdge(&DominatingFunction->getEntryBlock(), BB);
  1684. I->eraseFromParent();
  1685. LLVM_DEBUG(dbgs() << "Replacing uses of output " << *Arg << " in function "
  1686. << *Region.ExtractedFunction << " with " << *AggArg
  1687. << " in function " << *Group.OutlinedFunction << "\n");
  1688. Arg->replaceAllUsesWith(AggArg);
  1689. }
  1690. }
  1691. /// Within an extracted function, replace the constants that need to be lifted
  1692. /// into arguments with the actual argument.
  1693. ///
  1694. /// \param Region [in] - The region of extracted code to be changed.
  1695. void replaceConstants(OutlinableRegion &Region) {
  1696. OutlinableGroup &Group = *Region.Parent;
  1697. // Iterate over the constants that need to be elevated into arguments
  1698. for (std::pair<unsigned, Constant *> &Const : Region.AggArgToConstant) {
  1699. unsigned AggArgIdx = Const.first;
  1700. Function *OutlinedFunction = Group.OutlinedFunction;
  1701. assert(OutlinedFunction && "Overall Function is not defined?");
  1702. Constant *CST = Const.second;
  1703. Argument *Arg = Group.OutlinedFunction->getArg(AggArgIdx);
  1704. // Identify the argument it will be elevated to, and replace instances of
  1705. // that constant in the function.
  1706. // TODO: If in the future constants do not have one global value number,
  1707. // i.e. a constant 1 could be mapped to several values, this check will
  1708. // have to be more strict. It cannot be using only replaceUsesWithIf.
  1709. LLVM_DEBUG(dbgs() << "Replacing uses of constant " << *CST
  1710. << " in function " << *OutlinedFunction << " with "
  1711. << *Arg << "\n");
  1712. CST->replaceUsesWithIf(Arg, [OutlinedFunction](Use &U) {
  1713. if (Instruction *I = dyn_cast<Instruction>(U.getUser()))
  1714. return I->getFunction() == OutlinedFunction;
  1715. return false;
  1716. });
  1717. }
  1718. }
  1719. /// It is possible that there is a basic block that already performs the same
  1720. /// stores. This returns a duplicate block, if it exists
  1721. ///
  1722. /// \param OutputBBs [in] the blocks we are looking for a duplicate of.
  1723. /// \param OutputStoreBBs [in] The existing output blocks.
  1724. /// \returns an optional value with the number output block if there is a match.
  1725. std::optional<unsigned> findDuplicateOutputBlock(
  1726. DenseMap<Value *, BasicBlock *> &OutputBBs,
  1727. std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
  1728. bool Mismatch = false;
  1729. unsigned MatchingNum = 0;
  1730. // We compare the new set output blocks to the other sets of output blocks.
  1731. // If they are the same number, and have identical instructions, they are
  1732. // considered to be the same.
  1733. for (DenseMap<Value *, BasicBlock *> &CompBBs : OutputStoreBBs) {
  1734. Mismatch = false;
  1735. for (std::pair<Value *, BasicBlock *> &VToB : CompBBs) {
  1736. DenseMap<Value *, BasicBlock *>::iterator OutputBBIt =
  1737. OutputBBs.find(VToB.first);
  1738. if (OutputBBIt == OutputBBs.end()) {
  1739. Mismatch = true;
  1740. break;
  1741. }
  1742. BasicBlock *CompBB = VToB.second;
  1743. BasicBlock *OutputBB = OutputBBIt->second;
  1744. if (CompBB->size() - 1 != OutputBB->size()) {
  1745. Mismatch = true;
  1746. break;
  1747. }
  1748. BasicBlock::iterator NIt = OutputBB->begin();
  1749. for (Instruction &I : *CompBB) {
  1750. if (isa<BranchInst>(&I))
  1751. continue;
  1752. if (!I.isIdenticalTo(&(*NIt))) {
  1753. Mismatch = true;
  1754. break;
  1755. }
  1756. NIt++;
  1757. }
  1758. }
  1759. if (!Mismatch)
  1760. return MatchingNum;
  1761. MatchingNum++;
  1762. }
  1763. return std::nullopt;
  1764. }
  1765. /// Remove empty output blocks from the outlined region.
  1766. ///
  1767. /// \param BlocksToPrune - Mapping of return values output blocks for the \p
  1768. /// Region.
  1769. /// \param Region - The OutlinableRegion we are analyzing.
  1770. static bool
  1771. analyzeAndPruneOutputBlocks(DenseMap<Value *, BasicBlock *> &BlocksToPrune,
  1772. OutlinableRegion &Region) {
  1773. bool AllRemoved = true;
  1774. Value *RetValueForBB;
  1775. BasicBlock *NewBB;
  1776. SmallVector<Value *, 4> ToRemove;
  1777. // Iterate over the output blocks created in the outlined section.
  1778. for (std::pair<Value *, BasicBlock *> &VtoBB : BlocksToPrune) {
  1779. RetValueForBB = VtoBB.first;
  1780. NewBB = VtoBB.second;
  1781. // If there are no instructions, we remove it from the module, and also
  1782. // mark the value for removal from the return value to output block mapping.
  1783. if (NewBB->size() == 0) {
  1784. NewBB->eraseFromParent();
  1785. ToRemove.push_back(RetValueForBB);
  1786. continue;
  1787. }
  1788. // Mark that we could not remove all the blocks since they were not all
  1789. // empty.
  1790. AllRemoved = false;
  1791. }
  1792. // Remove the return value from the mapping.
  1793. for (Value *V : ToRemove)
  1794. BlocksToPrune.erase(V);
  1795. // Mark the region as having the no output scheme.
  1796. if (AllRemoved)
  1797. Region.OutputBlockNum = -1;
  1798. return AllRemoved;
  1799. }
  1800. /// For the outlined section, move needed the StoreInsts for the output
  1801. /// registers into their own block. Then, determine if there is a duplicate
  1802. /// output block already created.
  1803. ///
  1804. /// \param [in] OG - The OutlinableGroup of regions to be outlined.
  1805. /// \param [in] Region - The OutlinableRegion that is being analyzed.
  1806. /// \param [in,out] OutputBBs - the blocks that stores for this region will be
  1807. /// placed in.
  1808. /// \param [in] EndBBs - the final blocks of the extracted function.
  1809. /// \param [in] OutputMappings - OutputMappings the mapping of values that have
  1810. /// been replaced by a new output value.
  1811. /// \param [in,out] OutputStoreBBs - The existing output blocks.
  1812. static void alignOutputBlockWithAggFunc(
  1813. OutlinableGroup &OG, OutlinableRegion &Region,
  1814. DenseMap<Value *, BasicBlock *> &OutputBBs,
  1815. DenseMap<Value *, BasicBlock *> &EndBBs,
  1816. const DenseMap<Value *, Value *> &OutputMappings,
  1817. std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
  1818. // If none of the output blocks have any instructions, this means that we do
  1819. // not have to determine if it matches any of the other output schemes, and we
  1820. // don't have to do anything else.
  1821. if (analyzeAndPruneOutputBlocks(OutputBBs, Region))
  1822. return;
  1823. // Determine is there is a duplicate set of blocks.
  1824. std::optional<unsigned> MatchingBB =
  1825. findDuplicateOutputBlock(OutputBBs, OutputStoreBBs);
  1826. // If there is, we remove the new output blocks. If it does not,
  1827. // we add it to our list of sets of output blocks.
  1828. if (MatchingBB) {
  1829. LLVM_DEBUG(dbgs() << "Set output block for region in function"
  1830. << Region.ExtractedFunction << " to " << *MatchingBB);
  1831. Region.OutputBlockNum = *MatchingBB;
  1832. for (std::pair<Value *, BasicBlock *> &VtoBB : OutputBBs)
  1833. VtoBB.second->eraseFromParent();
  1834. return;
  1835. }
  1836. Region.OutputBlockNum = OutputStoreBBs.size();
  1837. Value *RetValueForBB;
  1838. BasicBlock *NewBB;
  1839. OutputStoreBBs.push_back(DenseMap<Value *, BasicBlock *>());
  1840. for (std::pair<Value *, BasicBlock *> &VtoBB : OutputBBs) {
  1841. RetValueForBB = VtoBB.first;
  1842. NewBB = VtoBB.second;
  1843. DenseMap<Value *, BasicBlock *>::iterator VBBIt =
  1844. EndBBs.find(RetValueForBB);
  1845. LLVM_DEBUG(dbgs() << "Create output block for region in"
  1846. << Region.ExtractedFunction << " to "
  1847. << *NewBB);
  1848. BranchInst::Create(VBBIt->second, NewBB);
  1849. OutputStoreBBs.back().insert(std::make_pair(RetValueForBB, NewBB));
  1850. }
  1851. }
  1852. /// Takes in a mapping, \p OldMap of ConstantValues to BasicBlocks, sorts keys,
  1853. /// before creating a basic block for each \p NewMap, and inserting into the new
  1854. /// block. Each BasicBlock is named with the scheme "<basename>_<key_idx>".
  1855. ///
  1856. /// \param OldMap [in] - The mapping to base the new mapping off of.
  1857. /// \param NewMap [out] - The output mapping using the keys of \p OldMap.
  1858. /// \param ParentFunc [in] - The function to put the new basic block in.
  1859. /// \param BaseName [in] - The start of the BasicBlock names to be appended to
  1860. /// by an index value.
  1861. static void createAndInsertBasicBlocks(DenseMap<Value *, BasicBlock *> &OldMap,
  1862. DenseMap<Value *, BasicBlock *> &NewMap,
  1863. Function *ParentFunc, Twine BaseName) {
  1864. unsigned Idx = 0;
  1865. std::vector<Value *> SortedKeys;
  1866. getSortedConstantKeys(SortedKeys, OldMap);
  1867. for (Value *RetVal : SortedKeys) {
  1868. BasicBlock *NewBB = BasicBlock::Create(
  1869. ParentFunc->getContext(),
  1870. Twine(BaseName) + Twine("_") + Twine(static_cast<unsigned>(Idx++)),
  1871. ParentFunc);
  1872. NewMap.insert(std::make_pair(RetVal, NewBB));
  1873. }
  1874. }
  1875. /// Create the switch statement for outlined function to differentiate between
  1876. /// all the output blocks.
  1877. ///
  1878. /// For the outlined section, determine if an outlined block already exists that
  1879. /// matches the needed stores for the extracted section.
  1880. /// \param [in] M - The module we are outlining from.
  1881. /// \param [in] OG - The group of regions to be outlined.
  1882. /// \param [in] EndBBs - The final blocks of the extracted function.
  1883. /// \param [in,out] OutputStoreBBs - The existing output blocks.
  1884. void createSwitchStatement(
  1885. Module &M, OutlinableGroup &OG, DenseMap<Value *, BasicBlock *> &EndBBs,
  1886. std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
  1887. // We only need the switch statement if there is more than one store
  1888. // combination, or there is more than one set of output blocks. The first
  1889. // will occur when we store different sets of values for two different
  1890. // regions. The second will occur when we have two outputs that are combined
  1891. // in a PHINode outside of the region in one outlined instance, and are used
  1892. // seaparately in another. This will create the same set of OutputGVNs, but
  1893. // will generate two different output schemes.
  1894. if (OG.OutputGVNCombinations.size() > 1) {
  1895. Function *AggFunc = OG.OutlinedFunction;
  1896. // Create a final block for each different return block.
  1897. DenseMap<Value *, BasicBlock *> ReturnBBs;
  1898. createAndInsertBasicBlocks(OG.EndBBs, ReturnBBs, AggFunc, "final_block");
  1899. for (std::pair<Value *, BasicBlock *> &RetBlockPair : ReturnBBs) {
  1900. std::pair<Value *, BasicBlock *> &OutputBlock =
  1901. *OG.EndBBs.find(RetBlockPair.first);
  1902. BasicBlock *ReturnBlock = RetBlockPair.second;
  1903. BasicBlock *EndBB = OutputBlock.second;
  1904. Instruction *Term = EndBB->getTerminator();
  1905. // Move the return value to the final block instead of the original exit
  1906. // stub.
  1907. Term->moveBefore(*ReturnBlock, ReturnBlock->end());
  1908. // Put the switch statement in the old end basic block for the function
  1909. // with a fall through to the new return block.
  1910. LLVM_DEBUG(dbgs() << "Create switch statement in " << *AggFunc << " for "
  1911. << OutputStoreBBs.size() << "\n");
  1912. SwitchInst *SwitchI =
  1913. SwitchInst::Create(AggFunc->getArg(AggFunc->arg_size() - 1),
  1914. ReturnBlock, OutputStoreBBs.size(), EndBB);
  1915. unsigned Idx = 0;
  1916. for (DenseMap<Value *, BasicBlock *> &OutputStoreBB : OutputStoreBBs) {
  1917. DenseMap<Value *, BasicBlock *>::iterator OSBBIt =
  1918. OutputStoreBB.find(OutputBlock.first);
  1919. if (OSBBIt == OutputStoreBB.end())
  1920. continue;
  1921. BasicBlock *BB = OSBBIt->second;
  1922. SwitchI->addCase(
  1923. ConstantInt::get(Type::getInt32Ty(M.getContext()), Idx), BB);
  1924. Term = BB->getTerminator();
  1925. Term->setSuccessor(0, ReturnBlock);
  1926. Idx++;
  1927. }
  1928. }
  1929. return;
  1930. }
  1931. assert(OutputStoreBBs.size() < 2 && "Different store sets not handled!");
  1932. // If there needs to be stores, move them from the output blocks to their
  1933. // corresponding ending block. We do not check that the OutputGVNCombinations
  1934. // is equal to 1 here since that could just been the case where there are 0
  1935. // outputs. Instead, we check whether there is more than one set of output
  1936. // blocks since this is the only case where we would have to move the
  1937. // stores, and erase the extraneous blocks.
  1938. if (OutputStoreBBs.size() == 1) {
  1939. LLVM_DEBUG(dbgs() << "Move store instructions to the end block in "
  1940. << *OG.OutlinedFunction << "\n");
  1941. DenseMap<Value *, BasicBlock *> OutputBlocks = OutputStoreBBs[0];
  1942. for (std::pair<Value *, BasicBlock *> &VBPair : OutputBlocks) {
  1943. DenseMap<Value *, BasicBlock *>::iterator EndBBIt =
  1944. EndBBs.find(VBPair.first);
  1945. assert(EndBBIt != EndBBs.end() && "Could not find end block");
  1946. BasicBlock *EndBB = EndBBIt->second;
  1947. BasicBlock *OutputBB = VBPair.second;
  1948. Instruction *Term = OutputBB->getTerminator();
  1949. Term->eraseFromParent();
  1950. Term = EndBB->getTerminator();
  1951. moveBBContents(*OutputBB, *EndBB);
  1952. Term->moveBefore(*EndBB, EndBB->end());
  1953. OutputBB->eraseFromParent();
  1954. }
  1955. }
  1956. }
  1957. /// Fill the new function that will serve as the replacement function for all of
  1958. /// the extracted regions of a certain structure from the first region in the
  1959. /// list of regions. Replace this first region's extracted function with the
  1960. /// new overall function.
  1961. ///
  1962. /// \param [in] M - The module we are outlining from.
  1963. /// \param [in] CurrentGroup - The group of regions to be outlined.
  1964. /// \param [in,out] OutputStoreBBs - The output blocks for each different
  1965. /// set of stores needed for the different functions.
  1966. /// \param [in,out] FuncsToRemove - Extracted functions to erase from module
  1967. /// once outlining is complete.
  1968. /// \param [in] OutputMappings - Extracted functions to erase from module
  1969. /// once outlining is complete.
  1970. static void fillOverallFunction(
  1971. Module &M, OutlinableGroup &CurrentGroup,
  1972. std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs,
  1973. std::vector<Function *> &FuncsToRemove,
  1974. const DenseMap<Value *, Value *> &OutputMappings) {
  1975. OutlinableRegion *CurrentOS = CurrentGroup.Regions[0];
  1976. // Move first extracted function's instructions into new function.
  1977. LLVM_DEBUG(dbgs() << "Move instructions from "
  1978. << *CurrentOS->ExtractedFunction << " to instruction "
  1979. << *CurrentGroup.OutlinedFunction << "\n");
  1980. moveFunctionData(*CurrentOS->ExtractedFunction,
  1981. *CurrentGroup.OutlinedFunction, CurrentGroup.EndBBs);
  1982. // Transfer the attributes from the function to the new function.
  1983. for (Attribute A : CurrentOS->ExtractedFunction->getAttributes().getFnAttrs())
  1984. CurrentGroup.OutlinedFunction->addFnAttr(A);
  1985. // Create a new set of output blocks for the first extracted function.
  1986. DenseMap<Value *, BasicBlock *> NewBBs;
  1987. createAndInsertBasicBlocks(CurrentGroup.EndBBs, NewBBs,
  1988. CurrentGroup.OutlinedFunction, "output_block_0");
  1989. CurrentOS->OutputBlockNum = 0;
  1990. replaceArgumentUses(*CurrentOS, NewBBs, OutputMappings, true);
  1991. replaceConstants(*CurrentOS);
  1992. // We first identify if any output blocks are empty, if they are we remove
  1993. // them. We then create a branch instruction to the basic block to the return
  1994. // block for the function for each non empty output block.
  1995. if (!analyzeAndPruneOutputBlocks(NewBBs, *CurrentOS)) {
  1996. OutputStoreBBs.push_back(DenseMap<Value *, BasicBlock *>());
  1997. for (std::pair<Value *, BasicBlock *> &VToBB : NewBBs) {
  1998. DenseMap<Value *, BasicBlock *>::iterator VBBIt =
  1999. CurrentGroup.EndBBs.find(VToBB.first);
  2000. BasicBlock *EndBB = VBBIt->second;
  2001. BranchInst::Create(EndBB, VToBB.second);
  2002. OutputStoreBBs.back().insert(VToBB);
  2003. }
  2004. }
  2005. // Replace the call to the extracted function with the outlined function.
  2006. CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
  2007. // We only delete the extracted functions at the end since we may need to
  2008. // reference instructions contained in them for mapping purposes.
  2009. FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
  2010. }
  2011. void IROutliner::deduplicateExtractedSections(
  2012. Module &M, OutlinableGroup &CurrentGroup,
  2013. std::vector<Function *> &FuncsToRemove, unsigned &OutlinedFunctionNum) {
  2014. createFunction(M, CurrentGroup, OutlinedFunctionNum);
  2015. std::vector<DenseMap<Value *, BasicBlock *>> OutputStoreBBs;
  2016. OutlinableRegion *CurrentOS;
  2017. fillOverallFunction(M, CurrentGroup, OutputStoreBBs, FuncsToRemove,
  2018. OutputMappings);
  2019. std::vector<Value *> SortedKeys;
  2020. for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) {
  2021. CurrentOS = CurrentGroup.Regions[Idx];
  2022. AttributeFuncs::mergeAttributesForOutlining(*CurrentGroup.OutlinedFunction,
  2023. *CurrentOS->ExtractedFunction);
  2024. // Create a set of BasicBlocks, one for each return block, to hold the
  2025. // needed store instructions.
  2026. DenseMap<Value *, BasicBlock *> NewBBs;
  2027. createAndInsertBasicBlocks(
  2028. CurrentGroup.EndBBs, NewBBs, CurrentGroup.OutlinedFunction,
  2029. "output_block_" + Twine(static_cast<unsigned>(Idx)));
  2030. replaceArgumentUses(*CurrentOS, NewBBs, OutputMappings);
  2031. alignOutputBlockWithAggFunc(CurrentGroup, *CurrentOS, NewBBs,
  2032. CurrentGroup.EndBBs, OutputMappings,
  2033. OutputStoreBBs);
  2034. CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
  2035. FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
  2036. }
  2037. // Create a switch statement to handle the different output schemes.
  2038. createSwitchStatement(M, CurrentGroup, CurrentGroup.EndBBs, OutputStoreBBs);
  2039. OutlinedFunctionNum++;
  2040. }
  2041. /// Checks that the next instruction in the InstructionDataList matches the
  2042. /// next instruction in the module. If they do not, there could be the
  2043. /// possibility that extra code has been inserted, and we must ignore it.
  2044. ///
  2045. /// \param ID - The IRInstructionData to check the next instruction of.
  2046. /// \returns true if the InstructionDataList and actual instruction match.
  2047. static bool nextIRInstructionDataMatchesNextInst(IRInstructionData &ID) {
  2048. // We check if there is a discrepancy between the InstructionDataList
  2049. // and the actual next instruction in the module. If there is, it means
  2050. // that an extra instruction was added, likely by the CodeExtractor.
  2051. // Since we do not have any similarity data about this particular
  2052. // instruction, we cannot confidently outline it, and must discard this
  2053. // candidate.
  2054. IRInstructionDataList::iterator NextIDIt = std::next(ID.getIterator());
  2055. Instruction *NextIDLInst = NextIDIt->Inst;
  2056. Instruction *NextModuleInst = nullptr;
  2057. if (!ID.Inst->isTerminator())
  2058. NextModuleInst = ID.Inst->getNextNonDebugInstruction();
  2059. else if (NextIDLInst != nullptr)
  2060. NextModuleInst =
  2061. &*NextIDIt->Inst->getParent()->instructionsWithoutDebug().begin();
  2062. if (NextIDLInst && NextIDLInst != NextModuleInst)
  2063. return false;
  2064. return true;
  2065. }
  2066. bool IROutliner::isCompatibleWithAlreadyOutlinedCode(
  2067. const OutlinableRegion &Region) {
  2068. IRSimilarityCandidate *IRSC = Region.Candidate;
  2069. unsigned StartIdx = IRSC->getStartIdx();
  2070. unsigned EndIdx = IRSC->getEndIdx();
  2071. // A check to make sure that we are not about to attempt to outline something
  2072. // that has already been outlined.
  2073. for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
  2074. if (Outlined.contains(Idx))
  2075. return false;
  2076. // We check if the recorded instruction matches the actual next instruction,
  2077. // if it does not, we fix it in the InstructionDataList.
  2078. if (!Region.Candidate->backInstruction()->isTerminator()) {
  2079. Instruction *NewEndInst =
  2080. Region.Candidate->backInstruction()->getNextNonDebugInstruction();
  2081. assert(NewEndInst && "Next instruction is a nullptr?");
  2082. if (Region.Candidate->end()->Inst != NewEndInst) {
  2083. IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
  2084. IRInstructionData *NewEndIRID = new (InstDataAllocator.Allocate())
  2085. IRInstructionData(*NewEndInst,
  2086. InstructionClassifier.visit(*NewEndInst), *IDL);
  2087. // Insert the first IRInstructionData of the new region after the
  2088. // last IRInstructionData of the IRSimilarityCandidate.
  2089. IDL->insert(Region.Candidate->end(), *NewEndIRID);
  2090. }
  2091. }
  2092. return none_of(*IRSC, [this](IRInstructionData &ID) {
  2093. if (!nextIRInstructionDataMatchesNextInst(ID))
  2094. return true;
  2095. return !this->InstructionClassifier.visit(ID.Inst);
  2096. });
  2097. }
  2098. void IROutliner::pruneIncompatibleRegions(
  2099. std::vector<IRSimilarityCandidate> &CandidateVec,
  2100. OutlinableGroup &CurrentGroup) {
  2101. bool PreviouslyOutlined;
  2102. // Sort from beginning to end, so the IRSimilarityCandidates are in order.
  2103. stable_sort(CandidateVec, [](const IRSimilarityCandidate &LHS,
  2104. const IRSimilarityCandidate &RHS) {
  2105. return LHS.getStartIdx() < RHS.getStartIdx();
  2106. });
  2107. IRSimilarityCandidate &FirstCandidate = CandidateVec[0];
  2108. // Since outlining a call and a branch instruction will be the same as only
  2109. // outlinining a call instruction, we ignore it as a space saving.
  2110. if (FirstCandidate.getLength() == 2) {
  2111. if (isa<CallInst>(FirstCandidate.front()->Inst) &&
  2112. isa<BranchInst>(FirstCandidate.back()->Inst))
  2113. return;
  2114. }
  2115. unsigned CurrentEndIdx = 0;
  2116. for (IRSimilarityCandidate &IRSC : CandidateVec) {
  2117. PreviouslyOutlined = false;
  2118. unsigned StartIdx = IRSC.getStartIdx();
  2119. unsigned EndIdx = IRSC.getEndIdx();
  2120. const Function &FnForCurrCand = *IRSC.getFunction();
  2121. for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
  2122. if (Outlined.contains(Idx)) {
  2123. PreviouslyOutlined = true;
  2124. break;
  2125. }
  2126. if (PreviouslyOutlined)
  2127. continue;
  2128. // Check over the instructions, and if the basic block has its address
  2129. // taken for use somewhere else, we do not outline that block.
  2130. bool BBHasAddressTaken = any_of(IRSC, [](IRInstructionData &ID){
  2131. return ID.Inst->getParent()->hasAddressTaken();
  2132. });
  2133. if (BBHasAddressTaken)
  2134. continue;
  2135. if (FnForCurrCand.hasOptNone())
  2136. continue;
  2137. if (FnForCurrCand.hasFnAttribute("nooutline")) {
  2138. LLVM_DEBUG({
  2139. dbgs() << "... Skipping function with nooutline attribute: "
  2140. << FnForCurrCand.getName() << "\n";
  2141. });
  2142. continue;
  2143. }
  2144. if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() &&
  2145. !OutlineFromLinkODRs)
  2146. continue;
  2147. // Greedily prune out any regions that will overlap with already chosen
  2148. // regions.
  2149. if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx)
  2150. continue;
  2151. bool BadInst = any_of(IRSC, [this](IRInstructionData &ID) {
  2152. if (!nextIRInstructionDataMatchesNextInst(ID))
  2153. return true;
  2154. return !this->InstructionClassifier.visit(ID.Inst);
  2155. });
  2156. if (BadInst)
  2157. continue;
  2158. OutlinableRegion *OS = new (RegionAllocator.Allocate())
  2159. OutlinableRegion(IRSC, CurrentGroup);
  2160. CurrentGroup.Regions.push_back(OS);
  2161. CurrentEndIdx = EndIdx;
  2162. }
  2163. }
  2164. InstructionCost
  2165. IROutliner::findBenefitFromAllRegions(OutlinableGroup &CurrentGroup) {
  2166. InstructionCost RegionBenefit = 0;
  2167. for (OutlinableRegion *Region : CurrentGroup.Regions) {
  2168. TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
  2169. // We add the number of instructions in the region to the benefit as an
  2170. // estimate as to how much will be removed.
  2171. RegionBenefit += Region->getBenefit(TTI);
  2172. LLVM_DEBUG(dbgs() << "Adding: " << RegionBenefit
  2173. << " saved instructions to overfall benefit.\n");
  2174. }
  2175. return RegionBenefit;
  2176. }
  2177. /// For the \p OutputCanon number passed in find the value represented by this
  2178. /// canonical number. If it is from a PHINode, we pick the first incoming
  2179. /// value and return that Value instead.
  2180. ///
  2181. /// \param Region - The OutlinableRegion to get the Value from.
  2182. /// \param OutputCanon - The canonical number to find the Value from.
  2183. /// \returns The Value represented by a canonical number \p OutputCanon in \p
  2184. /// Region.
  2185. static Value *findOutputValueInRegion(OutlinableRegion &Region,
  2186. unsigned OutputCanon) {
  2187. OutlinableGroup &CurrentGroup = *Region.Parent;
  2188. // If the value is greater than the value in the tracker, we have a
  2189. // PHINode and will instead use one of the incoming values to find the
  2190. // type.
  2191. if (OutputCanon > CurrentGroup.PHINodeGVNTracker) {
  2192. auto It = CurrentGroup.PHINodeGVNToGVNs.find(OutputCanon);
  2193. assert(It != CurrentGroup.PHINodeGVNToGVNs.end() &&
  2194. "Could not find GVN set for PHINode number!");
  2195. assert(It->second.second.size() > 0 && "PHINode does not have any values!");
  2196. OutputCanon = *It->second.second.begin();
  2197. }
  2198. std::optional<unsigned> OGVN =
  2199. Region.Candidate->fromCanonicalNum(OutputCanon);
  2200. assert(OGVN && "Could not find GVN for Canonical Number?");
  2201. std::optional<Value *> OV = Region.Candidate->fromGVN(*OGVN);
  2202. assert(OV && "Could not find value for GVN?");
  2203. return *OV;
  2204. }
  2205. InstructionCost
  2206. IROutliner::findCostOutputReloads(OutlinableGroup &CurrentGroup) {
  2207. InstructionCost OverallCost = 0;
  2208. for (OutlinableRegion *Region : CurrentGroup.Regions) {
  2209. TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
  2210. // Each output incurs a load after the call, so we add that to the cost.
  2211. for (unsigned OutputCanon : Region->GVNStores) {
  2212. Value *V = findOutputValueInRegion(*Region, OutputCanon);
  2213. InstructionCost LoadCost =
  2214. TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
  2215. TargetTransformInfo::TCK_CodeSize);
  2216. LLVM_DEBUG(dbgs() << "Adding: " << LoadCost
  2217. << " instructions to cost for output of type "
  2218. << *V->getType() << "\n");
  2219. OverallCost += LoadCost;
  2220. }
  2221. }
  2222. return OverallCost;
  2223. }
  2224. /// Find the extra instructions needed to handle any output values for the
  2225. /// region.
  2226. ///
  2227. /// \param [in] M - The Module to outline from.
  2228. /// \param [in] CurrentGroup - The collection of OutlinableRegions to analyze.
  2229. /// \param [in] TTI - The TargetTransformInfo used to collect information for
  2230. /// new instruction costs.
  2231. /// \returns the additional cost to handle the outputs.
  2232. static InstructionCost findCostForOutputBlocks(Module &M,
  2233. OutlinableGroup &CurrentGroup,
  2234. TargetTransformInfo &TTI) {
  2235. InstructionCost OutputCost = 0;
  2236. unsigned NumOutputBranches = 0;
  2237. OutlinableRegion &FirstRegion = *CurrentGroup.Regions[0];
  2238. IRSimilarityCandidate &Candidate = *CurrentGroup.Regions[0]->Candidate;
  2239. DenseSet<BasicBlock *> CandidateBlocks;
  2240. Candidate.getBasicBlocks(CandidateBlocks);
  2241. // Count the number of different output branches that point to blocks outside
  2242. // of the region.
  2243. DenseSet<BasicBlock *> FoundBlocks;
  2244. for (IRInstructionData &ID : Candidate) {
  2245. if (!isa<BranchInst>(ID.Inst))
  2246. continue;
  2247. for (Value *V : ID.OperVals) {
  2248. BasicBlock *BB = static_cast<BasicBlock *>(V);
  2249. if (!CandidateBlocks.contains(BB) && FoundBlocks.insert(BB).second)
  2250. NumOutputBranches++;
  2251. }
  2252. }
  2253. CurrentGroup.BranchesToOutside = NumOutputBranches;
  2254. for (const ArrayRef<unsigned> &OutputUse :
  2255. CurrentGroup.OutputGVNCombinations) {
  2256. for (unsigned OutputCanon : OutputUse) {
  2257. Value *V = findOutputValueInRegion(FirstRegion, OutputCanon);
  2258. InstructionCost StoreCost =
  2259. TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
  2260. TargetTransformInfo::TCK_CodeSize);
  2261. // An instruction cost is added for each store set that needs to occur for
  2262. // various output combinations inside the function, plus a branch to
  2263. // return to the exit block.
  2264. LLVM_DEBUG(dbgs() << "Adding: " << StoreCost
  2265. << " instructions to cost for output of type "
  2266. << *V->getType() << "\n");
  2267. OutputCost += StoreCost * NumOutputBranches;
  2268. }
  2269. InstructionCost BranchCost =
  2270. TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
  2271. LLVM_DEBUG(dbgs() << "Adding " << BranchCost << " to the current cost for"
  2272. << " a branch instruction\n");
  2273. OutputCost += BranchCost * NumOutputBranches;
  2274. }
  2275. // If there is more than one output scheme, we must have a comparison and
  2276. // branch for each different item in the switch statement.
  2277. if (CurrentGroup.OutputGVNCombinations.size() > 1) {
  2278. InstructionCost ComparisonCost = TTI.getCmpSelInstrCost(
  2279. Instruction::ICmp, Type::getInt32Ty(M.getContext()),
  2280. Type::getInt32Ty(M.getContext()), CmpInst::BAD_ICMP_PREDICATE,
  2281. TargetTransformInfo::TCK_CodeSize);
  2282. InstructionCost BranchCost =
  2283. TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
  2284. unsigned DifferentBlocks = CurrentGroup.OutputGVNCombinations.size();
  2285. InstructionCost TotalCost = ComparisonCost * BranchCost * DifferentBlocks;
  2286. LLVM_DEBUG(dbgs() << "Adding: " << TotalCost
  2287. << " instructions for each switch case for each different"
  2288. << " output path in a function\n");
  2289. OutputCost += TotalCost * NumOutputBranches;
  2290. }
  2291. return OutputCost;
  2292. }
  2293. void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) {
  2294. InstructionCost RegionBenefit = findBenefitFromAllRegions(CurrentGroup);
  2295. CurrentGroup.Benefit += RegionBenefit;
  2296. LLVM_DEBUG(dbgs() << "Current Benefit: " << CurrentGroup.Benefit << "\n");
  2297. InstructionCost OutputReloadCost = findCostOutputReloads(CurrentGroup);
  2298. CurrentGroup.Cost += OutputReloadCost;
  2299. LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
  2300. InstructionCost AverageRegionBenefit =
  2301. RegionBenefit / CurrentGroup.Regions.size();
  2302. unsigned OverallArgumentNum = CurrentGroup.ArgumentTypes.size();
  2303. unsigned NumRegions = CurrentGroup.Regions.size();
  2304. TargetTransformInfo &TTI =
  2305. getTTI(*CurrentGroup.Regions[0]->Candidate->getFunction());
  2306. // We add one region to the cost once, to account for the instructions added
  2307. // inside of the newly created function.
  2308. LLVM_DEBUG(dbgs() << "Adding: " << AverageRegionBenefit
  2309. << " instructions to cost for body of new function.\n");
  2310. CurrentGroup.Cost += AverageRegionBenefit;
  2311. LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
  2312. // For each argument, we must add an instruction for loading the argument
  2313. // out of the register and into a value inside of the newly outlined function.
  2314. LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
  2315. << " instructions to cost for each argument in the new"
  2316. << " function.\n");
  2317. CurrentGroup.Cost +=
  2318. OverallArgumentNum * TargetTransformInfo::TCC_Basic;
  2319. LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
  2320. // Each argument needs to either be loaded into a register or onto the stack.
  2321. // Some arguments will only be loaded into the stack once the argument
  2322. // registers are filled.
  2323. LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
  2324. << " instructions to cost for each argument in the new"
  2325. << " function " << NumRegions << " times for the "
  2326. << "needed argument handling at the call site.\n");
  2327. CurrentGroup.Cost +=
  2328. 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions;
  2329. LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
  2330. CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI);
  2331. LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
  2332. }
  2333. void IROutliner::updateOutputMapping(OutlinableRegion &Region,
  2334. ArrayRef<Value *> Outputs,
  2335. LoadInst *LI) {
  2336. // For and load instructions following the call
  2337. Value *Operand = LI->getPointerOperand();
  2338. std::optional<unsigned> OutputIdx;
  2339. // Find if the operand it is an output register.
  2340. for (unsigned ArgIdx = Region.NumExtractedInputs;
  2341. ArgIdx < Region.Call->arg_size(); ArgIdx++) {
  2342. if (Operand == Region.Call->getArgOperand(ArgIdx)) {
  2343. OutputIdx = ArgIdx - Region.NumExtractedInputs;
  2344. break;
  2345. }
  2346. }
  2347. // If we found an output register, place a mapping of the new value
  2348. // to the original in the mapping.
  2349. if (!OutputIdx)
  2350. return;
  2351. if (OutputMappings.find(Outputs[*OutputIdx]) == OutputMappings.end()) {
  2352. LLVM_DEBUG(dbgs() << "Mapping extracted output " << *LI << " to "
  2353. << *Outputs[*OutputIdx] << "\n");
  2354. OutputMappings.insert(std::make_pair(LI, Outputs[*OutputIdx]));
  2355. } else {
  2356. Value *Orig = OutputMappings.find(Outputs[*OutputIdx])->second;
  2357. LLVM_DEBUG(dbgs() << "Mapping extracted output " << *Orig << " to "
  2358. << *Outputs[*OutputIdx] << "\n");
  2359. OutputMappings.insert(std::make_pair(LI, Orig));
  2360. }
  2361. }
  2362. bool IROutliner::extractSection(OutlinableRegion &Region) {
  2363. SetVector<Value *> ArgInputs, Outputs, SinkCands;
  2364. assert(Region.StartBB && "StartBB for the OutlinableRegion is nullptr!");
  2365. BasicBlock *InitialStart = Region.StartBB;
  2366. Function *OrigF = Region.StartBB->getParent();
  2367. CodeExtractorAnalysisCache CEAC(*OrigF);
  2368. Region.ExtractedFunction =
  2369. Region.CE->extractCodeRegion(CEAC, ArgInputs, Outputs);
  2370. // If the extraction was successful, find the BasicBlock, and reassign the
  2371. // OutlinableRegion blocks
  2372. if (!Region.ExtractedFunction) {
  2373. LLVM_DEBUG(dbgs() << "CodeExtractor failed to outline " << Region.StartBB
  2374. << "\n");
  2375. Region.reattachCandidate();
  2376. return false;
  2377. }
  2378. // Get the block containing the called branch, and reassign the blocks as
  2379. // necessary. If the original block still exists, it is because we ended on
  2380. // a branch instruction, and so we move the contents into the block before
  2381. // and assign the previous block correctly.
  2382. User *InstAsUser = Region.ExtractedFunction->user_back();
  2383. BasicBlock *RewrittenBB = cast<Instruction>(InstAsUser)->getParent();
  2384. Region.PrevBB = RewrittenBB->getSinglePredecessor();
  2385. assert(Region.PrevBB && "PrevBB is nullptr?");
  2386. if (Region.PrevBB == InitialStart) {
  2387. BasicBlock *NewPrev = InitialStart->getSinglePredecessor();
  2388. Instruction *BI = NewPrev->getTerminator();
  2389. BI->eraseFromParent();
  2390. moveBBContents(*InitialStart, *NewPrev);
  2391. Region.PrevBB = NewPrev;
  2392. InitialStart->eraseFromParent();
  2393. }
  2394. Region.StartBB = RewrittenBB;
  2395. Region.EndBB = RewrittenBB;
  2396. // The sequences of outlinable regions has now changed. We must fix the
  2397. // IRInstructionDataList for consistency. Although they may not be illegal
  2398. // instructions, they should not be compared with anything else as they
  2399. // should not be outlined in this round. So marking these as illegal is
  2400. // allowed.
  2401. IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
  2402. Instruction *BeginRewritten = &*RewrittenBB->begin();
  2403. Instruction *EndRewritten = &*RewrittenBB->begin();
  2404. Region.NewFront = new (InstDataAllocator.Allocate()) IRInstructionData(
  2405. *BeginRewritten, InstructionClassifier.visit(*BeginRewritten), *IDL);
  2406. Region.NewBack = new (InstDataAllocator.Allocate()) IRInstructionData(
  2407. *EndRewritten, InstructionClassifier.visit(*EndRewritten), *IDL);
  2408. // Insert the first IRInstructionData of the new region in front of the
  2409. // first IRInstructionData of the IRSimilarityCandidate.
  2410. IDL->insert(Region.Candidate->begin(), *Region.NewFront);
  2411. // Insert the first IRInstructionData of the new region after the
  2412. // last IRInstructionData of the IRSimilarityCandidate.
  2413. IDL->insert(Region.Candidate->end(), *Region.NewBack);
  2414. // Remove the IRInstructionData from the IRSimilarityCandidate.
  2415. IDL->erase(Region.Candidate->begin(), std::prev(Region.Candidate->end()));
  2416. assert(RewrittenBB != nullptr &&
  2417. "Could not find a predecessor after extraction!");
  2418. // Iterate over the new set of instructions to find the new call
  2419. // instruction.
  2420. for (Instruction &I : *RewrittenBB)
  2421. if (CallInst *CI = dyn_cast<CallInst>(&I)) {
  2422. if (Region.ExtractedFunction == CI->getCalledFunction())
  2423. Region.Call = CI;
  2424. } else if (LoadInst *LI = dyn_cast<LoadInst>(&I))
  2425. updateOutputMapping(Region, Outputs.getArrayRef(), LI);
  2426. Region.reattachCandidate();
  2427. return true;
  2428. }
  2429. unsigned IROutliner::doOutline(Module &M) {
  2430. // Find the possible similarity sections.
  2431. InstructionClassifier.EnableBranches = !DisableBranches;
  2432. InstructionClassifier.EnableIndirectCalls = !DisableIndirectCalls;
  2433. InstructionClassifier.EnableIntrinsics = !DisableIntrinsics;
  2434. IRSimilarityIdentifier &Identifier = getIRSI(M);
  2435. SimilarityGroupList &SimilarityCandidates = *Identifier.getSimilarity();
  2436. // Sort them by size of extracted sections
  2437. unsigned OutlinedFunctionNum = 0;
  2438. // If we only have one SimilarityGroup in SimilarityCandidates, we do not have
  2439. // to sort them by the potential number of instructions to be outlined
  2440. if (SimilarityCandidates.size() > 1)
  2441. llvm::stable_sort(SimilarityCandidates,
  2442. [](const std::vector<IRSimilarityCandidate> &LHS,
  2443. const std::vector<IRSimilarityCandidate> &RHS) {
  2444. return LHS[0].getLength() * LHS.size() >
  2445. RHS[0].getLength() * RHS.size();
  2446. });
  2447. // Creating OutlinableGroups for each SimilarityCandidate to be used in
  2448. // each of the following for loops to avoid making an allocator.
  2449. std::vector<OutlinableGroup> PotentialGroups(SimilarityCandidates.size());
  2450. DenseSet<unsigned> NotSame;
  2451. std::vector<OutlinableGroup *> NegativeCostGroups;
  2452. std::vector<OutlinableRegion *> OutlinedRegions;
  2453. // Iterate over the possible sets of similarity.
  2454. unsigned PotentialGroupIdx = 0;
  2455. for (SimilarityGroup &CandidateVec : SimilarityCandidates) {
  2456. OutlinableGroup &CurrentGroup = PotentialGroups[PotentialGroupIdx++];
  2457. // Remove entries that were previously outlined
  2458. pruneIncompatibleRegions(CandidateVec, CurrentGroup);
  2459. // We pruned the number of regions to 0 to 1, meaning that it's not worth
  2460. // trying to outlined since there is no compatible similar instance of this
  2461. // code.
  2462. if (CurrentGroup.Regions.size() < 2)
  2463. continue;
  2464. // Determine if there are any values that are the same constant throughout
  2465. // each section in the set.
  2466. NotSame.clear();
  2467. CurrentGroup.findSameConstants(NotSame);
  2468. if (CurrentGroup.IgnoreGroup)
  2469. continue;
  2470. // Create a CodeExtractor for each outlinable region. Identify inputs and
  2471. // outputs for each section using the code extractor and create the argument
  2472. // types for the Aggregate Outlining Function.
  2473. OutlinedRegions.clear();
  2474. for (OutlinableRegion *OS : CurrentGroup.Regions) {
  2475. // Break the outlinable region out of its parent BasicBlock into its own
  2476. // BasicBlocks (see function implementation).
  2477. OS->splitCandidate();
  2478. // There's a chance that when the region is split, extra instructions are
  2479. // added to the region. This makes the region no longer viable
  2480. // to be split, so we ignore it for outlining.
  2481. if (!OS->CandidateSplit)
  2482. continue;
  2483. SmallVector<BasicBlock *> BE;
  2484. DenseSet<BasicBlock *> BlocksInRegion;
  2485. OS->Candidate->getBasicBlocks(BlocksInRegion, BE);
  2486. OS->CE = new (ExtractorAllocator.Allocate())
  2487. CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
  2488. false, nullptr, "outlined");
  2489. findAddInputsOutputs(M, *OS, NotSame);
  2490. if (!OS->IgnoreRegion)
  2491. OutlinedRegions.push_back(OS);
  2492. // We recombine the blocks together now that we have gathered all the
  2493. // needed information.
  2494. OS->reattachCandidate();
  2495. }
  2496. CurrentGroup.Regions = std::move(OutlinedRegions);
  2497. if (CurrentGroup.Regions.empty())
  2498. continue;
  2499. CurrentGroup.collectGVNStoreSets(M);
  2500. if (CostModel)
  2501. findCostBenefit(M, CurrentGroup);
  2502. // If we are adhering to the cost model, skip those groups where the cost
  2503. // outweighs the benefits.
  2504. if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) {
  2505. OptimizationRemarkEmitter &ORE =
  2506. getORE(*CurrentGroup.Regions[0]->Candidate->getFunction());
  2507. ORE.emit([&]() {
  2508. IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
  2509. OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize",
  2510. C->frontInstruction());
  2511. R << "did not outline "
  2512. << ore::NV(std::to_string(CurrentGroup.Regions.size()))
  2513. << " regions due to estimated increase of "
  2514. << ore::NV("InstructionIncrease",
  2515. CurrentGroup.Cost - CurrentGroup.Benefit)
  2516. << " instructions at locations ";
  2517. interleave(
  2518. CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
  2519. [&R](OutlinableRegion *Region) {
  2520. R << ore::NV(
  2521. "DebugLoc",
  2522. Region->Candidate->frontInstruction()->getDebugLoc());
  2523. },
  2524. [&R]() { R << " "; });
  2525. return R;
  2526. });
  2527. continue;
  2528. }
  2529. NegativeCostGroups.push_back(&CurrentGroup);
  2530. }
  2531. ExtractorAllocator.DestroyAll();
  2532. if (NegativeCostGroups.size() > 1)
  2533. stable_sort(NegativeCostGroups,
  2534. [](const OutlinableGroup *LHS, const OutlinableGroup *RHS) {
  2535. return LHS->Benefit - LHS->Cost > RHS->Benefit - RHS->Cost;
  2536. });
  2537. std::vector<Function *> FuncsToRemove;
  2538. for (OutlinableGroup *CG : NegativeCostGroups) {
  2539. OutlinableGroup &CurrentGroup = *CG;
  2540. OutlinedRegions.clear();
  2541. for (OutlinableRegion *Region : CurrentGroup.Regions) {
  2542. // We check whether our region is compatible with what has already been
  2543. // outlined, and whether we need to ignore this item.
  2544. if (!isCompatibleWithAlreadyOutlinedCode(*Region))
  2545. continue;
  2546. OutlinedRegions.push_back(Region);
  2547. }
  2548. if (OutlinedRegions.size() < 2)
  2549. continue;
  2550. // Reestimate the cost and benefit of the OutlinableGroup. Continue only if
  2551. // we are still outlining enough regions to make up for the added cost.
  2552. CurrentGroup.Regions = std::move(OutlinedRegions);
  2553. if (CostModel) {
  2554. CurrentGroup.Benefit = 0;
  2555. CurrentGroup.Cost = 0;
  2556. findCostBenefit(M, CurrentGroup);
  2557. if (CurrentGroup.Cost >= CurrentGroup.Benefit)
  2558. continue;
  2559. }
  2560. OutlinedRegions.clear();
  2561. for (OutlinableRegion *Region : CurrentGroup.Regions) {
  2562. Region->splitCandidate();
  2563. if (!Region->CandidateSplit)
  2564. continue;
  2565. OutlinedRegions.push_back(Region);
  2566. }
  2567. CurrentGroup.Regions = std::move(OutlinedRegions);
  2568. if (CurrentGroup.Regions.size() < 2) {
  2569. for (OutlinableRegion *R : CurrentGroup.Regions)
  2570. R->reattachCandidate();
  2571. continue;
  2572. }
  2573. LLVM_DEBUG(dbgs() << "Outlining regions with cost " << CurrentGroup.Cost
  2574. << " and benefit " << CurrentGroup.Benefit << "\n");
  2575. // Create functions out of all the sections, and mark them as outlined.
  2576. OutlinedRegions.clear();
  2577. for (OutlinableRegion *OS : CurrentGroup.Regions) {
  2578. SmallVector<BasicBlock *> BE;
  2579. DenseSet<BasicBlock *> BlocksInRegion;
  2580. OS->Candidate->getBasicBlocks(BlocksInRegion, BE);
  2581. OS->CE = new (ExtractorAllocator.Allocate())
  2582. CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
  2583. false, nullptr, "outlined");
  2584. bool FunctionOutlined = extractSection(*OS);
  2585. if (FunctionOutlined) {
  2586. unsigned StartIdx = OS->Candidate->getStartIdx();
  2587. unsigned EndIdx = OS->Candidate->getEndIdx();
  2588. for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
  2589. Outlined.insert(Idx);
  2590. OutlinedRegions.push_back(OS);
  2591. }
  2592. }
  2593. LLVM_DEBUG(dbgs() << "Outlined " << OutlinedRegions.size()
  2594. << " with benefit " << CurrentGroup.Benefit
  2595. << " and cost " << CurrentGroup.Cost << "\n");
  2596. CurrentGroup.Regions = std::move(OutlinedRegions);
  2597. if (CurrentGroup.Regions.empty())
  2598. continue;
  2599. OptimizationRemarkEmitter &ORE =
  2600. getORE(*CurrentGroup.Regions[0]->Call->getFunction());
  2601. ORE.emit([&]() {
  2602. IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
  2603. OptimizationRemark R(DEBUG_TYPE, "Outlined", C->front()->Inst);
  2604. R << "outlined " << ore::NV(std::to_string(CurrentGroup.Regions.size()))
  2605. << " regions with decrease of "
  2606. << ore::NV("Benefit", CurrentGroup.Benefit - CurrentGroup.Cost)
  2607. << " instructions at locations ";
  2608. interleave(
  2609. CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
  2610. [&R](OutlinableRegion *Region) {
  2611. R << ore::NV("DebugLoc",
  2612. Region->Candidate->frontInstruction()->getDebugLoc());
  2613. },
  2614. [&R]() { R << " "; });
  2615. return R;
  2616. });
  2617. deduplicateExtractedSections(M, CurrentGroup, FuncsToRemove,
  2618. OutlinedFunctionNum);
  2619. }
  2620. for (Function *F : FuncsToRemove)
  2621. F->eraseFromParent();
  2622. return OutlinedFunctionNum;
  2623. }
  2624. bool IROutliner::run(Module &M) {
  2625. CostModel = !NoCostModel;
  2626. OutlineFromLinkODRs = EnableLinkOnceODRIROutlining;
  2627. return doOutline(M) > 0;
  2628. }
  2629. // Pass Manager Boilerplate
  2630. namespace {
  2631. class IROutlinerLegacyPass : public ModulePass {
  2632. public:
  2633. static char ID;
  2634. IROutlinerLegacyPass() : ModulePass(ID) {
  2635. initializeIROutlinerLegacyPassPass(*PassRegistry::getPassRegistry());
  2636. }
  2637. void getAnalysisUsage(AnalysisUsage &AU) const override {
  2638. AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
  2639. AU.addRequired<TargetTransformInfoWrapperPass>();
  2640. AU.addRequired<IRSimilarityIdentifierWrapperPass>();
  2641. }
  2642. bool runOnModule(Module &M) override;
  2643. };
  2644. } // namespace
  2645. bool IROutlinerLegacyPass::runOnModule(Module &M) {
  2646. if (skipModule(M))
  2647. return false;
  2648. std::unique_ptr<OptimizationRemarkEmitter> ORE;
  2649. auto GORE = [&ORE](Function &F) -> OptimizationRemarkEmitter & {
  2650. ORE.reset(new OptimizationRemarkEmitter(&F));
  2651. return *ORE;
  2652. };
  2653. auto GTTI = [this](Function &F) -> TargetTransformInfo & {
  2654. return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
  2655. };
  2656. auto GIRSI = [this](Module &) -> IRSimilarityIdentifier & {
  2657. return this->getAnalysis<IRSimilarityIdentifierWrapperPass>().getIRSI();
  2658. };
  2659. return IROutliner(GTTI, GIRSI, GORE).run(M);
  2660. }
  2661. PreservedAnalyses IROutlinerPass::run(Module &M, ModuleAnalysisManager &AM) {
  2662. auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  2663. std::function<TargetTransformInfo &(Function &)> GTTI =
  2664. [&FAM](Function &F) -> TargetTransformInfo & {
  2665. return FAM.getResult<TargetIRAnalysis>(F);
  2666. };
  2667. std::function<IRSimilarityIdentifier &(Module &)> GIRSI =
  2668. [&AM](Module &M) -> IRSimilarityIdentifier & {
  2669. return AM.getResult<IRSimilarityAnalysis>(M);
  2670. };
  2671. std::unique_ptr<OptimizationRemarkEmitter> ORE;
  2672. std::function<OptimizationRemarkEmitter &(Function &)> GORE =
  2673. [&ORE](Function &F) -> OptimizationRemarkEmitter & {
  2674. ORE.reset(new OptimizationRemarkEmitter(&F));
  2675. return *ORE;
  2676. };
  2677. if (IROutliner(GTTI, GIRSI, GORE).run(M))
  2678. return PreservedAnalyses::none();
  2679. return PreservedAnalyses::all();
  2680. }
  2681. char IROutlinerLegacyPass::ID = 0;
  2682. INITIALIZE_PASS_BEGIN(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
  2683. false)
  2684. INITIALIZE_PASS_DEPENDENCY(IRSimilarityIdentifierWrapperPass)
  2685. INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
  2686. INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
  2687. INITIALIZE_PASS_END(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
  2688. false)
  2689. ModulePass *llvm::createIROutlinerPass() { return new IROutlinerLegacyPass(); }