mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Teach basicaa about some stdc functions.
llvm-svn: 12408
This commit is contained in:
parent
275dd432ab
commit
0ea40c6fac
@ -21,13 +21,13 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Argument.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/Function.h"
|
||||||
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
|
||||||
#include "llvm/DerivedTypes.h"
|
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -53,6 +53,9 @@ namespace {
|
|||||||
/// global) or not.
|
/// global) or not.
|
||||||
bool pointsToConstantMemory(const Value *P);
|
bool pointsToConstantMemory(const Value *P);
|
||||||
|
|
||||||
|
virtual bool doesNotAccessMemory(Function *F);
|
||||||
|
virtual bool onlyReadsMemory(Function *F);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// CheckGEPInstructions - Check two GEP instructions with known
|
// CheckGEPInstructions - Check two GEP instructions with known
|
||||||
// must-aliasing base pointers. This checks to see if the index expressions
|
// must-aliasing base pointers. This checks to see if the index expressions
|
||||||
@ -572,3 +575,95 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops,
|
|||||||
return MayAlias;
|
return MayAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct StringCompare {
|
||||||
|
bool operator()(const char *LHS, const char *RHS) {
|
||||||
|
return strcmp(LHS, RHS) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that this list cannot contain libm functions (such as acos and sqrt)
|
||||||
|
// that set errno on a domain or other error.
|
||||||
|
static const char *DoesntAccessMemoryTable[] = {
|
||||||
|
"abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
|
||||||
|
"trunc", "truncf", "truncl", "ldexp",
|
||||||
|
|
||||||
|
"atan", "atanf", "atanl", "atan2", "atan2f", "atan2l",
|
||||||
|
"cbrt",
|
||||||
|
"cos", "cosf", "cosl", "cosh", "coshf", "coshl",
|
||||||
|
"exp", "expf", "expl",
|
||||||
|
"hypot",
|
||||||
|
"sin", "sinf", "sinl", "sinh", "sinhf", "sinhl",
|
||||||
|
"tan", "tanf", "tanl", "tanh", "tanhf", "tanhl",
|
||||||
|
|
||||||
|
"isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", "isprint"
|
||||||
|
"ispunct", "isspace", "isupper", "isxdigit", "tolower", "toupper",
|
||||||
|
|
||||||
|
"iswalnum", "iswalpha", "iswcntrl", "iswdigit", "iswgraph", "iswlower",
|
||||||
|
"iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit",
|
||||||
|
|
||||||
|
"btowc", "wctob",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned DAMTableSize =
|
||||||
|
sizeof(DoesntAccessMemoryTable)/sizeof(DoesntAccessMemoryTable[0]);
|
||||||
|
|
||||||
|
/// doesNotAccessMemory - Return true if we know that the function does not
|
||||||
|
/// access memory at all. Since basicaa does no analysis, we can only do simple
|
||||||
|
/// things here. In particular, if we have an external function with the name
|
||||||
|
/// of a standard C library function, we are allowed to assume it will be
|
||||||
|
/// resolved by libc, so we can hardcode some entries in here.
|
||||||
|
bool BasicAliasAnalysis::doesNotAccessMemory(Function *F) {
|
||||||
|
if (!F->isExternal()) return false;
|
||||||
|
|
||||||
|
static bool Initialized = false;
|
||||||
|
if (!Initialized) {
|
||||||
|
// Sort the table the first time through.
|
||||||
|
std::sort(DoesntAccessMemoryTable, DoesntAccessMemoryTable+DAMTableSize,
|
||||||
|
StringCompare());
|
||||||
|
Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **Ptr = std::lower_bound(DoesntAccessMemoryTable,
|
||||||
|
DoesntAccessMemoryTable+DAMTableSize,
|
||||||
|
F->getName().c_str(), StringCompare());
|
||||||
|
return Ptr != DoesntAccessMemoryTable+DAMTableSize && *Ptr == F->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *OnlyReadsMemoryTable[] = {
|
||||||
|
"atoi", "atol", "atof", "atoll", "atoq",
|
||||||
|
"bcmp", "memcmp", "memchr", "wmemcmp", "wmemchr",
|
||||||
|
|
||||||
|
// Strings
|
||||||
|
"strcmp", "strcasecmp", "strcoll", "strncmp", "strncasecmp",
|
||||||
|
"strchr", "strcspn", "strlen", "strpbrk", "strrchr", "strspn", "strstr",
|
||||||
|
|
||||||
|
// Wide char strings
|
||||||
|
"wcschr", "wcscmp", "wcscoll", "wcscspn", "wcslen", "wcsncmp", "wcspbrk",
|
||||||
|
"wcsrchr", "wcsspn", "wcsstr",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned ORMTableSize =
|
||||||
|
sizeof(OnlyReadsMemoryTable)/sizeof(OnlyReadsMemoryTable[0]);
|
||||||
|
|
||||||
|
bool BasicAliasAnalysis::onlyReadsMemory(Function *F) {
|
||||||
|
if (doesNotAccessMemory(F)) return true;
|
||||||
|
if (!F->isExternal()) return false;
|
||||||
|
|
||||||
|
static bool Initialized = false;
|
||||||
|
if (!Initialized) {
|
||||||
|
// Sort the table the first time through.
|
||||||
|
std::sort(OnlyReadsMemoryTable, OnlyReadsMemoryTable+ORMTableSize,
|
||||||
|
StringCompare());
|
||||||
|
Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **Ptr = std::lower_bound(OnlyReadsMemoryTable,
|
||||||
|
OnlyReadsMemoryTable+ORMTableSize,
|
||||||
|
F->getName().c_str(), StringCompare());
|
||||||
|
return Ptr != OnlyReadsMemoryTable+ORMTableSize && *Ptr == F->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user