1193323Sed//===- LibCallSemantics.h - Describe library semantics --------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines interfaces that can be used to describe language specific
11193323Sed// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
16193323Sed#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H
17193323Sed
18193323Sed#include "llvm/Analysis/AliasAnalysis.h"
19193323Sed
20193323Sednamespace llvm {
21193323Sed
22193323Sed  /// LibCallLocationInfo - This struct describes a set of memory locations that
23193323Sed  /// are accessed by libcalls.  Identification of a location is doing with a
24193323Sed  /// simple callback function.
25193323Sed  ///
26193323Sed  /// For example, the LibCallInfo may be set up to model the behavior of
27193323Sed  /// standard libm functions.  The location that they may be interested in is
28193323Sed  /// an abstract location that represents errno for the current target.  In
29193323Sed  /// this case, a location for errno is anything such that the predicate
30193323Sed  /// returns true.  On Mac OS/X, this predicate would return true if the
31193323Sed  /// pointer is the result of a call to "__error()".
32193323Sed  ///
33193323Sed  /// Locations can also be defined in a constant-sensitive way.  For example,
34193323Sed  /// it is possible to define a location that returns true iff it is passed
35193323Sed  /// into the call as a specific argument.  This is useful for modeling things
36193323Sed  /// like "printf", which can store to memory, but only through pointers passed
37193323Sed  /// with a '%n' constraint.
38193323Sed  ///
39193323Sed  struct LibCallLocationInfo {
40193323Sed    // TODO: Flags: isContextSensitive etc.
41193323Sed
42193323Sed    /// isLocation - Return a LocResult if the specified pointer refers to this
43193323Sed    /// location for the specified call site.  This returns "Yes" if we can tell
44193323Sed    /// that the pointer *does definitely* refer to the location, "No" if we can
45193323Sed    /// tell that the location *definitely does not* refer to the location, and
46193323Sed    /// returns "Unknown" if we cannot tell for certain.
47193323Sed    enum LocResult {
48193323Sed      Yes, No, Unknown
49193323Sed    };
50212904Sdim    LocResult (*isLocation)(ImmutableCallSite CS,
51218893Sdim                            const AliasAnalysis::Location &Loc);
52193323Sed  };
53193323Sed
54193323Sed  /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
55193323Sed  /// records the behavior of one libcall that is known by the optimizer.  This
56193323Sed  /// captures things like the side effects of the call.  Side effects are
57193323Sed  /// modeled both universally (in the readnone/readonly) sense, but also
58193323Sed  /// potentially against a set of abstract locations defined by the optimizer.
59193323Sed  /// This allows an optimizer to define that some libcall (e.g. sqrt) is
60193323Sed  /// side-effect free except that it might modify errno (thus, the call is
61193323Sed  /// *not* universally readonly).  Or it might say that the side effects
62193323Sed  /// are unknown other than to say that errno is not modified.
63193323Sed  ///
64193323Sed  struct LibCallFunctionInfo {
65193323Sed    /// Name - This is the name of the libcall this describes.
66193323Sed    const char *Name;
67193323Sed
68193323Sed    /// TODO: Constant folding function: Constant* vector -> Constant*.
69193323Sed
70193323Sed    /// UniversalBehavior - This captures the absolute mod/ref behavior without
71193323Sed    /// any specific context knowledge.  For example, if the function is known
72193323Sed    /// to be readonly, this would be set to 'ref'.  If known to be readnone,
73193323Sed    /// this is set to NoModRef.
74193323Sed    AliasAnalysis::ModRefResult UniversalBehavior;
75193323Sed
76193323Sed    /// LocationMRInfo - This pair captures info about whether a specific
77193323Sed    /// location is modified or referenced by a libcall.
78193323Sed    struct LocationMRInfo {
79193323Sed      /// LocationID - ID # of the accessed location or ~0U for array end.
80193323Sed      unsigned LocationID;
81193323Sed      /// MRInfo - Mod/Ref info for this location.
82193323Sed      AliasAnalysis::ModRefResult MRInfo;
83193323Sed    };
84193323Sed
85193323Sed    /// DetailsType - Indicate the sense of the LocationDetails array.  This
86193323Sed    /// controls how the LocationDetails array is interpreted.
87193323Sed    enum {
88193323Sed      /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
89193323Sed      /// *only* mod/ref behavior of this function is captured by the
90193323Sed      /// LocationDetails array.  If we are trying to say that 'sqrt' can only
91193323Sed      /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
92193323Sed      /// array and have DetailsType set to DoesOnly.
93193323Sed      DoesOnly,
94193323Sed
95193323Sed      /// DoesNot - If DetailsType is set to DoesNot, then the sense of the
96193323Sed      /// LocationDetails array is completely inverted.  This means that we *do
97193323Sed      /// not* know everything about the side effects of this libcall, but we do
98193323Sed      /// know things that the libcall cannot do.  This is useful for complex
99193323Sed      /// functions like 'ctime' which have crazy mod/ref behavior, but are
100193323Sed      /// known to never read or write errno.  In this case, we'd have
101193323Sed      /// {errnoloc,modref} in the LocationDetails array and DetailsType would
102193323Sed      /// be set to DoesNot, indicating that ctime does not read or write the
103193323Sed      /// errno location.
104193323Sed      DoesNot
105193323Sed    } DetailsType;
106193323Sed
107193323Sed    /// LocationDetails - This is a pointer to an array of LocationMRInfo
108193323Sed    /// structs which indicates the behavior of the libcall w.r.t. specific
109193323Sed    /// locations.  For example, if this libcall is known to only modify
110193323Sed    /// 'errno', it would have a LocationDetails array with the errno ID and
111193323Sed    /// 'mod' in it.  See the DetailsType field for how this is interpreted.
112193323Sed    ///
113193323Sed    /// In the "DoesOnly" case, this information is 'may' information for: there
114193323Sed    /// is no guarantee that the specified side effect actually does happen,
115193323Sed    /// just that it could.  In the "DoesNot" case, this is 'must not' info.
116193323Sed    ///
117193323Sed    /// If this pointer is null, no details are known.
118193323Sed    ///
119193323Sed    const LocationMRInfo *LocationDetails;
120193323Sed  };
121193323Sed
122193323Sed
123193323Sed  /// LibCallInfo - Abstract interface to query about library call information.
124193323Sed  /// Instances of this class return known information about some set of
125193323Sed  /// libcalls.
126193323Sed  ///
127193323Sed  class LibCallInfo {
128193323Sed    // Implementation details of this object, private.
129193323Sed    mutable void *Impl;
130193323Sed    mutable const LibCallLocationInfo *Locations;
131193323Sed    mutable unsigned NumLocations;
132193323Sed  public:
133193323Sed    LibCallInfo() : Impl(0), Locations(0), NumLocations(0) {}
134193323Sed    virtual ~LibCallInfo();
135193323Sed
136193323Sed    //===------------------------------------------------------------------===//
137193323Sed    //  Accessor Methods: Efficient access to contained data.
138193323Sed    //===------------------------------------------------------------------===//
139193323Sed
140193323Sed    /// getLocationInfo - Return information about the specified LocationID.
141193323Sed    const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
142193323Sed
143193323Sed
144193323Sed    /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
145193323Sed    /// the specified function if we have it.  If not, return null.
146212904Sdim    const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
147193323Sed
148193323Sed
149193323Sed    //===------------------------------------------------------------------===//
150193323Sed    //  Implementation Methods: Subclasses should implement these.
151193323Sed    //===------------------------------------------------------------------===//
152193323Sed
153193323Sed    /// getLocationInfo - Return descriptors for the locations referenced by
154193323Sed    /// this set of libcalls.
155193323Sed    virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
156193323Sed      return 0;
157193323Sed    }
158193323Sed
159193323Sed    /// getFunctionInfoArray - Return an array of descriptors that describe the
160193323Sed    /// set of libcalls represented by this LibCallInfo object.  This array is
161193323Sed    /// terminated by an entry with a NULL name.
162193323Sed    virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
163193323Sed  };
164193323Sed
165193323Sed} // end namespace llvm
166193323Sed
167193323Sed#endif
168