[Transforms] Fix some Clang-tidy modernize-use-using and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 313198
This commit is contained in:
Eugene Zelenko 2017-09-13 21:43:53 +00:00
parent c0d066468e
commit 8002c504cd
7 changed files with 267 additions and 147 deletions

View File

@ -1,4 +1,4 @@
//===-- ConstantHoisting.h - Prepare code for expensive constants ---------===// //==- ConstantHoisting.h - Prepare code for expensive constants --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -31,41 +31,53 @@
// This optimization is only applied to integer constants in instructions and // This optimization is only applied to integer constants in instructions and
// simple (this means not nested) constant cast expressions. For example: // simple (this means not nested) constant cast expressions. For example:
// %0 = load i64* inttoptr (i64 big_constant to i64*) // %0 = load i64* inttoptr (i64 big_constant to i64*)
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
#define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H #define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
#include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Dominators.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include <algorithm>
#include <vector>
namespace llvm { namespace llvm {
class BasicBlock;
class BlockFrequencyInfo;
class Constant;
class ConstantInt;
class DominatorTree;
class Function;
class Instruction;
class TargetTransformInfo;
/// A private "module" namespace for types and utilities used by /// A private "module" namespace for types and utilities used by
/// ConstantHoisting. These are implementation details and should not be used by /// ConstantHoisting. These are implementation details and should not be used by
/// clients. /// clients.
namespace consthoist { namespace consthoist {
/// \brief Keeps track of the user of a constant and the operand index where the /// \brief Keeps track of the user of a constant and the operand index where the
/// constant is used. /// constant is used.
struct ConstantUser { struct ConstantUser {
Instruction *Inst; Instruction *Inst;
unsigned OpndIdx; unsigned OpndIdx;
ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { } ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
}; };
typedef SmallVector<ConstantUser, 8> ConstantUseListType; using ConstantUseListType = SmallVector<ConstantUser, 8>;
/// \brief Keeps track of a constant candidate and its uses. /// \brief Keeps track of a constant candidate and its uses.
struct ConstantCandidate { struct ConstantCandidate {
ConstantUseListType Uses; ConstantUseListType Uses;
ConstantInt *ConstInt; ConstantInt *ConstInt;
unsigned CumulativeCost; unsigned CumulativeCost = 0;
ConstantCandidate(ConstantInt *ConstInt) ConstantCandidate(ConstantInt *ConstInt) : ConstInt(ConstInt) {}
: ConstInt(ConstInt), CumulativeCost(0) { }
/// \brief Add the user to the use list and update the cost. /// \brief Add the user to the use list and update the cost.
void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) { void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
@ -81,17 +93,18 @@ struct RebasedConstantInfo {
Constant *Offset; Constant *Offset;
RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset) RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset)
: Uses(std::move(Uses)), Offset(Offset) { } : Uses(std::move(Uses)), Offset(Offset) {}
}; };
typedef SmallVector<RebasedConstantInfo, 4> RebasedConstantListType; using RebasedConstantListType = SmallVector<RebasedConstantInfo, 4>;
/// \brief A base constant and all its rebased constants. /// \brief A base constant and all its rebased constants.
struct ConstantInfo { struct ConstantInfo {
ConstantInt *BaseConstant; ConstantInt *BaseConstant;
RebasedConstantListType RebasedConstants; RebasedConstantListType RebasedConstants;
}; };
}
} // end namespace consthoist
class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> { class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
public: public:
@ -108,8 +121,8 @@ public:
} }
private: private:
typedef DenseMap<ConstantInt *, unsigned> ConstCandMapType; using ConstCandMapType = DenseMap<ConstantInt *, unsigned>;
typedef std::vector<consthoist::ConstantCandidate> ConstCandVecType; using ConstCandVecType = std::vector<consthoist::ConstantCandidate>;
const TargetTransformInfo *TTI; const TargetTransformInfo *TTI;
DominatorTree *DT; DominatorTree *DT;
@ -148,6 +161,7 @@ private:
void deleteDeadCastInst() const; void deleteDeadCastInst() const;
bool optimizeConstants(Function &Fn); bool optimizeConstants(Function &Fn);
}; };
}
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H #endif // LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H

View File

