#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.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/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <optional>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumPhis, "Number of phis propagated");
STATISTIC(NumPhiCommon, "Number of phis deleted via common incoming value");
STATISTIC(NumSelects, "Number of selects propagated");
STATISTIC(NumCmps, "Number of comparisons propagated");
STATISTIC(NumReturns, "Number of return values propagated");
STATISTIC(NumDeadCases, "Number of switch cases removed");
STATISTIC(NumSDivSRemsNarrowed,
"Number of sdivs/srems whose width was decreased");
STATISTIC(NumSDivs, "Number of sdiv converted to udiv");
STATISTIC(NumUDivURemsNarrowed,
"Number of udivs/urems whose width was decreased");
STATISTIC(NumAShrsConverted, "Number of ashr converted to lshr");
STATISTIC(NumAShrsRemoved, "Number of ashr removed");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumSExt, "Number of sext converted to zext");
STATISTIC(NumSIToFP, "Number of sitofp converted to uitofp");
STATISTIC(NumSICmps, "Number of signed icmp preds simplified to unsigned");
STATISTIC(NumAnd, "Number of ands removed");
STATISTIC(NumNW, "Number of no-wrap deductions");
STATISTIC(NumNSW, "Number of no-signed-wrap deductions");
STATISTIC(NumNUW, "Number of no-unsigned-wrap deductions");
STATISTIC(NumAddNW, "Number of no-wrap deductions for add");
STATISTIC(NumAddNSW, "Number of no-signed-wrap deductions for add");
STATISTIC(NumAddNUW, "Number of no-unsigned-wrap deductions for add");
STATISTIC(NumSubNW, "Number of no-wrap deductions for sub");
STATISTIC(NumSubNSW, "Number of no-signed-wrap deductions for sub");
STATISTIC(NumSubNUW, "Number of no-unsigned-wrap deductions for sub");
STATISTIC(NumMulNW, "Number of no-wrap deductions for mul");
STATISTIC(NumMulNSW, "Number of no-signed-wrap deductions for mul");
STATISTIC(NumMulNUW, "Number of no-unsigned-wrap deductions for mul");
STATISTIC(NumShlNW, "Number of no-wrap deductions for shl");
STATISTIC(NumShlNSW, "Number of no-signed-wrap deductions for shl");
STATISTIC(NumShlNUW, "Number of no-unsigned-wrap deductions for shl");
STATISTIC(NumAbs, "Number of llvm.abs intrinsics removed");
STATISTIC(NumOverflows, "Number of overflow checks removed");
STATISTIC(NumSaturating,
"Number of saturating arithmetics converted to normal arithmetics");
STATISTIC(NumNonNull, "Number of function pointer arguments marked non-null");
STATISTIC(NumCmpIntr, "Number of llvm.[us]cmp intrinsics removed");
STATISTIC(NumMinMax, "Number of llvm.[us]{min,max} intrinsics removed");
STATISTIC(NumSMinMax,
"Number of llvm.s{min,max} intrinsics simplified to unsigned");
STATISTIC(NumUDivURemsNarrowedExpanded,
"Number of bound udiv's/urem's expanded");
STATISTIC(NumNNeg, "Number of zext/uitofp non-negative deductions");
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) { … }
static bool processSelect(SelectInst *S, LazyValueInfo *LVI) { … }
static bool simplifyCommonValuePhi(PHINode *P, LazyValueInfo *LVI,
DominatorTree *DT) { … }
static Value *getValueOnEdge(LazyValueInfo *LVI, Value *Incoming,
BasicBlock *From, BasicBlock *To,
Instruction *CxtI) { … }
static bool processPHI(PHINode *P, LazyValueInfo *LVI, DominatorTree *DT,
const SimplifyQuery &SQ) { … }
static bool processICmp(ICmpInst *Cmp, LazyValueInfo *LVI) { … }
static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) { … }
static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) { … }
static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
DominatorTree *DT) { … }
static bool willNotOverflow(BinaryOpIntrinsic *BO, LazyValueInfo *LVI) { … }
static void setDeducedOverflowingFlags(Value *V, Instruction::BinaryOps Opcode,
bool NewNSW, bool NewNUW) { … }
static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI);
static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) { … }
static bool processCmpIntrinsic(CmpIntrinsic *CI, LazyValueInfo *LVI) { … }
static bool processMinMaxIntrinsic(MinMaxIntrinsic *MM, LazyValueInfo *LVI) { … }
static bool processOverflowIntrinsic(WithOverflowInst *WO, LazyValueInfo *LVI) { … }
static bool processSaturatingInst(SaturatingInst *SI, LazyValueInfo *LVI) { … }
static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) { … }
enum class Domain { … };
static Domain getDomain(const ConstantRange &CR) { … }
static bool narrowSDivOrSRem(BinaryOperator *Instr, const ConstantRange &LCR,
const ConstantRange &RCR) { … }
static bool expandUDivOrURem(BinaryOperator *Instr, const ConstantRange &XCR,
const ConstantRange &YCR) { … }
static bool narrowUDivOrURem(BinaryOperator *Instr, const ConstantRange &XCR,
const ConstantRange &YCR) { … }
static bool processUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) { … }
static bool processSRem(BinaryOperator *SDI, const ConstantRange &LCR,
const ConstantRange &RCR, LazyValueInfo *LVI) { … }
static bool processSDiv(BinaryOperator *SDI, const ConstantRange &LCR,
const ConstantRange &RCR, LazyValueInfo *LVI) { … }
static bool processSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) { … }
static bool processAShr(BinaryOperator *SDI, LazyValueInfo *LVI) { … }
static bool processSExt(SExtInst *SDI, LazyValueInfo *LVI) { … }
static bool processPossibleNonNeg(PossiblyNonNegInst *I, LazyValueInfo *LVI) { … }
static bool processZExt(ZExtInst *ZExt, LazyValueInfo *LVI) { … }
static bool processUIToFP(UIToFPInst *UIToFP, LazyValueInfo *LVI) { … }
static bool processSIToFP(SIToFPInst *SIToFP, LazyValueInfo *LVI) { … }
static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) { … }
static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) { … }
static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
const SimplifyQuery &SQ) { … }
PreservedAnalyses
CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) { … }