llvm.org GIT mirror llvm / 14852f2
Add a new interface for describing the behavior of library calls. This Currently is sufficient to describe mod/ref behavior but will hopefully eventually be extended for other purposes. This isn't used by anything yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50820 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
2 changed file(s) with 231 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- LibCallSemantics.h - Describe library semantics --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines interfaces that can be used to describe language specific
10 // runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
15 #define LLVM_ANALYSIS_LIBCALLSEMANTICS_H
16
17 #include "llvm/Analysis/AliasAnalysis.h"
18
19 namespace llvm {
20
21 /// LibCallLocationInfo - This struct describes a set of memory locations that
22 /// are accessed by libcalls. Identification of a location is doing with a
23 /// simple callback function.
24 ///
25 /// For example, the LibCallInfo may be set up to model the behavior of
26 /// standard libm functions. The location that they may be interested in is
27 /// an abstract location that represents errno for the current target. In
28 /// this case, a location for errno is anything such that the predicate
29 /// returns true. On Mac OS/X, this predicate would return true if the
30 /// pointer is the result of a call to "__error()".
31 ///
32 /// Locations can also be defined in a constant-sensitive way. For example,
33 /// it is possible to define a location that returns true iff it is passed
34 /// into the call as a specific argument. This is useful for modeling things
35 /// like "printf", which can store to memory, but only through pointers passed
36 /// with a '%n' constraint.
37 ///
38 struct LibCallLocationInfo {
39 // TODO: Flags: isContextSensitive etc.
40
41 /// isLocation - Return a LocResult if the specified pointer refers to this
42 /// location for the specified call site. This returns "Yes" if we can tell
43 /// that the pointer *does definitely* refer to the location, "No" if we can
44 /// tell that the location *definitely does not* refer to the location, and
45 /// returns "Unknown" if we cannot tell for certain.
46 enum LocResult {
47 Yes, No, Unknown
48 };
49 LocResult (*isLocation)(CallSite CS, const Value *Ptr, unsigned Size);
50 };
51
52 /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
53 /// records the behavior of one libcall that is known by the optimizer. This
54 /// captures things like the side effects of the call. Side effects are
55 /// modeled both universally (in the readnone/readonly) sense, but also
56 /// potentially against a set of abstract locations defined by the optimizer.
57 /// This allows an optimizer to define that some libcall (e.g. sqrt) is
58 /// side-effect free except that it might modify errno (thus, the call is
59 /// *not* universally readonly). Or it might say that the side effects
60 /// are unknown other than to say that errno is not modified.
61 ///
62 struct LibCallFunctionInfo {
63 /// Name - This is the name of the libcall this describes.
64 const char *Name;
65
66 /// TODO: Constant folding function: Constant* vector -> Constant*.
67
68 /// UniversalBehavior - This captures the absolute mod/ref behavior without
69 /// any specific context knowledge. For example, if the function is known
70 /// to be readonly, this would be set to 'ref'. If known to be readnone,
71 /// this is set to NoModRef.
72 AliasAnalysis::ModRefResult UniversalBehavior;
73
74 /// LocationMRInfo - This pair captures info about whether a specific
75 /// location is modified or referenced by a libcall.
76 struct LocationMRInfo {
77 /// LocationID - ID # of the accessed location or ~0U for array end.
78 unsigned LocationID;
79 /// MRInfo - Mod/Ref info for this location.
80 AliasAnalysis::ModRefResult MRInfo;
81 };
82
83 /// DetailsType - Indicate the sense of the LocationDetails array. This
84 /// controls how the LocationDetails array is interpreted.
85 enum {
86 /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
87 /// *only* mod/ref behavior of this function is captured by the
88 /// LocationDetails array. If we are trying to say that 'sqrt' can only
89 /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
90 /// array and have DetailsType set to DoesOnly.
91 DoesOnly,
92
93 /// DoesNot - If DetailsType is set to DoesNot, then the sense of the
94 /// LocationDetails array is completely inverted. This means that we *do
95 /// not* know everything about the side effects of this libcall, but we do
96 /// know things that the libcall cannot do. This is useful for complex
97 /// functions like 'ctime' which have crazy mod/ref behavior, but are
98 /// known to never read or write errno. In this case, we'd have
99 /// {errnoloc,modref} in the LocationDetails array and DetailsType would
100 /// be set to DoesNot, indicating that ctime does not read or write the
101 /// errno location.
102 DoesNot
103 } DetailsType;
104
105 /// LocationDetails - This is a pointer to an array of LocationMRInfo
106 /// structs which indicates the behavior of the libcall w.r.t. specific
107 /// locations. For example, if this libcall is known to only modify
108 /// 'errno', it would have a LocationDetails array with the errno ID and
109 /// 'mod' in it. See the DetailsType field for how this is interpreted.
110 ///
111 /// In the "DoesOnly" case, this information is 'may' information for: there
112 /// is no guarantee that the specified side effect actually does happen,
113 /// just that it could. In the "DoesNot" case, this is 'must not' info.
114 ///
115 /// If this pointer is null, no details are known.
116 ///
117 const LocationMRInfo *LocationDetails;
118 };
119
120
121 /// LibCallInfo - Abstract interface to query about library call information.
122 /// Instances of this class return known information about some set of
123 /// libcalls.
124 ///
125 class LibCallInfo {
126 // Implementation details of this object, private.
127 mutable void *Impl;
128 mutable const LibCallLocationInfo *Locations;
129 mutable unsigned NumLocations;
130 public:
131 LibCallInfo() : Impl(0), Locations(0), NumLocations(0) {}
132 virtual ~LibCallInfo();
133
134 //===------------------------------------------------------------------===//
135 // Accessor Methods: Efficient access to contained data.
136 //===------------------------------------------------------------------===//
137
138 /// getLocationInfo - Return information about the specified LocationID.
139 const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
140
141
142 /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
143 /// the specified function if we have it. If not, return null.
144 const LibCallFunctionInfo *getFunctionInfo(Function *F) const;
145
146
147 //===------------------------------------------------------------------===//
148 // Implementation Methods: Subclasses should implement these.
149 //===------------------------------------------------------------------===//
150
151 /// getLocationInfo - Return descriptors for the locations referenced by
152 /// this set of libcalls.
153 virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
154 return 0;
155 }
156
157 /// getFunctionInfoArray - Return an array of descriptors that describe the
158 /// set of libcalls represented by this LibCallInfo object. This array is
159 /// terminated by an entry with a NULL name.
160 virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
161 };
162
163 } // end namespace llvm
164
165 #endif
0 //===- LibCallSemantics.cpp - Describe library semantics ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements interfaces that can be used to describe language
10 // specific runtime library interfaces (e.g. libc, libm, etc) to LLVM
11 // optimizers.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Analysis/LibCallSemantics.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/Function.h"
18 using namespace llvm;
19
20 /// getMap - This impl pointer in ~LibCallInfo is actually a StringMap. This
21 /// helper does the cast.
22 static StringMap *getMap(void *Ptr) {
23 return static_cast *>(Ptr);
24 }
25
26 LibCallInfo::~LibCallInfo() {
27 delete getMap(Impl);
28 }
29
30 const LibCallLocationInfo &LibCallInfo::getLocationInfo(unsigned LocID) const {
31 // Get location info on the first call.
32 if (NumLocations == 0)
33 NumLocations = getLocationInfo(Locations);
34
35 assert(LocID < NumLocations && "Invalid location ID!");
36 return Locations[LocID];
37 }
38
39
40 /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
41 /// the specified function if we have it. If not, return null.
42 const LibCallFunctionInfo *LibCallInfo::getFunctionInfo(Function *F) const {
43 StringMap *Map = getMap(Impl);
44
45 /// If this is the first time we are querying for this info, lazily construct
46 /// the StringMap to index it.
47 if (Map == 0) {
48 Impl = Map = new StringMap();
49
50 const LibCallFunctionInfo *Array = getFunctionInfoArray();
51 if (Array == 0) return 0;
52
53 // We now have the array of entries. Populate the StringMap.
54 for (unsigned i = 0; Array[i].Name; ++i)
55 (*Map)[Array[i].Name] = Array+i;
56 }
57
58 // Look up this function in the string map.
59 const char *ValueName = F->getNameStart();
60 StringMap::iterator I =
61 Map->find(ValueName, ValueName+F->getNameLen());
62 return I != Map->end() ? I->second : 0;
63 }
64