aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r--include/llvm/Transforms/IPO.h15
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h6
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h13
-rw-r--r--include/llvm/Transforms/Instrumentation.h22
-rw-r--r--include/llvm/Transforms/ObjCARC.h1
-rw-r--r--include/llvm/Transforms/Scalar.h67
-rw-r--r--include/llvm/Transforms/Utils/ASanStackFrameLayout.h64
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h63
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h11
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h48
-rw-r--r--include/llvm/Transforms/Utils/CmpInstAnalysis.h3
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h3
-rw-r--r--include/llvm/Transforms/Utils/CtorUtils.h32
-rw-r--r--include/llvm/Transforms/Utils/IntegerDivision.h43
-rw-r--r--include/llvm/Transforms/Utils/Local.h38
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h41
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h2
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h12
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdaterImpl.h18
-rw-r--r--include/llvm/Transforms/Utils/SimplifyIndVar.h22
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h1
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h110
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h7
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h5
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h33
-rw-r--r--include/llvm/Transforms/Utils/VectorUtils.h195
-rw-r--r--include/llvm/Transforms/Vectorize.h6
27 files changed, 596 insertions, 285 deletions
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 7f51c516b9b5..ce1a7d6a5230 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -34,7 +34,7 @@ ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false);
//===----------------------------------------------------------------------===//
//
-// These functions strips symbols from functions and modules.
+// These functions strips symbols from functions and modules.
// Only debugging information is not stripped.
//
ModulePass *createStripNonDebugSymbolsPass();
@@ -58,40 +58,41 @@ ModulePass *createStripDeadDebugInfoPass();
///
ModulePass *createConstantMergePass();
-
//===----------------------------------------------------------------------===//
/// createGlobalOptimizerPass - This function returns a new pass that optimizes
/// non-address taken internal globals.
///
ModulePass *createGlobalOptimizerPass();
-
//===----------------------------------------------------------------------===//
/// createGlobalDCEPass - This transform is designed to eliminate unreachable
/// internal globals (functions or global variables)
///
ModulePass *createGlobalDCEPass();
-
//===----------------------------------------------------------------------===//
/// createGVExtractionPass - If deleteFn is true, this pass deletes
/// the specified global values. Otherwise, it deletes as much of the module as
/// possible, except for the global values specified.
///
-ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
+ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
deleteFn = false);
//===----------------------------------------------------------------------===//
/// createFunctionInliningPass - Return a new pass object that uses a heuristic
/// to inline direct function calls to small functions.
///
+/// The Threshold can be passed directly, or asked to be computed from the
+/// given optimization and size optimization arguments.
+///
/// The -inline-threshold command line option takes precedence over the
/// threshold given here.
Pass *createFunctionInliningPass();
Pass *createFunctionInliningPass(int Threshold);
+Pass *createFunctionInliningPass(unsigned OptLevel, unsigned SizeOptLevel);
//===----------------------------------------------------------------------===//
-/// createAlwaysInlinerPass - Return a new pass object that inlines only
+/// createAlwaysInlinerPass - Return a new pass object that inlines only
/// functions that are marked as "always_inline".
Pass *createAlwaysInlinerPass();
Pass *createAlwaysInlinerPass(bool InsertLifetime);
@@ -187,7 +188,7 @@ ModulePass *createMergeFunctionsPass();
/// createPartialInliningPass - This pass inlines parts of functions.
///
ModulePass *createPartialInliningPass();
-
+
//===----------------------------------------------------------------------===//
// createMetaRenamerPass - Rename everything with metasyntatic names.
//
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index 43a0ac8cc1f7..6a644ad4a63b 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -36,16 +36,16 @@ struct Inliner : public CallGraphSCCPass {
/// getAnalysisUsage - For this class, we declare that we require and preserve
/// the call graph. If the derived class implements this method, it should
/// always explicitly call the implementation here.
- virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
// Main run interface method, this implements the interface required by the
// Pass class.
- virtual bool runOnSCC(CallGraphSCC &SCC);
+ bool runOnSCC(CallGraphSCC &SCC) override;
using llvm::Pass::doFinalization;
// doFinalization - Remove now-dead linkonce functions at the end of
// processing to avoid breaking the SCC traversal.
- virtual bool doFinalization(CallGraph &CG);
+ bool doFinalization(CallGraph &CG) override;
/// This method returns the value specified by the -inline-threshold value,
/// specified on the command line. This is typically not directly needed.
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 27887749e960..50877d013702 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -55,7 +55,6 @@ using legacy::FunctionPassManager;
/// ...
class PassManagerBuilder {
public:
-
/// Extensions are passed the builder itself (so they can see how it is
/// configured) as well as the pass manager to add stuff to.
typedef void (*ExtensionFn)(const PassManagerBuilder &Builder,
@@ -86,7 +85,12 @@ public:
/// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
/// should not be disabled by O0 optimization level. The passes will be
/// inserted after the inlining pass.
- EP_EnabledOnOptLevel0
+ EP_EnabledOnOptLevel0,
+
+ /// EP_Peephole - This extension point allows adding passes that perform
+ /// peephole optimizations similar to the instruction combiner. These passes
+ /// will be inserted after each instance of the instruction combiner pass.
+ EP_Peephole,
};
/// The Optimization Level - Specify the basic optimization level.
@@ -106,13 +110,14 @@ public:
/// added to the per-module passes.
Pass *Inliner;
+ bool DisableTailCalls;
bool DisableUnitAtATime;
bool DisableUnrollLoops;
bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
- bool LateVectorize;
bool RerollLoops;
+ bool LoadCombine;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
@@ -130,8 +135,8 @@ public:
private:
void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const;
void addInitialAliasAnalysisPasses(PassManagerBase &PM) const;
-public:
+public:
/// populateFunctionPassManager - This fills in the function pass manager,
/// which is expected to be run on each function immediately as it is
/// generated. The idea is to reduce the size of the IR in memory.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 8a1b34e488be..c6a339b0fd22 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/StringRef.h"
-#if defined(__GNUC__) && defined(__linux__)
+#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
inline void *getDFSanArgTLSPtrForJIT() {
extern __thread __attribute__((tls_model("initial-exec")))
void *__dfsan_arg_tls;
@@ -64,27 +64,21 @@ ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
// Insert AddressSanitizer (address sanity checking) instrumentation
-FunctionPass *createAddressSanitizerFunctionPass(
- bool CheckInitOrder = true, bool CheckUseAfterReturn = false,
- bool CheckLifetime = false, StringRef BlacklistFile = StringRef(),
- bool ZeroBaseShadow = false);
-ModulePass *createAddressSanitizerModulePass(
- bool CheckInitOrder = true, StringRef BlacklistFile = StringRef(),
- bool ZeroBaseShadow = false);
+FunctionPass *createAddressSanitizerFunctionPass();
+ModulePass *createAddressSanitizerModulePass();
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
-FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
- StringRef BlacklistFile = StringRef());
+FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0);
// Insert ThreadSanitizer (race detection) instrumentation
-FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
+FunctionPass *createThreadSanitizerPass();
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
- void *(*getArgTLS)() = 0,
- void *(*getRetValTLS)() = 0);
+ void *(*getArgTLS)() = nullptr,
+ void *(*getRetValTLS)() = nullptr);
-#if defined(__GNUC__) && defined(__linux__)
+#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
StringRef()) {
return createDataFlowSanitizerPass(ABIListFile, getDFSanArgTLSPtrForJIT,
diff --git a/include/llvm/Transforms/ObjCARC.h b/include/llvm/Transforms/ObjCARC.h
index b3c19c077eab..1897adc2ffbf 100644
--- a/include/llvm/Transforms/ObjCARC.h
+++ b/include/llvm/Transforms/ObjCARC.h
@@ -46,4 +46,3 @@ Pass *createObjCARCOptPass();
} // End llvm namespace
#endif
-
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 1521c4cff562..413134e51c7a 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -19,6 +19,7 @@
namespace llvm {
+class BasicBlockPass;
class FunctionPass;
class Pass;
class GetElementPtrInst;
@@ -122,7 +123,7 @@ Pass *createLICMPass();
//
Pass *createLoopStrengthReducePass();
-Pass *createGlobalMergePass(const TargetMachine *TM = 0);
+Pass *createGlobalMergePass(const TargetMachine *TM = nullptr);
//===----------------------------------------------------------------------===//
//
@@ -142,6 +143,8 @@ Pass *createLoopInstSimplifyPass();
//
Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
int AllowPartial = -1, int Runtime = -1);
+// Create an unrolling pass for full unrolling only.
+Pass *createSimpleLoopUnrollPass();
//===----------------------------------------------------------------------===//
//
@@ -153,14 +156,14 @@ Pass *createLoopRerollPass();
//
// LoopRotate - This pass is a simple loop rotating pass.
//
-Pass *createLoopRotatePass();
+Pass *createLoopRotatePass(int MaxHeaderSize = -1);
//===----------------------------------------------------------------------===//
//
// LoopIdiom - This pass recognizes and replaces idioms in loops.
//
Pass *createLoopIdiomPass();
-
+
//===----------------------------------------------------------------------===//
//
// PromoteMemoryToRegister - This pass is used to promote memory references to
@@ -199,7 +202,7 @@ FunctionPass *createReassociatePass();
// preds always go to some succ.
//
FunctionPass *createJumpThreadingPass();
-
+
//===----------------------------------------------------------------------===//
//
// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
@@ -262,16 +265,10 @@ extern char &LowerSwitchID;
//===----------------------------------------------------------------------===//
//
-// LowerInvoke - This pass converts invoke and unwind instructions to use sjlj
-// exception handling mechanisms. Note that after this pass runs the CFG is not
-// entirely accurate (exceptional control flow edges are not correct anymore) so
-// only very simple things should be done after the lowerinvoke pass has run
-// (like generation of native code). This should *NOT* be used as a general
-// purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet"
-// lowering pass.
+// LowerInvoke - This pass removes invoke instructions, converting them to call
+// instructions.
//
-FunctionPass *createLowerInvokePass(const TargetMachine *TM = 0,
- bool useExpensiveEHSupport = false);
+FunctionPass *createLowerInvokePass();
extern char &LowerInvokePassID;
//===----------------------------------------------------------------------===//
@@ -288,10 +285,17 @@ extern char &LCSSAID;
// tree.
//
FunctionPass *createEarlyCSEPass();
-
+
+//===----------------------------------------------------------------------===//
+//
+// MergedLoadStoreMotion - This pass merges loads and stores in diamonds. Loads
+// are hoisted into the header, while stores sink into the footer.
+//
+FunctionPass *createMergedLoadStoreMotionPass();
+
//===----------------------------------------------------------------------===//
//
-// GVN - This pass performs global value numbering and redundant load
+// GVN - This pass performs global value numbering and redundant load
// elimination cotemporaneously.
//
FunctionPass *createGVNPass(bool NoLoads = false);
@@ -309,12 +313,12 @@ FunctionPass *createMemCpyOptPass();
// can prove are dead.
//
Pass *createLoopDeletionPass();
-
+
//===----------------------------------------------------------------------===//
//
-// CodeGenPrepare - This pass prepares a function for instruction selection.
+// ConstantHoisting - This pass prepares a function for expensive constants.
//
-FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
+FunctionPass *createConstantHoistingPass();
//===----------------------------------------------------------------------===//
//
@@ -322,7 +326,7 @@ FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
//
FunctionPass *createInstructionNamerPass();
extern char &InstructionNamerID;
-
+
//===----------------------------------------------------------------------===//
//
// Sink - Code Sinking
@@ -348,14 +352,12 @@ Pass *createCorrelatedValuePropagationPass();
FunctionPass *createInstructionSimplifierPass();
extern char &InstructionSimplifierID;
-
//===----------------------------------------------------------------------===//
//
// LowerExpectIntrinsics - Removes llvm.expect intrinsics and creates
// "block_weights" metadata.
FunctionPass *createLowerExpectIntrinsicPass();
-
//===----------------------------------------------------------------------===//
//
// PartiallyInlineLibCalls - Tries to inline the fast path of library
@@ -370,6 +372,29 @@ FunctionPass *createPartiallyInlineLibCallsPass();
FunctionPass *createSampleProfileLoaderPass();
FunctionPass *createSampleProfileLoaderPass(StringRef Name);
+//===----------------------------------------------------------------------===//
+//
+// ScalarizerPass - Converts vector operations into scalar operations
+//
+FunctionPass *createScalarizerPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AddDiscriminators - Add DWARF path discriminators to the IR.
+FunctionPass *createAddDiscriminatorsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SeparateConstOffsetFromGEP - Split GEPs for better CSE
+//
+FunctionPass *createSeparateConstOffsetFromGEPPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoadCombine - Combine loads into bigger loads.
+//
+BasicBlockPass *createLoadCombinePass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/ASanStackFrameLayout.h b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
new file mode 100644
index 000000000000..4e4f02c84ece
--- /dev/null
+++ b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
@@ -0,0 +1,64 @@
+//===- ASanStackFrameLayout.h - ComputeASanStackFrameLayout -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines ComputeASanStackFrameLayout and auxiliary data structs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class AllocaInst;
+
+// These magic constants should be the same as in
+// in asan_internal.h from ASan runtime in compiler-rt.
+static const int kAsanStackLeftRedzoneMagic = 0xf1;
+static const int kAsanStackMidRedzoneMagic = 0xf2;
+static const int kAsanStackRightRedzoneMagic = 0xf3;
+
+// Input/output data struct for ComputeASanStackFrameLayout.
+struct ASanStackVariableDescription {
+ const char *Name; // Name of the variable that will be displayed by asan
+ // if a stack-related bug is reported.
+ uint64_t Size; // Size of the variable in bytes.
+ size_t Alignment; // Alignment of the variable (power of 2).
+ AllocaInst *AI; // The actual AllocaInst.
+ size_t Offset; // Offset from the beginning of the frame;
+ // set by ComputeASanStackFrameLayout.
+};
+
+// Output data struct for ComputeASanStackFrameLayout.
+struct ASanStackFrameLayout {
+ // Frame description, see DescribeAddressIfStack in ASan runtime.
+ SmallString<64> DescriptionString;
+ // The contents of the shadow memory for the stack frame that we need
+ // to set at function entry.
+ SmallVector<uint8_t, 64> ShadowBytes;
+ size_t FrameAlignment; // Alignment for the entire frame.
+ size_t FrameSize; // Size of the frame in bytes.
+};
+
+void ComputeASanStackFrameLayout(
+ // The array of stack variables. The elements may get reordered and changed.
+ SmallVectorImpl<ASanStackVariableDescription> &Vars,
+ // AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64.
+ size_t Granularity,
+ // The minimal size of the left-most redzone (header).
+ // At least 4 pointer sizes, power of 2, and >= Granularity.
+ // The resulting FrameSize should be multiple of MinHeaderSize.
+ size_t MinHeaderSize,
+ // The result is put here.
+ ASanStackFrameLayout *Layout);
+
+} // llvm namespace
+
+#endif // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 65cafe2ec281..bcafda657c2b 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -18,11 +18,12 @@
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
#include "llvm/IR/BasicBlock.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
namespace llvm {
class AliasAnalysis;
+class DominatorTree;
class Instruction;
class MDNode;
class Pass;
@@ -34,23 +35,22 @@ class TerminatorInst;
/// predecessors.
void DeleteDeadBlock(BasicBlock *BB);
-
/// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are
/// any single-entry PHI nodes in it, fold them away. This handles the case
/// when all entries to the PHI nodes in a block are guaranteed equal, such as
/// when the block has exactly one predecessor.
-void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = 0);
+void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = nullptr);
/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
/// is dead. Also recursively delete any operands that become dead as
/// a result. This includes tracing the def-use list from the PHI to see if
/// it is ultimately unused or if it reaches an unused cycle. Return true
/// if any PHIs were deleted.
-bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = 0);
+bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr);
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure.
-bool MergeBlockIntoPredecessor(BasicBlock *BB, Pass *P = 0);
+bool MergeBlockIntoPredecessor(BasicBlock *BB, Pass *P = nullptr);
// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
// with a value, then remove and delete the original instruction.
@@ -89,12 +89,13 @@ void ReplaceInstWithInst(Instruction *From, Instruction *To);
/// to.
///
BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
- Pass *P = 0, bool MergeIdenticalEdges = false,
+ Pass *P = nullptr,
+ bool MergeIdenticalEdges = false,
bool DontDeleteUselessPHIs = false,
bool SplitLandingPads = false);
inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
- Pass *P = 0) {
+ Pass *P = nullptr) {
return SplitCriticalEdge(BB->getTerminator(), SI.getSuccessorIndex(), P);
}
@@ -103,7 +104,8 @@ inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
/// This updates all of the same analyses as the other SplitCriticalEdge
/// function. If P is specified, it updates the analyses
/// described above.
-inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI, Pass *P = 0) {
+inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI,
+ Pass *P = nullptr) {
bool MadeChange = false;
TerminatorInst *TI = (*PI)->getTerminator();
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
@@ -117,7 +119,7 @@ inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI, Pass *P = 0) {
/// an edge between the two blocks. If P is specified, it updates the analyses
/// described above.
inline BasicBlock *SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst,
- Pass *P = 0,
+ Pass *P = nullptr,
bool MergeIdenticalEdges = false,
bool DontDeleteUselessPHIs = false) {
TerminatorInst *TI = Src->getTerminator();
@@ -155,7 +157,7 @@ BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
/// is an exit of a loop with other exits).
///
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock*> Preds,
- const char *Suffix, Pass *P = 0);
+ const char *Suffix, Pass *P = nullptr);
/// SplitLandingPadPredecessors - This method transforms the landing pad,
/// OrigBB, by introducing two new basic blocks into the function. One of those
@@ -183,27 +185,49 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred);
/// SplitBlockAndInsertIfThen - Split the containing block at the
-/// specified instruction - everything before and including Cmp stays
-/// in the old basic block, and everything after Cmp is moved to a
+/// specified instruction - everything before and including SplitBefore stays
+/// in the old basic block, and everything after SplitBefore is moved to a
/// new block. The two blocks are connected by a conditional branch
/// (with value of Cmp being the condition).
/// Before:
/// Head
-/// Cmp
+/// SplitBefore
/// Tail
/// After:
/// Head
-/// Cmp
-/// if (Cmp)
+/// if (Cond)
/// ThenBlock
+/// SplitBefore
/// Tail
///
/// If Unreachable is true, then ThenBlock ends with
/// UnreachableInst, otherwise it branches to Tail.
/// Returns the NewBasicBlock's terminator.
-
-TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
- bool Unreachable, MDNode *BranchWeights = 0);
+///
+/// Updates DT if given.
+TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
+ bool Unreachable,
+ MDNode *BranchWeights = nullptr,
+ DominatorTree *DT = nullptr);
+
+/// SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen,
+/// but also creates the ElseBlock.
+/// Before:
+/// Head
+/// SplitBefore
+/// Tail
+/// After:
+/// Head
+/// if (Cond)
+/// ThenBlock
+/// else
+/// ElseBlock
+/// SplitBefore
+/// Tail
+void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
+ TerminatorInst **ThenTerm,
+ TerminatorInst **ElseTerm,
+ MDNode *BranchWeights = nullptr);
///
/// GetIfCondition - Check whether BB is the merge point of a if-region.
@@ -211,9 +235,8 @@ TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
/// 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);
+ BasicBlock *&IfFalse);
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 181ed071eab1..1e407fb468e1 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -21,7 +21,7 @@ namespace llvm {
class Value;
class DataLayout;
class TargetLibraryInfo;
-
+
/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Value *CastToCStr(Value *V, IRBuilder<> &B);
@@ -83,6 +83,14 @@ namespace llvm {
Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
const AttributeSet &Attrs);
+ /// EmitUnaryFloatFnCall - Emit a call to the binary function named 'Name'
+ /// (e.g. 'fmin'). This function is known to take type matching 'Op1' and
+ /// 'Op2' and return one value with the same type. If 'Op1/Op2' are long
+ /// double, 'l' is added as the suffix of name, if 'Op1/Op2' are float, we
+ /// add a 'f' suffix.
+ Value *EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
+ IRBuilder<> &B, const AttributeSet &Attrs);
+
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
@@ -116,6 +124,7 @@ namespace llvm {
virtual void replaceCall(Value *With) = 0;
virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
bool isString) const = 0;
+
public:
virtual ~SimplifyFortifiedLibCalls();
bool fold(CallInst *CI, const DataLayout *TD, const TargetLibraryInfo *TLI);
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 3ec132937c0d..bdf50ddf5cc6 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -20,8 +20,8 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/ValueMap.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
namespace llvm {
@@ -55,17 +55,16 @@ struct ClonedCodeInfo {
/// ContainsCalls - This is set to true if the cloned code contains a normal
/// call instruction.
bool ContainsCalls;
-
+
/// ContainsDynamicAllocas - This is set to true if the cloned code contains
/// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in
/// the entry block or they are in the entry block but are not a constant
/// size.
bool ContainsDynamicAllocas;
-
+
ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {}
};
-
/// CloneBasicBlock - Return a copy of the specified basic block, but without
/// embedding the block into a particular function. The block returned is an
/// exact copy of the specified basic block, without any remapping having been
@@ -96,8 +95,8 @@ struct ClonedCodeInfo {
///
BasicBlock *CloneBasicBlock(const BasicBlock *BB,
ValueToValueMapTy &VMap,
- const Twine &NameSuffix = "", Function *F = 0,
- ClonedCodeInfo *CodeInfo = 0);
+ const Twine &NameSuffix = "", Function *F = nullptr,
+ ClonedCodeInfo *CodeInfo = nullptr);
/// CloneFunction - Return a copy of the specified function, but without
/// embedding the function into another module. Also, any references specified
@@ -109,12 +108,12 @@ BasicBlock *CloneBasicBlock(const BasicBlock *BB,
/// information about the cloned code if non-null.
///
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
-/// mappings.
+/// mappings, and debug info metadata will not be cloned.
///
Function *CloneFunction(const Function *F,
ValueToValueMapTy &VMap,
bool ModuleLevelChanges,
- ClonedCodeInfo *CodeInfo = 0);
+ ClonedCodeInfo *CodeInfo = nullptr);
/// Clone OldFunc into NewFunc, transforming the old arguments into references
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
@@ -129,10 +128,10 @@ void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap,
bool ModuleLevelChanges,
SmallVectorImpl<ReturnInst*> &Returns,
- const char *NameSuffix = "",
- ClonedCodeInfo *CodeInfo = 0,
- ValueMapTypeRemapper *TypeMapper = 0,
- ValueMaterializer *Materializer = 0);
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = nullptr,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
/// except that it does some simple constant prop and DCE on the fly. The
@@ -149,23 +148,22 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap,
bool ModuleLevelChanges,
SmallVectorImpl<ReturnInst*> &Returns,
- const char *NameSuffix = "",
- ClonedCodeInfo *CodeInfo = 0,
- const DataLayout *TD = 0,
- Instruction *TheCall = 0);
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = nullptr,
+ const DataLayout *DL = nullptr,
+ Instruction *TheCall = nullptr);
-
/// InlineFunctionInfo - This class captures the data input to the
-/// InlineFunction call, and records the auxiliary results produced by it.
+/// InlineFunction call, and records the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *td = 0)
- : CG(cg), TD(td) {}
-
+ explicit InlineFunctionInfo(CallGraph *cg = nullptr, const DataLayout *DL = nullptr)
+ : CG(cg), DL(DL) {}
+
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- const DataLayout *TD;
+ const DataLayout *DL;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
@@ -174,13 +172,13 @@ public:
/// InlinedCalls - InlineFunction fills this in with callsites that were
/// inlined from the callee. This is only filled in if CG is non-null.
SmallVector<WeakVH, 8> InlinedCalls;
-
+
void reset() {
StaticAllocas.clear();
InlinedCalls.clear();
}
};
-
+
/// InlineFunction - This function inlines the called function into the basic
/// block of the caller. This returns false if it is not possible to inline
/// this call. The program is still in a well defined state if this occurs
diff --git a/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
index 488d7a59d329..73c15e42c359 100644
--- a/include/llvm/Transforms/Utils/CmpInstAnalysis.h
+++ b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
@@ -1,4 +1,4 @@
-//===-- CmpInstAnalysis.h - Utils to help fold compare insts ------===//
+//===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -63,4 +63,3 @@ namespace llvm {
} // end namespace llvm
#endif
-
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
index 1122678035b5..6b41e82dac73 100644
--- a/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -66,7 +66,7 @@ namespace llvm {
/// dominates the rest, prepare a code extractor object for pulling this
/// sequence out into its new function. When a DominatorTree is also given,
/// extra checking and transformations are enabled.
- CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = 0,
+ CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
bool AggregateArgs = false);
/// \brief Create a code extractor for a loop body.
@@ -120,7 +120,6 @@ namespace llvm {
BasicBlock *newHeader,
ValueSet &inputs,
ValueSet &outputs);
-
};
}
diff --git a/include/llvm/Transforms/Utils/CtorUtils.h b/include/llvm/Transforms/Utils/CtorUtils.h
new file mode 100644
index 000000000000..81e7b951c252
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CtorUtils.h
@@ -0,0 +1,32 @@
+//===- CtorUtils.h - Helpers for working with global_ctors ------*- 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 functions that are used to process llvm.global_ctors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
+#define LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
+
+#include "llvm/ADT/STLExtras.h"
+
+namespace llvm {
+
+class GlobalVariable;
+class Function;
+class Module;
+
+/// Call "ShouldRemove" for every entry in M's global_ctor list and remove the
+/// entries for which it returns true. Return true if anything changed.
+bool optimizeGlobalCtorsList(Module &M,
+ function_ref<bool(Function *)> ShouldRemove);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h
index 27d3c588b518..0ec3321b9cf8 100644
--- a/include/llvm/Transforms/Utils/IntegerDivision.h
+++ b/include/llvm/Transforms/Utils/IntegerDivision.h
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains an implementation of 32bit integer division for targets
-// that don't have native support. It's largely derived from compiler-rt's
-// implementation of __udivsi3, but hand-tuned for targets that prefer less
-// control flow.
+// This file contains an implementation of 32bit and 64bit scalar integer
+// division for targets that don't have native support. It's largely derived
+// from compiler-rt's implementations of __udivsi3 and __udivmoddi4,
+// but hand-tuned for targets that prefer less control flow.
//
//===----------------------------------------------------------------------===//
@@ -26,9 +26,8 @@ namespace llvm {
/// Generate code to calculate the remainder of two integers, replacing Rem
/// with the generated code. This currently generates code using the udiv
/// expansion, but future work includes generating more specialized code,
- /// e.g. when more information about the operands are known. Currently only
- /// implements 32bit scalar division (due to udiv's limitation), but future
- /// work is removing this limitation.
+ /// e.g. when more information about the operands are known. Implements both
+ /// 32bit and 64bit scalar division.
///
/// @brief Replace Rem with generated code.
bool expandRemainder(BinaryOperator *Rem);
@@ -36,27 +35,39 @@ namespace llvm {
/// Generate code to divide two integers, replacing Div with the generated
/// code. This currently generates code similarly to compiler-rt's
/// implementations, but future work includes generating more specialized code
- /// when more information about the operands are known. Currently only
- /// implements 32bit scalar division, but future work is removing this
- /// limitation.
+ /// when more information about the operands are known. Implements both
+ /// 32bit and 64bit scalar division.
///
/// @brief Replace Div with generated code.
bool expandDivision(BinaryOperator* Div);
/// Generate code to calculate the remainder of two integers, replacing Rem
- /// with the generated code. Uses the above 32bit routine, therefore adequate
- /// for targets with little or no support for less than 32 bit arithmetic.
+ /// with the generated code. Uses ExpandReminder with a 32bit Rem which
+ /// makes it useful for targets with little or no support for less than
+ /// 32 bit arithmetic.
///
/// @brief Replace Rem with generated code.
bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
- /// Generate code to divide two integers, replacing Div with the generated
- /// code. Uses the above 32bit routine, therefore adequate for targets with
- /// little or no support for less than 32 bit arithmetic.
- ///
+ /// Generate code to calculate the remainder of two integers, replacing Rem
+ /// with the generated code. Uses ExpandReminder with a 64bit Rem.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
+
+ /// Generate code to divide two integers, replacing Div with the generated
+ /// code. Uses ExpandDivision with a 32bit Div which makes it useful for
+ /// targets with little or no support for less than 32 bit arithmetic.
+ ///
/// @brief Replace Rem with generated code.
bool expandDivisionUpTo32Bits(BinaryOperator *Div);
+ /// Generate code to divide two integers, replacing Div with the generated
+ /// code. Uses ExpandDivision with a 64bit Div.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandDivisionUpTo64Bits(BinaryOperator *Div);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 5586c155bb11..c0c690664a9c 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -16,9 +16,9 @@
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
namespace llvm {
@@ -55,7 +55,7 @@ template<typename T> class SmallVectorImpl;
/// conditions and indirectbr addresses this might make dead if
/// DeleteDeadConditions is true.
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
- const TargetLibraryInfo *TLI = 0);
+ const TargetLibraryInfo *TLI = nullptr);
//===----------------------------------------------------------------------===//
// Local dead code elimination.
@@ -64,30 +64,31 @@ bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
/// isInstructionTriviallyDead - Return true if the result produced by the
/// instruction is not used, and the instruction has no side effects.
///
-bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0);
+bool isInstructionTriviallyDead(Instruction *I,
+ const TargetLibraryInfo *TLI = nullptr);
/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
/// trivially dead instruction, delete it. If that makes any of its operands
/// trivially dead, delete them too, recursively. Return true if any
/// instructions were deleted.
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V,
- const TargetLibraryInfo *TLI=0);
+ const TargetLibraryInfo *TLI = nullptr);
/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
/// dead PHI node, due to being a def-use chain of single-use nodes that
/// either forms a cycle or is terminated by a trivially dead instruction,
/// delete it. If that makes any of its operands trivially dead, delete them
/// too, recursively. Return true if a change was made.
-bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
-
+bool RecursivelyDeleteDeadPHINode(PHINode *PN,
+ const TargetLibraryInfo *TLI = nullptr);
/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
/// simplify any instructions in it and recursively delete dead instructions.
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
- const TargetLibraryInfo *TLI = 0);
+bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
+ const TargetLibraryInfo *TLI = nullptr);
//===----------------------------------------------------------------------===//
// Control Flow Graph Restructuring.
@@ -105,16 +106,14 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the 'and' to 0.
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- DataLayout *TD = 0);
-
+ DataLayout *TD = nullptr);
/// 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);
-
+void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = nullptr);
/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an
/// unconditional branch, and contains no instructions other than PHI nodes,
@@ -137,19 +136,19 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// the basic block that was pointed to.
///
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- const DataLayout *TD = 0);
+ const DataLayout *TD = nullptr);
/// 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);
+bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
/// 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
/// destination.
-bool FoldBranchToCommonDest(BranchInst *BI);
+bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr);
/// DemoteRegToStack - This function takes a virtual register computed by an
/// Instruction and replaces it with a slot in the stack frame, allocated via
@@ -159,22 +158,23 @@ bool FoldBranchToCommonDest(BranchInst *BI);
///
AllocaInst *DemoteRegToStack(Instruction &X,
bool VolatileLoads = false,
- Instruction *AllocaPoint = 0);
+ Instruction *AllocaPoint = nullptr);
/// 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.
-AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
+AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
/// we can determine, return it, otherwise return 0. If PrefAlign is specified,
/// and it is more than the alignment of the ultimate object, see if we can
/// increase the alignment of the ultimate object, making this check succeed.
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const DataLayout *TD = 0);
+ const DataLayout *TD = nullptr);
/// getKnownAlignment - Try to infer an alignment for the specified pointer.
-static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) {
+static inline unsigned getKnownAlignment(Value *V,
+ const DataLayout *TD = nullptr) {
return getOrEnforceKnownAlignment(V, 0, TD);
}
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 4745eba079ae..7e3a74aae93c 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -15,12 +15,51 @@
#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
namespace llvm {
-
+class AliasAnalysis;
+class BasicBlock;
+class DataLayout;
+class DominatorTree;
class Loop;
+class LoopInfo;
class Pass;
+class ScalarEvolution;
BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
+/// \brief Simplify each loop in a loop nest recursively.
+///
+/// This takes a potentially un-simplified loop L (and its children) and turns
+/// it into a simplified loop nest with preheaders and single backedges. It
+/// will optionally update \c AliasAnalysis and \c ScalarEvolution analyses if
+/// passed into it.
+bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
+ AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr,
+ const DataLayout *DL = nullptr);
+
+/// \brief Put loop into LCSSA form.
+///
+/// Looks at all instructions in the loop which have uses outside of the
+/// current loop. For each, an LCSSA PHI node is inserted and the uses outside
+/// the loop are rewritten to use this node.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = nullptr);
+
+/// \brief Put a loop nest into LCSSA form.
+///
+/// This recursively forms LCSSA for a loop nest.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSARecursively(Loop &L, DominatorTree &DT,
+ ScalarEvolution *SE = nullptr);
}
#endif
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 22f46e5fc963..c83fedb0e2ca 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -41,7 +41,7 @@ bool isAllocaPromotable(const AllocaInst *AI);
/// If AST is specified, the specified tracker is updated to reflect changes
/// made to the IR.
void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
- AliasSetTracker *AST = 0);
+ AliasSetTracker *AST = nullptr);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index 0c0e5de584fd..7874a5fd8119 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -56,7 +56,7 @@ private:
public:
/// If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
- explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = 0);
+ explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = nullptr);
~SSAUpdater();
/// \brief Reset this object to get ready for a new set of SSA updates with
@@ -133,31 +133,31 @@ private:
class LoadAndStorePromoter {
protected:
SSAUpdater &SSA;
+
public:
LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts,
SSAUpdater &S, StringRef Name = StringRef());
virtual ~LoadAndStorePromoter() {}
-
+
/// \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;
-
-
+
/// \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;
-
+
/// \brief This hook is invoked after all the stores are found and inserted as
/// available values.
virtual void doExtraRewritesBeforeFinalDeletion() const {
}
-
+
/// \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 {
diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
index a9adbd73c152..ed0841c46c27 100644
--- a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
+++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -17,12 +17,14 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
+#define DEBUG_TYPE "ssaupdater"
+
class CastInst;
class PHINode;
template<typename T> class SSAUpdaterTraits;
@@ -52,8 +54,8 @@ private:
PhiT *PHITag; // Marker for existing PHIs that match.
BBInfo(BlkT *ThisBB, ValT V)
- : BB(ThisBB), AvailableVal(V), DefBB(V ? this : 0), BlkNum(0), IDom(0),
- NumPreds(0), Preds(0), PHITag(0) { }
+ : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr), BlkNum(0),
+ IDom(nullptr), NumPreds(0), Preds(nullptr), PHITag(nullptr) {}
};
typedef DenseMap<BlkT*, ValT> AvailableValsTy;
@@ -115,7 +117,7 @@ public:
Traits::FindPredecessorBlocks(Info->BB, &Preds);
Info->NumPreds = Preds.size();
if (Info->NumPreds == 0)
- Info->Preds = 0;
+ Info->Preds = nullptr;
else
Info->Preds = static_cast<BBInfo**>
(Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
@@ -148,7 +150,7 @@ public:
// Now that we know what blocks are backwards-reachable from the starting
// block, do a forward depth-first traversal to assign postorder numbers
// to those blocks.
- BBInfo *PseudoEntry = new (Allocator) BBInfo(0, 0);
+ BBInfo *PseudoEntry = new (Allocator) BBInfo(nullptr, 0);
unsigned BlkNum = 1;
// Initialize the worklist with the roots from the backward traversal.
@@ -231,7 +233,7 @@ public:
for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
E = BlockList->rend(); I != E; ++I) {
BBInfo *Info = *I;
- BBInfo *NewIDom = 0;
+ BBInfo *NewIDom = nullptr;
// Iterate through the block's predecessors.
for (unsigned p = 0; p != Info->NumPreds; ++p) {
@@ -386,7 +388,7 @@ public:
// Match failed: clear all the PHITag values.
for (typename BlockListTy::iterator I = BlockList->begin(),
E = BlockList->end(); I != E; ++I)
- (*I)->PHITag = 0;
+ (*I)->PHITag = nullptr;
}
}
@@ -451,6 +453,8 @@ public:
}
};
+#undef DEBUG_TYPE // "ssaupdater"
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 7e97e218fb0b..dcb1d67cbf75 100644
--- a/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -16,12 +16,13 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class CastInst;
+class DominatorTree;
class IVUsers;
class Loop;
class LPPassManager;
@@ -31,16 +32,33 @@ class ScalarEvolution;
/// Interface for visiting interesting IV users that are recognized but not
/// simplified by this utility.
class IVVisitor {
+protected:
+ const DominatorTree *DT;
+ bool ShouldSplitOverflowIntrinsics;
+
virtual void anchor();
+
public:
+ IVVisitor(): DT(nullptr), ShouldSplitOverflowIntrinsics(false) {}
virtual ~IVVisitor() {}
+
+ const DominatorTree *getDomTree() const { return DT; }
+
+ bool shouldSplitOverflowInstrinsics() const {
+ return ShouldSplitOverflowIntrinsics;
+ }
+ void setSplitOverflowIntrinsics() {
+ ShouldSplitOverflowIntrinsics = true;
+ assert(DT && "Splitting overflow intrinsics requires a DomTree.");
+ }
+
virtual void visitCast(CastInst *Cast) = 0;
};
/// simplifyUsersOfIV - Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM,
- SmallVectorImpl<WeakVH> &Dead, IVVisitor *V = NULL);
+ SmallVectorImpl<WeakVH> &Dead, IVVisitor *V = nullptr);
/// SimplifyLoopIVs - Simplify users of induction variables within this
/// loop. This does not actually change or add IVs.
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 6bb81be2fd5f..a2a5f9a45601 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -30,6 +30,7 @@ namespace llvm {
/// Impl - A pointer to the actual implementation of the library call
/// simplifier.
LibCallSimplifierImpl *Impl;
+
public:
LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
bool UnsafeFPShrink);
diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h
deleted file mode 100644
index 34c28fc1cafe..000000000000
--- a/include/llvm/Transforms/Utils/SpecialCaseList.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- 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 933c85c51609..7ac2572f9af3 100644
--- a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -24,15 +24,16 @@ namespace llvm {
struct UnifyFunctionExitNodes : public FunctionPass {
BasicBlock *ReturnBlock, *UnwindBlock, *UnreachableBlock;
+
public:
static char ID; // Pass identification, replacement for typeid
UnifyFunctionExitNodes() : FunctionPass(ID),
- ReturnBlock(0), UnwindBlock(0) {
+ ReturnBlock(nullptr), UnwindBlock(nullptr) {
initializeUnifyFunctionExitNodesPass(*PassRegistry::getPassRegistry());
}
// We can preserve non-critical-edgeness when we unify function exit nodes
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
// getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistent)
// return, unwind, or unreachable basic blocks in the CFG.
@@ -41,7 +42,7 @@ public:
BasicBlock *getUnwindBlock() const { return UnwindBlock; }
BasicBlock *getUnreachableBlock() const { return UnreachableBlock; }
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
};
Pass *createUnifyFunctionExitNodesPass();
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index f175e8371e79..aaadd7d48bdc 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -21,13 +21,14 @@ namespace llvm {
class Loop;
class LoopInfo;
class LPPassManager;
+class Pass;
bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
- unsigned TripMultiple, LoopInfo* LI, LPPassManager* LPM);
+ unsigned TripMultiple, LoopInfo *LI, Pass *PP,
+ LPPassManager *LPM);
bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
LPPassManager* LPM);
-
}
#endif
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index d56ac07690fd..5774763575d3 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
-#include "llvm/ADT/ValueMap.h"
+#include "llvm/IR/ValueMap.h"
namespace llvm {
class Value;
@@ -28,7 +28,7 @@ namespace llvm {
virtual void anchor(); // Out of line method.
public:
virtual ~ValueMapTypeRemapper() {}
-
+
/// remapType - The client should implement this method if they want to
/// remap types while mapping values.
virtual Type *remapType(Type *SrcTy) = 0;
@@ -46,53 +46,52 @@ namespace llvm {
/// lazily.
virtual Value *materializeValueFor(Value *V) = 0;
};
-
+
/// RemapFlags - These are flags that the value mapping APIs allow.
enum RemapFlags {
RF_None = 0,
-
+
/// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that
/// only local values within a function (such as an instruction or argument)
/// are mapped, not global values like functions and global metadata.
RF_NoModuleLevelChanges = 1,
-
+
/// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores
/// entries that are not in the value map. If it is unset, it aborts if an
/// operand is asked to be remapped which doesn't exist in the mapping.
RF_IgnoreMissingEntries = 2
};
-
+
static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
return RemapFlags(unsigned(LHS)|unsigned(RHS));
}
-
+
Value *MapValue(const Value *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0,
- ValueMaterializer *Materializer = 0);
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
- ValueMapTypeRemapper *TypeMapper = 0,
- ValueMaterializer *Materializer = 0);
-
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
+
/// 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,
- ValueMaterializer *Materializer = 0) {
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr) {
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,
- ValueMaterializer *Materializer = 0) {
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr) {
return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper,
Materializer));
}
-
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h
new file mode 100644
index 000000000000..44a7149eee98
--- /dev/null
+++ b/include/llvm/Transforms/Utils/VectorUtils.h
@@ -0,0 +1,195 @@
+//===- llvm/Transforms/Utils/VectorUtils.h - Vector 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 vectorizer utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
+#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+
+namespace llvm {
+
+/// \brief Identify if the intrinsic is trivially vectorizable.
+///
+/// This method returns true if the intrinsic's argument types are all
+/// scalars for the scalar form of the intrinsic and all vectors for
+/// the vector form of the intrinsic.
+static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
+ switch (ID) {
+ case Intrinsic::sqrt:
+ case Intrinsic::sin:
+ case Intrinsic::cos:
+ case Intrinsic::exp:
+ case Intrinsic::exp2:
+ case Intrinsic::log:
+ case Intrinsic::log10:
+ case Intrinsic::log2:
+ case Intrinsic::fabs:
+ case Intrinsic::copysign:
+ case Intrinsic::floor:
+ case Intrinsic::ceil:
+ case Intrinsic::trunc:
+ case Intrinsic::rint:
+ case Intrinsic::nearbyint:
+ case Intrinsic::round:
+ case Intrinsic::bswap:
+ case Intrinsic::ctpop:
+ case Intrinsic::pow:
+ case Intrinsic::fma:
+ case Intrinsic::fmuladd:
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ case Intrinsic::powi:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
+ unsigned ScalarOpdIdx) {
+ switch (ID) {
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ case Intrinsic::powi:
+ return (ScalarOpdIdx == 1);
+ default:
+ return false;
+ }
+}
+
+static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
+ Intrinsic::ID ValidIntrinsicID) {
+ if (I.getNumArgOperands() != 1 ||
+ !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
+ I.getType() != I.getArgOperand(0)->getType() ||
+ !I.onlyReadsMemory())
+ return Intrinsic::not_intrinsic;
+
+ return ValidIntrinsicID;
+}
+
+static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
+ Intrinsic::ID ValidIntrinsicID) {
+ if (I.getNumArgOperands() != 2 ||
+ !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
+ !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
+ I.getType() != I.getArgOperand(0)->getType() ||
+ I.getType() != I.getArgOperand(1)->getType() ||
+ !I.onlyReadsMemory())
+ return Intrinsic::not_intrinsic;
+
+ return ValidIntrinsicID;
+}
+
+static Intrinsic::ID
+getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
+ // If we have an intrinsic call, check if it is trivially vectorizable.
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
+ Intrinsic::ID ID = II->getIntrinsicID();
+ if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
+ ID == Intrinsic::lifetime_end)
+ return ID;
+ else
+ return Intrinsic::not_intrinsic;
+ }
+
+ if (!TLI)
+ return Intrinsic::not_intrinsic;
+
+ LibFunc::Func Func;
+ Function *F = CI->getCalledFunction();
+ // We're going to make assumptions on the semantics of the functions, check
+ // that the target knows that it's available in this environment and it does
+ // not have local linkage.
+ if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
+ return Intrinsic::not_intrinsic;
+
+ // Otherwise check if we have a call to a function that can be turned into a
+ // vector intrinsic.
+ switch (Func) {
+ default:
+ break;
+ case LibFunc::sin:
+ case LibFunc::sinf:
+ case LibFunc::sinl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::sin);
+ case LibFunc::cos:
+ case LibFunc::cosf:
+ case LibFunc::cosl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::cos);
+ case LibFunc::exp:
+ case LibFunc::expf:
+ case LibFunc::expl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::exp);
+ case LibFunc::exp2:
+ case LibFunc::exp2f:
+ case LibFunc::exp2l:
+ return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
+ case LibFunc::log:
+ case LibFunc::logf:
+ case LibFunc::logl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::log);
+ case LibFunc::log10:
+ case LibFunc::log10f:
+ case LibFunc::log10l:
+ return checkUnaryFloatSignature(*CI, Intrinsic::log10);
+ case LibFunc::log2:
+ case LibFunc::log2f:
+ case LibFunc::log2l:
+ return checkUnaryFloatSignature(*CI, Intrinsic::log2);
+ case LibFunc::fabs:
+ case LibFunc::fabsf:
+ case LibFunc::fabsl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
+ case LibFunc::copysign:
+ case LibFunc::copysignf:
+ case LibFunc::copysignl:
+ return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
+ case LibFunc::floor:
+ case LibFunc::floorf:
+ case LibFunc::floorl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::floor);
+ case LibFunc::ceil:
+ case LibFunc::ceilf:
+ case LibFunc::ceill:
+ return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
+ case LibFunc::trunc:
+ case LibFunc::truncf:
+ case LibFunc::truncl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
+ case LibFunc::rint:
+ case LibFunc::rintf:
+ case LibFunc::rintl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::rint);
+ case LibFunc::nearbyint:
+ case LibFunc::nearbyintf:
+ case LibFunc::nearbyintl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
+ case LibFunc::round:
+ case LibFunc::roundf:
+ case LibFunc::roundl:
+ return checkUnaryFloatSignature(*CI, Intrinsic::round);
+ case LibFunc::pow:
+ case LibFunc::powf:
+ case LibFunc::powl:
+ return checkBinaryFloatSignature(*CI, Intrinsic::pow);
+ }
+
+ return Intrinsic::not_intrinsic;
+}
+
+} // llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 823c5fba745e..aec3993d68fc 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -47,6 +47,9 @@ struct VectorizeConfig {
/// @brief Vectorize floating-point math intrinsics.
bool VectorizeMath;
+ /// @brief Vectorize bit intrinsics.
+ bool VectorizeBitManipulations;
+
/// @brief Vectorize the fused-multiply-add intrinsic.
bool VectorizeFMA;
@@ -114,7 +117,8 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
//
// LoopVectorize - Create a loop vectorization pass.
//
-Pass *createLoopVectorizePass(bool NoUnrolling = false);
+Pass *createLoopVectorizePass(bool NoUnrolling = false,
+ bool AlwaysVectorize = true);
//===----------------------------------------------------------------------===//
//