[WinEH] Recognize CoreCLR personality function
[oota-llvm.git] / include / llvm / Analysis / LibCallSemantics.h
index 09411b9b86003615be092659bca1f545c700507c..14ecb55f340b5a0b5d64db2534b7d69ede87e9d4 100644 (file)
 namespace llvm {
 class InvokeInst;
 
-  /// LibCallLocationInfo - This struct describes a set of memory locations that
-  /// are accessed by libcalls.  Identification of a location is doing with a
-  /// simple callback function.
-  ///
-  /// For example, the LibCallInfo may be set up to model the behavior of
-  /// standard libm functions.  The location that they may be interested in is
-  /// an abstract location that represents errno for the current target.  In
-  /// this case, a location for errno is anything such that the predicate
-  /// returns true.  On Mac OS X, this predicate would return true if the
-  /// pointer is the result of a call to "__error()".
-  ///
-  /// Locations can also be defined in a constant-sensitive way.  For example,
-  /// it is possible to define a location that returns true iff it is passed
-  /// into the call as a specific argument.  This is useful for modeling things
-  /// like "printf", which can store to memory, but only through pointers passed
-  /// with a '%n' constraint.
-  ///
-  struct LibCallLocationInfo {
-    // TODO: Flags: isContextSensitive etc.
-    
-    /// isLocation - Return a LocResult if the specified pointer refers to this
-    /// location for the specified call site.  This returns "Yes" if we can tell
-    /// that the pointer *does definitely* refer to the location, "No" if we can
-    /// tell that the location *definitely does not* refer to the location, and
-    /// returns "Unknown" if we cannot tell for certain.
-    enum LocResult {
-      Yes, No, Unknown
-    };
-    LocResult (*isLocation)(ImmutableCallSite CS, const MemoryLocation &Loc);
-  };
-  
-  /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
-  /// records the behavior of one libcall that is known by the optimizer.  This
-  /// captures things like the side effects of the call.  Side effects are
-  /// modeled both universally (in the readnone/readonly) sense, but also
-  /// potentially against a set of abstract locations defined by the optimizer.
-  /// This allows an optimizer to define that some libcall (e.g. sqrt) is
-  /// side-effect free except that it might modify errno (thus, the call is
-  /// *not* universally readonly).  Or it might say that the side effects
-  /// are unknown other than to say that errno is not modified.
-  ///
-  struct LibCallFunctionInfo {
-    /// Name - This is the name of the libcall this describes.
-    const char *Name;
-    
-    /// TODO: Constant folding function: Constant* vector -> Constant*.
-    
-    /// UniversalBehavior - This captures the absolute mod/ref behavior without
-    /// any specific context knowledge.  For example, if the function is known
-    /// to be readonly, this would be set to 'ref'.  If known to be readnone,
-    /// this is set to NoModRef.
-    ModRefInfo UniversalBehavior;
-
-    /// LocationMRInfo - This pair captures info about whether a specific
-    /// location is modified or referenced by a libcall.
-    struct LocationMRInfo {
-      /// LocationID - ID # of the accessed location or ~0U for array end.
-      unsigned LocationID;
-      /// MRInfo - Mod/Ref info for this location.
-      ModRefInfo MRInfo;
-    };
-    
-    /// DetailsType - Indicate the sense of the LocationDetails array.  This
-    /// controls how the LocationDetails array is interpreted.
-    enum {
-      /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
-      /// *only* mod/ref behavior of this function is captured by the
-      /// LocationDetails array.  If we are trying to say that 'sqrt' can only
-      /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
-      /// array and have DetailsType set to DoesOnly.
-      DoesOnly,
-      
-      /// DoesNot - If DetailsType is set to DoesNot, then the sense of the
-      /// LocationDetails array is completely inverted.  This means that we *do
-      /// not* know everything about the side effects of this libcall, but we do
-      /// know things that the libcall cannot do.  This is useful for complex
-      /// functions like 'ctime' which have crazy mod/ref behavior, but are
-      /// known to never read or write errno.  In this case, we'd have
-      /// {errnoloc,modref} in the LocationDetails array and DetailsType would
-      /// be set to DoesNot, indicating that ctime does not read or write the
-      /// errno location.
-      DoesNot
-    } DetailsType;
-    
-    /// LocationDetails - This is a pointer to an array of LocationMRInfo
-    /// structs which indicates the behavior of the libcall w.r.t. specific
-    /// locations.  For example, if this libcall is known to only modify
-    /// 'errno', it would have a LocationDetails array with the errno ID and
-    /// 'mod' in it.  See the DetailsType field for how this is interpreted.
-    ///
-    /// In the "DoesOnly" case, this information is 'may' information for: there
-    /// is no guarantee that the specified side effect actually does happen,
-    /// just that it could.  In the "DoesNot" case, this is 'must not' info.
-    ///
-    /// If this pointer is null, no details are known.
-    ///
-    const LocationMRInfo *LocationDetails;
-  };
-  
-  
-  /// LibCallInfo - Abstract interface to query about library call information.
-  /// Instances of this class return known information about some set of
-  /// libcalls.
-  /// 
-  class LibCallInfo {
-    // Implementation details of this object, private.
-    mutable void *Impl;
-    mutable const LibCallLocationInfo *Locations;
-    mutable unsigned NumLocations;
-  public:
-    LibCallInfo() : Impl(nullptr), Locations(nullptr), NumLocations(0) {}
-    virtual ~LibCallInfo();
-    
-    //===------------------------------------------------------------------===//
-    //  Accessor Methods: Efficient access to contained data.
-    //===------------------------------------------------------------------===//
-    
-    /// getLocationInfo - Return information about the specified LocationID.
-    const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
-    
-    
-    /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
-    /// the specified function if we have it.  If not, return null.
-    const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
-    
-    
-    //===------------------------------------------------------------------===//
-    //  Implementation Methods: Subclasses should implement these.
-    //===------------------------------------------------------------------===//
-    
-    /// getLocationInfo - Return descriptors for the locations referenced by
-    /// this set of libcalls.
-    virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
-      return 0;
-    }
-    
-    /// getFunctionInfoArray - Return an array of descriptors that describe the
-    /// set of libcalls represented by this LibCallInfo object.  This array is
-    /// terminated by an entry with a NULL name.
-    virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
-  };
-
   enum class EHPersonality {
     Unknown,
     GNU_Ada,
@@ -171,6 +29,7 @@ class InvokeInst;
     MSVC_X86SEH,
     MSVC_Win64SEH,
     MSVC_CXX,
+    CoreCLR
   };
 
   /// \brief See if the given exception handling personality function is one
@@ -192,14 +51,14 @@ class InvokeInst;
     llvm_unreachable("invalid enum");
   }
 
-  /// \brief Returns true if this is an MSVC personality function.
-  inline bool isMSVCEHPersonality(EHPersonality Pers) {
-    // The two SEH personality functions can catch asynch exceptions. We assume
-    // unknown personalities don't catch asynch exceptions.
+  /// \brief Returns true if this is a personality function that invokes
+  /// handler funclets (which must return to it).
+  inline bool isFuncletEHPersonality(EHPersonality Pers) {
     switch (Pers) {
     case EHPersonality::MSVC_CXX:
     case EHPersonality::MSVC_X86SEH:
     case EHPersonality::MSVC_Win64SEH:
+    case EHPersonality::CoreCLR:
       return true;
     default: return false;
     }