summaryrefslogtreecommitdiff
path: root/include/llvm/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h16
-rw-r--r--include/llvm/Transforms/Instrumentation.h46
-rw-r--r--include/llvm/Transforms/Scalar.h18
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h5
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h14
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h11
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h4
-rw-r--r--include/llvm/Transforms/Utils/CtorUtils.h4
-rw-r--r--include/llvm/Transforms/Utils/Local.h25
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h9
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h4
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h4
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h175
-rw-r--r--include/llvm/Transforms/Utils/SymbolRewriter.h155
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h4
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h3
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h21
-rw-r--r--include/llvm/Transforms/Utils/VectorUtils.h14
18 files changed, 414 insertions, 118 deletions
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 50877d013702..b1426b4f45ca 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -18,16 +18,17 @@
#include <vector>
namespace llvm {
-class TargetLibraryInfo;
class Pass;
+class TargetLibraryInfo;
+class TargetMachine;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
-class PassManagerBase;
class FunctionPassManager;
+class PassManagerBase;
}
-using legacy::PassManagerBase;
using legacy::FunctionPassManager;
+using legacy::PassManagerBase;
/// PassManagerBuilder - This class is used to set up a standard optimization
/// sequence for languages like C and C++, allowing some APIs to customize the
@@ -118,6 +119,11 @@ public:
bool LoopVectorize;
bool RerollLoops;
bool LoadCombine;
+ bool DisableGVNLoadPRE;
+ bool VerifyInput;
+ bool VerifyOutput;
+ bool StripDebug;
+ bool MergeFunctions;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
@@ -135,6 +141,7 @@ public:
private:
void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const;
void addInitialAliasAnalysisPasses(PassManagerBase &PM) const;
+ void addLTOOptimizationPasses(PassManagerBase &PM);
public:
/// populateFunctionPassManager - This fills in the function pass manager,
@@ -144,8 +151,7 @@ public:
/// populateModulePassManager - This sets up the primary pass manager.
void populateModulePassManager(PassManagerBase &MPM);
- void populateLTOPassManager(PassManagerBase &PM, bool Internalize,
- bool RunInliner, bool DisableGVNLoadPRE = false);
+ void populateLTOPassManager(PassManagerBase &PM, TargetMachine *TM = nullptr);
};
/// Registers a function for adding a standard set of passes. This should be
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index c6a339b0fd22..24e3ef783ee6 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -63,6 +63,18 @@ struct GCOVOptions {
ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
+/// Options for the frontend instrumentation based profiling pass.
+struct InstrProfOptions {
+ InstrProfOptions() : NoRedZone(false) {}
+
+ // Add the 'noredzone' attribute to added runtime library calls.
+ bool NoRedZone;
+};
+
+/// Insert frontend instrumentation based profiling.
+ModulePass *createInstrProfilingPass(
+ const InstrProfOptions &Options = InstrProfOptions());
+
// Insert AddressSanitizer (address sanity checking) instrumentation
FunctionPass *createAddressSanitizerFunctionPass();
ModulePass *createAddressSanitizerModulePass();
@@ -78,6 +90,9 @@ ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
void *(*getArgTLS)() = nullptr,
void *(*getRetValTLS)() = nullptr);
+// Insert SanitizerCoverage instrumentation.
+ModulePass *createSanitizerCoverageModulePass(int CoverageLevel);
+
#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
StringRef()) {
@@ -90,37 +105,6 @@ inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
// 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 413134e51c7a..5dcd89948759 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -36,6 +36,13 @@ FunctionPass *createConstantPropagationPass();
//===----------------------------------------------------------------------===//
//
+// AlignmentFromAssumptions - Use assume intrinsics to set load/store
+// alignments.
+//
+FunctionPass *createAlignmentFromAssumptionsPass();
+
+//===----------------------------------------------------------------------===//
+//
// SCCP - Sparse conditional constant propagation.
//
FunctionPass *createSCCPPass();
@@ -199,16 +206,17 @@ FunctionPass *createReassociatePass();
//===----------------------------------------------------------------------===//
//
// JumpThreading - Thread control through mult-pred/multi-succ blocks where some
-// preds always go to some succ.
+// preds always go to some succ. Thresholds other than minus one override the
+// internal BB duplication default threshold.
//
-FunctionPass *createJumpThreadingPass();
+FunctionPass *createJumpThreadingPass(int Threshold = -1);
//===----------------------------------------------------------------------===//
//
// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
// simplify terminator instructions, etc...
//
-FunctionPass *createCFGSimplificationPass();
+FunctionPass *createCFGSimplificationPass(int Threshold = -1);
//===----------------------------------------------------------------------===//
//
@@ -387,7 +395,9 @@ FunctionPass *createAddDiscriminatorsPass();
//
// SeparateConstOffsetFromGEP - Split GEPs for better CSE
//
-FunctionPass *createSeparateConstOffsetFromGEPPass();
+FunctionPass *
+createSeparateConstOffsetFromGEPPass(const TargetMachine *TM = nullptr,
+ bool LowerGEP = false);
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index bcafda657c2b..19acf5b2db83 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -133,6 +133,11 @@ inline BasicBlock *SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst,
}
}
+// SplitAllCriticalEdges - Loop over all of the edges in the CFG,
+// breaking critical edges as they are found. Pass P must not be NULL.
+// Returns the number of broken edges.
+unsigned SplitAllCriticalEdges(Function &F, Pass *P);
+
/// SplitEdge - Split the edge connecting specified block. Pass P must
/// not be NULL.
BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P);
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 1e407fb468e1..6387c166ec71 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -115,20 +115,6 @@ namespace llvm {
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
const DataLayout *TD, const TargetLibraryInfo *TLI);
-
- /// SimplifyFortifiedLibCalls - Helper class for folding checked library
- /// calls (e.g. __strcpy_chk) into their unchecked counterparts.
- class SimplifyFortifiedLibCalls {
- protected:
- CallInst *CI;
- 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);
- };
}
#endif
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index bdf50ddf5cc6..6584abe822d8 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -43,6 +43,8 @@ class DataLayout;
class Loop;
class LoopInfo;
class AllocaInst;
+class AliasAnalysis;
+class AssumptionCacheTracker;
/// CloneModule - Return an exact copy of the specified module
///
@@ -157,13 +159,18 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
/// InlineFunction call, and records the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = nullptr, const DataLayout *DL = nullptr)
- : CG(cg), DL(DL) {}
+ explicit InlineFunctionInfo(CallGraph *cg = nullptr,
+ const DataLayout *DL = nullptr,
+ AliasAnalysis *AA = nullptr,
+ AssumptionCacheTracker *ACT = nullptr)
+ : CG(cg), DL(DL), AA(AA), ACT(ACT) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
const DataLayout *DL;
+ AliasAnalysis *AA;
+ AssumptionCacheTracker *ACT;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
index 6b41e82dac73..3a96d955cac2 100644
--- a/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
-#define LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+#ifndef LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H
+#define LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SetVector.h"
diff --git a/include/llvm/Transforms/Utils/CtorUtils.h b/include/llvm/Transforms/Utils/CtorUtils.h
index 81e7b951c252..63e564dcb87a 100644
--- a/include/llvm/Transforms/Utils/CtorUtils.h
+++ b/include/llvm/Transforms/Utils/CtorUtils.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
-#define LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
+#ifndef LLVM_TRANSFORMS_UTILS_CTORUTILS_H
+#define LLVM_TRANSFORMS_UTILS_CTORUTILS_H
#include "llvm/ADT/STLExtras.h"
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index c0c690664a9c..14844117f44f 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -34,12 +34,14 @@ class Value;
class Pass;
class PHINode;
class AllocaInst;
+class AssumptionCache;
class ConstantExpr;
class DataLayout;
class TargetLibraryInfo;
class TargetTransformInfo;
class DIBuilder;
class AliasAnalysis;
+class DominatorTree;
template<typename T> class SmallVectorImpl;
@@ -136,7 +138,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// the basic block that was pointed to.
///
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- const DataLayout *TD = nullptr);
+ unsigned BonusInstThreshold, const DataLayout *TD = nullptr,
+ AssumptionCache *AC = nullptr);
/// FlatternCFG - This function is used to flatten a CFG. For
/// example, it uses parallel-and and parallel-or mode to collapse
@@ -148,7 +151,8 @@ bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
/// 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, const DataLayout *DL = nullptr);
+bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr,
+ unsigned BonusInstThreshold = 1);
/// DemoteRegToStack - This function takes a virtual register computed by an
/// Instruction and replaces it with a slot in the stack frame, allocated via
@@ -170,12 +174,18 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
/// 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 = nullptr);
+ const DataLayout *TD = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr);
/// getKnownAlignment - Try to infer an alignment for the specified pointer.
static inline unsigned getKnownAlignment(Value *V,
- const DataLayout *TD = nullptr) {
- return getOrEnforceKnownAlignment(V, 0, TD);
+ const DataLayout *TD = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr) {
+ return getOrEnforceKnownAlignment(V, 0, TD, AC, CxtI, DT);
}
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
@@ -275,6 +285,11 @@ bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
/// Returns true if any basic block was removed.
bool removeUnreachableBlocks(Function &F);
+/// \brief Combine the metadata of two instructions so that K can replace J
+///
+/// Metadata not listed as known via KnownIDs is removed
+void combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsigned> KnownIDs);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 7e3a74aae93c..f315adc49d15 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -16,6 +16,7 @@
namespace llvm {
class AliasAnalysis;
+class AssumptionCache;
class BasicBlock;
class DataLayout;
class DominatorTree;
@@ -34,7 +35,8 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
/// passed into it.
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr,
- const DataLayout *DL = nullptr);
+ const DataLayout *DL = nullptr,
+ AssumptionCache *AC = nullptr);
/// \brief Put loop into LCSSA form.
///
@@ -47,7 +49,8 @@ bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
/// 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);
+bool formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI,
+ ScalarEvolution *SE = nullptr);
/// \brief Put a loop nest into LCSSA form.
///
@@ -58,7 +61,7 @@ bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = nullptr);
/// 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,
+bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
ScalarEvolution *SE = nullptr);
}
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index 98a19ed426ac..16904f16e369 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -20,7 +20,7 @@ class Module;
class Function;
class GlobalValue;
class GlobalVariable;
-template <class PtrType, unsigned SmallSize> class SmallPtrSet;
+template <class PtrType> class SmallPtrSetImpl;
/// 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
@@ -34,7 +34,7 @@ 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,
+ SmallPtrSetImpl<GlobalValue *> &Set,
bool CompilerUsed);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index c83fedb0e2ca..d0602bf47c92 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -22,6 +22,7 @@ namespace llvm {
class AllocaInst;
class DominatorTree;
class AliasSetTracker;
+class AssumptionCache;
/// \brief Return true if this alloca is legal for promotion.
///
@@ -41,7 +42,8 @@ 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 = nullptr);
+ AliasSetTracker *AST = nullptr,
+ AssumptionCache *AC = nullptr);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index a2a5f9a45601..d2f096fd1efd 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -15,40 +15,149 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/IRBuilder.h"
+
namespace llvm {
- class Value;
- class CallInst;
- class DataLayout;
- class Instruction;
- class TargetLibraryInfo;
- class LibCallSimplifierImpl;
-
- /// LibCallSimplifier - This class implements a collection of optimizations
- /// that replace well formed calls to library functions with a more optimal
- /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'.
- class LibCallSimplifier {
- /// Impl - A pointer to the actual implementation of the library call
- /// simplifier.
- LibCallSimplifierImpl *Impl;
-
- public:
- LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
- bool UnsafeFPShrink);
- virtual ~LibCallSimplifier();
-
- /// optimizeCall - Take the given call instruction and return a more
- /// optimal value to replace the instruction with or 0 if a more
- /// optimal form can't be found. Note that the returned value may
- /// be equal to the instruction being optimized. In this case all
- /// other instructions that use the given instruction were modified
- /// and the given instruction is dead.
- Value *optimizeCall(CallInst *CI);
-
- /// replaceAllUsesWith - This method is used when the library call
- /// simplifier needs to replace instructions other than the library
- /// call being modified.
- virtual void replaceAllUsesWith(Instruction *I, Value *With) const;
- };
+class Value;
+class CallInst;
+class DataLayout;
+class Instruction;
+class TargetLibraryInfo;
+class BasicBlock;
+class Function;
+
+/// \brief This class implements simplifications for calls to fortified library
+/// functions (__st*cpy_chk, __memcpy_chk, __memmove_chk, __memset_chk), to,
+/// when possible, replace them with their non-checking counterparts.
+/// Other optimizations can also be done, but it's possible to disable them and
+/// only simplify needless use of the checking versions (when the object size
+/// is unknown) by passing true for OnlyLowerUnknownSize.
+class FortifiedLibCallSimplifier {
+private:
+ const DataLayout *DL;
+ const TargetLibraryInfo *TLI;
+ bool OnlyLowerUnknownSize;
+
+public:
+ FortifiedLibCallSimplifier(const DataLayout *DL, const TargetLibraryInfo *TLI,
+ bool OnlyLowerUnknownSize = false);
+
+ /// \brief Take the given call instruction and return a more
+ /// optimal value to replace the instruction with or 0 if a more
+ /// optimal form can't be found.
+ /// The call must not be an indirect call.
+ Value *optimizeCall(CallInst *CI);
+
+private:
+ Value *optimizeMemCpyChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemMoveChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrCpyChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrNCpyChk(CallInst *CI, IRBuilder<> &B);
+
+ /// \brief Checks whether the call \p CI to a fortified libcall is foldable
+ /// to the non-fortified version.
+ bool isFortifiedCallFoldable(CallInst *CI, unsigned ObjSizeOp,
+ unsigned SizeOp, bool isString);
+};
+
+/// LibCallSimplifier - This class implements a collection of optimizations
+/// that replace well formed calls to library functions with a more optimal
+/// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'.
+class LibCallSimplifier {
+private:
+ FortifiedLibCallSimplifier FortifiedSimplifier;
+ const DataLayout *DL;
+ const TargetLibraryInfo *TLI;
+ bool UnsafeFPShrink;
+
+protected:
+ ~LibCallSimplifier() {}
+
+public:
+ LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+ /// optimizeCall - Take the given call instruction and return a more
+ /// optimal value to replace the instruction with or 0 if a more
+ /// optimal form can't be found. Note that the returned value may
+ /// be equal to the instruction being optimized. In this case all
+ /// other instructions that use the given instruction were modified
+ /// and the given instruction is dead.
+ /// The call must not be an indirect call.
+ Value *optimizeCall(CallInst *CI);
+
+ /// replaceAllUsesWith - This method is used when the library call
+ /// simplifier needs to replace instructions other than the library
+ /// call being modified.
+ virtual void replaceAllUsesWith(Instruction *I, Value *With) const;
+
+private:
+ // String and Memory Library Call Optimizations
+ Value *optimizeStrCat(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrNCat(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrChr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrRChr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrCmp(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrNCmp(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrCpy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStpCpy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrNCpy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrLen(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrPBrk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrTo(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrSpn(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B);
+ // Wrapper for all String/Memory Library Call Optimizations
+ Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
+
+ // Math Library Optimizations
+ Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B, bool CheckRetType);
+ Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
+ Value *optimizePow(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFabs(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
+
+ // Integer Library Call Optimizations
+ Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeAbs(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeIsDigit(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeIsAscii(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeToAscii(CallInst *CI, IRBuilder<> &B);
+
+ // Formatting and IO Library Call Optimizations
+ Value *optimizeErrorReporting(CallInst *CI, IRBuilder<> &B,
+ int StreamArg = -1);
+ Value *optimizePrintF(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeSPrintF(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFPrintF(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFWrite(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFPuts(CallInst *CI, IRBuilder<> &B);
+ Value *optimizePuts(CallInst *CI, IRBuilder<> &B);
+
+ // Helper methods
+ Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B);
+ void classifyArgUse(Value *Val, BasicBlock *BB, bool IsFloat,
+ SmallVectorImpl<CallInst *> &SinCalls,
+ SmallVectorImpl<CallInst *> &CosCalls,
+ SmallVectorImpl<CallInst *> &SinCosCalls);
+ void replaceTrigInsts(SmallVectorImpl<CallInst *> &Calls, Value *Res);
+ Value *optimizePrintFString(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeSPrintFString(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFPrintFString(CallInst *CI, IRBuilder<> &B);
+
+ /// hasFloatVersion - Checks if there is a float version of the specified
+ /// function by checking for an existing function with name FuncName + f
+ bool hasFloatVersion(StringRef FuncName);
+};
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/SymbolRewriter.h b/include/llvm/Transforms/Utils/SymbolRewriter.h
new file mode 100644
index 000000000000..af7937265795
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SymbolRewriter.h
@@ -0,0 +1,155 @@
+//===-- SymbolRewriter.h - Symbol Rewriting Pass ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the prototypes and definitions related to the Symbol
+// Rewriter pass.
+//
+// The Symbol Rewriter pass takes a set of rewrite descriptors which define
+// transformations for symbol names. These can be either single name to name
+// trnsformation or more broad regular expression based transformations.
+//
+// All the functions are re-written at the IR level. The Symbol Rewriter itself
+// is exposed as a module level pass. All symbols at the module level are
+// iterated. For any matching symbol, the requested transformation is applied,
+// updating references to it as well (a la RAUW). The resulting binary will
+// only contain the rewritten symbols.
+//
+// By performing this operation in the compiler, we are able to catch symbols
+// that would otherwise not be possible to catch (e.g. inlined symbols).
+//
+// This makes it possible to cleanly transform symbols without resorting to
+// overly-complex macro tricks and the pre-processor. An example of where this
+// is useful is the sanitizers where we would like to intercept a well-defined
+// set of functions across the module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SYMBOL_REWRITER_H
+#define LLVM_TRANSFORMS_UTILS_SYMBOL_REWRITER_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+class MemoryBuffer;
+
+namespace yaml {
+class KeyValueNode;
+class MappingNode;
+class ScalarNode;
+class Stream;
+}
+
+namespace SymbolRewriter {
+/// The basic entity representing a rewrite operation. It serves as the base
+/// class for any rewrite descriptor. It has a certain set of specializations
+/// which describe a particular rewrite.
+///
+/// The RewriteMapParser can be used to parse a mapping file that provides the
+/// mapping for rewriting the symbols. The descriptors individually describe
+/// whether to rewrite a function, global variable, or global alias. Each of
+/// these can be selected either by explicitly providing a name for the ones to
+/// be rewritten or providing a (posix compatible) regular expression that will
+/// select the symbols to rewrite. This descriptor list is passed to the
+/// SymbolRewriter pass.
+class RewriteDescriptor : public ilist_node<RewriteDescriptor> {
+ RewriteDescriptor(const RewriteDescriptor &) LLVM_DELETED_FUNCTION;
+
+ const RewriteDescriptor &
+ operator=(const RewriteDescriptor &) LLVM_DELETED_FUNCTION;
+
+public:
+ enum class Type {
+ Invalid, /// invalid
+ Function, /// function - descriptor rewrites a function
+ GlobalVariable, /// global variable - descriptor rewrites a global variable
+ NamedAlias, /// named alias - descriptor rewrites a global alias
+ };
+
+ virtual ~RewriteDescriptor() {}
+
+ Type getType() const { return Kind; }
+
+ virtual bool performOnModule(Module &M) = 0;
+
+protected:
+ explicit RewriteDescriptor(Type T) : Kind(T) {}
+
+private:
+ const Type Kind;
+};
+
+typedef iplist<RewriteDescriptor> RewriteDescriptorList;
+
+class RewriteMapParser {
+public:
+ RewriteMapParser() {}
+ ~RewriteMapParser() {}
+
+ bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
+
+private:
+ bool parse(std::unique_ptr<MemoryBuffer> &MapFile, RewriteDescriptorList *DL);
+ bool parseEntry(yaml::Stream &Stream, yaml::KeyValueNode &Entry,
+ RewriteDescriptorList *DL);
+ bool parseRewriteFunctionDescriptor(yaml::Stream &Stream,
+ yaml::ScalarNode *Key,
+ yaml::MappingNode *Value,
+ RewriteDescriptorList *DL);
+ bool parseRewriteGlobalVariableDescriptor(yaml::Stream &Stream,
+ yaml::ScalarNode *Key,
+ yaml::MappingNode *Value,
+ RewriteDescriptorList *DL);
+ bool parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
+ yaml::MappingNode *V,
+ RewriteDescriptorList *DL);
+};
+}
+
+template <>
+struct ilist_traits<SymbolRewriter::RewriteDescriptor>
+ : public ilist_default_traits<SymbolRewriter::RewriteDescriptor> {
+ mutable ilist_half_node<SymbolRewriter::RewriteDescriptor> Sentinel;
+
+public:
+ // createSentinel is used to get a reference to a node marking the end of
+ // the list. Because the sentinel is relative to this instance, use a
+ // non-static method.
+ SymbolRewriter::RewriteDescriptor *createSentinel() const {
+ // since i[p] lists always publicly derive from the corresponding
+ // traits, placing a data member in this class will augment the
+ // i[p]list. Since the NodeTy is expected to publicly derive from
+ // ilist_node<NodeTy>, there is a legal viable downcast from it to
+ // NodeTy. We use this trick to superpose i[p]list with a "ghostly"
+ // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
+ // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
+ // the superposition.
+ return static_cast<SymbolRewriter::RewriteDescriptor *>(&Sentinel);
+ }
+ void destroySentinel(SymbolRewriter::RewriteDescriptor *) {}
+
+ SymbolRewriter::RewriteDescriptor *provideInitialHead() const {
+ return createSentinel();
+ }
+
+ SymbolRewriter::RewriteDescriptor *
+ ensureHead(SymbolRewriter::RewriteDescriptor *&) const {
+ return createSentinel();
+ }
+
+ static void noteHead(SymbolRewriter::RewriteDescriptor *,
+ SymbolRewriter::RewriteDescriptor *) {}
+};
+
+ModulePass *createRewriteSymbolsPass();
+ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &);
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index 7ac2572f9af3..550292f6b7a3 100644
--- a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
-#define LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+#ifndef LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
+#define LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#include "llvm/Pass.h"
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index aaadd7d48bdc..807367cd4b12 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -18,6 +18,7 @@
namespace llvm {
+class AssumptionCache;
class Loop;
class LoopInfo;
class LPPassManager;
@@ -25,7 +26,7 @@ class Pass;
bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
unsigned TripMultiple, LoopInfo *LI, Pass *PP,
- LPPassManager *LPM);
+ LPPassManager *LPM, AssumptionCache *AC);
bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
LPPassManager* LPM);
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index 5774763575d3..047ab818711b 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -71,20 +71,23 @@ namespace llvm {
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);
+ Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
+
+ /// MapMetadata - provide versions that preserve type safety for MDNodes.
+ MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
+
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
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 = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper,
- Materializer));
- }
+ /// MapValue - provide versions that preserve type safety for Constants.
inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h
index 44a7149eee98..b47acf517b37 100644
--- a/include/llvm/Transforms/Utils/VectorUtils.h
+++ b/include/llvm/Transforms/Utils/VectorUtils.h
@@ -14,8 +14,8 @@
#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
-#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/Target/TargetLibraryInfo.h"
namespace llvm {
@@ -36,6 +36,8 @@ static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
case Intrinsic::log10:
case Intrinsic::log2:
case Intrinsic::fabs:
+ case Intrinsic::minnum:
+ case Intrinsic::maxnum:
case Intrinsic::copysign:
case Intrinsic::floor:
case Intrinsic::ceil:
@@ -99,7 +101,7 @@ getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
Intrinsic::ID ID = II->getIntrinsicID();
if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
- ID == Intrinsic::lifetime_end)
+ ID == Intrinsic::lifetime_end || ID == Intrinsic::assume)
return ID;
else
return Intrinsic::not_intrinsic;
@@ -153,6 +155,14 @@ getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
case LibFunc::fabsf:
case LibFunc::fabsl:
return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
+ case LibFunc::fmin:
+ case LibFunc::fminf:
+ case LibFunc::fminl:
+ return checkBinaryFloatSignature(*CI, Intrinsic::minnum);
+ case LibFunc::fmax:
+ case LibFunc::fmaxf:
+ case LibFunc::fmaxl:
+ return checkBinaryFloatSignature(*CI, Intrinsic::maxnum);
case LibFunc::copysign:
case LibFunc::copysignf:
case LibFunc::copysignl: