diff options
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r-- | include/llvm/Transforms/IPO/PassManagerBuilder.h | 16 | ||||
-rw-r--r-- | include/llvm/Transforms/Instrumentation.h | 3 | ||||
-rw-r--r-- | include/llvm/Transforms/Scalar.h | 25 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/BasicBlockUtils.h | 11 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/Cloning.h | 11 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/CodeExtractor.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/CtorUtils.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/Local.h | 26 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/LoopUtils.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/ModuleUtils.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/PromoteMemToReg.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/SimplifyLibCalls.h | 144 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/SymbolRewriter.h | 155 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h | 4 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/UnrollLoop.h | 3 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/VectorUtils.h | 12 |
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: |