summaryrefslogtreecommitdiff
path: root/include/llvm/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r--include/llvm/Transforms/IPO.h10
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h17
-rw-r--r--include/llvm/Transforms/Instrumentation.h67
-rw-r--r--include/llvm/Transforms/Scalar.h61
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h31
-rw-r--r--include/llvm/Transforms/Utils/BlackList.h59
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h3
-rw-r--r--include/llvm/Transforms/Utils/GlobalStatus.h82
-rw-r--r--include/llvm/Transforms/Utils/Local.h43
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h26
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h8
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h24
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h104
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h110
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h2
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h31
-rw-r--r--include/llvm/Transforms/Vectorize.h2
17 files changed, 482 insertions, 198 deletions
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index e6eb8d38bb8ca..7f51c516b9b50 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -104,12 +104,16 @@ Pass *createPruneEHPass();
//===----------------------------------------------------------------------===//
/// createInternalizePass - This pass loops over all of the functions in the
-/// input module, internalizing all globals (functions and variables) not in the
-/// given exportList.
+/// input module, internalizing all globals (functions and variables) it can.
+////
+/// The symbols in \p ExportList are never internalized.
+///
+/// The symbol in DSOList are internalized if it is safe to drop them from
+/// the symbol table.
///
/// Note that commandline options that are used with the above function are not
/// used now!
-ModulePass *createInternalizePass(ArrayRef<const char *> exportList);
+ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);
/// createInternalizePass - Same as above, but with an empty exportList.
ModulePass *createInternalizePass();
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 563721e128251..27887749e9607 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -18,10 +18,16 @@
#include <vector>
namespace llvm {
- class TargetLibraryInfo;
- class PassManagerBase;
- class Pass;
- class FunctionPassManager;
+class TargetLibraryInfo;
+class Pass;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+class FunctionPassManager;
+}
+using legacy::PassManagerBase;
+using legacy::FunctionPassManager;
/// PassManagerBuilder - This class is used to set up a standard optimization
/// sequence for languages like C and C++, allowing some APIs to customize the
@@ -100,12 +106,13 @@ public:
/// added to the per-module passes.
Pass *Inliner;
- bool DisableSimplifyLibCalls;
bool DisableUnitAtATime;
bool DisableUnrollLoops;
bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
+ bool LateVectorize;
+ bool RerollLoops;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 4aae200dd0835..8a1b34e488be7 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -16,20 +16,25 @@
#include "llvm/ADT/StringRef.h"
+#if defined(__GNUC__) && defined(__linux__)
+inline void *getDFSanArgTLSPtrForJIT() {
+ extern __thread __attribute__((tls_model("initial-exec")))
+ void *__dfsan_arg_tls;
+ return (void *)&__dfsan_arg_tls;
+}
+
+inline void *getDFSanRetValTLSPtrForJIT() {
+ extern __thread __attribute__((tls_model("initial-exec")))
+ void *__dfsan_retval_tls;
+ return (void *)&__dfsan_retval_tls;
+}
+#endif
+
namespace llvm {
class ModulePass;
class FunctionPass;
-// Insert edge profiling instrumentation
-ModulePass *createEdgeProfilerPass();
-
-// Insert optimal edge profiling instrumentation
-ModulePass *createOptimalEdgeProfilerPass();
-
-// Insert path profiling instrumentation
-ModulePass *createPathProfilerPass();
-
// Insert GCOV profiling instrumentation
struct GCOVOptions {
static GCOVOptions getDefault();
@@ -74,10 +79,54 @@ FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
// Insert ThreadSanitizer (race detection) instrumentation
FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
+// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
+ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
+ void *(*getArgTLS)() = 0,
+ void *(*getRetValTLS)() = 0);
+
+#if defined(__GNUC__) && defined(__linux__)
+inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
+ StringRef()) {
+ return createDataFlowSanitizerPass(ABIListFile, getDFSanArgTLSPtrForJIT,
+ getDFSanRetValTLSPtrForJIT);
+}
+#endif
+
// BoundsChecking - This pass instruments the code to perform run-time bounds
// checking on loads, stores, and other memory intrinsics.
FunctionPass *createBoundsCheckingPass();
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB (or
+/// GDB) and generate a file with the LLVM IR to be
+/// displayed in the debugger.
+///
+/// Existing debug metadata is preserved (but may be modified) in order to allow
+/// accessing variables in the original source. The line table and file
+/// information is modified to correspond to the lines in the LLVM IR. If
+/// Filename and Directory are empty, a file name is generated based on existing
+/// debug information. If no debug information is available, a temporary file
+/// name is generated.
+///
+/// @param HideDebugIntrinsics Omit debug intrinsics in emitted IR source file.
+/// @param HideDebugMetadata Omit debug metadata in emitted IR source file.
+/// @param Directory Embed this directory in the debug information.
+/// @param Filename Embed this file name in the debug information.
+ModulePass *createDebugIRPass(bool HideDebugIntrinsics,
+ bool HideDebugMetadata,
+ StringRef Directory = StringRef(),
+ StringRef Filename = StringRef());
+
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB
+/// (or GDB) with an existing IR file on disk. When creating
+/// a DebugIR pass with this function, no source file is
+/// output to disk and the existing one is unmodified. Debug
+/// metadata in the Module is created/updated to point to
+/// the existing textual IR file on disk.
+/// NOTE: If the IR file to be debugged is not on disk, use the version of this
+/// function with parameters in order to generate the file that will be
+/// seen by the debugger.
+ModulePass *createDebugIRPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index e833aaa6d69e5..1521c4cff562a 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -15,6 +15,8 @@
#ifndef LLVM_TRANSFORMS_SCALAR_H
#define LLVM_TRANSFORMS_SCALAR_H
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
class FunctionPass;
@@ -23,6 +25,7 @@ class GetElementPtrInst;
class PassInfo;
class TerminatorInst;
class TargetLowering;
+class TargetMachine;
//===----------------------------------------------------------------------===//
//
@@ -119,7 +122,7 @@ Pass *createLICMPass();
//
Pass *createLoopStrengthReducePass();
-Pass *createGlobalMergePass(const TargetLowering *TLI = 0);
+Pass *createGlobalMergePass(const TargetMachine *TM = 0);
//===----------------------------------------------------------------------===//
//
@@ -137,7 +140,14 @@ Pass *createLoopInstSimplifyPass();
//
// LoopUnroll - This pass is a simple loop unrolling pass.
//
-Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1, int AllowPartial = -1);
+Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
+ int AllowPartial = -1, int Runtime = -1);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopReroll - This pass is a simple loop rerolling pass.
+//
+Pass *createLoopRerollPass();
//===----------------------------------------------------------------------===//
//
@@ -199,6 +209,19 @@ FunctionPass *createCFGSimplificationPass();
//===----------------------------------------------------------------------===//
//
+// FlattenCFG - flatten CFG, reduce number of conditional branches by using
+// parallel-and and parallel-or mode, etc...
+//
+FunctionPass *createFlattenCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFG Structurization - Remove irreducible control flow
+//
+Pass *createStructurizeCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
// BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
// a dummy basic block. This pass may be "required" by passes that cannot deal
// with critical edges. For this usage, a pass must call:
@@ -247,20 +270,12 @@ extern char &LowerSwitchID;
// purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet"
// lowering pass.
//
-FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0);
-FunctionPass *createLowerInvokePass(const TargetLowering *TLI,
- bool useExpensiveEHSupport);
+FunctionPass *createLowerInvokePass(const TargetMachine *TM = 0,
+ bool useExpensiveEHSupport = false);
extern char &LowerInvokePassID;
//===----------------------------------------------------------------------===//
//
-// BlockPlacement - This pass reorders basic blocks in order to increase the
-// number of fall-through conditional branches.
-//
-FunctionPass *createBlockPlacementPass();
-
-//===----------------------------------------------------------------------===//
-//
// LCSSA - This pass inserts phi nodes at loop boundaries to simplify other loop
// optimizations.
//
@@ -297,15 +312,9 @@ Pass *createLoopDeletionPass();
//===----------------------------------------------------------------------===//
//
-/// createSimplifyLibCallsPass - This pass optimizes specific calls to
-/// specific well-known (library) functions.
-FunctionPass *createSimplifyLibCallsPass();
-
-//===----------------------------------------------------------------------===//
-//
// CodeGenPrepare - This pass prepares a function for instruction selection.
//
-FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
+FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
//===----------------------------------------------------------------------===//
//
@@ -347,6 +356,20 @@ extern char &InstructionSimplifierID;
FunctionPass *createLowerExpectIntrinsicPass();
+//===----------------------------------------------------------------------===//
+//
+// PartiallyInlineLibCalls - Tries to inline the fast path of library
+// calls such as sqrt.
+//
+FunctionPass *createPartiallyInlineLibCallsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SampleProfilePass - Loads sample profile data from disk and generates
+// IR metadata to reflect the profile.
+FunctionPass *createSampleProfileLoaderPass();
+FunctionPass *createSampleProfileLoaderPass(StringRef Name);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 8f1a6e2b75c31..65cafe2ec2812 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -70,28 +70,6 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
//
void ReplaceInstWithInst(Instruction *From, Instruction *To);
-/// FindFunctionBackedges - Analyze the specified function to find all of the
-/// loop backedges in the function and return them. This is a relatively cheap
-/// (compared to computing dominators and loop info) analysis.
-///
-/// The output is added to Result, as pairs of <from,to> edge info.
-void FindFunctionBackedges(const Function &F,
- SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result);
-
-
-/// GetSuccessorNumber - Search for the specified successor of basic block BB
-/// and return its position in the terminator instruction's list of
-/// successors. It is an error to call this with a block that is not a
-/// successor.
-unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
-
-/// isCriticalEdge - Return true if the specified edge is a critical edge.
-/// Critical edges are edges from a block with multiple successors to a block
-/// with multiple predecessors.
-///
-bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
- bool AllowIdenticalEdges = false);
-
/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
/// split the critical edge. This will update DominatorTree and
/// DominatorFrontier information if it is available, thus calling this pass
@@ -227,6 +205,15 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
bool Unreachable, MDNode *BranchWeights = 0);
+///
+/// GetIfCondition - Check whether BB is the merge point of a if-region.
+/// If so, return the boolean condition that determines which entry into
+/// BB will be taken. Also, return by references the block that will be
+/// entered from if the condition is true, and the block that will be
+/// entered if the condition is false.
+
+Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
+ BasicBlock *&IfFalse);
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BlackList.h b/include/llvm/Transforms/Utils/BlackList.h
deleted file mode 100644
index 316b364845caf..0000000000000
--- a/include/llvm/Transforms/Utils/BlackList.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- BlackList.h - blacklist for sanitizers ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===//
-//
-// This is a utility class for instrumentation passes (like AddressSanitizer
-// or ThreadSanitizer) to avoid instrumenting some functions or global
-// variables based on a user-supplied blacklist.
-//
-// The blacklist disables instrumentation of various functions and global
-// variables. Each line contains a prefix, followed by a wild card expression.
-// Empty lines and lines starting with "#" are ignored.
-// ---
-// # Blacklisted items:
-// fun:*_ZN4base6subtle*
-// global:*global_with_bad_access_or_initialization*
-// global-init:*global_with_initialization_issues*
-// global-init-type:*Namespace::ClassName*
-// src:file_with_tricky_code.cc
-// global-init-src:ignore-global-initializers-issues.cc
-// ---
-// Note that the wild card is in fact an llvm::Regex, but * is automatically
-// replaced with .*
-// This is similar to the "ignore" feature of ThreadSanitizer.
-// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
-//
-//===----------------------------------------------------------------------===//
-//
-
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
-class Function;
-class GlobalVariable;
-class Module;
-class Regex;
-class StringRef;
-
-class BlackList {
- public:
- BlackList(const StringRef Path);
- // Returns whether either this function or it's source file are blacklisted.
- bool isIn(const Function &F) const;
- // Returns whether either this global or it's source file are blacklisted.
- bool isIn(const GlobalVariable &G) const;
- // Returns whether this module is blacklisted by filename.
- bool isIn(const Module &M) const;
- // Returns whether a global should be excluded from initialization checking.
- bool isInInit(const GlobalVariable &G) const;
- private:
- StringMap<Regex*> Entries;
-
- bool inSection(const StringRef Section, const StringRef Query) const;
-};
-
-} // namespace llvm
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 14212f622ba59..3ec132937c0d9 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -131,7 +131,8 @@ void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = 0,
- ValueMapTypeRemapper *TypeMapper = 0);
+ ValueMapTypeRemapper *TypeMapper = 0,
+ ValueMaterializer *Materializer = 0);
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
/// except that it does some simple constant prop and DCE on the fly. The
diff --git a/include/llvm/Transforms/Utils/GlobalStatus.h b/include/llvm/Transforms/Utils/GlobalStatus.h
new file mode 100644
index 0000000000000..c36609508808d
--- /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 267825079e114..5586c155bb11b 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -39,9 +39,10 @@ class DataLayout;
class TargetLibraryInfo;
class TargetTransformInfo;
class DIBuilder;
+class AliasAnalysis;
template<typename T> class SmallVectorImpl;
-
+
//===----------------------------------------------------------------------===//
// Local constant propagation.
//
@@ -79,7 +80,7 @@ bool RecursivelyDeleteTriviallyDeadInstructions(Value *V,
/// too, recursively. Return true if a change was made.
bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
-
+
/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
/// simplify any instructions in it and recursively delete dead instructions.
///
@@ -87,7 +88,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
/// instructions in other blocks as well in this block.
bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
-
+
//===----------------------------------------------------------------------===//
// Control Flow Graph Restructuring.
//
@@ -105,15 +106,15 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
/// recursively fold the 'and' to 0.
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
DataLayout *TD = 0);
-
-
+
+
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
/// predecessor is known to have one successor (BB!). Eliminate the edge
/// between them, moving the instructions in the predecessor into BB. This
/// deletes the predecessor block.
///
void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = 0);
-
+
/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an
/// unconditional branch, and contains no instructions other than PHI nodes,
@@ -138,6 +139,12 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
const DataLayout *TD = 0);
+/// FlatternCFG - This function is used to flatten a CFG. For
+/// example, it uses parallel-and and parallel-or mode to collapse
+// if-conditions and merge if-regions with identical statements.
+///
+bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = 0);
+
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
/// and if a predecessor branches to us and one of our successors, fold the
/// setcc into the predecessor and use logical operations to pick the right
@@ -156,7 +163,7 @@ AllocaInst *DemoteRegToStack(Instruction &X,
/// DemotePHIToStack - This function takes a virtual register computed by a phi
/// node and replaces it with a slot in the stack frame, allocated via alloca.
-/// The phi node is deleted and it returns the pointer to the alloca inserted.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
@@ -179,28 +186,34 @@ static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) {
template<typename IRBuilderTy>
Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
bool NoAssumptions = false) {
- gep_type_iterator GTI = gep_type_begin(GEP);
- Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
+ GEPOperator *GEPOp = cast<GEPOperator>(GEP);
+ Type *IntPtrTy = TD.getIntPtrType(GEP->getType());
Value *Result = Constant::getNullValue(IntPtrTy);
// If the GEP is inbounds, we know that none of the addressing operations will
// overflow in an unsigned sense.
- bool isInBounds = cast<GEPOperator>(GEP)->isInBounds() && !NoAssumptions;
+ bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
// Build a mask for high order bits.
- unsigned IntPtrWidth = TD.getPointerSizeInBits();
- uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);
+ unsigned IntPtrWidth = IntPtrTy->getScalarType()->getIntegerBitWidth();
+ uint64_t PtrSizeMask = ~0ULL >> (64 - IntPtrWidth);
+ gep_type_iterator GTI = gep_type_begin(GEP);
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
++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/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
new file mode 100644
index 0000000000000..4745eba079aee
--- /dev/null
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -0,0 +1,26 @@
+//===- llvm/Transforms/Utils/LoopUtils.h - Loop utilities -*- C++ -*-=========//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines some loop transformation utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
+#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
+
+namespace llvm {
+
+class Loop;
+class Pass;
+
+BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
+
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index bb7fc06bf5307..98a19ed426ace 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -18,6 +18,9 @@ namespace llvm {
class Module;
class Function;
+class GlobalValue;
+class GlobalVariable;
+template <class PtrType, unsigned SmallSize> class SmallPtrSet;
/// Append F to the list of global ctors of module M with the given Priority.
/// This wraps the function in the appropriate structure and stores it along
@@ -28,6 +31,11 @@ void appendToGlobalCtors(Module &M, Function *F, int Priority);
/// Same as appendToGlobalCtors(), but for global dtors.
void appendToGlobalDtors(Module &M, Function *F, int Priority);
+/// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
+/// the initializer elements of that global in Set and return the global itself.
+GlobalVariable *collectUsedGlobalVariables(Module &M,
+ SmallPtrSet<GlobalValue *, 8> &Set,
+ bool CompilerUsed);
} // End llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 52a6157d95ad0..22f46e5fc963c 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
#define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
-#include <vector>
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
@@ -23,21 +23,25 @@ class AllocaInst;
class DominatorTree;
class AliasSetTracker;
-/// isAllocaPromotable - Return true if this alloca is legal for promotion.
-/// This is true if there are only loads and stores to the alloca...
+/// \brief Return true if this alloca is legal for promotion.
///
+/// This is true if there are only loads, stores, and lifetime markers
+/// (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);
-/// PromoteMemToReg - Promote the specified list of alloca instructions into
-/// scalar registers, inserting PHI nodes as appropriate. This function makes
-/// use of DominanceFrontier information. This function does not modify the CFG
-/// of the function at all. All allocas must be from the same function.
+/// \brief Promote the specified list of alloca instructions into scalar
+/// registers, inserting PHI nodes as appropriate.
+///
+/// This function makes use of DominanceFrontier information. This function
+/// does not modify the CFG of the function at all. All allocas must be from
+/// the same function.
///
/// If AST is specified, the specified tracker is updated to reflect changes
/// made to the IR.
-///
-void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
- DominatorTree &DT, AliasSetTracker *AST = 0);
+void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
+ AliasSetTracker *AST = 0);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index cd048936e0bf3..0c0e5de584fdc 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -28,82 +28,90 @@ namespace llvm {
class Use;
class Value;
-/// SSAUpdater - This class updates SSA form for a set of values defined in
-/// multiple blocks. This is used when code duplication or another unstructured
+/// \brief Helper class for SSA formation on a set of values defined in
+/// multiple blocks.
+///
+/// This is used when code duplication or another unstructured
/// transformation wants to rewrite a set of uses of one value with uses of a
/// set of values.
class SSAUpdater {
friend class SSAUpdaterTraits<SSAUpdater>;
private:
- /// AvailableVals - This keeps track of which value to use on a per-block
- /// basis. When we insert PHI nodes, we keep track of them here.
+ /// This keeps track of which value to use on a per-block basis. When we
+ /// insert PHI nodes, we keep track of them here.
//typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
void *AV;
/// ProtoType holds the type of the values being rewritten.
Type *ProtoType;
- // PHI nodes are given a name based on ProtoName.
+ /// PHI nodes are given a name based on ProtoName.
std::string ProtoName;
- /// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
- /// it creates to the vector.
+ /// If this is non-null, the SSAUpdater adds all PHI nodes that it creates to
+ /// the vector.
SmallVectorImpl<PHINode*> *InsertedPHIs;
public:
- /// SSAUpdater constructor. If InsertedPHIs is specified, it will be filled
+ /// If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = 0);
~SSAUpdater();
- /// Initialize - Reset this object to get ready for a new set of SSA
- /// updates with type 'Ty'. PHI nodes get a name based on 'Name'.
+ /// \brief Reset this object to get ready for a new set of SSA updates with
+ /// type 'Ty'.
+ ///
+ /// PHI nodes get a name based on 'Name'.
void Initialize(Type *Ty, StringRef Name);
- /// AddAvailableValue - Indicate that a rewritten value is available at the
- /// end of the specified block with the specified value.
+ /// \brief Indicate that a rewritten value is available in the specified block
+ /// with the specified value.
void AddAvailableValue(BasicBlock *BB, Value *V);
- /// HasValueForBlock - Return true if the SSAUpdater already has a value for
- /// the specified block.
+ /// \brief Return true if the SSAUpdater already has a value for the specified
+ /// block.
bool HasValueForBlock(BasicBlock *BB) const;
- /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
- /// live at the end of the specified block.
+ /// \brief Construct SSA form, materializing a value that is live at the end
+ /// of the specified block.
Value *GetValueAtEndOfBlock(BasicBlock *BB);
- /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
- /// is live in the middle of the specified block.
+ /// \brief Construct SSA form, materializing a value that is live in the
+ /// middle of the specified block.
///
- /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
- /// important case: if there is a definition of the rewritten value after the
- /// 'use' in BB. Consider code like this:
+ /// \c GetValueInMiddleOfBlock is the same as \c GetValueAtEndOfBlock except
+ /// in one important case: if there is a definition of the rewritten value
+ /// after the 'use' in BB. Consider code like this:
///
+ /// \code
/// X1 = ...
/// SomeBB:
/// use(X)
/// X2 = ...
/// br Cond, SomeBB, OutBB
+ /// \endcode
///
/// In this case, there are two values (X1 and X2) added to the AvailableVals
/// set by the client of the rewriter, and those values are both live out of
/// their respective blocks. However, the use of X happens in the *middle* of
/// a block. Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
- ///
Value *GetValueInMiddleOfBlock(BasicBlock *BB);
- /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
- /// which use their value in the corresponding predecessor. Note that this
- /// will not work if the use is supposed to be rewritten to a value defined in
- /// the same block as the use, but above it. Any 'AddAvailableValue's added
- /// for the use's block will be considered to be below it.
+ /// \brief Rewrite a use of the symbolic value.
+ ///
+ /// This handles PHI nodes, which use their value in the corresponding
+ /// predecessor. Note that this will not work if the use is supposed to be
+ /// rewritten to a value defined in the same block as the use, but above it.
+ /// Any 'AddAvailableValue's added for the use's block will be considered to
+ /// be below it.
void RewriteUse(Use &U);
- /// RewriteUseAfterInsertions - Rewrite a use, just like RewriteUse. However,
- /// this version of the method can rewrite uses in the same block as a
- /// definition, because it assumes that all uses of a value are below any
+ /// \brief Rewrite a use like \c RewriteUse but handling in-block definitions.
+ ///
+ /// This version of the method can rewrite uses in the same block as
+ /// a definition, because it assumes that all uses of a value are below any
/// inserted values.
void RewriteUseAfterInsertions(Use &U);
@@ -113,15 +121,15 @@ private:
void operator=(const SSAUpdater&) LLVM_DELETED_FUNCTION;
SSAUpdater(const SSAUpdater&) LLVM_DELETED_FUNCTION;
};
-
-/// LoadAndStorePromoter - This little helper class provides a convenient way to
-/// promote a collection of loads and stores into SSA Form using the SSAUpdater.
+
+/// \brief Helper class for promoting a collection of loads and stores into SSA
+/// Form using the SSAUpdater.
+///
/// This handles complexities that SSAUpdater doesn't, such as multiple loads
/// and stores in one block.
///
/// Clients of this class are expected to subclass this and implement the
/// virtual methods.
-///
class LoadAndStorePromoter {
protected:
SSAUpdater &SSA;
@@ -130,34 +138,36 @@ public:
SSAUpdater &S, StringRef Name = StringRef());
virtual ~LoadAndStorePromoter() {}
- /// run - This does the promotion. Insts is a list of loads and stores to
- /// promote, and Name is the basename for the PHIs to insert. After this is
- /// complete, the loads and stores are removed from the code.
+ /// \brief This does the promotion.
+ ///
+ /// Insts is a list of loads and stores to promote, and Name is the basename
+ /// for the PHIs to insert. After this is complete, the loads and stores are
+ /// removed from the code.
void run(const SmallVectorImpl<Instruction*> &Insts) const;
- /// Return true if the specified instruction is in the Inst list (which was
- /// passed into the run method). Clients should implement this with a more
- /// efficient version if possible.
+ /// \brief Return true if the specified instruction is in the Inst list.
+ ///
+ /// The Insts list is the one passed into the constructor. Clients should
+ /// implement this with a more efficient version if possible.
virtual bool isInstInList(Instruction *I,
const SmallVectorImpl<Instruction*> &Insts) const;
- /// doExtraRewritesBeforeFinalDeletion - This hook is invoked after all the
- /// stores are found and inserted as available values, but
+ /// \brief This hook is invoked after all the stores are found and inserted as
+ /// available values.
virtual void doExtraRewritesBeforeFinalDeletion() const {
}
- /// replaceLoadWithValue - Clients can choose to implement this to get
- /// notified right before a load is RAUW'd another value.
+ /// \brief Clients can choose to implement this to get notified right before
+ /// a load is RAUW'd another value.
virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
}
- /// This is called before each instruction is deleted.
+ /// \brief Called before each instruction is deleted.
virtual void instructionDeleted(Instruction *I) const {
}
- /// updateDebugInfo - This is called to update debug info associated with the
- /// instruction.
+ /// \brief Called to update debug info associated with the instruction.
virtual void updateDebugInfo(Instruction *I) const {
}
};
diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h
new file mode 100644
index 0000000000000..34c28fc1cafef
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SpecialCaseList.h
@@ -0,0 +1,110 @@
+//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class for instrumentation passes (like AddressSanitizer
+// or ThreadSanitizer) to avoid instrumenting some functions or global
+// variables based on a user-supplied list.
+//
+// The list can also specify categories for specific globals, which can be used
+// to instruct an instrumentation pass to treat certain functions or global
+// variables in a specific way, such as by omitting certain aspects of
+// instrumentation while keeping others, or informing the instrumentation pass
+// that a specific uninstrumentable function has certain semantics, thus
+// allowing the pass to instrument callers according to those semantics.
+//
+// For example, AddressSanitizer uses the "init" category for globals whose
+// initializers should not be instrumented, but which in all other respects
+// should be instrumented.
+//
+// Each line contains a prefix, followed by a colon and a wild card expression,
+// followed optionally by an equals sign and an instrumentation-specific
+// category. Empty lines and lines starting with "#" are ignored.
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global:*global_with_initialization_issues*=init
+// type:*Namespace::ClassName*=init
+// src:file_with_tricky_code.cc
+// src:ignore-global-initializers-issues.cc=init
+//
+// # Functions with pure functional semantics:
+// fun:cos=functional
+// fun:sin=functional
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+//
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class Function;
+class GlobalAlias;
+class GlobalVariable;
+class MemoryBuffer;
+class Module;
+class Regex;
+class StringRef;
+
+class SpecialCaseList {
+ public:
+ /// 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
+ /// given category, which may be omitted to search the empty category.
+ bool isIn(const Function &F, const StringRef Category = StringRef()) const;
+
+ /// Returns whether this global, its type or its source file are listed in the
+ /// given category, which may be omitted to search the empty category.
+ 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;
+
+ private:
+ SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+ SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+
+ struct Entry;
+ StringMap<StringMap<Entry> > Entries;
+
+ 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;
+};
+
+} // namespace llvm
diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index 54506cfff4c30..933c85c51609f 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; }
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index 5390c5e8ed47e..d56ac07690fd5 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -33,6 +33,19 @@ namespace llvm {
/// remap types while mapping values.
virtual Type *remapType(Type *SrcTy) = 0;
};
+
+ /// ValueMaterializer - This is a class that can be implemented by clients
+ /// to materialize Values on demand.
+ class ValueMaterializer {
+ virtual void anchor(); // Out of line method.
+ public:
+ virtual ~ValueMaterializer() {}
+
+ /// materializeValueFor - The client should implement this method if they
+ /// want to generate a mapped Value on demand. For example, if linking
+ /// lazily.
+ virtual Value *materializeValueFor(Value *V) = 0;
+ };
/// RemapFlags - These are flags that the value mapping APIs allow.
enum RemapFlags {
@@ -55,23 +68,29 @@ namespace llvm {
Value *MapValue(const Value *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0);
+ ValueMapTypeRemapper *TypeMapper = 0,
+ ValueMaterializer *Materializer = 0);
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0);
+ ValueMapTypeRemapper *TypeMapper = 0,
+ ValueMaterializer *Materializer = 0);
/// MapValue - provide versions that preserve type safety for MDNode and
/// Constants.
inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0) {
- return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper));
+ ValueMapTypeRemapper *TypeMapper = 0,
+ ValueMaterializer *Materializer = 0) {
+ return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper,
+ Materializer));
}
inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0) {
- return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper));
+ ValueMapTypeRemapper *TypeMapper = 0,
+ ValueMaterializer *Materializer = 0) {
+ return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper,
+ Materializer));
}
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 8d0db1611609d..823c5fba745ea 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -114,7 +114,7 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
//
// LoopVectorize - Create a loop vectorization pass.
//
-Pass *createLoopVectorizePass();
+Pass *createLoopVectorizePass(bool NoUnrolling = false);
//===----------------------------------------------------------------------===//
//