aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Transforms/Utils
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Transforms/Utils')
-rw-r--r--include/llvm/Transforms/Utils/GlobalStatus.h82
-rw-r--r--include/llvm/Transforms/Utils/Local.h11
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h5
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h46
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h2
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; }