@ -19,25 +19,45 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include <cstdint>
#include <utility>
#include <vector>
namespace llvm { namespace llvm {
class AssumptionCache;
class BasicBlock;
class BranchInst;
class CallInst;
class Constant;
class ExtractValueInst;
class Function;
class FunctionPass;
class IntrinsicInst; class IntrinsicInst;
class LoadInst;
class LoopInfo;
class OptimizationRemarkEmitter; class OptimizationRemarkEmitter;
class PHINode;
class TargetLibraryInfo;
class Value;
/// A private "module" namespace for types and utilities used by GVN. These /// A private "module" namespace for types and utilities used by GVN. These
/// are implementation details and should not be used by clients. /// are implementation details and should not be used by clients.
namespace gvn LLVM_LIBRARY_VISIBILITY { namespace gvn LLVM_LIBRARY_VISIBILITY {
struct AvailableValue; struct AvailableValue;
struct AvailableValueInBlock; struct AvailableValueInBlock;
class GVNLegacyPass; class GVNLegacyPass;
}
} // end namespace gvn
/// The core GVN pass object. /// The core GVN pass object.
/// ///
@ -45,6 +65,7 @@ class GVNLegacyPass;
/// this particular pass here. /// this particular pass here.
class GVN : public PassInfoMixin<GVN> { class GVN : public PassInfoMixin<GVN> {
public: public:
struct Expression;
/// \brief Run the pass over the function. /// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@ -60,8 +81,6 @@ public:
AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); } AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
MemoryDependenceResults &getMemDep() const { return *MD; } MemoryDependenceResults &getMemDep() const { return *MD; }
struct Expression;
/// This class holds the mapping between values and value numbers. It is used /// This class holds the mapping between values and value numbers. It is used
/// as an efficient mechanism to determine the expression-wise equivalence of /// as an efficient mechanism to determine the expression-wise equivalence of
/// two values. /// two values.
@ -74,20 +93,23 @@ public:
// instead of a DenseMap because filling such mapping is faster than // instead of a DenseMap because filling such mapping is faster than
// filling a DenseMap and the compile time is a little better. // filling a DenseMap and the compile time is a little better.
uint32_t nextExprNumber; uint32_t nextExprNumber;
std::vector<Expression> Expressions; std::vector<Expression> Expressions;
std::vector<uint32_t> ExprIdx; std::vector<uint32_t> ExprIdx;
// Value number to PHINode mapping. Used for phi-translate in scalarpre. // Value number to PHINode mapping. Used for phi-translate in scalarpre.
DenseMap<uint32_t, PHINode *> NumberingPhi; DenseMap<uint32_t, PHINode *> NumberingPhi;
// Cache for phi-translate in scalarpre. // Cache for phi-translate in scalarpre.
typedef DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t> using PhiTranslateMap =
PhiTranslateMap; DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t>;
PhiTranslateMap PhiTranslateTable; PhiTranslateMap PhiTranslateTable;
AliasAnalysis *AA; AliasAnalysis *AA;
MemoryDependenceResults *MD; MemoryDependenceResults *MD;
DominatorTree *DT; DominatorTree *DT;
uint32_t nextValueNumber; uint32_t nextValueNumber = 1;
Expression createExpr(Instruction *I); Expression createExpr(Instruction *I);
Expression createCmpExpr(unsigned Opcode, CmpInst::Predicate Predicate, Expression createCmpExpr(unsigned Opcode, CmpInst::Predicate Predicate,
@ -150,16 +172,16 @@ private:
// Block-local map of equivalent values to their leader, does not // Block-local map of equivalent values to their leader, does not
// propagate to any successors. Entries added mid-block are applied // propagate to any successors. Entries added mid-block are applied
// to the remaining instructions in the block. // to the remaining instructions in the block.
SmallMapVector<llvm::Value *, llvm::Constant *, 4> ReplaceWithConstMap; SmallMapVector<Value *, Constant *, 4> ReplaceWithConstMap;
SmallVector<Instruction *, 8> InstrsToErase; SmallVector<Instruction *, 8> InstrsToErase;
// Map the block to reversed postorder traversal number. It is used to // Map the block to reversed postorder traversal number. It is used to
// find back edge easily. // find back edge easily.
DenseMap<const BasicBlock *, uint32_t> BlockRPONumber; DenseMap<const BasicBlock *, uint32_t> BlockRPONumber;
typedef SmallVector<NonLocalDepResult, 64> LoadDepVect; using LoadDepVect = SmallVector<NonLocalDepResult, 64>;
typedef SmallVector<gvn::AvailableValueInBlock, 64> AvailValInBlkVect; using AvailValInBlkVect = SmallVector<gvn::AvailableValueInBlock, 64>;
typedef SmallVector<BasicBlock *, 64> UnavailBlkVect; using UnavailBlkVect = SmallVector<BasicBlock *, 64>;
bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA, const TargetLibraryInfo &RunTLI, AAResults &RunAA,
@ -218,17 +240,20 @@ private:
bool processLoad(LoadInst *L); bool processLoad(LoadInst *L);
bool processNonLocalLoad(LoadInst *L); bool processNonLocalLoad(LoadInst *L);
bool processAssumeIntrinsic(IntrinsicInst *II); bool processAssumeIntrinsic(IntrinsicInst *II);
/// Given a local dependency (Def or Clobber) determine if a value is /// Given a local dependency (Def or Clobber) determine if a value is
/// available for the load. Returns true if an value is known to be /// available for the load. Returns true if an value is known to be
/// available and populates Res. Returns false otherwise. /// available and populates Res. Returns false otherwise.
bool AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, bool AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
Value *Address, gvn::AvailableValue &Res); Value *Address, gvn::AvailableValue &Res);
/// Given a list of non-local dependencies, determine if a value is /// Given a list of non-local dependencies, determine if a value is
/// available for the load in each specified block. If it is, add it to /// available for the load in each specified block. If it is, add it to
/// ValuesPerBlock. If not, add it to UnavailableBlocks. /// ValuesPerBlock. If not, add it to UnavailableBlocks.
void AnalyzeLoadAvailability(LoadInst *LI, LoadDepVect &Deps, void AnalyzeLoadAvailability(LoadInst *LI, LoadDepVect &Deps,
AvailValInBlkVect &ValuesPerBlock, AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks); UnavailBlkVect &UnavailableBlocks);
bool PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock, bool PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks); UnavailBlkVect &UnavailableBlocks);
@ -265,12 +290,14 @@ struct GVNHoistPass : PassInfoMixin<GVNHoistPass> {
/// \brief Run the pass over the function. /// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
}; };
/// \brief Uses an "inverted" value numbering to decide the similarity of /// \brief Uses an "inverted" value numbering to decide the similarity of
/// expressions and sinks similar expressions into successors. /// expressions and sinks similar expressions into successors.
struct GVNSinkPass : PassInfoMixin<GVNSinkPass> { struct GVNSinkPass : PassInfoMixin<GVNSinkPass> {
/// \brief Run the pass over the function. /// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
}; };
}
#endif } // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_GVN_H

View File

