llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-amdgpu Author: Momchil Velikov (momchil-velikov) <details> <summary>Changes</summary> --- Patch is 217.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210330.diff 19 Files Affected: - (modified) clang/test/CodeGen/attr-counted-by-with-sanitizers.c (+26-28) - (modified) llvm/include/llvm/Transforms/Scalar/GVN.h (+137-97) - (modified) llvm/lib/Transforms/Scalar/GVN.cpp (+1770-1544) - (modified) llvm/test/CodeGen/AMDGPU/memcpy-crash-issue63986.ll (+65-82) - (modified) llvm/test/CodeGen/NVPTX/gvn-scalar-pre-reg-pressure.ll (+2-2) - (modified) llvm/test/Transforms/GVN/2012-05-22-PreCrash.ll (+1-1) - (modified) llvm/test/Transforms/GVN/PRE/load-pre-across-backedge.ll (+2-2) - (modified) llvm/test/Transforms/GVN/PRE/local-pre.ll (+2-2) - (modified) llvm/test/Transforms/GVN/PRE/no-scalar-pre.ll (+4-4) - (modified) llvm/test/Transforms/GVN/PRE/phi-translate.ll (+2-2) - (modified) llvm/test/Transforms/GVN/PRE/pre-basic-add.ll (+3-3) - (modified) llvm/test/Transforms/GVN/PRE/pre-load-through-select.ll (+2-2) - (modified) llvm/test/Transforms/GVN/PRE/pre-no-cost-phi.ll (+2-2) - (modified) llvm/test/Transforms/GVN/PRE/pre-poison-add.ll (+2-2) - (modified) llvm/test/Transforms/GVN/freeze.ll (+1-1) - (modified) llvm/test/Transforms/GVN/gc_relocate.ll (+1-1) - (added) llvm/test/Transforms/GVN/operand-bundle-unique-vn.ll (+18) - (added) llvm/test/Transforms/GVN/simple-gvn-hoist-limits.ll (+152) - (added) llvm/test/Transforms/GVN/simple-gvn-hoist-scalars.ll (+419) ``````````diff diff --git a/clang/test/CodeGen/attr-counted-by-with-sanitizers.c b/clang/test/CodeGen/attr-counted-by-with-sanitizers.c index e840db632957e..81be6bdad9936 100644 --- a/clang/test/CodeGen/attr-counted-by-with-sanitizers.c +++ b/clang/test/CodeGen/attr-counted-by-with-sanitizers.c @@ -234,16 +234,16 @@ size_t test_return_bdos_cast_of_whole_struct(struct annotated *p) { // SANITIZE-WITH-ATTR: [[CONT1]]: // SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[DOTCOUNTED_BY_LOAD]], 2 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = zext i32 [[INDEX]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label %[[CONT12:.*]], label %[[HANDLER_OUT_OF_BOUNDS8:.*]], !prof [[PROF7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS8]]: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP2]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT12]]: // SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 244 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i32 [[RESULT]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr [[ARRAYIDX10]], align 4, !tbaa [[INT_TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i32 [[RESULT]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[TMP2]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP3]], ptr [[ARRAYIDX10]], align 4, !tbaa [[INT_TBAA8]] // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT79:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 3 // SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT79]], label %[[HANDLER_OUT_OF_BOUNDS18:.*]], label %[[CONT19:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS18]]: @@ -251,37 +251,37 @@ size_t test_return_bdos_cast_of_whole_struct(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT19]]: // SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[INDEX]], 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp samesign ult i32 [[ADD]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM31:%.*]] = zext nneg i32 [[ADD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT38:.*]], label %[[HANDLER_OUT_OF_BOUNDS34:.*]], !prof [[PROF7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp samesign ult i32 [[ADD]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext nneg i32 [[ADD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label %[[CONT38:.*]], label %[[HANDLER_OUT_OF_BOUNDS34:.*]], !prof [[PROF7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS34]]: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM31]]) #[[ATTR7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT38]]: // SANITIZE-WITH-ATTR-NEXT: [[RESULT25:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 240 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = and i32 [[RESULT25]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[IDXPROM31]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP4]], ptr [[ARRAYIDX36]], align 4, !tbaa [[INT_TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i32 [[RESULT25]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[TMP5]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP6]], ptr [[ARRAYIDX36]], align 4, !tbaa [[INT_TBAA8]] // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i32 [[FAM_IDX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label %[[HANDLER_OUT_OF_BOUNDS45:.*]], label %[[CONT46:.*]], !prof [[PROF9]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS45]]: -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[FAM_IDX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[FAM_IDX]] to i64, !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP7]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT46]]: // SANITIZE-WITH-ATTR-NEXT: [[ADD59:%.*]] = add nuw nsw i32 [[INDEX]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp samesign ult i32 [[ADD59]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM60:%.*]] = zext nneg i32 [[ADD59]] to i64 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT67:.*]], label %[[HANDLER_OUT_OF_BOUNDS63:.*]], !prof [[PROF7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp samesign ult i32 [[ADD59]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = zext nneg i32 [[ADD59]] to i64 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label %[[CONT67:.*]], label %[[HANDLER_OUT_OF_BOUNDS63:.*]], !prof [[PROF7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS63]]: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM60]]) #[[ATTR7]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[TMP9]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT67]]: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX65:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[IDXPROM60]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX65:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARRAY]], i64 [[TMP9]] // SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = sub nsw i32 [[DOTCOUNTED_BY_LOAD]], [[FAM_IDX]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = shl i32 [[DOTTR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 252 -// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP8]], ptr [[ARRAYIDX65]], align 4, !tbaa [[INT_TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = shl i32 [[DOTTR]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = and i32 [[TMP10]], 252 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP11]], ptr [[ARRAYIDX65]], align 4, !tbaa [[INT_TBAA8]] // SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_assign_size_of_pointer_into_fam( @@ -483,15 +483,14 @@ size_t test_return_bdos_of_fam_in_anon_struct(struct anon_struct *p) { // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOTCOUNTED_BY_LOAD]] to i32, !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i32 [[INDEX]], [[TMP1]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT7:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]: -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP3]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT7]]: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[INTS]], i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[INTS]], i64 [[TMP3]] // SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[CHAR_TBAA10:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: ret void // @@ -529,15 +528,14 @@ size_t test_return_bdos_of_anon_struct(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i32, !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i32 [[INDEX]], [[TMP1]], !nosanitize [[META6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT14:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]: -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[TMP3]]) #[[ATTR7]], !nosanitize [[META6]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] // SANITIZE-WITH-ATTR: [[CONT14]]: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[INTS]], i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[INTS]], i64 [[TMP3]] // SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[CHAR_TBAA10]] // SANITIZE-WITH-ATTR-NEXT: ret void // diff --git a/llvm/include/llvm/Transforms/Scalar/GVN.h b/llvm/include/llvm/Transforms/Scalar/GVN.h index 9142defb34de2..dd0fbcee1e253 100644 --- a/llvm/include/llvm/Transforms/Scalar/GVN.h +++ b/llvm/include/llvm/Transforms/Scalar/GVN.h @@ -61,15 +61,6 @@ class PHINode; class TargetLibraryInfo; class Value; class IntrinsicInst; -/// A private "module" namespace for types and utilities used by GVN. These -/// are implementation details and should not be used by clients. -namespace LLVM_LIBRARY_VISIBILITY_NAMESPACE gvn { - -struct AvailableValue; -struct AvailableValueInBlock; -class GVNLegacyPass; - -} // end namespace gvn /// A set of parameters to control various transforms performed by GVN pass. // Each of the optional boolean parameters can be set to: @@ -129,35 +120,10 @@ struct GVNOptions { /// FIXME: We should have a good summary of the GVN algorithm implemented by /// this particular pass here. class GVNPass : public OptionalPassInfoMixin<GVNPass> { - GVNOptions Options; - public: struct Expression; - - GVNPass(GVNOptions Options = {}) : Options(Options) {} - - /// Run the pass over the function. - LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); - - LLVM_ABI void - printPipeline(raw_ostream &OS, - function_ref<StringRef(StringRef)> MapClassName2PassName); - - /// This removes the specified instruction from - /// our various maps and marks it for deletion. - LLVM_ABI void salvageAndRemoveInstruction(Instruction *I); - - DominatorTree &getDominatorTree() const { return *DT; } - AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); } - MemoryDependenceResults &getMemDep() const { return *MD; } - - LLVM_ABI bool isScalarPREEnabled() const; - LLVM_ABI bool isLoadPREEnabled() const; - LLVM_ABI bool isLoadInLoopPREEnabled() const; - LLVM_ABI bool isLoadPRESplitBackedgeEnabled() const; - LLVM_ABI bool isMemDepEnabled() const; - LLVM_ABI bool isMemorySSAEnabled() const; - + struct AvailableValue; + struct AvailableValueInBlock; /// This class holds the mapping between values and value numbers. It is used /// as an efficient mechanism to determine the expression-wise equivalence of /// two values. @@ -217,6 +183,7 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { LLVM_ABI ~ValueTable(); LLVM_ABI ValueTable &operator=(const ValueTable &Arg); + LLVM_ABI void add(Value *V, uint32_t Num); LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA); LLVM_ABI uint32_t lookupOrAdd(Value *V); LLVM_ABI uint32_t lookup(Value *V, bool Verify = true) const; @@ -229,7 +196,6 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock); LLVM_ABI bool exists(Value *V) const; - LLVM_ABI void add(Value *V, uint32_t Num); LLVM_ABI void clear(); LLVM_ABI void erase(Value *V); void setAliasAnalysis(AAResults *A) { AA = A; } @@ -248,9 +214,10 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { }; private: - friend class gvn::GVNLegacyPass; + friend class GVNLegacyPass; friend struct DenseMapInfo<Expression>; + GVNOptions Options; MemoryDependenceResults *MD = nullptr; DominatorTree *DT = nullptr; const TargetLibraryInfo *TLI = nullptr; @@ -261,7 +228,6 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { LoopInfo *LI = nullptr; AAResults *AA = nullptr; MemorySSAUpdater *MSSAU = nullptr; - ValueTable VN; /// A mapping from value numbers to lists of Value*'s that @@ -353,18 +319,53 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { // of BlockRPONumber prior to accessing the contents of BlockRPONumber. bool InvalidBlockRPONumbers = true; - using LoadDepVect = SmallVector<NonLocalDepResult, 64>; - using AvailValInBlkVect = SmallVector<gvn::AvailableValueInBlock, 64>; - using UnavailBlkVect = SmallVector<BasicBlock *, 64>; - - bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, - const TargetLibraryInfo &RunTLI, AAResults &RunAA, - MemoryDependenceResults *RunMD, LoopInfo &LI, - OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr); - // List of critical edges to be split between iterations. SmallVector<std::pair<Instruction *, unsigned>, 4> ToSplit; + // A pair of instructions with the same value number to be hoisted and merged, + // together with their respective hoist barriers. A pair of insructions can be + // hoisted iff both their barriers (if not null) are hoisted as well. The + // `WeakVH` is used to track when the barrier instruction itself is hoisted. + struct HoistPair { + Instruction *ThenI = nullptr; + Instruction *ThenB = nullptr; + Instruction *ElseI = nullptr; + WeakVH ElseB = nullptr; + }; + + /// A mapping from value numbers to a pair of instructions. This map + /// stores pairs of instructions with the same value number, from two blocks + /// having a single common predecessor, for the duration of a single top level + /// iteration in `performHoist`. + using HoistMap = DenseMap<uint32_t, HoistPair>; + HoistMap HoistPairs; + +public: + GVNPass(GVNOptions Options = {}) : Options(Options) {} + + /// Run the pass over the function. + LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + + LLVM_ABI void + printPipeline(raw_ostream &OS, + function_ref<StringRef(StringRef)> MapClassName2PassName); + +private: + DominatorTree &getDominatorTree() const { return *DT; } + AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); } + MemoryDependenceResults &getMemDep() const { return *MD; } + + bool isScalarPREEnabled() const; + bool isLoadPREEnabled() const; + bool isLoadInLoopPREEnabled() const; + bool isLoadPRESplitBackedgeEnabled() const; + bool isMemDepEnabled() const; + bool isMemorySSAEnabled() const; + + using LoadDepVect = SmallVector<NonLocalDepResult, 64>; + using AvailValInBlkVect = SmallVector<AvailableValueInBlock, 64>; + using UnavailBlkVect = SmallVector<BasicBlock *, 64>; + enum class DepKind { Other = 0, // Unknown value. Def, // Exactly overlapping locations. @@ -423,6 +424,41 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { using DependencyBlockSet = DenseMap<BasicBlock *, DependencyBlockInfo>; + /// Given a select-dependency for the load (the load address is a select of + /// \p TrueAddr and \p FalseAddr guarded by \p Cond), determine whether a + /// value is available by finding dominating values for both addresses. If + /// so, the load can be rematerialized as a select of those two values. + std::optional<AvailableValue> + analyzeSelectAvailability(LoadInst *Load, Value *Cond, Value *TrueAddr, + Value *FalseAddr, Instruction *From); + + /// Given a local dependency (Def or Clobber) determine if a value is + /// available for the load. + std::optional<AvailableValue> + analyzeLoadAvailability(LoadInst *Load, const ReachingMemVal &Dep, + Value *Address); + + /// 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 + /// ValuesPerBlock. If not, add it to UnavailableBlocks. + void analyzeLoadAvailability(LoadInst *Load, + SmallVectorImpl<ReachingMemVal> &Deps, + AvailValInBlkVect &ValuesPerBlock, + UnavailBlkVect &UnavailableBlocks); + + /// Given a critical edge from Pred to LoadBB, find a load instruction + /// which is identical to Load from another successor of Pred. + LoadInst *findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB, + LoadInst *Load); + + /// Eliminates partially redundant \p Load, replacing it with \p + /// AvailableLoads (connected by Phis if needed). + void eliminatePartiallyRedundantLoad( + LoadInst *Load, AvailValInBlkVect &ValuesPerBlock, + MapVector<BasicBlock *, Value *> &AvailableLoads, + MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad); + + // Helper functions for d etermining load dependencies. std::optional<GVNPass::ReachingMemVal> scanMemoryAccessesUsers( const MemoryLocation &Loc, bool IsInvariantLoad, BasicBlock *BB, const SmallVectorImpl<MemoryAccess *> &ClobbersList, MemorySSA &MSSA, @@ -445,41 +481,7 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> { SmallVectorImpl<ReachingMemVal> &Values, MemorySSA &MSSA, AAResults &AA); - // Helper functions of redundant load elimination. - bool processLoad(LoadInst *L); - bool processMaskedLoad(IntrinsicInst *I); - bool processNonLocalLoad(LoadInst *L); - bool processNonLocalLoad(LoadInst *L, SmallVectorImpl<ReachingMemVal> &Deps); - bool processAssumeIntrinsic(AssumeInst *II); - - /// Given a local dependency (Def or Clobber) determine if a value is - /// available for the load. - std::optional<gvn::AvailableValue> - AnalyzeLoadAvailability(LoadInst *Load, const ReachingMemVal &Dep, - Value *Address); - - /// Given a select-dependency for the load (the load address is a select of - /// \p TrueAddr and \p FalseAddr guarded by \p Cond), determine whether a - /// value is available by finding dominating values... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/210330 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
