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