mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
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
This commit is contained in:
parent
094aa6ce47
commit
14852f27e7
166
include/llvm/Analysis/LibCallSemantics.h
Normal file
166
include/llvm/Analysis/LibCallSemantics.h
Normal file
@ -0,0 +1,166 @@
|
||||
//===- 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)(CallSite CS, const Value *Ptr, unsigned Size);
|
||||
};
|
||||
|
||||
/// 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(0), Locations(0), 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(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
|
65
lib/Analysis/LibCallSemantics.cpp
Normal file
65
lib/Analysis/LibCallSemantics.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//===- LibCallSemantics.cpp - 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 implements interfaces that can be used to describe language
|
||||
// specific runtime library interfaces (e.g. libc, libm, etc) to LLVM
|
||||
// optimizers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/LibCallSemantics.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Function.h"
|
||||
using namespace llvm;
|
||||
|
||||
/// getMap - This impl pointer in ~LibCallInfo is actually a StringMap. This
|
||||
/// helper does the cast.
|
||||
static StringMap<const LibCallFunctionInfo*> *getMap(void *Ptr) {
|
||||
return static_cast<StringMap<const LibCallFunctionInfo*> *>(Ptr);
|
||||
}
|
||||
|
||||
LibCallInfo::~LibCallInfo() {
|
||||
delete getMap(Impl);
|
||||
}
|
||||
|
||||
const LibCallLocationInfo &LibCallInfo::getLocationInfo(unsigned LocID) const {
|
||||
// Get location info on the first call.
|
||||
if (NumLocations == 0)
|
||||
NumLocations = getLocationInfo(Locations);
|
||||
|
||||
assert(LocID < NumLocations && "Invalid location ID!");
|
||||
return Locations[LocID];
|
||||
}
|
||||
|
||||
|
||||
/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
|
||||
/// the specified function if we have it. If not, return null.
|
||||
const LibCallFunctionInfo *LibCallInfo::getFunctionInfo(Function *F) const {
|
||||
StringMap<const LibCallFunctionInfo*> *Map = getMap(Impl);
|
||||
|
||||
/// If this is the first time we are querying for this info, lazily construct
|
||||
/// the StringMap to index it.
|
||||
if (Map == 0) {
|
||||
Impl = Map = new StringMap<const LibCallFunctionInfo*>();
|
||||
|
||||
const LibCallFunctionInfo *Array = getFunctionInfoArray();
|
||||
if (Array == 0) return 0;
|
||||
|
||||
// We now have the array of entries. Populate the StringMap.
|
||||
for (unsigned i = 0; Array[i].Name; ++i)
|
||||
(*Map)[Array[i].Name] = Array+i;
|
||||
}
|
||||
|
||||
// Look up this function in the string map.
|
||||
const char *ValueName = F->getNameStart();
|
||||
StringMap<const LibCallFunctionInfo*>::iterator I =
|
||||
Map->find(ValueName, ValueName+F->getNameLen());
|
||||
return I != Map->end() ? I->second : 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user