Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===----- llvm/Analysis/CaptureTracking.h - Pointer capture ----*- C++ -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file contains routines that help determine which pointers are captured. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #ifndef LLVM_ANALYSIS_CAPTURETRACKING_H |
| 14 | #define LLVM_ANALYSIS_CAPTURETRACKING_H |
| 15 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 16 | #include "llvm/ADT/DenseMap.h" |
| 17 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 18 | namespace llvm { |
| 19 | |
| 20 | class Value; |
| 21 | class Use; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 22 | class DataLayout; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 23 | class Instruction; |
| 24 | class DominatorTree; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 25 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 26 | /// getDefaultMaxUsesToExploreForCaptureTracking - Return default value of |
| 27 | /// the maximal number of uses to explore before giving up. It is used by |
| 28 | /// PointerMayBeCaptured family analysis. |
| 29 | unsigned getDefaultMaxUsesToExploreForCaptureTracking(); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 30 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 31 | /// PointerMayBeCaptured - Return true if this pointer value may be captured |
| 32 | /// by the enclosing function (which is required to exist). This routine can |
| 33 | /// be expensive, so consider caching the results. The boolean ReturnCaptures |
| 34 | /// specifies whether returning the value (or part of it) from the function |
| 35 | /// counts as capturing it or not. The boolean StoreCaptures specified |
| 36 | /// whether storing the value (or part of it) into memory anywhere |
| 37 | /// automatically counts as capturing it or not. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 38 | /// MaxUsesToExplore specifies how many uses the analysis should explore for |
| 39 | /// one value before giving up due too "too many uses". If MaxUsesToExplore |
| 40 | /// is zero, a default value is assumed. |
| 41 | bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 42 | bool StoreCaptures, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 43 | unsigned MaxUsesToExplore = 0); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 44 | |
| 45 | /// PointerMayBeCapturedBefore - Return true if this pointer value may be |
| 46 | /// captured by the enclosing function (which is required to exist). If a |
| 47 | /// DominatorTree is provided, only captures which happen before the given |
| 48 | /// instruction are considered. This routine can be expensive, so consider |
| 49 | /// caching the results. The boolean ReturnCaptures specifies whether |
| 50 | /// returning the value (or part of it) from the function counts as capturing |
| 51 | /// it or not. The boolean StoreCaptures specified whether storing the value |
| 52 | /// (or part of it) into memory anywhere automatically counts as capturing it |
| 53 | /// or not. Captures by the provided instruction are considered if the |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 54 | /// final parameter is true. |
| 55 | /// MaxUsesToExplore specifies how many uses the analysis should explore for |
| 56 | /// one value before giving up due too "too many uses". If MaxUsesToExplore |
| 57 | /// is zero, a default value is assumed. |
| 58 | bool PointerMayBeCapturedBefore( |
| 59 | const Value *V, bool ReturnCaptures, bool StoreCaptures, |
| 60 | const Instruction *I, const DominatorTree *DT, bool IncludeI = false, |
| 61 | unsigned MaxUsesToExplore = 0); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 62 | |
| 63 | /// This callback is used in conjunction with PointerMayBeCaptured. In |
| 64 | /// addition to the interface here, you'll need to provide your own getters |
| 65 | /// to see whether anything was captured. |
| 66 | struct CaptureTracker { |
| 67 | virtual ~CaptureTracker(); |
| 68 | |
| 69 | /// tooManyUses - The depth of traversal has breached a limit. There may be |
| 70 | /// capturing instructions that will not be passed into captured(). |
| 71 | virtual void tooManyUses() = 0; |
| 72 | |
| 73 | /// shouldExplore - This is the use of a value derived from the pointer. |
| 74 | /// To prune the search (ie., assume that none of its users could possibly |
| 75 | /// capture) return false. To search it, return true. |
| 76 | /// |
| 77 | /// U->getUser() is always an Instruction. |
| 78 | virtual bool shouldExplore(const Use *U); |
| 79 | |
| 80 | /// captured - Information about the pointer was captured by the user of |
| 81 | /// use U. Return true to stop the traversal or false to continue looking |
| 82 | /// for more capturing instructions. |
| 83 | virtual bool captured(const Use *U) = 0; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 84 | |
| 85 | /// isDereferenceableOrNull - Overload to allow clients with additional |
| 86 | /// knowledge about pointer dereferenceability to provide it and thereby |
| 87 | /// avoid conservative responses when a pointer is compared to null. |
| 88 | virtual bool isDereferenceableOrNull(Value *O, const DataLayout &DL); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 89 | }; |
| 90 | |
| 91 | /// PointerMayBeCaptured - Visit the value and the values derived from it and |
| 92 | /// find values which appear to be capturing the pointer value. This feeds |
| 93 | /// results into and is controlled by the CaptureTracker object. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 94 | /// MaxUsesToExplore specifies how many uses the analysis should explore for |
| 95 | /// one value before giving up due too "too many uses". If MaxUsesToExplore |
| 96 | /// is zero, a default value is assumed. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 97 | void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 98 | unsigned MaxUsesToExplore = 0); |
| 99 | |
| 100 | /// Returns true if the pointer is to a function-local object that never |
| 101 | /// escapes from the function. |
| 102 | bool isNonEscapingLocalObject( |
| 103 | const Value *V, |
| 104 | SmallDenseMap<const Value *, bool, 8> *IsCapturedCache = nullptr); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 105 | } // end namespace llvm |
| 106 | |
| 107 | #endif |