aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r--include/llvm/Transforms/IPO/LowerBitSets.h71
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h2
-rw-r--r--include/llvm/Transforms/Instrumentation.h4
-rw-r--r--include/llvm/Transforms/Scalar.h8
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h32
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h10
-rw-r--r--include/llvm/Transforms/Utils/Local.h32
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h17
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h9
9 files changed, 115 insertions, 70 deletions
diff --git a/include/llvm/Transforms/IPO/LowerBitSets.h b/include/llvm/Transforms/IPO/LowerBitSets.h
index 0f60617..55d7d84 100644
--- a/include/llvm/Transforms/IPO/LowerBitSets.h
+++ b/include/llvm/Transforms/IPO/LowerBitSets.h
@@ -30,8 +30,8 @@ class GlobalVariable;
class Value;
struct BitSetInfo {
- // The actual bitset.
- std::vector<uint8_t> Bits;
+ // The indices of the set bits in the bitset.
+ std::set<uint64_t> Bits;
// The byte offset into the combined global represented by the bitset.
uint64_t ByteOffset;
@@ -45,26 +45,18 @@ struct BitSetInfo {
unsigned AlignLog2;
bool isSingleOffset() const {
- return Bits.size() == 1 && Bits[0] == 1;
+ return Bits.size() == 1;
}
bool isAllOnes() const {
- for (unsigned I = 0; I != Bits.size() - 1; ++I)
- if (Bits[I] != 0xFF)
- return false;
-
- if (BitSize % 8 == 0)
- return Bits[Bits.size() - 1] == 0xFF;
-
- return Bits[Bits.size() - 1] == (1 << (BitSize % 8)) - 1;
+ return Bits.size() == BitSize;
}
bool containsGlobalOffset(uint64_t Offset) const;
- bool containsValue(const DataLayout *DL,
+ bool containsValue(const DataLayout &DL,
const DenseMap<GlobalVariable *, uint64_t> &GlobalLayout,
Value *V, uint64_t COffset = 0) const;
-
};
struct BitSetBuilder {
@@ -148,6 +140,59 @@ struct GlobalLayoutBuilder {
void addFragment(const std::set<uint64_t> &F);
};
+/// This class is used to build a byte array containing overlapping bit sets. By
+/// loading from indexed offsets into the byte array and applying a mask, a
+/// program can test bits from the bit set with a relatively short instruction
+/// sequence. For example, suppose we have 15 bit sets to lay out:
+///
+/// A (16 bits), B (15 bits), C (14 bits), D (13 bits), E (12 bits),
+/// F (11 bits), G (10 bits), H (9 bits), I (7 bits), J (6 bits), K (5 bits),
+/// L (4 bits), M (3 bits), N (2 bits), O (1 bit)
+///
+/// These bits can be laid out in a 16-byte array like this:
+///
+/// Byte Offset
+/// 0123456789ABCDEF
+/// Bit
+/// 7 HHHHHHHHHIIIIIII
+/// 6 GGGGGGGGGGJJJJJJ
+/// 5 FFFFFFFFFFFKKKKK
+/// 4 EEEEEEEEEEEELLLL
+/// 3 DDDDDDDDDDDDDMMM
+/// 2 CCCCCCCCCCCCCCNN
+/// 1 BBBBBBBBBBBBBBBO
+/// 0 AAAAAAAAAAAAAAAA
+///
+/// For example, to test bit X of A, we evaluate ((bits[X] & 1) != 0), or to
+/// test bit X of I, we evaluate ((bits[9 + X] & 0x80) != 0). This can be done
+/// in 1-2 machine instructions on x86, or 4-6 instructions on ARM.
+///
+/// This is a byte array, rather than (say) a 2-byte array or a 4-byte array,
+/// because for one thing it gives us better packing (the more bins there are,
+/// the less evenly they will be filled), and for another, the instruction
+/// sequences can be slightly shorter, both on x86 and ARM.
+struct ByteArrayBuilder {
+ /// The byte array built so far.
+ std::vector<uint8_t> Bytes;
+
+ enum { BitsPerByte = 8 };
+
+ /// The number of bytes allocated so far for each of the bits.
+ uint64_t BitAllocs[BitsPerByte];
+
+ ByteArrayBuilder() {
+ memset(BitAllocs, 0, sizeof(BitAllocs));
+ }
+
+ /// Allocate BitSize bits in the byte array where Bits contains the bits to
+ /// set. AllocByteOffset is set to the offset within the byte array and
+ /// AllocMask is set to the bitmask for those bits. This uses the LPT (Longest
+ /// Processing Time) multiprocessor scheduling algorithm to lay out the bits
+ /// efficiently; the pass allocates bit sets in decreasing size order.
+ void allocate(const std::set<uint64_t> &Bits, uint64_t BitSize,
+ uint64_t &AllocByteOffset, uint8_t &AllocMask);
+};
+
} // namespace llvm
#endif
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 65f4712..5d574ae 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -120,7 +120,6 @@ public:
bool DisableGVNLoadPRE;
bool VerifyInput;
bool VerifyOutput;
- bool StripDebug;
bool MergeFunctions;
private:
@@ -141,6 +140,7 @@ private:
legacy::PassManagerBase &PM) const;
void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
+ void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
public:
/// populateFunctionPassManager - This fills in the function pass manager,
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 8fac6ca..a147793 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -60,6 +60,10 @@ struct GCOVOptions {
// Emit the name of the function in the .gcda files. This is redundant, as
// the function identifier can be used to find the name from the .gcno file.
bool FunctionNamesInData;
+
+ // Emit the exit block immediately after the start block, rather than after
+ // all of the function body's blocks.
+ bool ExitBlockBeforeBody;
};
ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 558b81e..2d754d0 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -140,6 +140,13 @@ Pass *createLICMPass();
//===----------------------------------------------------------------------===//
//
+// LoopInterchange - This pass interchanges loops to provide a more
+// cache-friendly memory access patterns.
+//
+Pass *createLoopInterchangePass();
+
+//===----------------------------------------------------------------------===//
+//
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
// a loop's canonical induction variable as one of their indices.
//
@@ -422,7 +429,6 @@ BasicBlockPass *createLoadCombinePass();
FunctionPass *createStraightLineStrengthReducePass();
-
//===----------------------------------------------------------------------===//
//
// PlaceSafepoints - Rewrite any IR calls to gc.statepoints and insert any
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 6387c16..879f295 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -28,52 +28,50 @@ namespace llvm {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, and the
/// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, MaxLen must
/// be of size_t type, and the return value has 'intptr_t' type.
Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitStrChr - Emit a call to the strchr function to the builder, for the
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
const TargetLibraryInfo *TLI);
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI,
- StringRef Name = "strcpy");
+ const TargetLibraryInfo *TLI, StringRef Name = "strcpy");
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI,
- StringRef Name = "strncpy");
+ const TargetLibraryInfo *TLI, StringRef Name = "strncpy");
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const DataLayout *TD,
+ IRBuilder<> &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitMemCmp - Emit a call to the memcmp function.
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
@@ -93,28 +91,26 @@ namespace llvm {
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
- const TargetLibraryInfo *TLI);
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetLibraryInfo *TLI);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
- Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
- const TargetLibraryInfo *TLI);
+ Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetLibraryInfo *TLI);
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an i32, and File is a pointer to FILE.
Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const TargetLibraryInfo *TLI);
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
- Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
const TargetLibraryInfo *TLI);
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// 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);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
}
#endif
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index d1563ef..cb187ec 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -144,7 +144,9 @@ public:
///< Skip this instruction but continue cloning the current basic block.
SkipInstruction,
///< Skip this instruction and stop cloning the current basic block.
- StopCloningBB
+ StopCloningBB,
+ ///< Don't clone the terminator but clone the current block's successors.
+ CloneSuccessors
};
virtual ~CloningDirector() {}
@@ -164,7 +166,6 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
- const DataLayout *DL = nullptr,
CloningDirector *Director = nullptr);
@@ -184,7 +185,6 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
- const DataLayout *DL = nullptr,
Instruction *TheCall = nullptr);
/// InlineFunctionInfo - This class captures the data input to the
@@ -192,15 +192,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
class InlineFunctionInfo {
public:
explicit InlineFunctionInfo(CallGraph *cg = nullptr,
- const DataLayout *DL = nullptr,
AliasAnalysis *AA = nullptr,
AssumptionCacheTracker *ACT = nullptr)
- : CG(cg), DL(DL), AA(AA), ACT(ACT) {}
+ : CG(cg), 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;
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 463ab96..e89169c 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -88,7 +88,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN,
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
+bool SimplifyInstructionsInBlock(BasicBlock *BB,
const TargetLibraryInfo *TLI = nullptr);
//===----------------------------------------------------------------------===//
@@ -106,8 +106,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
///
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the 'and' to 0.
-void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- DataLayout *TD = nullptr);
+void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred);
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
/// predecessor is known to have one successor (BB!). Eliminate the edge
@@ -137,8 +136,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// the basic block that was pointed to.
///
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, const DataLayout *TD = nullptr,
- AssumptionCache *AC = nullptr);
+ unsigned BonusInstThreshold, AssumptionCache *AC = nullptr);
/// FlatternCFG - This function is used to flatten a CFG. For
/// example, it uses parallel-and and parallel-or mode to collapse
@@ -150,8 +148,7 @@ 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,
- unsigned BonusInstThreshold = 1);
+bool FoldBranchToCommonDest(BranchInst *BI, 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
@@ -173,18 +170,17 @@ 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,
- AssumptionCache *AC = nullptr,
+ const DataLayout &DL,
const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = 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,
- AssumptionCache *AC = nullptr,
+static inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
const DominatorTree *DT = nullptr) {
- return getOrEnforceKnownAlignment(V, 0, TD, AC, CxtI, DT);
+ return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
}
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
@@ -192,11 +188,11 @@ static inline unsigned getKnownAlignment(Value *V,
/// in the base pointer). Return the result as a signed integer of intptr size.
/// When NoAssumptions is true, no assumptions about index computation not
/// overflowing is made.
-template<typename IRBuilderTy>
-Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
+template <typename IRBuilderTy>
+Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
bool NoAssumptions = false) {
GEPOperator *GEPOp = cast<GEPOperator>(GEP);
- Type *IntPtrTy = TD.getIntPtrType(GEP->getType());
+ Type *IntPtrTy = DL.getIntPtrType(GEP->getType());
Value *Result = Constant::getNullValue(IntPtrTy);
// If the GEP is inbounds, we know that none of the addressing operations will
@@ -211,7 +207,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
++i, ++GTI) {
Value *Op = *i;
- uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
+ uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
if (Constant *OpC = dyn_cast<Constant>(Op)) {
if (OpC->isZeroValue())
continue;
@@ -222,7 +218,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
OpC = OpC->getSplatValue();
uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
- Size = TD.getStructLayout(STy)->getElementOffset(OpValue);
+ Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
if (Size)
Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index bb80f20..2eb2555 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -52,7 +52,6 @@ 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,
AssumptionCache *AC = nullptr);
/// \brief Put loop into LCSSA form.
@@ -85,13 +84,13 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
/// dominated by the specified block, and that are in the current loop) in
/// reverse depth first order w.r.t the DominatorTree. This allows us to visit
/// uses before definitions, allowing us to sink a loop body in one pass without
-/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
-/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
-/// instructions of the loop and loop safety information as arguments.
-/// It returns changed status.
+/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
+/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
+/// instructions of the loop and loop safety information as arguments.
+/// It returns changed status.
bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
- const DataLayout *, TargetLibraryInfo *, Loop *,
- AliasSetTracker *, LICMSafetyInfo *);
+ TargetLibraryInfo *, Loop *, AliasSetTracker *,
+ LICMSafetyInfo *);
/// \brief Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in depth
@@ -101,8 +100,8 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// TargetLibraryInfo, Loop, AliasSet information for all instructions of the
/// loop and loop safety information as arguments. It returns changed status.
bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
- const DataLayout *, TargetLibraryInfo *, Loop *,
- AliasSetTracker *, LICMSafetyInfo *);
+ TargetLibraryInfo *, Loop *, AliasSetTracker *,
+ LICMSafetyInfo *);
/// \brief Try to promote memory values to scalars by sinking stores out of
/// the loop and moving loads to before the loop. We do this by looping over
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 08358e1..4115960 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -15,6 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
@@ -36,12 +37,11 @@ class Function;
/// 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,
+ FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI,
bool OnlyLowerUnknownSize = false);
/// \brief Take the given call instruction and return a more
@@ -71,7 +71,7 @@ private:
class LibCallSimplifier {
private:
FortifiedLibCallSimplifier FortifiedSimplifier;
- const DataLayout *DL;
+ const DataLayout &DL;
const TargetLibraryInfo *TLI;
bool UnsafeFPShrink;
function_ref<void(Instruction *, Value *)> Replacer;
@@ -86,7 +86,7 @@ private:
void replaceAllUsesWith(Instruction *I, Value *With);
public:
- LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
+ LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI,
function_ref<void(Instruction *, Value *)> Replacer =
&replaceAllUsesWithDefault);
@@ -116,6 +116,7 @@ private:
Value *optimizeStrSpn(CallInst *CI, IRBuilder<> &B);
Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B);
Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemChr(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);