diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -2400,8 +2400,8 @@ } static bool inlineGetBaseAndOffset(Function &F, - SmallVectorImpl &Intrinsics) { - DefiningValueMapTy DVCache; + SmallVectorImpl &Intrinsics, + DefiningValueMapTy &DVCache) { auto &Context = F.getContext(); auto &DL = F.getParent()->getDataLayout(); bool Changed = false; @@ -2451,7 +2451,8 @@ static bool insertParsePoints(Function &F, DominatorTree &DT, TargetTransformInfo &TTI, - SmallVectorImpl &ToUpdate) { + SmallVectorImpl &ToUpdate, + DefiningValueMapTy &DVCache) { #ifndef NDEBUG // sanity check the input std::set Uniqued; @@ -2502,16 +2503,10 @@ findLiveReferences(F, DT, ToUpdate, Records); // B) Find the base pointers for each live pointer - /* scope for caching */ { - // Cache the 'defining value' relation used in the computation and - // insertion of base phis and selects. This ensures that we don't insert - // large numbers of duplicate base_phis. - DefiningValueMapTy DVCache; - for (size_t i = 0; i < Records.size(); i++) { - PartiallyConstructedSafepointRecord &info = Records[i]; - findBasePointers(DT, DVCache, ToUpdate[i], info); - } - } // end of cache scope + for (size_t i = 0; i < Records.size(); i++) { + PartiallyConstructedSafepointRecord &info = Records[i]; + findBasePointers(DT, DVCache, ToUpdate[i], info); + } // The base phi insertion logic (for any safepoint) may have inserted new // instructions which are now live at some safepoint. The simplest such @@ -2937,13 +2932,20 @@ } } + // Cache the 'defining value' relation used in the computation and + // insertion of base phis and selects. This ensures that we don't insert + // large numbers of duplicate base_phis. Use one cache for both + // inlineGetBaseAndOffset() and insertParsePoints(). + DefiningValueMapTy DVCache; + if (!Intrinsics.empty()) // Inline @gc.get.pointer.base() and @gc.get.pointer.offset() before finding // live references. - MadeChange |= inlineGetBaseAndOffset(F, Intrinsics); + MadeChange |= inlineGetBaseAndOffset(F, Intrinsics, DVCache); if (!ParsePointNeeded.empty()) - MadeChange |= insertParsePoints(F, DT, TTI, ParsePointNeeded); + MadeChange |= insertParsePoints(F, DT, TTI, ParsePointNeeded, DVCache); + return MadeChange; } diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/intrinsics-bare.ll b/llvm/test/Transforms/RewriteStatepointsForGC/intrinsics-bare.ll --- a/llvm/test/Transforms/RewriteStatepointsForGC/intrinsics-bare.ll +++ b/llvm/test/Transforms/RewriteStatepointsForGC/intrinsics-bare.ll @@ -10,11 +10,10 @@ ; CHECK-NEXT: [[OBJ1_12:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[OBJ1:%.*]], i64 12 ; CHECK-NEXT: [[OBJ2_16:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[OBJ2:%.*]], i64 16 ; CHECK-NEXT: [[SELECTED_BASE:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[OBJ2]], i8 addrspace(1)* [[OBJ1]], !is_base_value !0 -; CHECK-NEXT: [[SELECTED_BASE1:%.*]] = select i1 [[C]], i8 addrspace(1)* [[OBJ2]], i8 addrspace(1)* [[OBJ1]], !is_base_value !0 ; CHECK-NEXT: [[SELECTED:%.*]] = select i1 [[C]], i8 addrspace(1)* [[OBJ2_16]], i8 addrspace(1)* [[OBJ1_12]] -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[SELECTED]], i8 addrspace(1)* [[SELECTED_BASE1]]) ] +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[SELECTED]], i8 addrspace(1)* [[SELECTED_BASE]]) ] ; CHECK-NEXT: [[SELECTED_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) -; CHECK-NEXT: [[SELECTED_BASE1_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) +; CHECK-NEXT: [[SELECTED_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) ; CHECK-NEXT: ret i8 addrspace(1)* [[SELECTED_RELOCATED]] ; entry: