//===- LibCallSemantics.h - Describe library semantics --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines interfaces that can be used to describe language specific
// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H

#include "llvm/Analysis/AliasAnalysis.h"

namespace llvm {

  /// 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 AliasAnalysis::Location &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.
    AliasAnalysis::ModRefResult 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.
      AliasAnalysis::ModRefResult 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;
  };

} // end namespace llvm

#endif
