diff options
Diffstat (limited to 'include/llvm/Transforms/Utils')
-rw-r--r-- | include/llvm/Transforms/Utils/GlobalStatus.h | 82 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/Local.h | 11 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/PromoteMemToReg.h | 5 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/SpecialCaseList.h | 46 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h | 2 |
5 files changed, 120 insertions, 26 deletions
diff --git a/include/llvm/Transforms/Utils/GlobalStatus.h b/include/llvm/Transforms/Utils/GlobalStatus.h new file mode 100644 index 0000000000..c366095088 --- /dev/null +++ b/include/llvm/Transforms/Utils/GlobalStatus.h @@ -0,0 +1,82 @@ +//===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H +#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H + +#include "llvm/IR/Instructions.h" + +namespace llvm { +class Value; +class Function; + +/// It is safe to destroy a constant iff it is only used by constants itself. +/// Note that constants cannot be cyclic, so this test is pretty easy to +/// implement recursively. +/// +bool isSafeToDestroyConstant(const Constant *C); + +/// As we analyze each global, keep track of some information about it. If we +/// find out that the address of the global is taken, none of this info will be +/// accurate. +struct GlobalStatus { + /// True if the global's address is used in a comparison. + bool IsCompared; + + /// True if the global is ever loaded. If the global isn't ever loaded it + /// can be deleted. + bool IsLoaded; + + /// Keep track of what stores to the global look like. + enum StoredType { + /// There is no store to this global. It can thus be marked constant. + NotStored, + + /// This global is stored to, but the only thing stored is the constant it + /// was initialized with. This is only tracked for scalar globals. + InitializerStored, + + /// This global is stored to, but only its initializer and one other value + /// is ever stored to it. If this global isStoredOnce, we track the value + /// stored to it in StoredOnceValue below. This is only tracked for scalar + /// globals. + StoredOnce, + + /// This global is stored to by multiple values or something else that we + /// cannot track. + Stored + } StoredType; + + /// If only one value (besides the initializer constant) is ever stored to + /// this global, keep track of what value it is. + Value *StoredOnceValue; + + /// These start out null/false. When the first accessing function is noticed, + /// it is recorded. When a second different accessing function is noticed, + /// HasMultipleAccessingFunctions is set to true. + const Function *AccessingFunction; + bool HasMultipleAccessingFunctions; + + /// Set to true if this global has a user that is not an instruction (e.g. a + /// constant expr or GV initializer). + bool HasNonInstructionUser; + + /// Set to the strongest atomic ordering requirement. + AtomicOrdering Ordering; + + /// Look at all uses of the global and fill in the GlobalStatus structure. If + /// the global has its address taken, return true to indicate we can't do + /// anything with it. + static bool analyzeGlobal(const Value *V, GlobalStatus &GS); + + GlobalStatus(); +}; +} + +#endif diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 65755d076e..5586c155bb 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -203,12 +203,17 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, ++i, ++GTI) { Value *Op = *i; uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; - if (ConstantInt *OpC = dyn_cast<ConstantInt>(Op)) { - if (OpC->isZero()) continue; + if (Constant *OpC = dyn_cast<Constant>(Op)) { + if (OpC->isZeroValue()) + continue; // Handle a struct index, which adds its field offset to the pointer. if (StructType *STy = dyn_cast<StructType>(*GTI)) { - Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue()); + if (OpC->getType()->isVectorTy()) + OpC = OpC->getSplatValue(); + + uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue(); + Size = TD.getStructLayout(STy)->getElementOffset(OpValue); if (Size) Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size), diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h index 2f28f3333f..22f46e5fc9 100644 --- a/include/llvm/Transforms/Utils/PromoteMemToReg.h +++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h @@ -20,7 +20,6 @@ namespace llvm { class AllocaInst; -class DataLayout; class DominatorTree; class AliasSetTracker; @@ -30,7 +29,7 @@ class AliasSetTracker; /// (transitively) using this alloca. This also enforces that there is only /// ever one layer of bitcasts or GEPs between the alloca and the lifetime /// markers. -bool isAllocaPromotable(const AllocaInst *AI, const DataLayout *DL); +bool isAllocaPromotable(const AllocaInst *AI); /// \brief Promote the specified list of alloca instructions into scalar /// registers, inserting PHI nodes as appropriate. @@ -42,7 +41,7 @@ bool isAllocaPromotable(const AllocaInst *AI, const DataLayout *DL); /// If AST is specified, the specified tracker is updated to reflect changes /// made to the IR. void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT, - const DataLayout *DL, AliasSetTracker *AST = 0); + AliasSetTracker *AST = 0); } // End llvm namespace diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h index 787ddb0c7c..34c28fc1ca 100644 --- a/include/llvm/Transforms/Utils/SpecialCaseList.h +++ b/include/llvm/Transforms/Utils/SpecialCaseList.h @@ -49,6 +49,7 @@ namespace llvm { class Function; +class GlobalAlias; class GlobalVariable; class MemoryBuffer; class Module; @@ -57,8 +58,17 @@ class StringRef; class SpecialCaseList { public: - SpecialCaseList(const StringRef Path); - SpecialCaseList(const MemoryBuffer *MB); + /// Parses the special case list from a file. If Path is empty, returns + /// an empty special case list. On failure, returns 0 and writes an error + /// message to string. + static SpecialCaseList *create(const StringRef Path, std::string &Error); + /// Parses the special case list from a memory buffer. On failure, returns + /// 0 and writes an error message to string. + static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error); + /// Parses the special case list from a file. On failure, reports a fatal + /// error. + static SpecialCaseList *createOrDie(const StringRef Path); + ~SpecialCaseList(); /// Returns whether either this function or its source file are listed in the @@ -70,31 +80,29 @@ class SpecialCaseList { bool isIn(const GlobalVariable &G, const StringRef Category = StringRef()) const; + /// Returns whether this global alias is listed in the given category, which + /// may be omitted to search the empty category. + /// + /// If GA aliases a function, the alias's name is matched as a function name + /// would be. Similarly, aliases of globals are matched like globals. + bool isIn(const GlobalAlias &GA, + const StringRef Category = StringRef()) const; + /// Returns whether this module is listed in the given category, which may be /// omitted to search the empty category. bool isIn(const Module &M, const StringRef Category = StringRef()) const; - /// Returns whether either this function or its source file are listed in any - /// category. Category will contain the name of an arbitrary category in - /// which this function is listed. - bool findCategory(const Function &F, StringRef &Category) const; - - /// Returns whether this global, its type or its source file are listed in any - /// category. Category will contain the name of an arbitrary category in - /// which this global is listed. - bool findCategory(const GlobalVariable &G, StringRef &Category) const; - - /// Returns whether this module is listed in any category. Category will - /// contain the name of an arbitrary category in which this module is listed. - bool findCategory(const Module &M, StringRef &Category) const; - private: + SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION; + SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION; + struct Entry; StringMap<StringMap<Entry> > Entries; - void init(const MemoryBuffer *MB); - bool findCategory(const StringRef Section, const StringRef Query, - StringRef &Category) const; + SpecialCaseList(); + /// Parses just-constructed SpecialCaseList entries from a memory buffer. + bool parse(const MemoryBuffer *MB, std::string &Error); + bool inSectionCategory(const StringRef Section, const StringRef Query, const StringRef Category) const; }; diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h index 54506cfff4..933c85c516 100644 --- a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h +++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h @@ -34,7 +34,7 @@ public: // We can preserve non-critical-edgeness when we unify function exit nodes virtual void getAnalysisUsage(AnalysisUsage &AU) const; - // getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistant) + // getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistent) // return, unwind, or unreachable basic blocks in the CFG. // BasicBlock *getReturnBlock() const { return ReturnBlock; } |