#include "llvm/Transforms/Scalar/MergeICmps.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include <algorithm>
#include <numeric>
#include <utility>
#include <vector>
usingnamespacellvm;
namespace {
#define DEBUG_TYPE …
struct BCEAtom { … };
class BaseIdentifier { … };
BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId) { … }
struct BCECmp { … };
class BCECmpBlock { … };
bool BCECmpBlock::canSinkBCECmpInst(const Instruction *Inst,
AliasAnalysis &AA) const { … }
void BCECmpBlock::split(BasicBlock *NewParent, AliasAnalysis &AA) const { … }
bool BCECmpBlock::canSplit(AliasAnalysis &AA) const { … }
bool BCECmpBlock::doesOtherWork() const { … }
std::optional<BCECmp> visitICmp(const ICmpInst *const CmpI,
const ICmpInst::Predicate ExpectedPredicate,
BaseIdentifier &BaseId) { … }
std::optional<BCECmpBlock> visitCmpBlock(Value *const Val,
BasicBlock *const Block,
const BasicBlock *const PhiBlock,
BaseIdentifier &BaseId) { … }
static inline void enqueueBlock(std::vector<BCECmpBlock> &Comparisons,
BCECmpBlock &&Comparison) { … }
class BCECmpChain { … };
static bool areContiguous(const BCECmpBlock &First, const BCECmpBlock &Second) { … }
static unsigned getMinOrigOrder(const BCECmpChain::ContiguousBlocks &Blocks) { … }
static std::vector<BCECmpChain::ContiguousBlocks>
mergeBlocks(std::vector<BCECmpBlock> &&Blocks) { … }
BCECmpChain::BCECmpChain(const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
AliasAnalysis &AA)
: … { … }
namespace {
class MergedBlockName { … };
}
static BasicBlock *mergeComparisons(ArrayRef<BCECmpBlock> Comparisons,
BasicBlock *const InsertBefore,
BasicBlock *const NextCmpBlock,
PHINode &Phi, const TargetLibraryInfo &TLI,
AliasAnalysis &AA, DomTreeUpdater &DTU) { … }
bool BCECmpChain::simplify(const TargetLibraryInfo &TLI, AliasAnalysis &AA,
DomTreeUpdater &DTU) { … }
std::vector<BasicBlock *> getOrderedBlocks(PHINode &Phi,
BasicBlock *const LastBlock,
int NumBlocks) { … }
bool processPhi(PHINode &Phi, const TargetLibraryInfo &TLI, AliasAnalysis &AA,
DomTreeUpdater &DTU) { … }
static bool runImpl(Function &F, const TargetLibraryInfo &TLI,
const TargetTransformInfo &TTI, AliasAnalysis &AA,
DominatorTree *DT) { … }
class MergeICmpsLegacyPass : public FunctionPass { … };
}
char MergeICmpsLegacyPass::ID = …;
INITIALIZE_PASS_BEGIN(MergeICmpsLegacyPass, "mergeicmps",
"Merge contiguous icmps into a memcmp", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(MergeICmpsLegacyPass, "mergeicmps",
"Merge contiguous icmps into a memcmp", false, false)
Pass *llvm::createMergeICmpsLegacyPass() { … }
PreservedAnalyses MergeICmpsPass::run(Function &F,
FunctionAnalysisManager &AM) { … }