@ -1,4 +1,4 @@
//======- GVNExpression.h - GVN Expression classes --------------*- C++ -*-===// //===- GVNExpression.h - GVN Expression classes -----------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -6,11 +6,12 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// ///
/// The header file for the GVN pass that contains expression handling /// The header file for the GVN pass that contains expression handling
/// classes /// classes
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
@ -25,7 +26,7 @@
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h" #include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -34,6 +35,9 @@
namespace llvm { namespace llvm {
class BasicBlock;
class Type;
namespace GVNExpression { namespace GVNExpression {
enum ExpressionType { enum ExpressionType {
@ -58,17 +62,18 @@ class Expression {
private: private:
ExpressionType EType; ExpressionType EType;
unsigned Opcode; unsigned Opcode;
mutable hash_code HashVal; mutable hash_code HashVal = 0;
public: public:
Expression(ExpressionType ET = ET_Base, unsigned O = ~2U) Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
: EType(ET), Opcode(O), HashVal(0) {} : EType(ET), Opcode(O) {}
Expression(const Expression &) = delete; Expression(const Expression &) = delete;
Expression &operator=(const Expression &) = delete; Expression &operator=(const Expression &) = delete;
virtual ~Expression(); virtual ~Expression();
static unsigned getEmptyKey() { return ~0U; } static unsigned getEmptyKey() { return ~0U; }
static unsigned getTombstoneKey() { return ~1U; } static unsigned getTombstoneKey() { return ~1U; }
bool operator!=(const Expression &Other) const { return !(*this == Other); } bool operator!=(const Expression &Other) const { return !(*this == Other); }
bool operator==(const Expression &Other) const { bool operator==(const Expression &Other) const {
if (getOpcode() != Other.getOpcode()) if (getOpcode() != Other.getOpcode())
@ -83,6 +88,7 @@ public:
return equals(Other); return equals(Other);
} }
hash_code getComputedHash() const { hash_code getComputedHash() const {
// It's theoretically possible for a thing to hash to zero. In that case, // It's theoretically possible for a thing to hash to zero. In that case,
// we will just compute the hash a few extra times, which is no worse that // we will just compute the hash a few extra times, which is no worse that
@ -93,6 +99,7 @@ public:
} }
virtual bool equals(const Expression &Other) const { return true; } virtual bool equals(const Expression &Other) const { return true; }
// Return true if the two expressions are exactly the same, including the // Return true if the two expressions are exactly the same, including the
// normally ignored fields. // normally ignored fields.
virtual bool exactlyEquals(const Expression &Other) const { virtual bool exactlyEquals(const Expression &Other) const {
@ -106,9 +113,7 @@ public:
// We deliberately leave the expression type out of the hash value. // We deliberately leave the expression type out of the hash value.
virtual hash_code getHashValue() const { return getOpcode(); } virtual hash_code getHashValue() const { return getOpcode(); }
//
// Debugging support // Debugging support
//
virtual void printInternal(raw_ostream &OS, bool PrintEType) const { virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
if (PrintEType) if (PrintEType)
OS << "etype = " << getExpressionType() << ","; OS << "etype = " << getExpressionType() << ",";
@ -131,19 +136,19 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
class BasicExpression : public Expression { class BasicExpression : public Expression {
private: private:
typedef ArrayRecycler<Value *> RecyclerType; using RecyclerType = ArrayRecycler<Value *>;
typedef RecyclerType::Capacity RecyclerCapacity; using RecyclerCapacity = RecyclerType::Capacity;
Value **Operands;
Value **Operands = nullptr;
unsigned MaxOperands; unsigned MaxOperands;
unsigned NumOperands; unsigned NumOperands = 0;
Type *ValueType; Type *ValueType = nullptr;
public: public:
BasicExpression(unsigned NumOperands) BasicExpression(unsigned NumOperands)
: BasicExpression(NumOperands, ET_Basic) {} : BasicExpression(NumOperands, ET_Basic) {}
BasicExpression(unsigned NumOperands, ExpressionType ET) BasicExpression(unsigned NumOperands, ExpressionType ET)
: Expression(ET), Operands(nullptr), MaxOperands(NumOperands), : Expression(ET), MaxOperands(NumOperands) {}
NumOperands(0), ValueType(nullptr) {}
BasicExpression() = delete; BasicExpression() = delete;
BasicExpression(const BasicExpression &) = delete; BasicExpression(const BasicExpression &) = delete;
BasicExpression &operator=(const BasicExpression &) = delete; BasicExpression &operator=(const BasicExpression &) = delete;
@ -174,8 +179,9 @@ public:
unsigned getNumOperands() const { return NumOperands; } unsigned getNumOperands() const { return NumOperands; }
typedef Value **op_iterator; using op_iterator = Value **;
typedef Value *const *const_op_iterator; using const_op_iterator = Value *const *;
op_iterator op_begin() { return Operands; } op_iterator op_begin() { return Operands; }
op_iterator op_end() { return Operands + NumOperands; } op_iterator op_end() { return Operands + NumOperands; }
const_op_iterator op_begin() const { return Operands; } const_op_iterator op_begin() const { return Operands; }
@ -219,9 +225,7 @@ public:
hash_combine_range(op_begin(), op_end())); hash_combine_range(op_begin(), op_end()));
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeBasic, "; OS << "ExpressionTypeBasic, ";
@ -240,7 +244,8 @@ public:
class op_inserter class op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> { : public std::iterator<std::output_iterator_tag, void, void, void, void> {
private: private:
typedef BasicExpression Container; using Container = BasicExpression;
Container *BE; Container *BE;
public: public:
@ -263,15 +268,16 @@ private:
public: public:
MemoryExpression(unsigned NumOperands, enum ExpressionType EType, MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
const MemoryAccess *MemoryLeader) const MemoryAccess *MemoryLeader)
: BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader){}; : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
MemoryExpression() = delete; MemoryExpression() = delete;
MemoryExpression(const MemoryExpression &) = delete; MemoryExpression(const MemoryExpression &) = delete;
MemoryExpression &operator=(const MemoryExpression &) = delete; MemoryExpression &operator=(const MemoryExpression &) = delete;
static bool classof(const Expression *EB) { static bool classof(const Expression *EB) {
return EB->getExpressionType() > ET_MemoryStart && return EB->getExpressionType() > ET_MemoryStart &&
EB->getExpressionType() < ET_MemoryEnd; EB->getExpressionType() < ET_MemoryEnd;
} }
hash_code getHashValue() const override { hash_code getHashValue() const override {
return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader); return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
} }
@ -305,9 +311,7 @@ public:
return EB->getExpressionType() == ET_Call; return EB->getExpressionType() == ET_Call;
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeCall, "; OS << "ExpressionTypeCall, ";
@ -326,11 +330,13 @@ public:
LoadExpression(unsigned NumOperands, LoadInst *L, LoadExpression(unsigned NumOperands, LoadInst *L,
const MemoryAccess *MemoryLeader) const MemoryAccess *MemoryLeader)
: LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {} : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L, LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
const MemoryAccess *MemoryLeader) const MemoryAccess *MemoryLeader)
: MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) { : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
Alignment = L ? L->getAlignment() : 0; Alignment = L ? L->getAlignment() : 0;
} }
LoadExpression() = delete; LoadExpression() = delete;
LoadExpression(const LoadExpression &) = delete; LoadExpression(const LoadExpression &) = delete;
LoadExpression &operator=(const LoadExpression &) = delete; LoadExpression &operator=(const LoadExpression &) = delete;
@ -352,9 +358,7 @@ public:
cast<LoadExpression>(Other).getLoadInst() == getLoadInst(); cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeLoad, "; OS << "ExpressionTypeLoad, ";
@ -388,13 +392,13 @@ public:
Value *getStoredValue() const { return StoredValue; } Value *getStoredValue() const { return StoredValue; }
bool equals(const Expression &Other) const override; bool equals(const Expression &Other) const override;
bool exactlyEquals(const Expression &Other) const override { bool exactlyEquals(const Expression &Other) const override {
return Expression::exactlyEquals(Other) && return Expression::exactlyEquals(Other) &&
cast<StoreExpression>(Other).getStoreInst() == getStoreInst(); cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
} }
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeStore, "; OS << "ExpressionTypeStore, ";
@ -409,14 +413,13 @@ public:
class AggregateValueExpression final : public BasicExpression { class AggregateValueExpression final : public BasicExpression {
private: private:
unsigned MaxIntOperands; unsigned MaxIntOperands;
unsigned NumIntOperands; unsigned NumIntOperands = 0;
unsigned *IntOperands; unsigned *IntOperands = nullptr;
public: public:
AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands) AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
: BasicExpression(NumOperands, ET_AggregateValue), : BasicExpression(NumOperands, ET_AggregateValue),
MaxIntOperands(NumIntOperands), NumIntOperands(0), MaxIntOperands(NumIntOperands) {}
IntOperands(nullptr) {}
AggregateValueExpression() = delete; AggregateValueExpression() = delete;
AggregateValueExpression(const AggregateValueExpression &) = delete; AggregateValueExpression(const AggregateValueExpression &) = delete;
AggregateValueExpression & AggregateValueExpression &
@ -427,8 +430,8 @@ public:
return EB->getExpressionType() == ET_AggregateValue; return EB->getExpressionType() == ET_AggregateValue;
} }
typedef unsigned *int_arg_iterator; using int_arg_iterator = unsigned *;
typedef const unsigned *const_int_arg_iterator; using const_int_arg_iterator = const unsigned *;
int_arg_iterator int_op_begin() { return IntOperands; } int_arg_iterator int_op_begin() { return IntOperands; }
int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; } int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
@ -463,9 +466,7 @@ public:
hash_combine_range(int_op_begin(), int_op_end())); hash_combine_range(int_op_begin(), int_op_end()));
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeAggregateValue, "; OS << "ExpressionTypeAggregateValue, ";
@ -481,7 +482,8 @@ public:
class int_op_inserter class int_op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> { : public std::iterator<std::output_iterator_tag, void, void, void, void> {
private: private:
typedef AggregateValueExpression Container; using Container = AggregateValueExpression;
Container *AVE; Container *AVE;
public: public:
@ -524,9 +526,7 @@ public:
return hash_combine(this->BasicExpression::getHashValue(), BB); return hash_combine(this->BasicExpression::getHashValue(), BB);
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypePhi, "; OS << "ExpressionTypePhi, ";
@ -573,9 +573,7 @@ public:
VariableValue->getType(), VariableValue); VariableValue->getType(), VariableValue);
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeVariable, "; OS << "ExpressionTypeVariable, ";
@ -612,9 +610,7 @@ public:
ConstantValue->getType(), ConstantValue); ConstantValue->getType(), ConstantValue);
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeConstant, "; OS << "ExpressionTypeConstant, ";
@ -649,9 +645,7 @@ public:
return hash_combine(this->Expression::getHashValue(), Inst); return hash_combine(this->Expression::getHashValue(), Inst);
} }
//
// Debugging support // Debugging support
//
void printInternal(raw_ostream &OS, bool PrintEType) const override { void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType) if (PrintEType)
OS << "ExpressionTypeUnknown, "; OS << "ExpressionTypeUnknown, ";

View File

@ -6,41 +6,57 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// See the comments on JumpThreadingPass. /// See the comments on JumpThreadingPass.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H #ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
#define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H #define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueHandle.h"
#include <memory>
#include <utility>
namespace llvm { namespace llvm {
class BasicBlock;
class BinaryOperator;
class BranchInst;
class CmpInst;
class Constant;
class Function;
class Instruction;
class IntrinsicInst;
class LazyValueInfo;
class LoadInst;
class PHINode;
class TargetLibraryInfo;
class Value;
/// A private "module" namespace for types and utilities used by /// A private "module" namespace for types and utilities used by
/// JumpThreading. /// JumpThreading.
/// These are implementation details and should not be used by clients. /// These are implementation details and should not be used by clients.
namespace jumpthreading { namespace jumpthreading {
// These are at global scope so static functions can use them too. // These are at global scope so static functions can use them too.
typedef SmallVectorImpl<std::pair<Constant *, BasicBlock *>> PredValueInfo; using PredValueInfo = SmallVectorImpl<std::pair<Constant *, BasicBlock *>>;
typedef SmallVector<std::pair<Constant *, BasicBlock *>, 8> PredValueInfoTy; using PredValueInfoTy = SmallVector<std::pair<Constant *, BasicBlock *>, 8>;
// This is used to keep track of what kind of constant we're currently hoping // This is used to keep track of what kind of constant we're currently hoping
// to find. // to find.
enum ConstantPreference { WantInteger, WantBlockAddress }; enum ConstantPreference { WantInteger, WantBlockAddress };
}
} // end namespace jumpthreading
/// This pass performs 'jump threading', which looks at blocks that have /// This pass performs 'jump threading', which looks at blocks that have
/// multiple predecessors and multiple successors. If one or more of the /// multiple predecessors and multiple successors. If one or more of the
@ -57,7 +73,6 @@ enum ConstantPreference { WantInteger, WantBlockAddress };
/// ///
/// In this case, the unconditional branch at the end of the first if can be /// In this case, the unconditional branch at the end of the first if can be
/// revectored to the false side of the second if. /// revectored to the false side of the second if.
///
class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> { class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
TargetLibraryInfo *TLI; TargetLibraryInfo *TLI;
LazyValueInfo *LVI; LazyValueInfo *LVI;
@ -141,4 +156,4 @@ private:
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H

View File

@ -34,18 +34,38 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar/ConstantHoisting.h" #include "llvm/Transforms/Scalar/ConstantHoisting.h"
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <tuple> #include <tuple>
#include <utility>
using namespace llvm; using namespace llvm;
using namespace consthoist; using namespace consthoist;
@ -62,10 +82,12 @@ static cl::opt<bool> ConstHoistWithBlockFrequency(
"without hoisting.")); "without hoisting."));
namespace { namespace {
/// \brief The constant hoisting pass. /// \brief The constant hoisting pass.
class ConstantHoistingLegacyPass : public FunctionPass { class ConstantHoistingLegacyPass : public FunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
ConstantHoistingLegacyPass() : FunctionPass(ID) { ConstantHoistingLegacyPass() : FunctionPass(ID) {
initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry()); initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry());
} }
@ -87,9 +109,11 @@ public:
private: private:
ConstantHoistingPass Impl; ConstantHoistingPass Impl;
}; };
}
} // end anonymous namespace
char ConstantHoistingLegacyPass::ID = 0; char ConstantHoistingLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist", INITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist",
"Constant Hoisting", false, false) "Constant Hoisting", false, false)
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
@ -128,7 +152,6 @@ bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {
return MadeChange; return MadeChange;
} }
/// \brief Find the constant materialization insertion point. /// \brief Find the constant materialization insertion point.
Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
unsigned Idx) const { unsigned Idx) const {
@ -217,8 +240,9 @@ static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI,
} }
// Visit Orders in bottom-up order. // Visit Orders in bottom-up order.
typedef std::pair<SmallPtrSet<BasicBlock *, 16>, BlockFrequency> using InsertPtsCostPair =
InsertPtsCostPair; std::pair<SmallPtrSet<BasicBlock *, 16>, BlockFrequency>;
// InsertPtsMap is a map from a BB to the best insertion points for the // InsertPtsMap is a map from a BB to the best insertion points for the
// subtree of BB (subtree not including the BB itself). // subtree of BB (subtree not including the BB itself).
DenseMap<BasicBlock *, InsertPtsCostPair> InsertPtsMap; DenseMap<BasicBlock *, InsertPtsCostPair> InsertPtsMap;
@ -310,7 +334,6 @@ SmallPtrSet<Instruction *, 8> ConstantHoistingPass::findConstantInsertionPoint(
return InsertPts; return InsertPts;
} }
/// \brief Record constant integer ConstInt for instruction Inst at operand /// \brief Record constant integer ConstInt for instruction Inst at operand
/// index Idx. /// index Idx.
/// ///
@ -351,7 +374,6 @@ void ConstantHoistingPass::collectConstantCandidates(
} }
} }
/// \brief Check the operand for instruction Inst at index Idx. /// \brief Check the operand for instruction Inst at index Idx.
void ConstantHoistingPass::collectConstantCandidates( void ConstantHoistingPass::collectConstantCandidates(
ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) { ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) {
@ -393,7 +415,6 @@ void ConstantHoistingPass::collectConstantCandidates(
} }
} }
/// \brief Scan the instruction for expensive integer constants and record them /// \brief Scan the instruction for expensive integer constants and record them
/// in the constant candidate vector. /// in the constant candidate vector.
void ConstantHoistingPass::collectConstantCandidates( void ConstantHoistingPass::collectConstantCandidates(
@ -427,9 +448,8 @@ void ConstantHoistingPass::collectConstantCandidates(Function &Fn) {
// bit widths (APInt Operator- does not like that). If the value cannot be // bit widths (APInt Operator- does not like that). If the value cannot be
// represented in uint64 we return an "empty" APInt. This is then interpreted // represented in uint64 we return an "empty" APInt. This is then interpreted
// as the value is not in range. // as the value is not in range.
static llvm::Optional<APInt> calculateOffsetDiff(const APInt &V1, static Optional<APInt> calculateOffsetDiff(const APInt &V1, const APInt &V2) {
const APInt &V2) { Optional<APInt> Res = None;
llvm::Optional<APInt> Res = None;
unsigned BW = V1.getBitWidth() > V2.getBitWidth() ? unsigned BW = V1.getBitWidth() > V2.getBitWidth() ?
V1.getBitWidth() : V2.getBitWidth(); V1.getBitWidth() : V2.getBitWidth();
uint64_t LimVal1 = V1.getLimitedValue(); uint64_t LimVal1 = V1.getLimitedValue();
@ -496,9 +516,9 @@ ConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S,
DEBUG(dbgs() << "Cost: " << Cost << "\n"); DEBUG(dbgs() << "Cost: " << Cost << "\n");
for (auto C2 = S; C2 != E; ++C2) { for (auto C2 = S; C2 != E; ++C2) {
llvm::Optional<APInt> Diff = calculateOffsetDiff( Optional<APInt> Diff = calculateOffsetDiff(
C2->ConstInt->getValue(), C2->ConstInt->getValue(),
ConstCand->ConstInt->getValue()); ConstCand->ConstInt->getValue());
if (Diff) { if (Diff) {
const int ImmCosts = const int ImmCosts =
TTI->getIntImmCodeSizeCost(Opcode, OpndIdx, Diff.getValue(), Ty); TTI->getIntImmCodeSizeCost(Opcode, OpndIdx, Diff.getValue(), Ty);

View File

@ -20,39 +20,63 @@
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/Hashing.h" #include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h" #include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/OptimizationDiagnosticInfo.h" #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h" #include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/VNCoercion.h" #include "llvm/Transforms/Utils/VNCoercion.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <utility>
#include <vector> #include <vector>
using namespace llvm; using namespace llvm;
using namespace llvm::gvn; using namespace llvm::gvn;
using namespace llvm::VNCoercion; using namespace llvm::VNCoercion;
@ -80,10 +104,10 @@ MaxRecurseDepth("max-recurse-depth", cl::Hidden, cl::init(1000), cl::ZeroOrMore,
struct llvm::GVN::Expression { struct llvm::GVN::Expression {
uint32_t opcode; uint32_t opcode;
Type *type; Type *type;
bool commutative; bool commutative = false;
SmallVector<uint32_t, 4> varargs; SmallVector<uint32_t, 4> varargs;
Expression(uint32_t o = ~2U) : opcode(o), commutative(false) {} Expression(uint32_t o = ~2U) : opcode(o) {}
bool operator==(const Expression &other) const { bool operator==(const Expression &other) const {
if (opcode != other.opcode) if (opcode != other.opcode)
@ -105,20 +129,23 @@ struct llvm::GVN::Expression {
}; };
namespace llvm { namespace llvm {
template <> struct DenseMapInfo<GVN::Expression> { template <> struct DenseMapInfo<GVN::Expression> {
static inline GVN::Expression getEmptyKey() { return ~0U; } static inline GVN::Expression getEmptyKey() { return ~0U; }
static inline GVN::Expression getTombstoneKey() { return ~1U; } static inline GVN::Expression getTombstoneKey() { return ~1U; }
static unsigned getHashValue(const GVN::Expression &e) { static unsigned getHashValue(const GVN::Expression &e) {
using llvm::hash_value; using llvm::hash_value;
return static_cast<unsigned>(hash_value(e)); return static_cast<unsigned>(hash_value(e));
} }
static bool isEqual(const GVN::Expression &LHS, const GVN::Expression &RHS) { static bool isEqual(const GVN::Expression &LHS, const GVN::Expression &RHS) {
return LHS == RHS; return LHS == RHS;
} }
}; };
} // End llvm namespace.
} // end namespace llvm
/// Represents a particular available value that we know how to materialize. /// Represents a particular available value that we know how to materialize.
/// Materialization of an AvailableValue never fails. An AvailableValue is /// Materialization of an AvailableValue never fails. An AvailableValue is
@ -217,6 +244,7 @@ struct llvm::gvn::AvailableValueInBlock {
unsigned Offset = 0) { unsigned Offset = 0) {
return get(BB, AvailableValue::get(V, Offset)); return get(BB, AvailableValue::get(V, Offset));
} }
static AvailableValueInBlock getUndef(BasicBlock *BB) { static AvailableValueInBlock getUndef(BasicBlock *BB) {
return get(BB, AvailableValue::getUndef()); return get(BB, AvailableValue::getUndef());
} }
@ -344,7 +372,7 @@ GVN::Expression GVN::ValueTable::createExtractvalueExpr(ExtractValueInst *EI) {
// ValueTable External Functions // ValueTable External Functions
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
GVN::ValueTable::ValueTable() : nextValueNumber(1) {} GVN::ValueTable::ValueTable() = default;
GVN::ValueTable::ValueTable(const ValueTable &) = default; GVN::ValueTable::ValueTable(const ValueTable &) = default;
GVN::ValueTable::ValueTable(ValueTable &&) = default; GVN::ValueTable::ValueTable(ValueTable &&) = default;
GVN::ValueTable::~ValueTable() = default; GVN::ValueTable::~ValueTable() = default;
@ -456,7 +484,6 @@ uint32_t GVN::ValueTable::lookupOrAddCall(CallInst *C) {
uint32_t v = lookupOrAdd(cdep); uint32_t v = lookupOrAdd(cdep);
valueNumbering[C] = v; valueNumbering[C] = v;
return v; return v;
} else { } else {
valueNumbering[C] = nextValueNumber; valueNumbering[C] = nextValueNumber;
return nextValueNumber++; return nextValueNumber++;
@ -710,9 +737,6 @@ SpeculationFailure:
return false; return false;
} }
/// Given a set of loads specified by ValuesPerBlock, /// Given a set of loads specified by ValuesPerBlock,
/// construct SSA form, allowing us to eliminate LI. This returns the value /// construct SSA form, allowing us to eliminate LI. This returns the value
/// that should be used at LI's definition site. /// that should be used at LI's definition site.
@ -806,6 +830,7 @@ static void reportMayClobberedLoad(LoadInst *LI, MemDepResult DepInfo,
DominatorTree *DT, DominatorTree *DT,
OptimizationRemarkEmitter *ORE) { OptimizationRemarkEmitter *ORE) {
using namespace ore; using namespace ore;
User *OtherAccess = nullptr; User *OtherAccess = nullptr;
OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", LI); OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", LI);
@ -834,7 +859,6 @@ static void reportMayClobberedLoad(LoadInst *LI, MemDepResult DepInfo,
bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
Value *Address, AvailableValue &Res) { Value *Address, AvailableValue &Res) {
assert((DepInfo.isDef() || DepInfo.isClobber()) && assert((DepInfo.isDef() || DepInfo.isClobber()) &&
"expected a local dependence"); "expected a local dependence");
assert(LI->isUnordered() && "rules below are incorrect for ordered access"); assert(LI->isUnordered() && "rules below are incorrect for ordered access");
@ -966,7 +990,6 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
void GVN::AnalyzeLoadAvailability(LoadInst *LI, LoadDepVect &Deps, void GVN::AnalyzeLoadAvailability(LoadInst *LI, LoadDepVect &Deps,
AvailValInBlkVect &ValuesPerBlock, AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks) { UnavailBlkVect &UnavailableBlocks) {
// Filter out useless results (non-locals, etc). Keep track of the blocks // Filter out useless results (non-locals, etc). Keep track of the blocks
// where we have a value available in repl, also keep track of whether we see // where we have a value available in repl, also keep track of whether we see
// dependencies that produce an unknown value for the load (such as a call // dependencies that produce an unknown value for the load (such as a call
@ -1232,6 +1255,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
static void reportLoadElim(LoadInst *LI, Value *AvailableValue, static void reportLoadElim(LoadInst *LI, Value *AvailableValue,
OptimizationRemarkEmitter *ORE) { OptimizationRemarkEmitter *ORE) {
using namespace ore; using namespace ore;
ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI) ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
<< "load of type " << NV("Type", LI->getType()) << " eliminated" << "load of type " << NV("Type", LI->getType()) << " eliminated"
<< setExtraArgs() << " in favor of " << setExtraArgs() << " in favor of "
@ -1613,7 +1637,6 @@ static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E,
return Pred != nullptr; return Pred != nullptr;
} }
void GVN::assignBlockRPONumber(Function &F) { void GVN::assignBlockRPONumber(Function &F) {
uint32_t NextBlockNumber = 1; uint32_t NextBlockNumber = 1;
ReversePostOrderTraversal<Function *> RPOT(&F); ReversePostOrderTraversal<Function *> RPOT(&F);
@ -1621,7 +1644,6 @@ void GVN::assignBlockRPONumber(Function &F) {
BlockRPONumber[BB] = NextBlockNumber++; BlockRPONumber[BB] = NextBlockNumber++;
} }
// Tries to replace instruction with const, using information from // Tries to replace instruction with const, using information from
// ReplaceWithConstMap. // ReplaceWithConstMap.
bool GVN::replaceOperandsWithConsts(Instruction *Instr) const { bool GVN::replaceOperandsWithConsts(Instruction *Instr) const {
@ -2145,7 +2167,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) {
// when CurInst has operand defined in CurrentBlock (so it may be defined // when CurInst has operand defined in CurrentBlock (so it may be defined
// by phi in the loop header). // by phi in the loop header).
if (BlockRPONumber[P] >= BlockRPONumber[CurrentBlock] && if (BlockRPONumber[P] >= BlockRPONumber[CurrentBlock] &&
any_of(CurInst->operands(), [&](const Use &U) { llvm::any_of(CurInst->operands(), [&](const Use &U) {
if (auto *Inst = dyn_cast<Instruction>(U.get())) if (auto *Inst = dyn_cast<Instruction>(U.get()))
return Inst->getParent() == CurrentBlock; return Inst->getParent() == CurrentBlock;
return false; return false;
@ -2205,7 +2227,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) {
// Either we should have filled in the PRE instruction, or we should // Either we should have filled in the PRE instruction, or we should
// not have needed insertions. // not have needed insertions.
assert (PREInstr != nullptr || NumWithout == 0); assert(PREInstr != nullptr || NumWithout == 0);
++NumGVNPRE; ++NumGVNPRE;
@ -2461,6 +2483,7 @@ void GVN::assignValNumForDeadCode() {
class llvm::gvn::GVNLegacyPass : public FunctionPass { class llvm::gvn::GVNLegacyPass : public FunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
explicit GVNLegacyPass(bool NoLoads = false) explicit GVNLegacyPass(bool NoLoads = false)
: FunctionPass(ID), NoLoads(NoLoads) { : FunctionPass(ID), NoLoads(NoLoads) {
initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry()); initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry());
@ -2504,11 +2527,6 @@ private:
char GVNLegacyPass::ID = 0; char GVNLegacyPass::ID = 0;
// The public interface to this file...
FunctionPass *llvm::createGVNPass(bool NoLoads) {
return new GVNLegacyPass(NoLoads);
}
INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false) INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
@ -2518,3 +2536,8 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false) INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
// The public interface to this file...
FunctionPass *llvm::createGVNPass(bool NoLoads) {
return new GVNLegacyPass(NoLoads);
}

View File

@ -14,25 +14,50 @@
#include "llvm/Transforms/Scalar/JumpThreading.h" #include "llvm/Transforms/Scalar/JumpThreading.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h" #include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CFG.h" #include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h" #include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h" #include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h" #include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -41,8 +66,15 @@
#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <memory> #include <memory>
#include <utility>
using namespace llvm; using namespace llvm;
using namespace jumpthreading; using namespace jumpthreading;
@ -70,6 +102,7 @@ static cl::opt<bool> PrintLVIAfterJumpThreading(
cl::Hidden); cl::Hidden);
namespace { namespace {
/// This pass performs 'jump threading', which looks at blocks that have /// This pass performs 'jump threading', which looks at blocks that have
/// multiple predecessors and multiple successors. If one or more of the /// multiple predecessors and multiple successors. If one or more of the
/// predecessors of the block can be proven to always jump to one of the /// predecessors of the block can be proven to always jump to one of the
@ -85,12 +118,12 @@ namespace {
/// ///
/// In this case, the unconditional branch at the end of the first if can be /// In this case, the unconditional branch at the end of the first if can be
/// revectored to the false side of the second if. /// revectored to the false side of the second if.
///
class JumpThreading : public FunctionPass { class JumpThreading : public FunctionPass {
JumpThreadingPass Impl; JumpThreadingPass Impl;
public: public:
static char ID; // Pass identification static char ID; // Pass identification
JumpThreading(int T = -1) : FunctionPass(ID), Impl(T) { JumpThreading(int T = -1) : FunctionPass(ID), Impl(T) {
initializeJumpThreadingPass(*PassRegistry::getPassRegistry()); initializeJumpThreadingPass(*PassRegistry::getPassRegistry());
} }
@ -108,9 +141,11 @@ namespace {
void releaseMemory() override { Impl.releaseMemory(); } void releaseMemory() override { Impl.releaseMemory(); }
}; };
}
} // end anonymous namespace
char JumpThreading::ID = 0; char JumpThreading::ID = 0;
INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading", INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading",
"Jump Threading", false, false) "Jump Threading", false, false)
INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
@ -120,7 +155,9 @@ INITIALIZE_PASS_END(JumpThreading, "jump-threading",
"Jump Threading", false, false) "Jump Threading", false, false)
// Public interface to the Jump Threading pass // Public interface to the Jump Threading pass
FunctionPass *llvm::createJumpThreadingPass(int Threshold) { return new JumpThreading(Threshold); } FunctionPass *llvm::createJumpThreadingPass(int Threshold) {
return new JumpThreading(Threshold);
}
JumpThreadingPass::JumpThreadingPass(int T) { JumpThreadingPass::JumpThreadingPass(int T) {
BBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T); BBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T);
@ -177,7 +214,7 @@ static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB) {
BasicBlock *PhiBB) -> std::pair<BasicBlock *, BasicBlock *> { BasicBlock *PhiBB) -> std::pair<BasicBlock *, BasicBlock *> {
auto *PredBB = IncomingBB; auto *PredBB = IncomingBB;
auto *SuccBB = PhiBB; auto *SuccBB = PhiBB;
for (;;) { while (true) {
BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator()); BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator());
if (PredBr && PredBr->isConditional()) if (PredBr && PredBr->isConditional())
return {PredBB, SuccBB}; return {PredBB, SuccBB};
@ -236,7 +273,6 @@ static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB) {
} }
/// runOnFunction - Toplevel algorithm. /// runOnFunction - Toplevel algorithm.
///
bool JumpThreading::runOnFunction(Function &F) { bool JumpThreading::runOnFunction(Function &F) {
if (skipFunction(F)) if (skipFunction(F))
return false; return false;
@ -264,7 +300,6 @@ bool JumpThreading::runOnFunction(Function &F) {
PreservedAnalyses JumpThreadingPass::run(Function &F, PreservedAnalyses JumpThreadingPass::run(Function &F,
FunctionAnalysisManager &AM) { FunctionAnalysisManager &AM) {
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F); auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &LVI = AM.getResult<LazyValueAnalysis>(F); auto &LVI = AM.getResult<LazyValueAnalysis>(F);
auto &AA = AM.getResult<AAManager>(F); auto &AA = AM.getResult<AAManager>(F);
@ -293,7 +328,6 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
bool HasProfileData_, bool HasProfileData_,
std::unique_ptr<BlockFrequencyInfo> BFI_, std::unique_ptr<BlockFrequencyInfo> BFI_,
std::unique_ptr<BranchProbabilityInfo> BPI_) { std::unique_ptr<BranchProbabilityInfo> BPI_) {
DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n"); DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n");
TLI = TLI_; TLI = TLI_;
LVI = LVI_; LVI = LVI_;
@ -493,7 +527,6 @@ static unsigned getJumpThreadDuplicationCost(BasicBlock *BB,
/// within the loop (forming a nested loop). This simple analysis is not rich /// within the loop (forming a nested loop). This simple analysis is not rich
/// enough to track all of these properties and keep it up-to-date as the CFG /// enough to track all of these properties and keep it up-to-date as the CFG
/// mutates, so we don't allow any of these transformations. /// mutates, so we don't allow any of these transformations.
///
void JumpThreadingPass::FindLoopHeaders(Function &F) { void JumpThreadingPass::FindLoopHeaders(Function &F) {
SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> Edges; SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> Edges;
FindFunctionBackedges(F, Edges); FindFunctionBackedges(F, Edges);
@ -527,7 +560,6 @@ static Constant *getKnownConstant(Value *Val, ConstantPreference Preference) {
/// BB in the result vector. /// BB in the result vector.
/// ///
/// This returns true if there were any known values. /// This returns true if there were any known values.
///
bool JumpThreadingPass::ComputeValueKnownInPredecessors( bool JumpThreadingPass::ComputeValueKnownInPredecessors(
Value *V, BasicBlock *BB, PredValueInfo &Result, Value *V, BasicBlock *BB, PredValueInfo &Result,
ConstantPreference Preference, Instruction *CxtI) { ConstantPreference Preference, Instruction *CxtI) {
@ -764,6 +796,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors(
// x as a live-in. // x as a live-in.
{ {
using namespace PatternMatch; using namespace PatternMatch;
Value *AddLHS; Value *AddLHS;
ConstantInt *AddConst; ConstantInt *AddConst;
if (isa<ConstantInt>(CmpConst) && if (isa<ConstantInt>(CmpConst) &&
@ -860,14 +893,11 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors(
return !Result.empty(); return !Result.empty();
} }
/// GetBestDestForBranchOnUndef - If we determine that the specified block ends /// GetBestDestForBranchOnUndef - If we determine that the specified block ends
/// in an undefined jump, decide which block is best to revector to. /// in an undefined jump, decide which block is best to revector to.
/// ///
/// Since we can pick an arbitrary destination, we pick the successor with the /// Since we can pick an arbitrary destination, we pick the successor with the
/// fewest predecessors. This should reduce the in-degree of the others. /// fewest predecessors. This should reduce the in-degree of the others.
///
static unsigned GetBestDestForJumpOnUndef(BasicBlock *BB) { static unsigned GetBestDestForJumpOnUndef(BasicBlock *BB) {
TerminatorInst *BBTerm = BB->getTerminator(); TerminatorInst *BBTerm = BB->getTerminator();
unsigned MinSucc = 0; unsigned MinSucc = 0;
@ -1088,7 +1118,6 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) {
// for loads that are used by a switch or by the condition for the branch. If // for loads that are used by a switch or by the condition for the branch. If
// we see one, check to see if it's partially redundant. If so, insert a PHI // we see one, check to see if it's partially redundant. If so, insert a PHI
// which can then be used to thread the values. // which can then be used to thread the values.
//
Value *SimplifyValue = CondInst; Value *SimplifyValue = CondInst;
if (CmpInst *CondCmp = dyn_cast<CmpInst>(SimplifyValue)) if (CmpInst *CondCmp = dyn_cast<CmpInst>(SimplifyValue))
if (isa<Constant>(CondCmp->getOperand(1))) if (isa<Constant>(CondCmp->getOperand(1)))
@ -1108,7 +1137,6 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) {
// Handle a variety of cases where we are branching on something derived from // Handle a variety of cases where we are branching on something derived from
// a PHI node in the current block. If we can prove that any predecessors // a PHI node in the current block. If we can prove that any predecessors
// compute a predictable value based on a PHI node, thread those predecessors. // compute a predictable value based on a PHI node, thread those predecessors.
//
if (ProcessThreadableEdges(CondInst, BB, Preference, Terminator)) if (ProcessThreadableEdges(CondInst, BB, Preference, Terminator))
return true; return true;
@ -1238,7 +1266,9 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
LI->getAAMetadata(AATags); LI->getAAMetadata(AATags);
SmallPtrSet<BasicBlock*, 8> PredsScanned; SmallPtrSet<BasicBlock*, 8> PredsScanned;
typedef SmallVector<std::pair<BasicBlock*, Value*>, 8> AvailablePredsTy;
using AvailablePredsTy = SmallVector<std::pair<BasicBlock *, Value *>, 8>;
AvailablePredsTy AvailablePreds; AvailablePredsTy AvailablePreds;
BasicBlock *OneUnavailablePred = nullptr; BasicBlock *OneUnavailablePred = nullptr;
SmallVector<LoadInst*, 8> CSELoads; SmallVector<LoadInst*, 8> CSELoads;
@ -1397,8 +1427,8 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
/// the list. /// the list.
static BasicBlock * static BasicBlock *
FindMostPopularDest(BasicBlock *BB, FindMostPopularDest(BasicBlock *BB,
const SmallVectorImpl<std::pair<BasicBlock*, const SmallVectorImpl<std::pair<BasicBlock *,
BasicBlock*> > &PredToDestList) { BasicBlock *>> &PredToDestList) {
assert(!PredToDestList.empty()); assert(!PredToDestList.empty());
// Determine popularity. If there are multiple possible destinations, we // Determine popularity. If there are multiple possible destinations, we
@ -1616,7 +1646,6 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
/// ProcessBranchOnPHI - We have an otherwise unthreadable conditional branch on /// ProcessBranchOnPHI - We have an otherwise unthreadable conditional branch on
/// a PHI node in the current block. See if there are any simplifications we /// a PHI node in the current block. See if there are any simplifications we
/// can do based on inputs to the phi node. /// can do based on inputs to the phi node.
///
bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) { bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) {
BasicBlock *BB = PN->getParent(); BasicBlock *BB = PN->getParent();
@ -1646,7 +1675,6 @@ bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) {
/// ProcessBranchOnXOR - We have an otherwise unthreadable conditional branch on /// ProcessBranchOnXOR - We have an otherwise unthreadable conditional branch on
/// a xor instruction in the current block. See if there are any /// a xor instruction in the current block. See if there are any
/// simplifications we can do based on inputs to the xor. /// simplifications we can do based on inputs to the xor.
///
bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) { bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) {
BasicBlock *BB = BO->getParent(); BasicBlock *BB = BO->getParent();
@ -1751,7 +1779,6 @@ bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) {
return DuplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto); return DuplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
} }
/// AddPHINodeEntriesForMappedBlock - We're adding 'NewPred' as a new /// AddPHINodeEntriesForMappedBlock - We're adding 'NewPred' as a new
/// predecessor to the PHIBB block. If it has PHI nodes, add entries for /// predecessor to the PHIBB block. If it has PHI nodes, add entries for
/// NewPred using the entries from OldPred (suitably mapped). /// NewPred using the entries from OldPred (suitably mapped).
@ -1914,7 +1941,6 @@ bool JumpThreadingPass::ThreadEdge(BasicBlock *BB,
DEBUG(dbgs() << "\n"); DEBUG(dbgs() << "\n");
} }
// Ok, NewBB is good to go. Update the terminator of PredBB to jump to // Ok, NewBB is good to go. Update the terminator of PredBB to jump to
// NewBB instead of BB. This eliminates predecessors from BB, which requires // NewBB instead of BB. This eliminates predecessors from BB, which requires
// us to simplify any PHI nodes in BB. // us to simplify any PHI nodes in BB.
@ -2313,7 +2339,7 @@ bool JumpThreadingPass::TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {
/// %p = phi [0, %bb1], [1, %bb2], [0, %bb3], [1, %bb4], ... /// %p = phi [0, %bb1], [1, %bb2], [0, %bb3], [1, %bb4], ...
/// %c = cmp %p, 0 /// %c = cmp %p, 0
/// %s = select %c, trueval, falseval /// %s = select %c, trueval, falseval
// ///
/// And expand the select into a branch structure. This later enables /// And expand the select into a branch structure. This later enables
/// jump-threading over bb in this pass. /// jump-threading over bb in this pass.
/// ///
@ -2399,6 +2425,7 @@ bool JumpThreadingPass::TryToUnfoldSelectInCurrBB(BasicBlock *BB) {
/// guard is then threaded to one of them. /// guard is then threaded to one of them.
bool JumpThreadingPass::ProcessGuards(BasicBlock *BB) { bool JumpThreadingPass::ProcessGuards(BasicBlock *BB) {
using namespace PatternMatch; using namespace PatternMatch;
// We only want to deal with two predecessors. // We only want to deal with two predecessors.
BasicBlock *Pred1, *Pred2; BasicBlock *Pred1, *Pred2;
auto PI = pred_begin(BB), PE = pred_end(BB); auto PI = pred_begin(BB), PE = pred_end(BB);