#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/IteratedDominanceFrontier.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <memory>
#include <utility>
#include <vector>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumHoisted, "Number of instructions hoisted");
STATISTIC(NumRemoved, "Number of instructions removed");
STATISTIC(NumLoadsHoisted, "Number of loads hoisted");
STATISTIC(NumLoadsRemoved, "Number of loads removed");
STATISTIC(NumStoresHoisted, "Number of stores hoisted");
STATISTIC(NumStoresRemoved, "Number of stores removed");
STATISTIC(NumCallsHoisted, "Number of calls hoisted");
STATISTIC(NumCallsRemoved, "Number of calls removed");
static cl::opt<int>
MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1),
cl::desc("Max number of instructions to hoist "
"(default unlimited = -1)"));
static cl::opt<int> MaxNumberOfBBSInPath(
"gvn-hoist-max-bbs", cl::Hidden, cl::init(4),
cl::desc("Max number of basic blocks on the path between "
"hoisting locations (default = 4, unlimited = -1)"));
static cl::opt<int> MaxDepthInBB(
"gvn-hoist-max-depth", cl::Hidden, cl::init(100),
cl::desc("Hoist instructions from the beginning of the BB up to the "
"maximum specified depth (default = 100, unlimited = -1)"));
static cl::opt<int>
MaxChainLength("gvn-hoist-max-chain-length", cl::Hidden, cl::init(10),
cl::desc("Maximum length of dependent chains to hoist "
"(default = 10, unlimited = -1)"));
namespace llvm {
BBSideEffectsSet;
SmallVecInsn;
SmallVecImplInsn;
HoistingPointInfo;
HoistingPointList;
VNType;
VNtoInsns;
struct CHIArg { … };
CHIIt;
CHIArgs;
OutValuesType;
InValuesType;
enum : uintptr_t { … };
class InsnInfo { … };
class LoadInfo { … };
class StoreInfo { … };
class CallInfo { … };
class GVNHoist { … };
bool GVNHoist::run(Function &F) { … }
unsigned int GVNHoist::rank(const Value *V) const { … }
bool GVNHoist::hasEH(const BasicBlock *BB) { … }
bool GVNHoist::hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
const BasicBlock *BB) { … }
bool GVNHoist::hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
int &NBBsOnAllPaths) { … }
bool GVNHoist::hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
int &NBBsOnAllPaths) { … }
bool GVNHoist::hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
int &NBBsOnAllPaths) { … }
bool GVNHoist::safeToHoistLdSt(const Instruction *NewPt,
const Instruction *OldPt, MemoryUseOrDef *U,
GVNHoist::InsKind K, int &NBBsOnAllPaths) { … }
bool GVNHoist::valueAnticipable(CHIArgs C, Instruction *TI) const { … }
void GVNHoist::checkSafety(CHIArgs C, BasicBlock *BB, GVNHoist::InsKind K,
SmallVectorImpl<CHIArg> &Safe) { … }
void GVNHoist::fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
GVNHoist::RenameStackType &RenameStack) { … }
void GVNHoist::fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
GVNHoist::RenameStackType &RenameStack) { … }
void GVNHoist::findHoistableCandidates(OutValuesType &CHIBBs,
GVNHoist::InsKind K,
HoistingPointList &HPL) { … }
bool GVNHoist::allOperandsAvailable(const Instruction *I,
const BasicBlock *HoistPt) const { … }
bool GVNHoist::allGepOperandsAvailable(const Instruction *I,
const BasicBlock *HoistPt) const { … }
void GVNHoist::makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
const SmallVecInsn &InstructionsToHoist,
Instruction *Gep) const { … }
void GVNHoist::updateAlignment(Instruction *I, Instruction *Repl) { … }
unsigned GVNHoist::rauw(const SmallVecInsn &Candidates, Instruction *Repl,
MemoryUseOrDef *NewMemAcc) { … }
void GVNHoist::raMPHIuw(MemoryUseOrDef *NewMemAcc) { … }
unsigned GVNHoist::removeAndReplace(const SmallVecInsn &Candidates,
Instruction *Repl, BasicBlock *DestBB,
bool MoveAccess) { … }
bool GVNHoist::makeGepOperandsAvailable(
Instruction *Repl, BasicBlock *HoistPt,
const SmallVecInsn &InstructionsToHoist) const { … }
std::pair<unsigned, unsigned> GVNHoist::hoist(HoistingPointList &HPL) { … }
std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(Function &F) { … }
}
PreservedAnalyses GVNHoistPass::run(Function &F, FunctionAnalysisManager &AM) { … }