llvm.org GIT mirror llvm / 0b24b74
Remove @brief commands from doxygen comments, too. This is a follow-up to r331272. We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all. Patch produced by for i in $(git grep -l '\@brief'); do perl -pi -e 's/\@brief //g' $i & done https://reviews.llvm.org/D46290 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331275 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 1 year, 6 months ago
87 changed file(s) with 857 addition(s) and 857 deletion(s). Raw diff Collapse all Expand all
432432
433433 .. code-block:: c++
434434
435 /// @brief The map for a single function's stack frame. One of these is
435 /// The map for a single function's stack frame. One of these is
436436 /// compiled as constant data into the executable for each function.
437437 ///
438438 /// Storage of metadata values is elided if the %metadata parameter to
443443 const void *Meta[0]; //< Metadata for each root.
444444 };
445445
446 /// @brief A link in the dynamic shadow stack. One of these is embedded in
446 /// A link in the dynamic shadow stack. One of these is embedded in
447447 /// the stack frame of each function on the call stack.
448448 struct StackEntry {
449449 StackEntry *Next; //< Link to next stack entry (the caller's).
451451 void *Roots[0]; //< Stack roots (in-place array).
452452 };
453453
454 /// @brief The head of the singly-linked list of StackEntries. Functions push
454 /// The head of the singly-linked list of StackEntries. Functions push
455455 /// and pop onto this in their prologue and epilogue.
456456 ///
457457 /// Since there is only a global list, this technique is not threadsafe.
458458 StackEntry *llvm_gc_root_chain;
459459
460 /// @brief Calls Visitor(root, meta) for each GC root on the stack.
460 /// Calls Visitor(root, meta) for each GC root on the stack.
461461 /// root and meta are exactly the values passed to
462462 /// @llvm.gcroot.
463463 ///
310310 APInt(unsigned numBits, StringRef str, uint8_t radix);
311311
312312 /// Simply makes *this a copy of that.
313 /// @brief Copy Constructor.
313 /// Copy Constructor.
314314 APInt(const APInt &that) : BitWidth(that.BitWidth) {
315315 if (isSingleWord())
316316 U.VAL = that.U.VAL;
736736 return *this;
737737 }
738738
739 /// @brief Move assignment operator.
739 /// Move assignment operator.
740740 APInt &operator=(APInt &&that) {
741741 #ifdef _MSC_VER
742742 // The MSVC std::shuffle implementation still does self-assignment.
3535 DOTGraphTraitsViewer(StringRef GraphName, char &ID)
3636 : FunctionPass(ID), Name(GraphName) {}
3737
38 /// @brief Return true if this function should be processed.
38 /// Return true if this function should be processed.
3939 ///
4040 /// An implementation of this class my override this function to indicate that
4141 /// only certain functions should be viewed.
7777 DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
7878 : FunctionPass(ID), Name(GraphName) {}
7979
80 /// @brief Return true if this function should be processed.
80 /// Return true if this function should be processed.
8181 ///
8282 /// An implementation of this class my override this function to indicate that
8383 /// only certain functions should be printed.
2525 class Module;
2626 class Function;
2727
28 /// @brief Create a lint pass.
28 /// Create a lint pass.
2929 ///
3030 /// Check a module or function.
3131 FunctionPass *createLintPass();
3232
33 /// @brief Check a module.
33 /// Check a module.
3434 ///
3535 /// This should only be used for debugging, because it plays games with
3636 /// PassManagers and stuff.
::getEntry(); ::getParent(); &Node);
102102 }
103103 };
104104
105 /// @brief Marker class to iterate over the elements of a Region in flat mode.
105 /// Marker class to iterate over the elements of a Region in flat mode.
106106 ///
107107 /// The class is used to either iterate in Flat mode or by not using it to not
108108 /// iterate in Flat mode. During a Flat mode iteration all Regions are entered
112112 template
113113 class FlatIt {};
114114
115 /// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
115 /// A RegionNode represents a subregion or a BasicBlock that is part of a
116116 /// Region.
117117 template
118118 class RegionNodeBase {
135135 /// RegionNode.
136136 PointerIntPair entry;
137137
138 /// @brief The parent Region of this RegionNode.
138 /// The parent Region of this RegionNode.
139139 /// @see getParent()
140140 RegionT *parent;
141141
142142 protected:
143 /// @brief Create a RegionNode.
143 /// Create a RegionNode.
144144 ///
145145 /// @param Parent The parent of this RegionNode.
146146 /// @param Entry The entry BasicBlock of the RegionNode. If this
156156 RegionNodeBase(const RegionNodeBase &) = delete;
157157 RegionNodeBase &operator=(const RegionNodeBase &) = delete;
158158
159 /// @brief Get the parent Region of this RegionNode.
159 /// Get the parent Region of this RegionNode.
160160 ///
161161 /// The parent Region is the Region this RegionNode belongs to. If for
162162 /// example a BasicBlock is element of two Regions, there exist two
166166 /// @return Get the parent Region of this RegionNode.
167167 inline RegionT *getParent() const { return parent; }
168168
169 /// @brief Get the entry BasicBlock of this RegionNode.
169 /// Get the entry BasicBlock of this RegionNode.
170170 ///
171171 /// If this RegionNode represents a BasicBlock this is just the BasicBlock
172172 /// itself, otherwise we return the entry BasicBlock of the Subregion
174174 /// @return The entry BasicBlock of this RegionNode.
175175 inline BlockT *getEntry() const { return entry.getPointer(); }
176176
177 /// @brief Get the content of this RegionNode.
177 /// Get the content of this RegionNode.
178178 ///
179179 /// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
180180 /// check the type of the content with the isSubRegion() function call.
182182 /// @return The content of this RegionNode.
183183 template inline T *getNodeAs() const;
184184
185 /// @brief Is this RegionNode a subregion?
185 /// Is this RegionNode a subregion?
186186 ///
187187 /// @return True if it contains a subregion. False if it contains a
188188 /// BasicBlock.
190190 };
191191
192192 //===----------------------------------------------------------------------===//
193 /// @brief A single entry single exit Region.
193 /// A single entry single exit Region.
194194 ///
195195 /// A Region is a connected subgraph of a control flow graph that has exactly
196196 /// two connections to the remaining graph. It can be used to analyze or
301301 void verifyRegionNest() const;
302302
303303 public:
304 /// @brief Create a new region.
304 /// Create a new region.
305305 ///
306306 /// @param Entry The entry basic block of the region.
307307 /// @param Exit The exit basic block of the region.
318318 /// Delete the Region and all its subregions.
319319 ~RegionBase();
320320
321 /// @brief Get the entry BasicBlock of the Region.
321 /// Get the entry BasicBlock of the Region.
322322 /// @return The entry BasicBlock of the region.
323323 BlockT *getEntry() const {
324324 return RegionNodeBase
325325 }
326326
327 /// @brief Replace the entry basic block of the region with the new basic
327 /// Replace the entry basic block of the region with the new basic
328328 /// block.
329329 ///
330330 /// @param BB The new entry basic block of the region.
331331 void replaceEntry(BlockT *BB);
332332
333 /// @brief Replace the exit basic block of the region with the new basic
333 /// Replace the exit basic block of the region with the new basic
334334 /// block.
335335 ///
336336 /// @param BB The new exit basic block of the region.
337337 void replaceExit(BlockT *BB);
338338
339 /// @brief Recursively replace the entry basic block of the region.
339 /// Recursively replace the entry basic block of the region.
340340 ///
341341 /// This function replaces the entry basic block with a new basic block. It
342342 /// also updates all child regions that have the same entry basic block as
345345 /// @param NewEntry The new entry basic block.
346346 void replaceEntryRecursive(BlockT *NewEntry);
347347
348 /// @brief Recursively replace the exit basic block of the region.
348 /// Recursively replace the exit basic block of the region.
349349 ///
350350 /// This function replaces the exit basic block with a new basic block. It
351351 /// also updates all child regions that have the same exit basic block as
354354 /// @param NewExit The new exit basic block.
355355 void replaceExitRecursive(BlockT *NewExit);
356356
357 /// @brief Get the exit BasicBlock of the Region.
357 /// Get the exit BasicBlock of the Region.
358358 /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
359359 /// Region.
360360 BlockT *getExit() const { return exit; }
361361
362 /// @brief Get the parent of the Region.
362 /// Get the parent of the Region.
363363 /// @return The parent of the Region or NULL if this is a top level
364364 /// Region.
365365 RegionT *getParent() const {
366366 return RegionNodeBase
367367 }
368368
369 /// @brief Get the RegionNode representing the current Region.
369 /// Get the RegionNode representing the current Region.
370370 /// @return The RegionNode representing the current Region.
371371 RegionNodeT *getNode() const {
372372 return const_cast(
373373 reinterpret_cast(this));
374374 }
375375
376 /// @brief Get the nesting level of this Region.
376 /// Get the nesting level of this Region.
377377 ///
378378 /// An toplevel Region has depth 0.
379379 ///
380380 /// @return The depth of the region.
381381 unsigned getDepth() const;
382382
383 /// @brief Check if a Region is the TopLevel region.
383 /// Check if a Region is the TopLevel region.
384384 ///
385385 /// The toplevel region represents the whole function.
386386 bool isTopLevelRegion() const { return exit == nullptr; }
387387
388 /// @brief Return a new (non-canonical) region, that is obtained by joining
388 /// Return a new (non-canonical) region, that is obtained by joining
389389 /// this region with its predecessors.
390390 ///
391391 /// @return A region also starting at getEntry(), but reaching to the next
393393 /// NULL if such a basic block does not exist.
394394 RegionT *getExpandedRegion() const;
395395
396 /// @brief Return the first block of this region's single entry edge,
396 /// Return the first block of this region's single entry edge,
397397 /// if existing.
398398 ///
399399 /// @return The BasicBlock starting this region's single entry edge,
400400 /// else NULL.
401401 BlockT *getEnteringBlock() const;
402402
403 /// @brief Return the first block of this region's single exit edge,
403 /// Return the first block of this region's single exit edge,
404404 /// if existing.
405405 ///
406406 /// @return The BasicBlock starting this region's single exit edge,
407407 /// else NULL.
408408 BlockT *getExitingBlock() const;
409409
410 /// @brief Collect all blocks of this region's single exit edge, if existing.
410 /// Collect all blocks of this region's single exit edge, if existing.
411411 ///
412412 /// @return True if this region contains all the predecessors of the exit.
413413 bool getExitingBlocks(SmallVectorImpl &Exitings) const;
414414
415 /// @brief Is this a simple region?
415 /// Is this a simple region?
416416 ///
417417 /// A region is simple if it has exactly one exit and one entry edge.
418418 ///
419419 /// @return True if the Region is simple.
420420 bool isSimple() const;
421421
422 /// @brief Returns the name of the Region.
422 /// Returns the name of the Region.
423423 /// @return The Name of the Region.
424424 std::string getNameStr() const;
425425
426 /// @brief Return the RegionInfo object, that belongs to this Region.
426 /// Return the RegionInfo object, that belongs to this Region.
427427 RegionInfoT *getRegionInfo() const { return RI; }
428428
429429 /// PrintStyle - Print region in difference ways.
430430 enum PrintStyle { PrintNone, PrintBB, PrintRN };
431431
432 /// @brief Print the region.
432 /// Print the region.
433433 ///
434434 /// @param OS The output stream the Region is printed to.
435435 /// @param printTree Print also the tree of subregions.
438438 PrintStyle Style = PrintNone) const;
439439
440440 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
441 /// @brief Print the region to stderr.
441 /// Print the region to stderr.
442442 void dump() const;
443443 #endif
444444
445 /// @brief Check if the region contains a BasicBlock.
445 /// Check if the region contains a BasicBlock.
446446 ///
447447 /// @param BB The BasicBlock that might be contained in this Region.
448448 /// @return True if the block is contained in the region otherwise false.
449449 bool contains(const BlockT *BB) const;
450450
451 /// @brief Check if the region contains another region.
451 /// Check if the region contains another region.
452452 ///
453453 /// @param SubRegion The region that might be contained in this Region.
454454 /// @return True if SubRegion is contained in the region otherwise false.
462462 SubRegion->getExit() == getExit());
463463 }
464464
465 /// @brief Check if the region contains an Instruction.
465 /// Check if the region contains an Instruction.
466466 ///
467467 /// @param Inst The Instruction that might be contained in this region.
468468 /// @return True if the Instruction is contained in the region otherwise
469469 /// false.
470470 bool contains(const InstT *Inst) const { return contains(Inst->getParent()); }
471471
472 /// @brief Check if the region contains a loop.
472 /// Check if the region contains a loop.
473473 ///
474474 /// @param L The loop that might be contained in this region.
475475 /// @return True if the loop is contained in the region otherwise false.
478478 /// In that case true is returned.
479479 bool contains(const LoopT *L) const;
480480
481 /// @brief Get the outermost loop in the region that contains a loop.
481 /// Get the outermost loop in the region that contains a loop.
482482 ///
483483 /// Find for a Loop L the outermost loop OuterL that is a parent loop of L
484484 /// and is itself contained in the region.
488488 /// exist or if the region describes the whole function.
489489 LoopT *outermostLoopInRegion(LoopT *L) const;
490490
491 /// @brief Get the outermost loop in the region that contains a basic block.
491 /// Get the outermost loop in the region that contains a basic block.
492492 ///
493493 /// Find for a basic block BB the outermost loop L that contains BB and is
494494 /// itself contained in the region.
499499 /// exist or if the region describes the whole function.
500500 LoopT *outermostLoopInRegion(LoopInfoT *LI, BlockT *BB) const;
501501
502 /// @brief Get the subregion that starts at a BasicBlock
502 /// Get the subregion that starts at a BasicBlock
503503 ///
504504 /// @param BB The BasicBlock the subregion should start.
505505 /// @return The Subregion if available, otherwise NULL.
506506 RegionT *getSubRegionNode(BlockT *BB) const;
507507
508 /// @brief Get the RegionNode for a BasicBlock
508 /// Get the RegionNode for a BasicBlock
509509 ///
510510 /// @param BB The BasicBlock at which the RegionNode should start.
511511 /// @return If available, the RegionNode that represents the subregion
513513 /// representing BB.
514514 RegionNodeT *getNode(BlockT *BB) const;
515515
516 /// @brief Get the BasicBlock RegionNode for a BasicBlock
516 /// Get the BasicBlock RegionNode for a BasicBlock
517517 ///
518518 /// @param BB The BasicBlock for which the RegionNode is requested.
519519 /// @return The RegionNode representing the BB.
520520 RegionNodeT *getBBNode(BlockT *BB) const;
521521
522 /// @brief Add a new subregion to this Region.
522 /// Add a new subregion to this Region.
523523 ///
524524 /// @param SubRegion The new subregion that will be added.
525525 /// @param moveChildren Move the children of this region, that are also
526526 /// contained in SubRegion into SubRegion.
527527 void addSubRegion(RegionT *SubRegion, bool moveChildren = false);
528528
529 /// @brief Remove a subregion from this Region.
529 /// Remove a subregion from this Region.
530530 ///
531531 /// The subregion is not deleted, as it will probably be inserted into another
532532 /// region.
533533 /// @param SubRegion The SubRegion that will be removed.
534534 RegionT *removeSubRegion(RegionT *SubRegion);
535535
536 /// @brief Move all direct child nodes of this Region to another Region.
536 /// Move all direct child nodes of this Region to another Region.
537537 ///
538538 /// @param To The Region the child nodes will be transferred to.
539539 void transferChildrenTo(RegionT *To);
540540
541 /// @brief Verify if the region is a correct region.
541 /// Verify if the region is a correct region.
542542 ///
543543 /// Check if this is a correctly build Region. This is an expensive check, as
544544 /// the complete CFG of the Region will be walked.
545545 void verifyRegion() const;
546546
547 /// @brief Clear the cache for BB RegionNodes.
547 /// Clear the cache for BB RegionNodes.
548548 ///
549549 /// After calling this function the BasicBlock RegionNodes will be stored at
550550 /// different memory locations. RegionNodes obtained before this function is
620620 using block_range = iterator_range;
621621 using const_block_range = iterator_range;
622622
623 /// @brief Returns a range view of the basic blocks in the region.
623 /// Returns a range view of the basic blocks in the region.
624624 inline block_range blocks() {
625625 return block_range(block_begin(), block_end());
626626 }
627627
628 /// @brief Returns a range view of the basic blocks in the region.
628 /// Returns a range view of the basic blocks in the region.
629629 ///
630630 /// This is the 'const' version of the range view.
631631 inline const_block_range blocks() const {
667667 inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase
668668
669669 //===----------------------------------------------------------------------===//
670 /// @brief Analysis that detects all canonical Regions.
670 /// Analysis that detects all canonical Regions.
671671 ///
672672 /// The RegionInfo pass detects all canonical regions in a function. The Regions
673673 /// are connected using the parent relation. This builds a Program Structure
811811
812812 void releaseMemory();
813813
814 /// @brief Get the smallest region that contains a BasicBlock.
814 /// Get the smallest region that contains a BasicBlock.
815815 ///
816816 /// @param BB The basic block.
817817 /// @return The smallest region, that contains BB or NULL, if there is no
818818 /// region containing BB.
819819 RegionT *getRegionFor(BlockT *BB) const;
820820
821 /// @brief Set the smallest region that surrounds a basic block.
821 /// Set the smallest region that surrounds a basic block.
822822 ///
823823 /// @param BB The basic block surrounded by a region.
824824 /// @param R The smallest region that surrounds BB.
825825 void setRegionFor(BlockT *BB, RegionT *R);
826826
827 /// @brief A shortcut for getRegionFor().
827 /// A shortcut for getRegionFor().
828828 ///
829829 /// @param BB The basic block.
830830 /// @return The smallest region, that contains BB or NULL, if there is no
831831 /// region containing BB.
832832 RegionT *operator[](BlockT *BB) const;
833833
834 /// @brief Return the exit of the maximal refined region, that starts at a
834 /// Return the exit of the maximal refined region, that starts at a
835835 /// BasicBlock.
836836 ///
837837 /// @param BB The BasicBlock the refined region starts.
838838 BlockT *getMaxRegionExit(BlockT *BB) const;
839839
840 /// @brief Find the smallest region that contains two regions.
840 /// Find the smallest region that contains two regions.
841841 ///
842842 /// @param A The first region.
843843 /// @param B The second region.
844844 /// @return The smallest region containing A and B.
845845 RegionT *getCommonRegion(RegionT *A, RegionT *B) const;
846846
847 /// @brief Find the smallest region that contains two basic blocks.
847 /// Find the smallest region that contains two basic blocks.
848848 ///
849849 /// @param A The first basic block.
850850 /// @param B The second basic block.
853853 return getCommonRegion(getRegionFor(A), getRegionFor(B));
854854 }
855855
856 /// @brief Find the smallest region that contains a set of regions.
856 /// Find the smallest region that contains a set of regions.
857857 ///
858858 /// @param Regions A vector of regions.
859859 /// @return The smallest region that contains all regions in Regions.
860860 RegionT *getCommonRegion(SmallVectorImpl &Regions) const;
861861
862 /// @brief Find the smallest region that contains a set of basic blocks.
862 /// Find the smallest region that contains a set of basic blocks.
863863 ///
864864 /// @param BBs A vector of basic blocks.
865865 /// @return The smallest region that contains all basic blocks in BBS.
867867
868868 RegionT *getTopLevelRegion() const { return TopLevelRegion; }
869869
870 /// @brief Clear the Node Cache for all Regions.
870 /// Clear the Node Cache for all Regions.
871871 ///
872872 /// @see Region::clearNodeCache()
873873 void clearNodeCache() {
930930 DominanceFrontier *DF);
931931
932932 #ifndef NDEBUG
933 /// @brief Opens a viewer to show the GraphViz visualization of the regions.
933 /// Opens a viewer to show the GraphViz visualization of the regions.
934934 ///
935935 /// Useful during debugging as an alternative to dump().
936936 void view();
937937
938 /// @brief Opens a viewer to show the GraphViz visualization of this region
938 /// Opens a viewer to show the GraphViz visualization of this region
939939 /// without instructions in the BasicBlocks.
940940 ///
941941 /// Useful during debugging as an alternative to dump().
2525 class BasicBlock;
2626
2727 //===----------------------------------------------------------------------===//
28 /// @brief Hierarchical RegionNode successor iterator.
28 /// Hierarchical RegionNode successor iterator.
2929 ///
3030 /// This iterator iterates over all successors of a RegionNode.
3131 ///
101101 using Self = RNSuccIterator;
102102 using value_type = typename super::value_type;
103103
104 /// @brief Create begin iterator of a RegionNode.
104 /// Create begin iterator of a RegionNode.
105105 inline RNSuccIterator(NodeRef node)
106106 : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
107107 BItor(BlockTraits::child_begin(node->getEntry())) {
114114 advanceRegionSucc();
115115 }
116116
117 /// @brief Create an end iterator.
117 /// Create an end iterator.
118118 inline RNSuccIterator(NodeRef node, bool)
119119 : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
120120 BItor(BlockTraits::child_end(node->getEntry())) {}
157157 };
158158
159159 //===----------------------------------------------------------------------===//
160 /// @brief Flat RegionNode iterator.
160 /// Flat RegionNode iterator.
161161 ///
162162 /// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
163163 /// are contained in the Region and its subregions. This is close to a virtual
176176 using Self = RNSuccIterator, BlockT, RegionT>;
177177 using value_type = typename super::value_type;
178178
179 /// @brief Create the iterator from a RegionNode.
179 /// Create the iterator from a RegionNode.
180180 ///
181181 /// Note that the incoming node must be a bb node, otherwise it will trigger
182182 /// an assertion when we try to get a BasicBlock.
192192 ++Itor;
193193 }
194194
195 /// @brief Create an end iterator
195 /// Create an end iterator
196196 inline RNSuccIterator(NodeRef node, bool)
197197 : Node(node), Itor(BlockTraits::child_end(node->getEntry())) {
198198 assert(!Node->isSubRegion() &&
2727 class Function;
2828
2929 //===----------------------------------------------------------------------===//
30 /// @brief A pass that runs on each Region in a function.
30 /// A pass that runs on each Region in a function.
3131 ///
3232 /// RegionPass is managed by RGPassManager.
3333 class RegionPass : public Pass {
3838 /// @name To be implemented by every RegionPass
3939 ///
4040 //@{
41 /// @brief Run the pass on a specific Region
41 /// Run the pass on a specific Region
4242 ///
4343 /// Accessing regions not contained in the current region is not allowed.
4444 ///
4848 /// @return True if the pass modifies this Region.
4949 virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0;
5050
51 /// @brief Get a pass to print the LLVM IR in the region.
51 /// Get a pass to print the LLVM IR in the region.
5252 ///
5353 /// @param O The output stream to print the Region.
5454 /// @param Banner The banner to separate different printed passes.
8484 bool skipRegion(Region &R) const;
8585 };
8686
87 /// @brief The pass manager to schedule RegionPasses.
87 /// The pass manager to schedule RegionPasses.
8888 class RGPassManager : public FunctionPass, public PMDataManager {
8989 std::deque RQ;
9090 bool skipThisRegion;
9696 static char ID;
9797 explicit RGPassManager();
9898
99 /// @brief Execute all of the passes scheduled for execution.
99 /// Execute all of the passes scheduled for execution.
100100 ///
101101 /// @return True if any of the passes modifies the function.
102102 bool runOnFunction(Function &F) override;
110110 PMDataManager *getAsPMDataManager() override { return this; }
111111 Pass *getAsPass() override { return this; }
112112
113 /// @brief Print passes managed by this manager.
113 /// Print passes managed by this manager.
114114 void dumpPassStructure(unsigned Offset) override;
115115
116 /// @brief Get passes contained by this manager.
116 /// Get passes contained by this manager.
117117 Pass *getContainedPass(unsigned N) {
118118 assert(N < PassVector.size() && "Pass number out of range!");
119119 Pass *FP = static_cast(PassVector[N]);
2525 FunctionPass *createRegionOnlyPrinterPass();
2626
2727 #ifndef NDEBUG
28 /// @brief Open a viewer to display the GraphViz vizualization of the analysis
28 /// Open a viewer to display the GraphViz vizualization of the analysis
2929 /// result.
3030 ///
3131 /// Practical to call in the debugger.
3434 /// @param RI The analysis to display.
3535 void viewRegion(llvm::RegionInfo *RI);
3636
37 /// @brief Analyze the regions of a function and open its GraphViz
37 /// Analyze the regions of a function and open its GraphViz
3838 /// visualization in a viewer.
3939 ///
4040 /// Useful to call in the debugger.
4545 /// @param F Function to analyze.
4646 void viewRegion(const llvm::Function *F);
4747
48 /// @brief Open a viewer to display the GraphViz vizualization of the analysis
48 /// Open a viewer to display the GraphViz vizualization of the analysis
4949 /// result.
5050 ///
5151 /// Useful to call in the debugger.
5454 /// @param RI The analysis to display.
5555 void viewRegionOnly(llvm::RegionInfo *RI);
5656
57 /// @brief Analyze the regions of a function and open its GraphViz
57 /// Analyze the regions of a function and open its GraphViz
5858 /// visualization in a viewer.
5959 ///
6060 /// Useful to call in the debugger.
462462 AuxiliarySectionDefinition SectionDefinition;
463463 };
464464
465 /// @brief The Import Directory Table.
465 /// The Import Directory Table.
466466 ///
467467 /// There is a single array of these and one entry per imported DLL.
468468 struct ImportDirectoryTableEntry {
473473 uint32_t ImportAddressTableRVA;
474474 };
475475
476 /// @brief The PE32 Import Lookup Table.
476 /// The PE32 Import Lookup Table.
477477 ///
478478 /// There is an array of these for each imported DLL. It represents either
479479 /// the ordinal to import from the target DLL, or a name to lookup and import
484484 struct ImportLookupTableEntry32 {
485485 uint32_t data;
486486
487 /// @brief Is this entry specified by ordinal, or name?
487 /// Is this entry specified by ordinal, or name?
488488 bool isOrdinal() const { return data & 0x80000000; }
489489
490 /// @brief Get the ordinal value of this entry. isOrdinal must be true.
490 /// Get the ordinal value of this entry. isOrdinal must be true.
491491 uint16_t getOrdinal() const {
492492 assert(isOrdinal() && "ILT entry is not an ordinal!");
493493 return data & 0xFFFF;
494494 }
495495
496 /// @brief Set the ordinal value and set isOrdinal to true.
496 /// Set the ordinal value and set isOrdinal to true.
497497 void setOrdinal(uint16_t o) {
498498 data = o;
499499 data |= 0x80000000;
500500 }
501501
502 /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
502 /// Get the Hint/Name entry RVA. isOrdinal must be false.
503503 uint32_t getHintNameRVA() const {
504504 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
505505 return data;
506506 }
507507
508 /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
508 /// Set the Hint/Name entry RVA and set isOrdinal to false.
509509 void setHintNameRVA(uint32_t rva) { data = rva; }
510510 };
511511
512 /// @brief The DOS compatible header at the front of all PEs.
512 /// The DOS compatible header at the front of all PEs.
513513 struct DOSHeader {
514514 uint16_t Magic;
515515 uint16_t UsedBytesInTheLastPage;
5858 Impl V = unknown;
5959 };
6060
61 /// @brief Identify the type of a binary file based on how magical it is.
61 /// Identify the type of a binary file based on how magical it is.
6262 file_magic identify_magic(StringRef magic);
6363
64 /// @brief Get and identify \a path's type based on its content.
64 /// Get and identify \a path's type based on its content.
6565 ///
6666 /// @param path Input path.
6767 /// @param result Set to the type of file, or file_magic::unknown.
6262 /// This class is a data container for one entry in a MachineConstantPool.
6363 /// It contains a pointer to the value and an offset from the start of
6464 /// the constant pool.
65 /// @brief An entry in a MachineConstantPool
65 /// An entry in a MachineConstantPool
6666 class MachineConstantPoolEntry {
6767 public:
6868 /// The constant itself.
116116 /// the use of MO_ConstantPoolIndex values. When emitting assembly or machine
117117 /// code, these virtual address references are converted to refer to the
118118 /// address of the function constant pool values.
119 /// @brief The machine constant pool.
119 /// The machine constant pool.
120120 class MachineConstantPool {
121121 unsigned PoolAlignment; ///< The alignment for the pool.
122122 std::vector Constants; ///< The pool of constants.
127127 const DataLayout &getDataLayout() const { return DL; }
128128
129129 public:
130 /// @brief The only constructor.
130 /// The only constructor.
131131 explicit MachineConstantPool(const DataLayout &DL)
132132 : PoolAlignment(1), DL(DL) {}
133133 ~MachineConstantPool();
8484 /// stack offsets of the object, eliminating all MO_FrameIndex operands from
8585 /// the program.
8686 ///
87 /// @brief Abstract Stack Frame Information
87 /// Abstract Stack Frame Information
8888 class MachineFrameInfo {
8989
9090 // Represent a single object allocated on the stack.
2828 using NodeId = unsigned;
2929 using EdgeId = unsigned;
3030
31 /// @brief Returns a value representing an invalid (non-existent) node.
31 /// Returns a value representing an invalid (non-existent) node.
3232 static NodeId invalidNodeId() {
3333 return std::numeric_limits::max();
3434 }
3535
36 /// @brief Returns a value representing an invalid (non-existent) edge.
36 /// Returns a value representing an invalid (non-existent) edge.
3737 static EdgeId invalidEdgeId() {
3838 return std::numeric_limits::max();
3939 }
337337 const NodeEntry &NE;
338338 };
339339
340 /// @brief Construct an empty PBQP graph.
340 /// Construct an empty PBQP graph.
341341 Graph() = default;
342342
343 /// @brief Construct an empty PBQP graph with the given graph metadata.
343 /// Construct an empty PBQP graph with the given graph metadata.
344344 Graph(GraphMetadata Metadata) : Metadata(std::move(Metadata)) {}
345345
346 /// @brief Get a reference to the graph metadata.
346 /// Get a reference to the graph metadata.
347347 GraphMetadata& getMetadata() { return Metadata; }
348348
349 /// @brief Get a const-reference to the graph metadata.
349 /// Get a const-reference to the graph metadata.
350350 const GraphMetadata& getMetadata() const { return Metadata; }
351351
352 /// @brief Lock this graph to the given solver instance in preparation
352 /// Lock this graph to the given solver instance in preparation
353353 /// for running the solver. This method will call solver.handleAddNode for
354354 /// each node in the graph, and handleAddEdge for each edge, to give the
355355 /// solver an opportunity to set up any requried metadata.
362362 Solver->handleAddEdge(EId);
363363 }
364364
365 /// @brief Release from solver instance.
365 /// Release from solver instance.
366366 void unsetSolver() {
367367 assert(Solver && "Solver not set.");
368368 Solver = nullptr;
369369 }
370370
371 /// @brief Add a node with the given costs.
371 /// Add a node with the given costs.
372372 /// @param Costs Cost vector for the new node.
373373 /// @return Node iterator for the added node.
374374 template
381381 return NId;
382382 }
383383
384 /// @brief Add a node bypassing the cost allocator.
384 /// Add a node bypassing the cost allocator.
385385 /// @param Costs Cost vector ptr for the new node (must be convertible to
386386 /// VectorPtr).
387387 /// @return Node iterator for the added node.
400400 return NId;
401401 }
402402
403 /// @brief Add an edge between the given nodes with the given costs.
403 /// Add an edge between the given nodes with the given costs.
404404 /// @param N1Id First node.
405405 /// @param N2Id Second node.
406406 /// @param Costs Cost matrix for new edge.
418418 return EId;
419419 }
420420
421 /// @brief Add an edge bypassing the cost allocator.
421 /// Add an edge bypassing the cost allocator.
422422 /// @param N1Id First node.
423423 /// @param N2Id Second node.
424424 /// @param Costs Cost matrix for new edge.
443443 return EId;
444444 }
445445
446 /// @brief Returns true if the graph is empty.
446 /// Returns true if the graph is empty.
447447 bool empty() const { return NodeIdSet(*this).empty(); }
448448
449449 NodeIdSet nodeIds() const { return NodeIdSet(*this); }
451451
452452 AdjEdgeIdSet adjEdgeIds(NodeId NId) { return AdjEdgeIdSet(getNode(NId)); }
453453
454 /// @brief Get the number of nodes in the graph.
454 /// Get the number of nodes in the graph.
455455 /// @return Number of nodes in the graph.
456456 unsigned getNumNodes() const { return NodeIdSet(*this).size(); }
457457
458 /// @brief Get the number of edges in the graph.
458 /// Get the number of edges in the graph.
459459 /// @return Number of edges in the graph.
460460 unsigned getNumEdges() const { return EdgeIdSet(*this).size(); }
461461
462 /// @brief Set a node's cost vector.
462 /// Set a node's cost vector.
463463 /// @param NId Node to update.
464464 /// @param Costs New costs to set.
465465 template
470470 getNode(NId).Costs = AllocatedCosts;
471471 }
472472
473 /// @brief Get a VectorPtr to a node's cost vector. Rarely useful - use
473 /// Get a VectorPtr to a node's cost vector. Rarely useful - use
474474 /// getNodeCosts where possible.
475475 /// @param NId Node id.
476476 /// @return VectorPtr to node cost vector.
482482 return getNode(NId).Costs;
483483 }
484484
485 /// @brief Get a node's cost vector.
485 /// Get a node's cost vector.
486486 /// @param NId Node id.
487487 /// @return Node cost vector.
488488 const Vector& getNodeCosts(NodeId NId) const {
501501 return getNode(NId).getAdjEdgeIds().size();
502502 }
503503
504 /// @brief Update an edge's cost matrix.
504 /// Update an edge's cost matrix.
505505 /// @param EId Edge id.
506506 /// @param Costs New cost matrix.
507507 template
512512 getEdge(EId).Costs = AllocatedCosts;
513513 }
514514
515 /// @brief Get a MatrixPtr to a node's cost matrix. Rarely useful - use
515 /// Get a MatrixPtr to a node's cost matrix. Rarely useful - use
516516 /// getEdgeCosts where possible.
517517 /// @param EId Edge id.
518518 /// @return MatrixPtr to edge cost matrix.
524524 return getEdge(EId).Costs;
525525 }
526526
527 /// @brief Get an edge's cost matrix.
527 /// Get an edge's cost matrix.
528528 /// @param EId Edge id.
529529 /// @return Edge cost matrix.
530530 const Matrix& getEdgeCosts(EdgeId EId) const {
539539 return getEdge(EId).Metadata;
540540 }
541541
542 /// @brief Get the first node connected to this edge.
542 /// Get the first node connected to this edge.
543543 /// @param EId Edge id.
544544 /// @return The first node connected to the given edge.
545545 NodeId getEdgeNode1Id(EdgeId EId) const {
546546 return getEdge(EId).getN1Id();
547547 }
548548
549 /// @brief Get the second node connected to this edge.
549 /// Get the second node connected to this edge.
550550 /// @param EId Edge id.
551551 /// @return The second node connected to the given edge.
552552 NodeId getEdgeNode2Id(EdgeId EId) const {
553553 return getEdge(EId).getN2Id();
554554 }
555555
556 /// @brief Get the "other" node connected to this edge.
556 /// Get the "other" node connected to this edge.
557557 /// @param EId Edge id.
558558 /// @param NId Node id for the "given" node.
559559 /// @return The iterator for the "other" node connected to this edge.
565565 return E.getN1Id();
566566 }
567567
568 /// @brief Get the edge connecting two nodes.
568 /// Get the edge connecting two nodes.
569569 /// @param N1Id First node id.
570570 /// @param N2Id Second node id.
571571 /// @return An id for edge (N1Id, N2Id) if such an edge exists,
580580 return invalidEdgeId();
581581 }
582582
583 /// @brief Remove a node from the graph.
583 /// Remove a node from the graph.
584584 /// @param NId Node id.
585585 void removeNode(NodeId NId) {
586586 if (Solver)
597597 FreeNodeIds.push_back(NId);
598598 }
599599
600 /// @brief Disconnect an edge from the given node.
600 /// Disconnect an edge from the given node.
601601 ///
602602 /// Removes the given edge from the adjacency list of the given node.
603603 /// This operation leaves the edge in an 'asymmetric' state: It will no
630630 E.disconnectFrom(*this, NId);
631631 }
632632
633 /// @brief Convenience method to disconnect all neighbours from the given
633 /// Convenience method to disconnect all neighbours from the given
634634 /// node.
635635 void disconnectAllNeighborsFromNode(NodeId NId) {
636636 for (auto AEId : adjEdgeIds(NId))
637637 disconnectEdge(AEId, getEdgeOtherNodeId(AEId, NId));
638638 }
639639
640 /// @brief Re-attach an edge to its nodes.
640 /// Re-attach an edge to its nodes.
641641 ///
642642 /// Adds an edge that had been previously disconnected back into the
643643 /// adjacency set of the nodes that the edge connects.
648648 Solver->handleReconnectEdge(EId, NId);
649649 }
650650
651 /// @brief Remove an edge from the graph.
651 /// Remove an edge from the graph.
652652 /// @param EId Edge id.
653653 void removeEdge(EdgeId EId) {
654654 if (Solver)
659659 Edges[EId].invalidate();
660660 }
661661
662 /// @brief Remove all nodes and edges from the graph.
662 /// Remove all nodes and edges from the graph.
663663 void clear() {
664664 Nodes.clear();
665665 FreeNodeIds.clear();
3232
3333 using PBQPRAGraph = PBQP::RegAlloc::PBQPRAGraph;
3434
35 /// @brief Abstract base for classes implementing PBQP register allocation
35 /// Abstract base for classes implementing PBQP register allocation
3636 /// constraints (e.g. Spill-costs, interference, coalescing).
3737 class PBQPRAConstraint {
3838 public:
4343 virtual void anchor();
4444 };
4545
46 /// @brief PBQP register allocation constraint composer.
46 /// PBQP register allocation constraint composer.
4747 ///
4848 /// Constraints added to this list will be applied, in the order that they are
4949 /// added, to the PBQP graph.
4242 namespace PBQP {
4343 namespace RegAlloc {
4444
45 /// @brief Spill option index.
45 /// Spill option index.
4646 inline unsigned getSpillOptionIdx() { return 0; }
4747
4848 /// Metadata to speed allocatability test.
504504 public:
505505 PBQPRAGraph(GraphMetadata Metadata) : BaseT(std::move(Metadata)) {}
506506
507 /// @brief Dump this graph to dbgs().
507 /// Dump this graph to dbgs().
508508 void dump() const;
509509
510 /// @brief Dump this graph to an output stream.
510 /// Dump this graph to an output stream.
511511 /// @param OS Output stream to print on.
512512 void dump(raw_ostream &OS) const;
513513
514 /// @brief Print a representation of this graph in DOT format.
514 /// Print a representation of this graph in DOT format.
515515 /// @param OS Output stream to print on.
516516 void printDot(raw_ostream &OS) const;
517517 };
526526 } // end namespace RegAlloc
527527 } // end namespace PBQP
528528
529 /// @brief Create a PBQP register allocator instance.
529 /// Create a PBQP register allocator instance.
530530 FunctionPass *
531531 createPBQPRegisterAllocator(char *customPassID = nullptr);
532532
8989
9090 void grow();
9191
92 /// @brief returns true if the specified virtual register is
92 /// returns true if the specified virtual register is
9393 /// mapped to a physical register
9494 bool hasPhys(unsigned virtReg) const {
9595 return getPhys(virtReg) != NO_PHYS_REG;
9696 }
9797
98 /// @brief returns the physical register mapped to the specified
98 /// returns the physical register mapped to the specified
9999 /// virtual register
100100 unsigned getPhys(unsigned virtReg) const {
101101 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
102102 return Virt2PhysMap[virtReg];
103103 }
104104
105 /// @brief creates a mapping for the specified virtual register to
105 /// creates a mapping for the specified virtual register to
106106 /// the specified physical register
107107 void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg);
108108
109 /// @brief clears the specified virtual register's, physical
109 /// clears the specified virtual register's, physical
110110 /// register mapping
111111 void clearVirt(unsigned virtReg) {
112112 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
115115 Virt2PhysMap[virtReg] = NO_PHYS_REG;
116116 }
117117
118 /// @brief clears all virtual to physical register mappings
118 /// clears all virtual to physical register mappings
119119 void clearAllVirt() {
120120 Virt2PhysMap.clear();
121121 grow();
122122 }
123123
124 /// @brief returns true if VirtReg is assigned to its preferred physreg.
124 /// returns true if VirtReg is assigned to its preferred physreg.
125125 bool hasPreferredPhys(unsigned VirtReg);
126126
127 /// @brief returns true if VirtReg has a known preferred register.
127 /// returns true if VirtReg has a known preferred register.
128128 /// This returns false if VirtReg has a preference that is a virtual
129129 /// register that hasn't been assigned yet.
130130 bool hasKnownPreference(unsigned VirtReg);
131131
132 /// @brief records virtReg is a split live interval from SReg.
132 /// records virtReg is a split live interval from SReg.
133133 void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
134134 Virt2SplitMap[virtReg] = SReg;
135135 }
136136
137 /// @brief returns the live interval virtReg is split from.
137 /// returns the live interval virtReg is split from.
138138 unsigned getPreSplitReg(unsigned virtReg) const {
139139 return Virt2SplitMap[virtReg];
140140 }
148148 return Orig ? Orig : VirtReg;
149149 }
150150
151 /// @brief returns true if the specified virtual register is not
151 /// returns true if the specified virtual register is not
152152 /// mapped to a stack slot or rematerialized.
153153 bool isAssignedReg(unsigned virtReg) const {
154154 if (getStackSlot(virtReg) == NO_STACK_SLOT)
158158 return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG);
159159 }
160160
161 /// @brief returns the stack slot mapped to the specified virtual
161 /// returns the stack slot mapped to the specified virtual
162162 /// register
163163 int getStackSlot(unsigned virtReg) const {
164164 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
165165 return Virt2StackSlotMap[virtReg];
166166 }
167167
168 /// @brief create a mapping for the specifed virtual register to
168 /// create a mapping for the specifed virtual register to
169169 /// the next available stack slot
170170 int assignVirt2StackSlot(unsigned virtReg);
171171
172 /// @brief create a mapping for the specified virtual register to
172 /// create a mapping for the specified virtual register to
173173 /// the specified stack slot
174174 void assignVirt2StackSlot(unsigned virtReg, int frameIndex);
175175
3535
3636 } // end namespace object
3737
38 /// @brief Represents an address in the target process's address space.
38 /// Represents an address in the target process's address space.
3939 using JITTargetAddress = uint64_t;
4040
41 /// @brief Flags for symbols in the JIT.
41 /// Flags for symbols in the JIT.
4242 class JITSymbolFlags {
4343 public:
4444 using UnderlyingType = uint8_t;
5959 return static_cast(Orig.Flags & ~Lazy & ~Materializing);
6060 }
6161
62 /// @brief Default-construct a JITSymbolFlags instance.
62 /// Default-construct a JITSymbolFlags instance.
6363 JITSymbolFlags() = default;
6464
65 /// @brief Construct a JITSymbolFlags instance from the given flags.
65 /// Construct a JITSymbolFlags instance from the given flags.
6666 JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
6767
68 /// @brief Construct a JITSymbolFlags instance from the given flags and target
68 /// Construct a JITSymbolFlags instance from the given flags and target
6969 /// flags.
7070 JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags)
7171 : Flags(Flags), TargetFlags(TargetFlags) {}
7272
73 /// @brief Return true if there was an error retrieving this symbol.
73 /// Return true if there was an error retrieving this symbol.
7474 bool hasError() const {
7575 return (Flags & HasError) == HasError;
7676 }
7777
78 /// @brief Returns true if this is a lazy symbol.
78 /// Returns true if this is a lazy symbol.
7979 /// This flag is used internally by the JIT APIs to track
8080 /// materialization states.
8181 bool isLazy() const { return Flags & Lazy; }
8282
83 /// @brief Returns true if this symbol is in the process of being
83 /// Returns true if this symbol is in the process of being
8484 /// materialized.
8585 bool isMaterializing() const { return Flags & Materializing; }
8686
87 /// @brief Returns true if this symbol is fully materialized.
87 /// Returns true if this symbol is fully materialized.
8888 /// (i.e. neither lazy, nor materializing).
8989 bool isMaterialized() const { return !(Flags & (Lazy | Materializing)); }
9090
91 /// @brief Returns true if the Weak flag is set.
91 /// Returns true if the Weak flag is set.
9292 bool isWeak() const {
9393 return (Flags & Weak) == Weak;
9494 }
9595
96 /// @brief Returns true if the Common flag is set.
96 /// Returns true if the Common flag is set.
9797 bool isCommon() const {
9898 return (Flags & Common) == Common;
9999 }
100100
101 /// @brief Returns true if the symbol isn't weak or common.
101 /// Returns true if the symbol isn't weak or common.
102102 bool isStrong() const {
103103 return !isWeak() && !isCommon();
104104 }
105105
106 /// @brief Returns true if the Exported flag is set.
106 /// Returns true if the Exported flag is set.
107107 bool isExported() const {
108108 return (Flags & Exported) == Exported;
109109 }
110110
111 /// @brief Implicitly convert to the underlying flags type.
111 /// Implicitly convert to the underlying flags type.
112112 operator UnderlyingType&() { return Flags; }
113113
114 /// @brief Implicitly convert to the underlying flags type.
114 /// Implicitly convert to the underlying flags type.
115115 operator const UnderlyingType&() const { return Flags; }
116116
117 /// @brief Return a reference to the target-specific flags.
117 /// Return a reference to the target-specific flags.
118118 TargetFlagsType& getTargetFlags() { return TargetFlags; }
119119
120 /// @brief Return a reference to the target-specific flags.
120 /// Return a reference to the target-specific flags.
121121 const TargetFlagsType& getTargetFlags() const { return TargetFlags; }
122122
123123 /// Construct a JITSymbolFlags value based on the flags of the given global
133133 TargetFlagsType TargetFlags = 0;
134134 };
135135
136 /// @brief ARM-specific JIT symbol flags.
136 /// ARM-specific JIT symbol flags.
137137 /// FIXME: This should be moved into a target-specific header.
138138 class ARMJITSymbolFlags {
139139 public:
152152 JITSymbolFlags::TargetFlagsType Flags = 0;
153153 };
154154
155 /// @brief Represents a symbol that has been evaluated to an address already.
155 /// Represents a symbol that has been evaluated to an address already.
156156 class JITEvaluatedSymbol {
157157 public:
158158 JITEvaluatedSymbol() = default;
159159
160 /// @brief Create a 'null' symbol.
160 /// Create a 'null' symbol.
161161 JITEvaluatedSymbol(std::nullptr_t) {}
162162
163 /// @brief Create a symbol for the given address and flags.
163 /// Create a symbol for the given address and flags.
164164 JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
165165 : Address(Address), Flags(Flags) {}
166166
167 /// @brief An evaluated symbol converts to 'true' if its address is non-zero.
167 /// An evaluated symbol converts to 'true' if its address is non-zero.
168168 explicit operator bool() const { return Address != 0; }
169169
170 /// @brief Return the address of this symbol.
170 /// Return the address of this symbol.
171171 JITTargetAddress getAddress() const { return Address; }
172172
173 /// @brief Return the flags for this symbol.
173 /// Return the flags for this symbol.
174174 JITSymbolFlags getFlags() const { return Flags; }
175175
176176 private:
178178 JITSymbolFlags Flags;
179179 };
180180
181 /// @brief Represents a symbol in the JIT.
181 /// Represents a symbol in the JIT.
182182 class JITSymbol {
183183 public:
184184 using GetAddressFtor = std::function()>;
185185
186 /// @brief Create a 'null' symbol, used to represent a "symbol not found"
186 /// Create a 'null' symbol, used to represent a "symbol not found"
187187 /// result from a successful (non-erroneous) lookup.
188188 JITSymbol(std::nullptr_t)
189189 : CachedAddr(0) {}
190190
191 /// @brief Create a JITSymbol representing an error in the symbol lookup
191 /// Create a JITSymbol representing an error in the symbol lookup
192192 /// process (e.g. a network failure during a remote lookup).
193193 JITSymbol(Error Err)
194194 : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {}
195195
196 /// @brief Create a symbol for a definition with a known address.
196 /// Create a symbol for a definition with a known address.
197197 JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
198198 : CachedAddr(Addr), Flags(Flags) {}
199199
200 /// @brief Construct a JITSymbol from a JITEvaluatedSymbol.
200 /// Construct a JITSymbol from a JITEvaluatedSymbol.
201201 JITSymbol(JITEvaluatedSymbol Sym)
202202 : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {}
203203
204 /// @brief Create a symbol for a definition that doesn't have a known address
204 /// Create a symbol for a definition that doesn't have a known address
205205 /// yet.
206206 /// @param GetAddress A functor to materialize a definition (fixing the
207207 /// address) on demand.
241241 CachedAddr.~JITTargetAddress();
242242 }
243243
244 /// @brief Returns true if the symbol exists, false otherwise.
244 /// Returns true if the symbol exists, false otherwise.
245245 explicit operator bool() const {
246246 return !Flags.hasError() && (CachedAddr || GetAddress);
247247 }
248248
249 /// @brief Move the error field value out of this JITSymbol.
249 /// Move the error field value out of this JITSymbol.
250250 Error takeError() {
251251 if (Flags.hasError())
252252 return std::move(Err);
253253 return Error::success();
254254 }
255255
256 /// @brief Get the address of the symbol in the target address space. Returns
256 /// Get the address of the symbol in the target address space. Returns
257257 /// '0' if the symbol does not exist.
258258 Expected getAddress() {
259259 assert(!Flags.hasError() && "getAddress called on error value");
279279 JITSymbolFlags Flags;
280280 };
281281
282 /// @brief Symbol resolution interface.
282 /// Symbol resolution interface.
283283 ///
284284 /// Allows symbol flags and addresses to be looked up by name.
285285 /// Symbol queries are done in bulk (i.e. you request resolution of a set of
293293
294294 virtual ~JITSymbolResolver() = default;
295295
296 /// @brief Returns the fully resolved address and flags for each of the given
296 /// Returns the fully resolved address and flags for each of the given
297297 /// symbols.
298298 ///
299299 /// This method will return an error if any of the given symbols can not be
300300 /// resolved, or if the resolution process itself triggers an error.
301301 virtual Expected lookup(const LookupSet &Symbols) = 0;
302302
303 /// @brief Returns the symbol flags for each of the given symbols.
303 /// Returns the symbol flags for each of the given symbols.
304304 ///
305305 /// This method does NOT return an error if any of the given symbols is
306306 /// missing. Instead, that symbol will be left out of the result map.
313313 /// Legacy symbol resolution interface.
314314 class LegacyJITSymbolResolver : public JITSymbolResolver {
315315 public:
316 /// @brief Performs lookup by, for each symbol, first calling
316 /// Performs lookup by, for each symbol, first calling
317317 /// findSymbolInLogicalDylib and if that fails calling
318318 /// findSymbol.
319319 Expected lookup(const LookupSet &Symbols) final;
320320
321 /// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
321 /// Performs flags lookup by calling findSymbolInLogicalDylib and
322322 /// returning the flags value for that symbol.
323323 Expected lookupFlags(const LookupSet &Symbols) final;
324324
5656
5757 namespace orc {
5858
59 /// @brief Compile-on-demand layer.
59 /// Compile-on-demand layer.
6060 ///
6161 /// When a module is added to this layer a stub is created for each of its
6262 /// function definitions. The stubs and other global values are immediately
195195
196196 public:
197197
198 /// @brief Module partitioning functor.
198 /// Module partitioning functor.
199199 using PartitioningFtor = std::function(Function&)>;
200200
201 /// @brief Builder for IndirectStubsManagers.
201 /// Builder for IndirectStubsManagers.
202202 using IndirectStubsManagerBuilderT =
203203 std::function()>;
204204
208208 using SymbolResolverSetter =
209209 std::function R)>;
210210
211 /// @brief Construct a compile-on-demand layer instance.
211 /// Construct a compile-on-demand layer instance.
212212 CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
213213 SymbolResolverGetter GetSymbolResolver,
214214 SymbolResolverSetter SetSymbolResolver,
229229 consumeError(removeModule(LogicalDylibs.begin()->first));
230230 }
231231
232 /// @brief Add a module to the compile-on-demand layer.
232 /// Add a module to the compile-on-demand layer.
233233 Error addModule(VModuleKey K, std::unique_ptr M) {
234234
235235 assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
241241 return addLogicalModule(I->second, std::move(M));
242242 }
243243
244 /// @brief Add extra modules to an existing logical module.
244 /// Add extra modules to an existing logical module.
245245 Error addExtraModule(VModuleKey K, std::unique_ptr M) {
246246 return addLogicalModule(LogicalDylibs[K], std::move(M));
247247 }
248248
249 /// @brief Remove the module represented by the given key.
249 /// Remove the module represented by the given key.
250250 ///
251251 /// This will remove all modules in the layers below that were derived from
252252 /// the module represented by K.
258258 return Err;
259259 }
260260
261 /// @brief Search for the given named symbol.
261 /// Search for the given named symbol.
262262 /// @param Name The name of the symbol to search for.
263263 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
264264 /// @return A handle for the given named symbol, if it exists.
274274 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
275275 }
276276
277 /// @brief Get the address of a symbol provided by this layer, or some layer
277 /// Get the address of a symbol provided by this layer, or some layer
278278 /// below this one.
279279 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
280280 bool ExportedSymbolsOnly) {
282282 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
283283 }
284284
285 /// @brief Update the stub for the given function to point at FnBodyAddr.
285 /// Update the stub for the given function to point at FnBodyAddr.
286286 /// This can be used to support re-optimization.
287287 /// @return true if the function exists and the stub is updated, false
288288 /// otherwise.
3434
3535 namespace orc {
3636
37 /// @brief Simple compile functor: Takes a single IR module and returns an
37 /// Simple compile functor: Takes a single IR module and returns an
3838 /// ObjectFile.
3939 class SimpleCompiler {
4040 private:
5555 public:
5656 using CompileResult = std::unique_ptr;
5757
58 /// @brief Construct a simple compile functor with the given target.
58 /// Construct a simple compile functor with the given target.
5959 SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
6060 : TM(TM), ObjCache(ObjCache) {}
6161
62 /// @brief Set an ObjectCache to query before compiling.
62 /// Set an ObjectCache to query before compiling.
6363 void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
6464
65 /// @brief Compile a Module to an ObjectFile.
65 /// Compile a Module to an ObjectFile.
6666 CompileResult operator()(Module &M) {
6767 CompileResult CachedObject = tryToLoadFromObjectCache(M);
6868 if (CachedObject)
3232 /// ExecutionSessions) for a module added to the JIT.
3333 using VModuleKey = uint64_t;
3434
35 /// @brief A set of symbol names (represented by SymbolStringPtrs for
35 /// A set of symbol names (represented by SymbolStringPtrs for
3636 // efficiency).
3737 using SymbolNameSet = std::set;
3838
39 /// @brief Render a SymbolNameSet to an ostream.
39 /// Render a SymbolNameSet to an ostream.
4040 raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
4141
42 /// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols
42 /// A map from symbol names (as SymbolStringPtrs) to JITSymbols
4343 /// (address/flags pairs).
4444 using SymbolMap = std::map;
4545
46 /// @brief Render a SymbolMap to an ostream.
46 /// Render a SymbolMap to an ostream.
4747 raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols);
4848
49 /// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
49 /// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
5050 using SymbolFlagsMap = std::map;
5151
52 /// @brief Render a SymbolMap to an ostream.
52 /// Render a SymbolMap to an ostream.
5353 raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &Symbols);
5454
55 /// @brief A base class for materialization failures that allows the failing
55 /// A base class for materialization failures that allows the failing
5656 /// symbols to be obtained for logging.
5757 class FailedToMaterialize : public ErrorInfo {
5858 public:
6060 virtual const SymbolNameSet &getSymbols() const = 0;
6161 };
6262
63 /// @brief Used to notify a VSO that the given set of symbols failed to resolve.
63 /// Used to notify a VSO that the given set of symbols failed to resolve.
6464 class FailedToResolve : public ErrorInfo {
6565 public:
6666 static char ID;
7474 SymbolNameSet Symbols;
7575 };
7676
77 /// @brief Used to notify a VSO that the given set of symbols failed to
77 /// Used to notify a VSO that the given set of symbols failed to
7878 /// finalize.
7979 class FailedToFinalize
8080 : public ErrorInfo {
9090 SymbolNameSet Symbols;
9191 };
9292
93 /// @brief A symbol query that returns results via a callback when results are
93 /// A symbol query that returns results via a callback when results are
9494 /// ready.
9595 ///
9696 /// makes a callback when all symbols are available.
9797 class AsynchronousSymbolQuery {
9898 public:
99 /// @brief Callback to notify client that symbols have been resolved.
99 /// Callback to notify client that symbols have been resolved.
100100 using SymbolsResolvedCallback = std::function)>;
101101
102 /// @brief Callback to notify client that symbols are ready for execution.
102 /// Callback to notify client that symbols are ready for execution.
103103 using SymbolsReadyCallback = std::function;
104104
105 /// @brief Create a query for the given symbols, notify-resolved and
105 /// Create a query for the given symbols, notify-resolved and
106106 /// notify-ready callbacks.
107107 AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
108108 SymbolsResolvedCallback NotifySymbolsResolved,
109109 SymbolsReadyCallback NotifySymbolsReady);
110110
111 /// @brief Notify client that the query failed.
111 /// Notify client that the query failed.
112112 ///
113113 /// If the notify-resolved callback has not been made yet, then it is called
114114 /// with the given error, and the notify-finalized callback is never made.
119119 /// It is illegal to call setFailed after both callbacks have been made.
120120 void notifyMaterializationFailed(Error Err);
121121
122 /// @brief Set the resolved symbol information for the given symbol name.
122 /// Set the resolved symbol information for the given symbol name.
123123 ///
124124 /// If this symbol was the last one not resolved, this will trigger a call to
125125 /// the notify-finalized callback passing the completed sybol map.
126126 void resolve(SymbolStringPtr Name, JITEvaluatedSymbol Sym);
127127
128 /// @brief Notify the query that a requested symbol is ready for execution.
128 /// Notify the query that a requested symbol is ready for execution.
129129 ///
130130 /// This decrements the query's internal count of not-yet-ready symbols. If
131131 /// this call to notifySymbolFinalized sets the counter to zero, it will call
140140 SymbolsReadyCallback NotifySymbolsReady;
141141 };
142142
143 /// @brief SymbolResolver is a composable interface for looking up symbol flags
143 /// SymbolResolver is a composable interface for looking up symbol flags
144144 /// and addresses using the AsynchronousSymbolQuery type. It will
145145 /// eventually replace the LegacyJITSymbolResolver interface as the
146146 /// stardard ORC symbol resolver type.
148148 public:
149149 virtual ~SymbolResolver() = default;
150150
151 /// @brief Returns the flags for each symbol in Symbols that can be found,
151 /// Returns the flags for each symbol in Symbols that can be found,
152152 /// along with the set of symbol that could not be found.
153153 virtual SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
154154 const SymbolNameSet &Symbols) = 0;
155155
156 /// @brief For each symbol in Symbols that can be found, assigns that symbols
156 /// For each symbol in Symbols that can be found, assigns that symbols
157157 /// value in Query. Returns the set of symbols that could not be found.
158158 virtual SymbolNameSet lookup(std::shared_ptr Query,
159159 SymbolNameSet Symbols) = 0;
162162 virtual void anchor();
163163 };
164164
165 /// @brief Implements SymbolResolver with a pair of supplied function objects
165 /// Implements SymbolResolver with a pair of supplied function objects
166166 /// for convenience. See createSymbolResolver.
167167 template
168168 class LambdaSymbolResolver final : public SymbolResolver {
187187 LookupFn Lookup;
188188 };
189189
190 /// @brief Creates a SymbolResolver implementation from the pair of supplied
190 /// Creates a SymbolResolver implementation from the pair of supplied
191191 /// function objects.
192192 template
193193 std::unique_ptr
205205 std::forward(LookupFlags), std::forward(Lookup));
206206 }
207207
208 /// @brief Tracks responsibility for materialization.
208 /// Tracks responsibility for materialization.
209209 ///
210210 /// An instance of this class is passed to MaterializationUnits when their
211211 /// materialize method is called. It allows MaterializationUnits to resolve and
213213 /// symbols of an error.
214214 class MaterializationResponsibility {
215215 public:
216 /// @brief Create a MaterializationResponsibility for the given VSO and
216 /// Create a MaterializationResponsibility for the given VSO and
217217 /// initial symbols.
218218 MaterializationResponsibility(VSO &V, SymbolFlagsMap SymbolFlags);
219219
221221 MaterializationResponsibility &
222222 operator=(MaterializationResponsibility &&) = default;
223223
224 /// @brief Destruct a MaterializationResponsibility instance. In debug mode
224 /// Destruct a MaterializationResponsibility instance. In debug mode
225225 /// this asserts that all symbols being tracked have been either
226226 /// finalized or notified of an error.
227227 ~MaterializationResponsibility();
228228
229 /// @brief Returns the target VSO that these symbols are being materialized
229 /// Returns the target VSO that these symbols are being materialized
230230 /// into.
231231 const VSO &getTargetVSO() const { return V; }
232232
233 /// @brief Resolves the given symbols. Individual calls to this method may
233 /// Resolves the given symbols. Individual calls to this method may
234234 /// resolve a subset of the symbols, but all symbols must have been
235235 /// resolved prior to calling finalize.
236236 void resolve(const SymbolMap &Symbols);
237237
238 /// @brief Finalizes all symbols tracked by this instance.
238 /// Finalizes all symbols tracked by this instance.
239239 void finalize();
240240
241 /// @brief Notify all unfinalized symbols that an error has occurred.
241 /// Notify all unfinalized symbols that an error has occurred.
242242 /// This method should be called if materialization of any symbol is
243243 /// abandoned.
244244 void notifyMaterializationFailed();
245245
246 /// @brief Transfers responsibility for the given symbols to a new
246 /// Transfers responsibility for the given symbols to a new
247247 /// MaterializationResponsibility class. This is useful if a
248248 /// MaterializationUnit wants to transfer responsibility for a subset
249249 /// of symbols to another MaterializationUnit or utility.
254254 SymbolFlagsMap SymbolFlags;
255255 };
256256
257 /// @brief A MaterializationUnit represents a set of symbol definitions that can
257 /// A MaterializationUnit represents a set of symbol definitions that can
258258 /// be materialized as a group, or individually discarded (when
259259 /// overriding definitions are encountered).
260260 ///
266266 public:
267267 virtual ~MaterializationUnit() {}
268268
269 /// @brief Return the set of symbols that this source provides.
269 /// Return the set of symbols that this source provides.
270270 virtual SymbolFlagsMap getSymbols() = 0;
271271
272 /// @brief Implementations of this method should materialize all symbols
272 /// Implementations of this method should materialize all symbols
273273 /// in the materialzation unit, except for those that have been
274274 /// previously discarded.
275275 virtual void materialize(MaterializationResponsibility R) = 0;
276276
277 /// @brief Implementations of this method should discard the given symbol
277 /// Implementations of this method should discard the given symbol
278278 /// from the source (e.g. if the source is an LLVM IR Module and the
279279 /// symbol is a function, delete the function body or mark it available
280280 /// externally).
284284 virtual void anchor();
285285 };
286286
287 /// @brief Represents a dynamic linkage unit in a JIT process.
287 /// Represents a dynamic linkage unit in a JIT process.
288288 ///
289289 /// VSO acts as a symbol table (symbol definitions can be set and the dylib
290290 /// queried to find symbol addresses) and as a key for tracking resources
328328 VSO(VSO &&) = delete;
329329 VSO &operator=(VSO &&) = delete;
330330
331 /// @brief Compare new linkage with existing linkage.
331 /// Compare new linkage with existing linkage.
332332 static RelativeLinkageStrength
333333 compareLinkage(Optional OldFlags, JITSymbolFlags NewFlags);
334334
335 /// @brief Compare new linkage with an existing symbol's linkage.
335 /// Compare new linkage with an existing symbol's linkage.
336336 RelativeLinkageStrength compareLinkage(SymbolStringPtr Name,
337337 JITSymbolFlags NewFlags) const;
338338
339 /// @brief Adds the given symbols to the mapping as resolved, finalized
339 /// Adds the given symbols to the mapping as resolved, finalized
340340 /// symbols.
341341 ///
342342 /// FIXME: We can take this by const-ref once symbol-based laziness is
343343 /// removed.
344344 Error define(SymbolMap NewSymbols);
345345
346 /// @brief Adds the given symbols to the mapping as lazy symbols.
346 /// Adds the given symbols to the mapping as lazy symbols.
347347 Error defineLazy(std::unique_ptr Source);
348348
349 /// @brief Look up the flags for the given symbols.
349 /// Look up the flags for the given symbols.
350350 ///
351351 /// Returns the flags for the give symbols, together with the set of symbols
352352 /// not found.
353353 SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, SymbolNameSet Symbols);
354354
355 /// @brief Apply the given query to the given symbols in this VSO.
355 /// Apply the given query to the given symbols in this VSO.
356356 ///
357357 /// For symbols in this VSO that have already been materialized, their address
358358 /// will be set in the query immediately.
368368 SymbolNameSet Symbols);
369369
370370 private:
371 /// @brief Add the given symbol/address mappings to the dylib, but do not
371 /// Add the given symbol/address mappings to the dylib, but do not
372372 /// mark the symbols as finalized yet.
373373 void resolve(const SymbolMap &SymbolValues);
374374
375 /// @brief Finalize the given symbols.
375 /// Finalize the given symbols.
376376 void finalize(const SymbolNameSet &SymbolsToFinalize);
377377
378 /// @brief Notify the VSO that the given symbols failed to materialized.
378 /// Notify the VSO that the given symbols failed to materialized.
379379 void notifyMaterializationFailed(const SymbolNameSet &Names);
380380
381381 class UnmaterializedInfo {
450450 MaterializingInfoMap MaterializingInfos;
451451 };
452452
453 /// @brief An ExecutionSession represents a running JIT program.
453 /// An ExecutionSession represents a running JIT program.
454454 class ExecutionSession {
455455 public:
456456 using ErrorReporter = std::function;
457457
458 /// @brief Construct an ExecutionEngine.
458 /// Construct an ExecutionEngine.
459459 ///
460460 /// SymbolStringPools may be shared between ExecutionSessions.
461461 ExecutionSession(std::shared_ptr SSP = nullptr)
462462 : SSP(SSP ? std::move(SSP) : std::make_shared()) {}
463463
464 /// @brief Returns the SymbolStringPool for this ExecutionSession.
464 /// Returns the SymbolStringPool for this ExecutionSession.
465465 SymbolStringPool &getSymbolStringPool() const { return *SSP; }
466466
467 /// @brief Set the error reporter function.
467 /// Set the error reporter function.
468468 void setErrorReporter(ErrorReporter ReportError) {
469469 this->ReportError = std::move(ReportError);
470470 }
471471
472 /// @brief Report a error for this execution session.
472 /// Report a error for this execution session.
473473 ///
474474 /// Unhandled errors can be sent here to log them.
475475 void reportError(Error Err) { ReportError(std::move(Err)); }
476476
477 /// @brief Allocate a module key for a new module to add to the JIT.
477 /// Allocate a module key for a new module to add to the JIT.
478478 VModuleKey allocateVModule() { return ++LastKey; }
479479
480 /// @brief Return a module key to the ExecutionSession so that it can be
480 /// Return a module key to the ExecutionSession so that it can be
481481 /// re-used. This should only be done once all resources associated
482482 //// with the original key have been released.
483483 void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */ }
500500 /// Materialization function object wrapper for the lookup method.
501501 using MaterializationDispatcher = std::function;
502502
503 /// @brief Look up a set of symbols by searching a list of VSOs.
503 /// Look up a set of symbols by searching a list of VSOs.
504504 ///
505505 /// All VSOs in the list should be non-null.
506506 Expected lookup(const std::vector &VSOs, SymbolNameSet Names,
507507 MaterializationDispatcher DispatchMaterialization);
508508
509 /// @brief Look up a symbol by searching a list of VSOs.
509 /// Look up a symbol by searching a list of VSOs.
510510 Expected
511511 lookup(const std::vector VSOs, SymbolStringPtr Name,
512512 MaterializationDispatcher DispatchMaterialization);
3535
3636 namespace orc {
3737
38 /// @brief This iterator provides a convenient way to iterate over the elements
38 /// This iterator provides a convenient way to iterate over the elements
3939 /// of an llvm.global_ctors/llvm.global_dtors instance.
4040 ///
4141 /// The easiest way to get hold of instances of this class is to use the
4242 /// getConstructors/getDestructors functions.
4343 class CtorDtorIterator {
4444 public:
45 /// @brief Accessor for an element of the global_ctors/global_dtors array.
45 /// Accessor for an element of the global_ctors/global_dtors array.
4646 ///
4747 /// This class provides a read-only view of the element with any casts on
4848 /// the function stripped away.
5555 Value *Data;
5656 };
5757
58 /// @brief Construct an iterator instance. If End is true then this iterator
58 /// Construct an iterator instance. If End is true then this iterator
5959 /// acts as the end of the range, otherwise it is the beginning.
6060 CtorDtorIterator(const GlobalVariable *GV, bool End);
6161
62 /// @brief Test iterators for equality.
62 /// Test iterators for equality.
6363 bool operator==(const CtorDtorIterator &Other) const;
6464
65 /// @brief Test iterators for inequality.
65 /// Test iterators for inequality.
6666 bool operator!=(const CtorDtorIterator &Other) const;
6767
68 /// @brief Pre-increment iterator.
68 /// Pre-increment iterator.
6969 CtorDtorIterator& operator++();
7070
71 /// @brief Post-increment iterator.
71 /// Post-increment iterator.
7272 CtorDtorIterator operator++(int);
7373
74 /// @brief Dereference iterator. The resulting value provides a read-only view
74 /// Dereference iterator. The resulting value provides a read-only view
7575 /// of this element of the global_ctors/global_dtors list.
7676 Element operator*() const;
7777
8080 unsigned I;
8181 };
8282
83 /// @brief Create an iterator range over the entries of the llvm.global_ctors
83 /// Create an iterator range over the entries of the llvm.global_ctors
8484 /// array.
8585 iterator_range getConstructors(const Module &M);
8686
87 /// @brief Create an iterator range over the entries of the llvm.global_ctors
87 /// Create an iterator range over the entries of the llvm.global_ctors
8888 /// array.
8989 iterator_range getDestructors(const Module &M);
9090
91 /// @brief Convenience class for recording constructor/destructor names for
91 /// Convenience class for recording constructor/destructor names for
9292 /// later execution.
9393 template
9494 class CtorDtorRunner {
9595 public:
96 /// @brief Construct a CtorDtorRunner for the given range using the given
96 /// Construct a CtorDtorRunner for the given range using the given
9797 /// name mangling function.
9898 CtorDtorRunner(std::vector CtorDtorNames, VModuleKey K)
9999 : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
100100
101 /// @brief Run the recorded constructors/destructors through the given JIT
101 /// Run the recorded constructors/destructors through the given JIT
102102 /// layer.
103103 Error runViaLayer(JITLayerT &JITLayer) const {
104104 using CtorDtorTy = void (*)();
126126 orc::VModuleKey K;
127127 };
128128
129 /// @brief Support class for static dtor execution. For hosted (in-process) JITs
129 /// Support class for static dtor execution. For hosted (in-process) JITs
130130 /// only!
131131 ///
132132 /// If a __cxa_atexit function isn't found C++ programs that use static
2626
2727 namespace orc {
2828
29 /// @brief Global mapping layer.
29 /// Global mapping layer.
3030 ///
3131 /// This layer overrides the findSymbol method to first search a local symbol
3232 /// table that the client can define. It can be used to inject new symbol
3737 class GlobalMappingLayer {
3838 public:
3939
40 /// @brief Handle to an added module.
40 /// Handle to an added module.
4141 using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
4242
43 /// @brief Construct an GlobalMappingLayer with the given BaseLayer
43 /// Construct an GlobalMappingLayer with the given BaseLayer
4444 GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
4545
46 /// @brief Add the given module to the JIT.
46 /// Add the given module to the JIT.
4747 /// @return A handle for the added modules.
4848 Expected
4949 addModule(std::shared_ptr M,
5151 return BaseLayer.addModule(std::move(M), std::move(Resolver));
5252 }
5353
54 /// @brief Remove the module set associated with the handle H.
54 /// Remove the module set associated with the handle H.
5555 Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
5656
57 /// @brief Manually set the address to return for the given symbol.
57 /// Manually set the address to return for the given symbol.
5858 void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
5959 SymbolTable[Name] = Addr;
6060 }
6161
62 /// @brief Remove the given symbol from the global mapping.
62 /// Remove the given symbol from the global mapping.
6363 void eraseGlobalMapping(const std::string &Name) {
6464 SymbolTable.erase(Name);
6565 }
6666
67 /// @brief Search for the given named symbol.
67 /// Search for the given named symbol.
6868 ///
6969 /// This method will first search the local symbol table, returning
7070 /// any symbol found there. If the symbol is not found in the local
8080 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
8181 }
8282
83 /// @brief Get the address of the given symbol in the context of the of the
83 /// Get the address of the given symbol in the context of the of the
8484 /// module represented by the handle H. This call is forwarded to the
8585 /// base layer's implementation.
8686 /// @param H The handle for the module to search in.
9393 return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
9494 }
9595
96 /// @brief Immediately emit and finalize the module set represented by the
96 /// Immediately emit and finalize the module set represented by the
9797 /// given handle.
9898 /// @param H Handle for module set to emit/finalize.
9999 Error emitAndFinalize(ModuleHandleT H) {
2626
2727 namespace orc {
2828
29 /// @brief Eager IR compiling layer.
29 /// Eager IR compiling layer.
3030 ///
3131 /// This layer immediately compiles each IR module added via addModule to an
3232 /// object file and adds this module file to the layer below, which must
3434 template
3535 class IRCompileLayer {
3636 public:
37 /// @brief Callback type for notifications when modules are compiled.
37 /// Callback type for notifications when modules are compiled.
3838 using NotifyCompiledCallback =
3939 std::function)>;
4040
41 /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
41 /// Construct an IRCompileLayer with the given BaseLayer, which must
4242 /// implement the ObjectLayer concept.
4343 IRCompileLayer(
4444 BaseLayerT &BaseLayer, CompileFtor Compile,
4646 : BaseLayer(BaseLayer), Compile(std::move(Compile)),
4747 NotifyCompiled(std::move(NotifyCompiled)) {}
4848
49 /// @brief Get a reference to the compiler functor.
49 /// Get a reference to the compiler functor.
5050 CompileFtor& getCompiler() { return Compile; }
5151
52 /// @brief (Re)set the NotifyCompiled callback.
52 /// (Re)set the NotifyCompiled callback.
5353 void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) {
5454 this->NotifyCompiled = std::move(NotifyCompiled);
5555 }
5656
57 /// @brief Compile the module, and add the resulting object to the base layer
57 /// Compile the module, and add the resulting object to the base layer
5858 /// along with the given memory manager and symbol resolver.
5959 Error addModule(VModuleKey K, std::unique_ptr M) {
6060 if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M)))
6464 return Error::success();
6565 }
6666
67 /// @brief Remove the module associated with the VModuleKey K.
67 /// Remove the module associated with the VModuleKey K.
6868 Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
6969
70 /// @brief Search for the given named symbol.
70 /// Search for the given named symbol.
7171 /// @param Name The name of the symbol to search for.
7272 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
7373 /// @return A handle for the given named symbol, if it exists.
7575 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
7676 }
7777
78 /// @brief Get the address of the given symbol in compiled module represented
78 /// Get the address of the given symbol in compiled module represented
7979 /// by the handle H. This call is forwarded to the base layer's
8080 /// implementation.
8181 /// @param K The VModuleKey for the module to search in.
8888 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
8989 }
9090
91 /// @brief Immediately emit and finalize the module represented by the given
91 /// Immediately emit and finalize the module represented by the given
9292 /// handle.
9393 /// @param K The VModuleKey for the module to emit/finalize.
9494 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
2222 class Module;
2323 namespace orc {
2424
25 /// @brief IR mutating layer.
25 /// IR mutating layer.
2626 ///
2727 /// This layer applies a user supplied transform to each module that is added,
2828 /// then adds the transformed module to the layer below.
3030 class IRTransformLayer {
3131 public:
3232
33 /// @brief Construct an IRTransformLayer with the given BaseLayer
33 /// Construct an IRTransformLayer with the given BaseLayer
3434 IRTransformLayer(BaseLayerT &BaseLayer,
3535 TransformFtor Transform = TransformFtor())
3636 : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
3737
38 /// @brief Apply the transform functor to the module, then add the module to
38 /// Apply the transform functor to the module, then add the module to
3939 /// the layer below, along with the memory manager and symbol resolver.
4040 ///
4141 /// @return A handle for the added modules.
4343 return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
4444 }
4545
46 /// @brief Remove the module associated with the VModuleKey K.
46 /// Remove the module associated with the VModuleKey K.
4747 Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
4848
49 /// @brief Search for the given named symbol.
49 /// Search for the given named symbol.
5050 /// @param Name The name of the symbol to search for.
5151 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
5252 /// @return A handle for the given named symbol, if it exists.
5454 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
5555 }
5656
57 /// @brief Get the address of the given symbol in the context of the module
57 /// Get the address of the given symbol in the context of the module
5858 /// represented by the VModuleKey K. This call is forwarded to the base
5959 /// layer's implementation.
6060 /// @param K The VModuleKey for the module to search in.
6767 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
6868 }
6969
70 /// @brief Immediately emit and finalize the module represented by the given
70 /// Immediately emit and finalize the module represented by the given
7171 /// VModuleKey.
7272 /// @param K The VModuleKey for the module to emit/finalize.
7373 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
7474
75 /// @brief Access the transform functor directly.
75 /// Access the transform functor directly.
7676 TransformFtor& getTransform() { return Transform; }
7777
78 /// @brief Access the mumate functor directly.
78 /// Access the mumate functor directly.
7979 const TransformFtor& getTransform() const { return Transform; }
8080
8181 private:
4545
4646 namespace orc {
4747
48 /// @brief Target-independent base class for compile callback management.
48 /// Target-independent base class for compile callback management.
4949 class JITCompileCallbackManager {
5050 public:
5151 using CompileFtor = std::function;
5252
53 /// @brief Handle to a newly created compile callback. Can be used to get an
53 /// Handle to a newly created compile callback. Can be used to get an
5454 /// IR constant representing the address of the trampoline, and to set
5555 /// the compile action for the callback.
5656 class CompileCallbackInfo {
6868 CompileFtor &Compile;
6969 };
7070
71 /// @brief Construct a JITCompileCallbackManager.
71 /// Construct a JITCompileCallbackManager.
7272 /// @param ErrorHandlerAddress The address of an error handler in the target
7373 /// process to be used if a compile callback fails.
7474 JITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress)
7676
7777 virtual ~JITCompileCallbackManager() = default;
7878
79 /// @brief Execute the callback for the given trampoline id. Called by the JIT
79 /// Execute the callback for the given trampoline id. Called by the JIT
8080 /// to compile functions on demand.
8181 JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr) {
8282 auto I = ActiveTrampolines.find(TrampolineAddr);
103103 return ErrorHandlerAddress;
104104 }
105105
106 /// @brief Reserve a compile callback.
106 /// Reserve a compile callback.
107107 Expected getCompileCallback() {
108108 if (auto TrampolineAddrOrErr = getAvailableTrampolineAddr()) {
109109 const auto &TrampolineAddr = *TrampolineAddrOrErr;
113113 return TrampolineAddrOrErr.takeError();
114114 }
115115
116 /// @brief Get a CompileCallbackInfo for an existing callback.
116 /// Get a CompileCallbackInfo for an existing callback.
117117 CompileCallbackInfo getCompileCallbackInfo(JITTargetAddress TrampolineAddr) {
118118 auto I = ActiveTrampolines.find(TrampolineAddr);
119119 assert(I != ActiveTrampolines.end() && "Not an active trampoline.");
120120 return CompileCallbackInfo(I->first, I->second);
121121 }
122122
123 /// @brief Release a compile callback.
123 /// Release a compile callback.
124124 ///
125125 /// Note: Callbacks are auto-released after they execute. This method should
126126 /// only be called to manually release a callback that is not going to
157157 virtual void anchor();
158158 };
159159
160 /// @brief Manage compile callbacks for in-process JITs.
160 /// Manage compile callbacks for in-process JITs.
161161 template
162162 class LocalJITCompileCallbackManager : public JITCompileCallbackManager {
163163 public:
164 /// @brief Construct a InProcessJITCompileCallbackManager.
164 /// Construct a InProcessJITCompileCallbackManager.
165165 /// @param ErrorHandlerAddress The address of an error handler in the target
166166 /// process to be used if a compile callback fails.
167167 LocalJITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress)
228228 std::vector TrampolineBlocks;
229229 };
230230
231 /// @brief Base class for managing collections of named indirect stubs.
231 /// Base class for managing collections of named indirect stubs.
232232 class IndirectStubsManager {
233233 public:
234 /// @brief Map type for initializing the manager. See init.
234 /// Map type for initializing the manager. See init.
235235 using StubInitsMap = StringMap>;
236236
237237 virtual ~IndirectStubsManager() = default;
238238
239 /// @brief Create a single stub with the given name, target address and flags.
239 /// Create a single stub with the given name, target address and flags.
240240 virtual Error createStub(StringRef StubName, JITTargetAddress StubAddr,
241241 JITSymbolFlags StubFlags) = 0;
242242
243 /// @brief Create StubInits.size() stubs with the given names, target
243 /// Create StubInits.size() stubs with the given names, target
244244 /// addresses, and flags.
245245 virtual Error createStubs(const StubInitsMap &StubInits) = 0;
246246
247 /// @brief Find the stub with the given name. If ExportedStubsOnly is true,
247 /// Find the stub with the given name. If ExportedStubsOnly is true,
248248 /// this will only return a result if the stub's flags indicate that it
249249 /// is exported.
250250 virtual JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) = 0;
251251
252 /// @brief Find the implementation-pointer for the stub.
252 /// Find the implementation-pointer for the stub.
253253 virtual JITSymbol findPointer(StringRef Name) = 0;
254254
255 /// @brief Change the value of the implementation pointer for the stub.
255 /// Change the value of the implementation pointer for the stub.
256256 virtual Error updatePointer(StringRef Name, JITTargetAddress NewAddr) = 0;
257257
258258 private:
259259 virtual void anchor();
260260 };
261261
262 /// @brief IndirectStubsManager implementation for the host architecture, e.g.
262 /// IndirectStubsManager implementation for the host architecture, e.g.
263263 /// OrcX86_64. (See OrcArchitectureSupport.h).
264264 template
265265 class LocalIndirectStubsManager : public IndirectStubsManager {
353353 StringMap> StubIndexes;
354354 };
355355
356 /// @brief Create a local compile callback manager.
356 /// Create a local compile callback manager.
357357 ///
358358 /// The given target triple will determine the ABI, and the given
359359 /// ErrorHandlerAddress will be used by the resulting compile callback
362362 createLocalCompileCallbackManager(const Triple &T,
363363 JITTargetAddress ErrorHandlerAddress);
364364
365 /// @brief Create a local indriect stubs manager builder.
365 /// Create a local indriect stubs manager builder.
366366 ///
367367 /// The given target triple will determine the ABI.
368368 std::function()>
369369 createLocalIndirectStubsManagerBuilder(const Triple &T);
370370
371 /// @brief Build a function pointer of FunctionType with the given constant
371 /// Build a function pointer of FunctionType with the given constant
372372 /// address.
373373 ///
374374 /// Usage example: Turn a trampoline address into a function pointer constant
375375 /// for use in a stub.
376376 Constant *createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr);
377377
378 /// @brief Create a function pointer with the given type, name, and initializer
378 /// Create a function pointer with the given type, name, and initializer
379379 /// in the given Module.
380380 GlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name,
381381 Constant *Initializer);
382382
383 /// @brief Turn a function declaration into a stub function that makes an
383 /// Turn a function declaration into a stub function that makes an
384384 /// indirect call using the given function pointer.
385385 void makeStub(Function &F, Value &ImplPointer);
386386
387 /// @brief Raise linkage types and rename as necessary to ensure that all
387 /// Raise linkage types and rename as necessary to ensure that all
388388 /// symbols are accessible for other modules.
389389 ///
390390 /// This should be called before partitioning a module to ensure that the
391391 /// partitions retain access to each other's symbols.
392392 void makeAllSymbolsExternallyAccessible(Module &M);
393393
394 /// @brief Clone a function declaration into a new module.
394 /// Clone a function declaration into a new module.
395395 ///
396396 /// This function can be used as the first step towards creating a callback
397397 /// stub (see makeStub), or moving a function body (see moveFunctionBody).
406406 Function *cloneFunctionDecl(Module &Dst, const Function &F,
407407 ValueToValueMapTy *VMap = nullptr);
408408
409 /// @brief Move the body of function 'F' to a cloned function declaration in a
409 /// Move the body of function 'F' to a cloned function declaration in a
410410 /// different module (See related cloneFunctionDecl).
411411 ///
412412 /// If the target function declaration is not supplied via the NewF parameter
418418 ValueMaterializer *Materializer = nullptr,
419419 Function *NewF = nullptr);
420420
421 /// @brief Clone a global variable declaration into a new module.
421 /// Clone a global variable declaration into a new module.
422422 GlobalVariable *cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
423423 ValueToValueMapTy *VMap = nullptr);
424424
425 /// @brief Move global variable GV from its parent module to cloned global
425 /// Move global variable GV from its parent module to cloned global
426426 /// declaration in a different module.
427427 ///
428428 /// If the target global declaration is not supplied via the NewGV parameter
435435 ValueMaterializer *Materializer = nullptr,
436436 GlobalVariable *NewGV = nullptr);
437437
438 /// @brief Clone a global alias declaration into a new module.
438 /// Clone a global alias declaration into a new module.
439439 GlobalAlias *cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
440440 ValueToValueMapTy &VMap);
441441
442 /// @brief Clone module flags metadata into the destination module.
442 /// Clone module flags metadata into the destination module.
443443 void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
444444 ValueToValueMapTy &VMap);
445445
3232 namespace llvm {
3333 namespace orc {
3434
35 /// @brief Lazy-emitting IR layer.
35 /// Lazy-emitting IR layer.
3636 ///
3737 /// This layer accepts LLVM IR Modules (via addModule), but does not
3838 /// immediately emit them the layer below. Instead, emissing to the base layer
195195
196196 public:
197197
198 /// @brief Construct a lazy emitting layer.
198 /// Construct a lazy emitting layer.
199199 LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
200200
201 /// @brief Add the given module to the lazy emitting layer.
201 /// Add the given module to the lazy emitting layer.
202202 Error addModule(VModuleKey K, std::unique_ptr M) {
203203 assert(!ModuleMap.count(K) && "VModuleKey K already in use");
204204 ModuleMap[K] =
206206 return Error::success();
207207 }
208208
209 /// @brief Remove the module represented by the given handle.
209 /// Remove the module represented by the given handle.
210210 ///
211211 /// This method will free the memory associated with the given module, both
212212 /// in this layer, and the base layer.
218218 return EDM->removeModuleFromBaseLayer(BaseLayer);
219219 }
220220
221 /// @brief Search for the given named symbol.
221 /// Search for the given named symbol.
222222 /// @param Name The name of the symbol to search for.
223223 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
224224 /// @return A handle for the given named symbol, if it exists.
238238 return nullptr;
239239 }
240240
241 /// @brief Get the address of the given symbol in the context of the of
241 /// Get the address of the given symbol in the context of the of
242242 /// compiled modules represented by the key K.
243243 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
244244 bool ExportedSymbolsOnly) {
246246 return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
247247 }
248248
249 /// @brief Immediately emit and finalize the module represented by the given
249 /// Immediately emit and finalize the module represented by the given
250250 /// key.
251251 Error emitAndFinalize(VModuleKey K) {
252252 assert(ModuleMap.count(K) && "VModuleKey K not valid here");
3131 SymbolResolver &R;
3232 };
3333
34 /// @brief Use the given legacy-style FindSymbol function (i.e. a function that
34 /// Use the given legacy-style FindSymbol function (i.e. a function that
3535 /// takes a const std::string& or StringRef and returns a JITSymbol) to
3636 /// find the flags for each symbol in Symbols and store their flags in
3737 /// SymbolFlags. If any JITSymbol returned by FindSymbol is in an error
5757 return SymbolsNotFound;
5858 }
5959
60 /// @brief Use the given legacy-style FindSymbol function (i.e. a function that
60 /// Use the given legacy-style FindSymbol function (i.e. a function that
6161 /// takes a const std::string& or StringRef and returns a JITSymbol) to
6262 /// find the address and flags for each symbol in Symbols and store the
6363 /// result in Query. If any JITSymbol returned by FindSymbol is in an
9191 return SymbolsNotFound;
9292 }
9393
94 /// @brief An ORC SymbolResolver implementation that uses a legacy
94 /// An ORC SymbolResolver implementation that uses a legacy
9595 /// findSymbol-like function to perform lookup;
9696 template
9797 class LegacyLookupFnResolver final : public SymbolResolver {
2222 namespace llvm {
2323 namespace orc {
2424
25 /// @brief Object mutating layer.
25 /// Object mutating layer.
2626 ///
2727 /// This layer accepts sets of ObjectFiles (via addObject). It
2828 /// immediately applies the user supplied functor to each object, then adds
3030 template
3131 class ObjectTransformLayer {
3232 public:
33 /// @brief Construct an ObjectTransformLayer with the given BaseLayer
33 /// Construct an ObjectTransformLayer with the given BaseLayer
3434 ObjectTransformLayer(BaseLayerT &BaseLayer,
3535 TransformFtor Transform = TransformFtor())
3636 : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
3737
38 /// @brief Apply the transform functor to each object in the object set, then
38 /// Apply the transform functor to each object in the object set, then
3939 /// add the resulting set of objects to the base layer, along with the
4040 /// memory manager and symbol resolver.
4141 ///
4444 return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
4545 }
4646
47 /// @brief Remove the object set associated with the VModuleKey K.
47 /// Remove the object set associated with the VModuleKey K.
4848 Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); }
4949
50 /// @brief Search for the given named symbol.
50 /// Search for the given named symbol.
5151 /// @param Name The name of the symbol to search for.
5252 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
5353 /// @return A handle for the given named symbol, if it exists.
5555 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
5656 }
5757
58 /// @brief Get the address of the given symbol in the context of the set of
58 /// Get the address of the given symbol in the context of the set of
5959 /// objects represented by the VModuleKey K. This call is forwarded to
6060 /// the base layer's implementation.
6161 /// @param K The VModuleKey associated with the object set to search in.
6868 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
6969 }
7070
71 /// @brief Immediately emit and finalize the object set represented by the
71 /// Immediately emit and finalize the object set represented by the
7272 /// given VModuleKey K.
7373 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
7474
75 /// @brief Map section addresses for the objects associated with the
75 /// Map section addresses for the objects associated with the
7676 /// VModuleKey K.
7777 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
7878 JITTargetAddress TargetAddr) {
7979 BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr);
8080 }
8181
82 /// @brief Access the transform functor directly.
82 /// Access the transform functor directly.
8383 TransformFtor &getTransform() { return Transform; }
8484
85 /// @brief Access the mumate functor directly.
85 /// Access the mumate functor directly.
8686 const TransformFtor &getTransform() const { return Transform; }
8787
8888 private:
7070 }
7171 };
7272
73 /// @brief Provide information about stub blocks generated by the
73 /// Provide information about stub blocks generated by the
7474 /// makeIndirectStubsBlock function.
7575 template class GenericIndirectStubsInfo {
7676 public:
9191 return *this;
9292 }
9393
94 /// @brief Number of stubs in this block.
94 /// Number of stubs in this block.
9595 unsigned getNumStubs() const { return NumStubs; }
9696
97 /// @brief Get a pointer to the stub at the given index, which must be in
97 /// Get a pointer to the stub at the given index, which must be in
9898 /// the range 0 .. getNumStubs() - 1.
9999 void *getStub(unsigned Idx) const {
100100 return static_cast(StubsMem.base()) + Idx * StubSize;
101101 }
102102
103 /// @brief Get a pointer to the implementation-pointer at the given index,
103 /// Get a pointer to the implementation-pointer at the given index,
104104 /// which must be in the range 0 .. getNumStubs() - 1.
105105 void **getPtr(unsigned Idx) const {
106106 char *PtrsBase = static_cast(StubsMem.base()) + NumStubs * StubSize;
123123 using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
124124 void *TrampolineId);
125125
126 /// @brief Write the resolver code into the given memory. The user is be
127 /// responsible for allocating the memory and setting permissions.
128 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
129 void *CallbackMgr);
130
131 /// @brief Write the requsted number of trampolines into the given memory,
126 /// Write the resolver code into the given memory. The user is be
127 /// responsible for allocating the memory and setting permissions.
128 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
129 void *CallbackMgr);
130
131 /// Write the requsted number of trampolines into the given memory,
132132 /// which must be big enough to hold 1 pointer, plus NumTrampolines
133133 /// trampolines.
134134 static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
135135 unsigned NumTrampolines);
136136
137 /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
137 /// Emit at least MinStubs worth of indirect call stubs, rounded out to
138138 /// the nearest page size.
139139 ///
140140 /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
144144 unsigned MinStubs, void *InitialPtrVal);
145145 };
146146
147 /// @brief X86_64 code that's common to all ABIs.
147 /// X86_64 code that's common to all ABIs.
148148 ///
149149 /// X86_64 supports lazy JITing.
150150 class OrcX86_64_Base {
154154
155155 using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
156156
157 /// @brief Write the requsted number of trampolines into the given memory,
157 /// Write the requsted number of trampolines into the given memory,
158158 /// which must be big enough to hold 1 pointer, plus NumTrampolines
159159 /// trampolines.
160160 static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
161161 unsigned NumTrampolines);
162162
163 /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
163 /// Emit at least MinStubs worth of indirect call stubs, rounded out to
164164 /// the nearest page size.
165165 ///
166166 /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
170170 unsigned MinStubs, void *InitialPtrVal);
171171 };
172172
173 /// @brief X86_64 support for SysV ABI (Linux, MacOSX).
173 /// X86_64 support for SysV ABI (Linux, MacOSX).
174174 ///
175175 /// X86_64_SysV supports lazy JITing.
176176 class OrcX86_64_SysV : public OrcX86_64_Base {
180180 using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
181181 void *TrampolineId);
182182
183 /// @brief Write the resolver code into the given memory. The user is be
184 /// responsible for allocating the memory and setting permissions.
185 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
186 void *CallbackMgr);
187 };
188
189 /// @brief X86_64 support for Win32.
183 /// Write the resolver code into the given memory. The user is be
184 /// responsible for allocating the memory and setting permissions.
185 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
186 void *CallbackMgr);
187 };
188
189 /// X86_64 support for Win32.
190190 ///
191191 /// X86_64_Win32 supports lazy JITing.
192192 class OrcX86_64_Win32 : public OrcX86_64_Base {
196196 using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
197197 void *TrampolineId);
198198
199 /// @brief Write the resolver code into the given memory. The user is be
200 /// responsible for allocating the memory and setting permissions.
201 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
202 void *CallbackMgr);
203 };
204
205 /// @brief I386 support.
199 /// Write the resolver code into the given memory. The user is be
200 /// responsible for allocating the memory and setting permissions.
201 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
202 void *CallbackMgr);
203 };
204
205 /// I386 support.
206206 ///
207207 /// I386 supports lazy JITing.
208208 class OrcI386 {
216216 using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
217217 void *TrampolineId);
218218
219 /// @brief Write the resolver code into the given memory. The user is be
220 /// responsible for allocating the memory and setting permissions.
221 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
222 void *CallbackMgr);
223
224 /// @brief Write the requsted number of trampolines into the given memory,
219 /// Write the resolver code into the given memory. The user is be
220 /// responsible for allocating the memory and setting permissions.
221 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
222 void *CallbackMgr);
223
224 /// Write the requsted number of trampolines into the given memory,
225225 /// which must be big enough to hold 1 pointer, plus NumTrampolines
226226 /// trampolines.
227227 static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
228228 unsigned NumTrampolines);
229229
230 /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
230 /// Emit at least MinStubs worth of indirect call stubs, rounded out to
231231 /// the nearest page size.
232232 ///
233233 /// E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k
16821682 uint32_t NumOutstandingCalls = 0;
16831683 };
16841684
1685 /// @brief Convenience class for grouping RPC Functions into APIs that can be
1685 /// Convenience class for grouping RPC Functions into APIs that can be
16861686 /// negotiated as a block.
16871687 ///
16881688 template
16891689 class APICalls {
16901690 public:
16911691
1692 /// @brief Test whether this API contains Function F.
1692 /// Test whether this API contains Function F.
16931693 template
16941694 class Contains {
16951695 public:
16961696 static const bool value = false;
16971697 };
16981698
1699 /// @brief Negotiate all functions in this API.
1699 /// Negotiate all functions in this API.
17001700 template
17011701 static Error negotiate(RPCEndpoint &R) {
17021702 return Error::success();
4040
4141 protected:
4242
43 /// @brief Holds an object to be allocated/linked as a unit in the JIT.
43 /// Holds an object to be allocated/linked as a unit in the JIT.
4444 ///
4545 /// An instance of this class will be created for each object added
4646 /// via JITObjectLayer::addObject. Deleting the instance (via
8080 };
8181 };
8282
83 /// @brief Bare bones object linking layer.
83 /// Bare bones object linking layer.
8484 ///
8585 /// This class is intended to be used as the base layer for a JIT. It allows
8686 /// object files to be loaded into memory, linked, and the addresses of their
9191
9292 using RTDyldObjectLinkingLayerBase::ObjectPtr;
9393
94 /// @brief Functor for receiving object-loaded notifications.
94 /// Functor for receiving object-loaded notifications.
9595 using NotifyLoadedFtor =
9696 std::function
9797 const RuntimeDyld::LoadedObjectInfo &)>;
9898
99 /// @brief Functor for receiving finalization notifications.
99 /// Functor for receiving finalization notifications.
100100 using NotifyFinalizedFtor = std::function;
101101
102102 private:
234234
235235 using ResourcesGetter = std::function;
236236
237 /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
237 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
238238 /// and NotifyFinalized functors.
239239 RTDyldObjectLinkingLayer(
240240 ExecutionSession &ES, ResourcesGetter GetResources,
245245 NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {
246246 }
247247
248 /// @brief Set the 'ProcessAllSections' flag.
248 /// Set the 'ProcessAllSections' flag.
249249 ///
250250 /// If set to true, all sections in each object file will be allocated using
251251 /// the memory manager, rather than just the sections required for execution.
255255 this->ProcessAllSections = ProcessAllSections;
256256 }
257257
258 /// @brief Add an object to the JIT.
258 /// Add an object to the JIT.
259259 Error addObject(VModuleKey K, ObjectPtr ObjBuffer) {
260260
261261 auto Obj =
274274 return Error::success();
275275 }
276276
277 /// @brief Remove the object associated with VModuleKey K.
277 /// Remove the object associated with VModuleKey K.
278278 ///
279279 /// All memory allocated for the object will be freed, and the sections and
280280 /// symbols it provided will no longer be available. No attempt is made to
289289 return Error::success();
290290 }
291291
292 /// @brief Search for the given named symbol.
292 /// Search for the given named symbol.
293293 /// @param Name The name of the symbol to search for.
294294 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
295295 /// @return A handle for the given named symbol, if it exists.
303303 return nullptr;
304304 }
305305
306 /// @brief Search for the given named symbol in the context of the loaded
306 /// Search for the given named symbol in the context of the loaded
307307 /// object represented by the VModuleKey K.
308308 /// @param K The VModuleKey for the object to search in.
309309 /// @param Name The name of the symbol to search for.
316316 return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
317317 }
318318
319 /// @brief Map section addresses for the object associated with the
319 /// Map section addresses for the object associated with the
320320 /// VModuleKey K.
321321 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
322322 JITTargetAddress TargetAddr) {
324324 LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
325325 }
326326
327 /// @brief Immediately emit and finalize the object represented by the given
327 /// Immediately emit and finalize the object represented by the given
328328 /// VModuleKey.
329329 /// @param K VModuleKey for object to emit/finalize.
330330 Error emitAndFinalize(VModuleKey K) {
321321 *this, &ThisT::lookupInLogicalDylib);
322322 }
323323
324 /// @brief Add an object to the JIT.
324 /// Add an object to the JIT.
325325 ///
326326 /// @return A handle that can be used to refer to the loaded object (for
327327 /// symbol searching, finalization, freeing memory, etc.).
339339 return HandleOrErr.takeError();
340340 }
341341
342 /// @brief Remove the given object from the JIT.
342 /// Remove the given object from the JIT.
343343 Error removeObject(ObjHandleT H) {
344344 return this->Remote.template callB(H);
345345 }
346346
347 /// @brief Search for the given named symbol.
347 /// Search for the given named symbol.
348348 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
349349 return remoteToJITSymbol(
350350 this->Remote.template callB(Name,
351351 ExportedSymbolsOnly));
352352 }
353353
354 /// @brief Search for the given named symbol within the given context.
354 /// Search for the given named symbol within the given context.
355355 JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
356356 return remoteToJITSymbol(
357357 this->Remote.template callB(H, Name,
358358 ExportedSymbolsOnly));
359359 }
360360
361 /// @brief Immediately emit and finalize the object with the given handle.
361 /// Immediately emit and finalize the object with the given handle.
362362 Error emitAndFinalize(ObjHandleT H) {
363363 return this->Remote.template callB(H);
364364 }
2222
2323 class SymbolStringPtr;
2424
25 /// @brief String pool for symbol names used by the JIT.
25 /// String pool for symbol names used by the JIT.
2626 class SymbolStringPool {
2727 friend class SymbolStringPtr;
2828 public:
29 /// @brief Destroy a SymbolStringPool.
29 /// Destroy a SymbolStringPool.
3030 ~SymbolStringPool();
3131
32 /// @brief Create a symbol string pointer from the given string.
32 /// Create a symbol string pointer from the given string.
3333 SymbolStringPtr intern(StringRef S);
3434
35 /// @brief Remove from the pool any entries that are no longer referenced.
35 /// Remove from the pool any entries that are no longer referenced.
3636 void clearDeadEntries();
3737
38 /// @brief Returns true if the pool is empty.
38 /// Returns true if the pool is empty.
3939 bool empty() const;
4040 private:
4141 using RefCountType = std::atomic;
4545 PoolMap Pool;
4646 };
4747
48 /// @brief Pointer to a pooled string representing a symbol name.
48 /// Pointer to a pooled string representing a symbol name.
4949 class SymbolStringPtr {
5050 friend class SymbolStringPool;
5151 friend bool operator==(const SymbolStringPtr &LHS,
2525
2626 /// A set of enums which specify the assigned numeric values for known llvm
2727 /// calling conventions.
28 /// @brief LLVM Calling Convention Representation
28 /// LLVM Calling Convention Representation
2929 enum {
3030 /// C - The default llvm calling convention, compatible with C. This
3131 /// convention is the only calling convention that supports varargs calls.
3737 /// structurally equivalent constants will always have the same address.
3838 /// Constants are created on demand as needed and never deleted: thus clients
3939 /// don't have to worry about the lifetime of the objects.
40 /// @brief LLVM Constant Representation
40 /// LLVM Constant Representation
4141 class Constant : public User {
4242 protected:
4343 Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
152152
153153 /// @returns the value for an integer or vector of integer constant of the
154154 /// given type that has all its bits set to true.
155 /// @brief Get the all ones value
155 /// Get the all ones value
156156 static Constant *getAllOnesValue(Type* Ty);
157157
158158 /// Return the value for an integer or pointer constant, or a vector thereof,
5353 /// Initialize a range to hold the single specified value.
5454 ConstantRange(APInt Value);
5555
56 /// @brief Initialize a range of values explicitly. This will assert out if
56 /// Initialize a range of values explicitly. This will assert out if
5757 /// Lower==Upper and Lower != Min or Max value for its type. It will also
5858 /// assert out if the two APInt's are not the same bit width.
5959 ConstantRange(APInt Lower, APInt Upper);
7979 //===----------------------------------------------------------------------===//
8080 /// This is the shared class of boolean and integer constants. This class
8181 /// represents both boolean and integral constants.
82 /// @brief Class for constant integers.
82 /// Class for constant integers.
8383 class ConstantInt final : public ConstantData {
8484 friend class Constant;
8585
106106 /// to fit the type, unless isSigned is true, in which case the value will
107107 /// be interpreted as a 64-bit signed integer and sign-extended to fit
108108 /// the type.
109 /// @brief Get a ConstantInt for a specific value.
109 /// Get a ConstantInt for a specific value.
110110 static ConstantInt *get(IntegerType *Ty, uint64_t V,
111111 bool isSigned = false);
112112
114114 /// value V will be canonicalized to a an unsigned APInt. Accessing it with
115115 /// either getSExtValue() or getZExtValue() will yield a correctly sized and
116116 /// signed value for the type Ty.
117 /// @brief Get a ConstantInt for a specific signed value.
117 /// Get a ConstantInt for a specific signed value.
118118 static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
119119 static Constant *getSigned(Type *Ty, int64_t V);
120120
133133
134134 /// Return the constant as an APInt value reference. This allows clients to
135135 /// obtain a full-precision copy of the value.
136 /// @brief Return the constant's value.
136 /// Return the constant's value.
137137 inline const APInt &getValue() const {
138138 return Val;
139139 }
144144 /// Return the constant as a 64-bit unsigned integer value after it
145145 /// has been zero extended as appropriate for the type of this constant. Note
146146 /// that this method can assert if the value does not fit in 64 bits.
147 /// @brief Return the zero extended value.
147 /// Return the zero extended value.
148148 inline uint64_t getZExtValue() const {
149149 return Val.getZExtValue();
150150 }
152152 /// Return the constant as a 64-bit integer value after it has been sign
153153 /// extended as appropriate for the type of this constant. Note that
154154 /// this method can assert if the value does not fit in 64 bits.
155 /// @brief Return the sign extended value.
155 /// Return the sign extended value.
156156 inline int64_t getSExtValue() const {
157157 return Val.getSExtValue();
158158 }
160160 /// A helper method that can be used to determine if the constant contained
161161 /// within is equal to a constant. This only works for very small values,
162162 /// because this is all that can be represented with all types.
163 /// @brief Determine if this constant's value is same as an unsigned char.
163 /// Determine if this constant's value is same as an unsigned char.
164164 bool equalsInt(uint64_t V) const {
165165 return Val == V;
166166 }
180180 /// the signed version avoids callers having to convert a signed quantity
181181 /// to the appropriate unsigned type before calling the method.
182182 /// @returns true if V is a valid value for type Ty
183 /// @brief Determine if the value is in range for the given type.
183 /// Determine if the value is in range for the given type.
184184 static bool isValueValidForType(Type *Ty, uint64_t V);
185185 static bool isValueValidForType(Type *Ty, int64_t V);
186186
196196 /// This is just a convenience method to make client code smaller for a
197197 /// common case. It also correctly performs the comparison without the
198198 /// potential for an assertion from getZExtValue().
199 /// @brief Determine if the value is one.
199 /// Determine if the value is one.
200200 bool isOne() const {
201201 return Val.isOneValue();
202202 }
204204 /// This function will return true iff every bit in this constant is set
205205 /// to true.
206206 /// @returns true iff this constant's bits are all set to true.
207 /// @brief Determine if the value is all ones.
207 /// Determine if the value is all ones.
208208 bool isMinusOne() const {
209209 return Val.isAllOnesValue();
210210 }
213213 /// value that may be represented by the constant's type.
214214 /// @returns true iff this is the largest value that may be represented
215215 /// by this type.
216 /// @brief Determine if the value is maximal.
216 /// Determine if the value is maximal.
217217 bool isMaxValue(bool isSigned) const {
218218 if (isSigned)
219219 return Val.isMaxSignedValue();
225225 /// value that may be represented by this constant's type.
226226 /// @returns true if this is the smallest value that may be represented by
227227 /// this type.
228 /// @brief Determine if the value is minimal.
228 /// Determine if the value is minimal.
229229 bool isMinValue(bool isSigned) const {
230230 if (isSigned)
231231 return Val.isMinSignedValue();
237237 /// active bits bigger than 64 bits or a value greater than the given uint64_t
238238 /// value.
239239 /// @returns true iff this constant is greater or equal to the given number.
240 /// @brief Determine if the value is greater or equal to the given number.
240 /// Determine if the value is greater or equal to the given number.
241241 bool uge(uint64_t Num) const {
242242 return Val.uge(Num);
243243 }
246246 /// return it, otherwise return the limit value. This causes the value
247247 /// to saturate to the limit.
248248 /// @returns the min of the value of the constant and the specified value
249 /// @brief Get the constant's value with a saturation limit
249 /// Get the constant's value with a saturation limit
250250 uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
251251 return Val.getLimitedValue(Limit);
252252 }
253253
254 /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
254 /// Methods to support type inquiry through isa, cast, and dyn_cast.
255255 static bool classof(const Value *V) {
256256 return V->getValueID() == ConstantIntVal;
257257 }
814814 /// Return the ConstantTokenNone.
815815 static ConstantTokenNone *get(LLVMContext &Context);
816816
817 /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
817 /// Methods to support type inquiry through isa, cast, and dyn_cast.
818818 static bool classof(const Value *V) {
819819 return V->getValueID() == ConstantTokenNoneVal;
820820 }
10301030 static Constant *getCast(unsigned ops, Constant *C, Type *Ty,
10311031 bool OnlyIfReduced = false);
10321032
1033 // @brief Create a ZExt or BitCast cast constant expression
1033 // Create a ZExt or BitCast cast constant expression
10341034 static Constant *getZExtOrBitCast(
10351035 Constant *C, ///< The constant to zext or bitcast
10361036 Type *Ty ///< The type to zext or bitcast C to
10371037 );
10381038
1039 // @brief Create a SExt or BitCast cast constant expression
1039 // Create a SExt or BitCast cast constant expression
10401040 static Constant *getSExtOrBitCast(
10411041 Constant *C, ///< The constant to sext or bitcast
10421042 Type *Ty ///< The type to sext or bitcast C to
10431043 );
10441044
1045 // @brief Create a Trunc or BitCast cast constant expression
1045 // Create a Trunc or BitCast cast constant expression
10461046 static Constant *getTruncOrBitCast(
10471047 Constant *C, ///< The constant to trunc or bitcast
10481048 Type *Ty ///< The type to trunc or bitcast C to
10491049 );
10501050
1051 /// @brief Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
1051 /// Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
10521052 /// expression.
10531053 static Constant *getPointerCast(
10541054 Constant *C, ///< The pointer value to be casted (operand 0)
10551055 Type *Ty ///< The type to which cast should be made
10561056 );
10571057
1058 /// @brief Create a BitCast or AddrSpaceCast for a pointer type depending on
1058 /// Create a BitCast or AddrSpaceCast for a pointer type depending on
10591059 /// the address space.
10601060 static Constant *getPointerBitCastOrAddrSpaceCast(
10611061 Constant *C, ///< The constant to addrspacecast or bitcast
10621062 Type *Ty ///< The type to bitcast or addrspacecast C to
10631063 );
10641064
1065 /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
1065 /// Create a ZExt, Bitcast or Trunc for integer -> integer casts
10661066 static Constant *getIntegerCast(
10671067 Constant *C, ///< The integer constant to be casted
10681068 Type *Ty, ///< The integer type to cast to
10691069 bool isSigned ///< Whether C should be treated as signed or not
10701070 );
10711071
1072 /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
1072 /// Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
10731073 static Constant *getFPCast(
10741074 Constant *C, ///< The integer constant to be casted
10751075 Type *Ty ///< The integer type to cast to
10761076 );
10771077
1078 /// @brief Return true if this is a convert constant expression
1078 /// Return true if this is a convert constant expression
10791079 bool isCast() const;
10801080
1081 /// @brief Return true if this is a compare constant expression
1081 /// Return true if this is a compare constant expression
10821082 bool isCompare() const;
10831083
1084 /// @brief Return true if this is an insertvalue or extractvalue expression,
1084 /// Return true if this is an insertvalue or extractvalue expression,
10851085 /// and the getIndices() method may be used.
10861086 bool hasIndices() const;
10871087
1088 /// @brief Return true if this is a getelementptr expression and all
1088 /// Return true if this is a getelementptr expression and all
10891089 /// the index operands are compile-time known integers within the
10901090 /// corresponding notional static array extents. Note that this is
10911091 /// not equivalant to, a subset of, or a superset of the "inbounds"
3535 /// Class to represent integer types. Note that this class is also used to
3636 /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
3737 /// Int64Ty.
38 /// @brief Integer representation type
38 /// Integer representation type
3939 class IntegerType : public Type {
4040 friend class LLVMContextImpl;
4141
5858 /// If an IntegerType with the same NumBits value was previously instantiated,
5959 /// that instance will be returned. Otherwise a new one will be created. Only
6060 /// one instance with a given NumBits value is ever created.
61 /// @brief Get or create an IntegerType instance.
61