aboutsummaryrefslogtreecommitdiffstats
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.h3
-rw-r--r--include/llvm/Transforms/Scalar.h25
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h11
-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.h26
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h4
-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.h144
-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/VectorUtils.h12
16 files changed, 368 insertions, 62 deletions
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 50877d0..b1426b4 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 c6a339b..87422df 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -78,6 +78,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()) {
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 8ecfd80..5dcd899 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);
//===----------------------------------------------------------------------===//
//
@@ -288,6 +296,13 @@ 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
// elimination cotemporaneously.
//
@@ -380,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 7309f69..19acf5b 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -23,6 +23,7 @@
namespace llvm {
class AliasAnalysis;
+class DominatorTree;
class Instruction;
class MDNode;
class Pass;
@@ -132,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);
@@ -202,9 +208,12 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
/// If Unreachable is true, then ThenBlock ends with
/// UnreachableInst, otherwise it branches to Tail.
/// Returns the NewBasicBlock's terminator.
+///
+/// Updates DT if given.
TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
bool Unreachable,
- MDNode *BranchWeights = nullptr);
+ MDNode *BranchWeights = nullptr,
+ DominatorTree *DT = nullptr);
/// SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen,
/// but also creates the ElseBlock.
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index bdf50dd..740d725 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 AssumptionTracker;
/// 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,
+ AssumptionTracker *AT = nullptr)
+ : CG(cg), DL(DL), AA(AA), AT(AT) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
const DataLayout *DL;
+ AliasAnalysis *AA;
+ AssumptionTracker *AT;
/// 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 6b41e82..3a96d95 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 81e7b95..63e564d 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 c0c6906..e89e5e5 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 AssumptionTracker;
class ConstantExpr;
class DataLayout;
class TargetLibraryInfo;
class TargetTransformInfo;
class DIBuilder;
class AliasAnalysis;
+class DominatorTree;
template<typename T> class SmallVectorImpl;
@@ -136,7 +138,9 @@ 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,
+ AssumptionTracker *AT = nullptr);
/// FlatternCFG - This function is used to flatten a CFG. For
/// example, it uses parallel-and and parallel-or mode to collapse
@@ -148,7 +152,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 +175,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,
+ AssumptionTracker *AT = 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,
+ AssumptionTracker *AT = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr) {
+ return getOrEnforceKnownAlignment(V, 0, TD, AT, CxtI, DT);
}
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
@@ -275,6 +286,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 7e3a74a..fdae80d 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -16,6 +16,7 @@
namespace llvm {
class AliasAnalysis;
+class AssumptionTracker;
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,
+ AssumptionTracker *AT = nullptr);
/// \brief Put loop into LCSSA form.
///
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index 98a19ed..16904f1 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 c83fedb..3fdd5e9 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 AssumptionTracker;
/// \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,
+ AssumptionTracker *AT = nullptr);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index a2a5f9a..6765ac1 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -15,40 +15,118 @@
#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;
+
+/// 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:
+ 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.
+ 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:
+ // Fortified Library Call Optimizations
+ 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 *optimizeStpCpyChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrNCpyChk(CallInst *CI, IRBuilder<> &B);
+
+ // 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);
+
+ // 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 0000000..af79372
--- /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 7ac2572..550292f 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 aaadd7d..0b88d25 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -18,6 +18,7 @@
namespace llvm {
+class AssumptionTracker;
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, AssumptionTracker *AT);
bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
LPPassManager* LPM);
diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h
index 44a7149..83871fc 100644
--- a/include/llvm/Transforms/Utils/VectorUtils.h
+++ b/include/llvm/Transforms/Utils/VectorUtils.h
@@ -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: