Home | History | Annotate | Download | only in Analysis
      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:
    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.
    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.
    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.
    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