From 0ea40c6fac411f29df1a5b7c723ac9e0537058a3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Mar 2004 03:36:49 +0000 Subject: [PATCH] Teach basicaa about some stdc functions. llvm-svn: 12408 --- lib/Analysis/BasicAliasAnalysis.cpp | 105 ++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index e928a265ff0..967b453ed52 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -21,13 +21,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Pass.h" -#include "llvm/Argument.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/iOther.h" #include "llvm/iMemory.h" -#include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" -#include "llvm/DerivedTypes.h" +#include "llvm/Pass.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" using namespace llvm; @@ -53,6 +53,9 @@ namespace { /// global) or not. bool pointsToConstantMemory(const Value *P); + virtual bool doesNotAccessMemory(Function *F); + virtual bool onlyReadsMemory(Function *F); + private: // CheckGEPInstructions - Check two GEP instructions with known // must-aliasing base pointers. This checks to see if the index expressions @@ -572,3 +575,95 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector &GEP1Ops, 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(); +} + +