1 //===- LibCallSemantics.h - Describe library semantics --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines interfaces that can be used to describe language specific 11 // runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H 16 #define LLVM_ANALYSIS_LIBCALLSEMANTICS_H 17 18 #include "llvm/Analysis/AliasAnalysis.h" 19 20 namespace llvm { 21 class InvokeInst; 22 23 /// LibCallLocationInfo - This struct describes a set of memory locations that 24 /// are accessed by libcalls. Identification of a location is doing with a 25 /// simple callback function. 26 /// 27 /// For example, the LibCallInfo may be set up to model the behavior of 28 /// standard libm functions. The location that they may be interested in is 29 /// an abstract location that represents errno for the current target. In 30 /// this case, a location for errno is anything such that the predicate 31 /// returns true. On Mac OS X, this predicate would return true if the 32 /// pointer is the result of a call to "__error()". 33 /// 34 /// Locations can also be defined in a constant-sensitive way. For example, 35 /// it is possible to define a location that returns true iff it is passed 36 /// into the call as a specific argument. This is useful for modeling things 37 /// like "printf", which can store to memory, but only through pointers passed 38 /// with a '%n' constraint. 39 /// 40 struct LibCallLocationInfo { 41 // TODO: Flags: isContextSensitive etc. 42 43 /// isLocation - Return a LocResult if the specified pointer refers to this 44 /// location for the specified call site. This returns "Yes" if we can tell 45 /// that the pointer *does definitely* refer to the location, "No" if we can 46 /// tell that the location *definitely does not* refer to the location, and 47 /// returns "Unknown" if we cannot tell for certain. 48 enum LocResult { 49 Yes, No, Unknown 50 }; 51 LocResult (*isLocation)(ImmutableCallSite CS, 52 const AliasAnalysis::Location &Loc); 53 }; 54 55 /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs 56 /// records the behavior of one libcall that is known by the optimizer. This 57 /// captures things like the side effects of the call. Side effects are 58 /// modeled both universally (in the readnone/readonly) sense, but also 59 /// potentially against a set of abstract locations defined by the optimizer. 60 /// This allows an optimizer to define that some libcall (e.g. sqrt) is 61 /// side-effect free except that it might modify errno (thus, the call is 62 /// *not* universally readonly). Or it might say that the side effects 63 /// are unknown other than to say that errno is not modified. 64 /// 65 struct LibCallFunctionInfo { 66 /// Name - This is the name of the libcall this describes. 67 const char *Name; 68 69 /// TODO: Constant folding function: Constant* vector -> Constant*. 70 71 /// UniversalBehavior - This captures the absolute mod/ref behavior without 72 /// any specific context knowledge. For example, if the function is known 73 /// to be readonly, this would be set to 'ref'. If known to be readnone, 74 /// this is set to NoModRef. 75 AliasAnalysis::ModRefResult UniversalBehavior; 76 77 /// LocationMRInfo - This pair captures info about whether a specific 78 /// location is modified or referenced by a libcall. 79 struct LocationMRInfo { 80 /// LocationID - ID # of the accessed location or ~0U for array end. 81 unsigned LocationID; 82 /// MRInfo - Mod/Ref info for this location. 83 AliasAnalysis::ModRefResult MRInfo; 84 }; 85 86 /// DetailsType - Indicate the sense of the LocationDetails array. This 87 /// controls how the LocationDetails array is interpreted. 88 enum { 89 /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the 90 /// *only* mod/ref behavior of this function is captured by the 91 /// LocationDetails array. If we are trying to say that 'sqrt' can only 92 /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails 93 /// array and have DetailsType set to DoesOnly. 94 DoesOnly, 95 96 /// DoesNot - If DetailsType is set to DoesNot, then the sense of the 97 /// LocationDetails array is completely inverted. This means that we *do 98 /// not* know everything about the side effects of this libcall, but we do 99 /// know things that the libcall cannot do. This is useful for complex 100 /// functions like 'ctime' which have crazy mod/ref behavior, but are 101 /// known to never read or write errno. In this case, we'd have 102 /// {errnoloc,modref} in the LocationDetails array and DetailsType would 103 /// be set to DoesNot, indicating that ctime does not read or write the 104 /// errno location. 105 DoesNot 106 } DetailsType; 107 108 /// LocationDetails - This is a pointer to an array of LocationMRInfo 109 /// structs which indicates the behavior of the libcall w.r.t. specific 110 /// locations. For example, if this libcall is known to only modify 111 /// 'errno', it would have a LocationDetails array with the errno ID and 112 /// 'mod' in it. See the DetailsType field for how this is interpreted. 113 /// 114 /// In the "DoesOnly" case, this information is 'may' information for: there 115 /// is no guarantee that the specified side effect actually does happen, 116 /// just that it could. In the "DoesNot" case, this is 'must not' info. 117 /// 118 /// If this pointer is null, no details are known. 119 /// 120 const LocationMRInfo *LocationDetails; 121 }; 122 123 124 /// LibCallInfo - Abstract interface to query about library call information. 125 /// Instances of this class return known information about some set of 126 /// libcalls. 127 /// 128 class LibCallInfo { 129 // Implementation details of this object, private. 130 mutable void *Impl; 131 mutable const LibCallLocationInfo *Locations; 132 mutable unsigned NumLocations; 133 public: LibCallInfo()134 LibCallInfo() : Impl(nullptr), Locations(nullptr), NumLocations(0) {} 135 virtual ~LibCallInfo(); 136 137 //===------------------------------------------------------------------===// 138 // Accessor Methods: Efficient access to contained data. 139 //===------------------------------------------------------------------===// 140 141 /// getLocationInfo - Return information about the specified LocationID. 142 const LibCallLocationInfo &getLocationInfo(unsigned LocID) const; 143 144 145 /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to 146 /// the specified function if we have it. If not, return null. 147 const LibCallFunctionInfo *getFunctionInfo(const Function *F) const; 148 149 150 //===------------------------------------------------------------------===// 151 // Implementation Methods: Subclasses should implement these. 152 //===------------------------------------------------------------------===// 153 154 /// getLocationInfo - Return descriptors for the locations referenced by 155 /// this set of libcalls. getLocationInfo(const LibCallLocationInfo * & Array)156 virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const { 157 return 0; 158 } 159 160 /// getFunctionInfoArray - Return an array of descriptors that describe the 161 /// set of libcalls represented by this LibCallInfo object. This array is 162 /// terminated by an entry with a NULL name. 163 virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0; 164 }; 165 166 enum class EHPersonality { 167 Unknown, 168 GNU_Ada, 169 GNU_C, 170 GNU_CXX, 171 GNU_ObjC, 172 MSVC_X86SEH, 173 MSVC_Win64SEH, 174 MSVC_CXX, 175 }; 176 177 /// \brief See if the given exception handling personality function is one 178 /// that we understand. If so, return a description of it; otherwise return 179 /// Unknown. 180 EHPersonality classifyEHPersonality(const Value *Pers); 181 182 /// \brief Returns true if this personality function catches asynchronous 183 /// exceptions. isAsynchronousEHPersonality(EHPersonality Pers)184 inline bool isAsynchronousEHPersonality(EHPersonality Pers) { 185 // The two SEH personality functions can catch asynch exceptions. We assume 186 // unknown personalities don't catch asynch exceptions. 187 switch (Pers) { 188 case EHPersonality::MSVC_X86SEH: 189 case EHPersonality::MSVC_Win64SEH: 190 return true; 191 default: return false; 192 } 193 llvm_unreachable("invalid enum"); 194 } 195 196 /// \brief Returns true if this is an MSVC personality function. isMSVCEHPersonality(EHPersonality Pers)197 inline bool isMSVCEHPersonality(EHPersonality Pers) { 198 // The two SEH personality functions can catch asynch exceptions. We assume 199 // unknown personalities don't catch asynch exceptions. 200 switch (Pers) { 201 case EHPersonality::MSVC_CXX: 202 case EHPersonality::MSVC_X86SEH: 203 case EHPersonality::MSVC_Win64SEH: 204 return true; 205 default: return false; 206 } 207 llvm_unreachable("invalid enum"); 208 } 209 210 bool canSimplifyInvokeNoUnwind(const InvokeInst *II); 211 212 } // end namespace llvm 213 214 #endif 215