From 92694eba933ef4ea0b1b6377809ff266df37d61b Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Sun, 13 Oct 2019 02:21:23 +0000 Subject: [PATCH] [SROA] Reuse existing lifetime markers if possible Summary: If the underlying alloca did not change, we do not necessarily need new lifetime markers. This patch adds a check and reuses the old ones if possible. Reviewers: reames, ssarda, t.p.northover, hfinkel Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68900 llvm-svn: 374692 --- llvm/lib/Transforms/Scalar/SROA.cpp | 10 +++- .../test/Transforms/SROA/reuse_lifetime_markers.ll | 69 ++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/SROA/reuse_lifetime_markers.ll diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 4b81683..a36b3c5 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -3072,6 +3072,13 @@ private: LLVM_DEBUG(dbgs() << " original: " << II << "\n"); assert(II.getArgOperand(1) == OldPtr); + bool EntireRange = (NewBeginOffset == NewAllocaBeginOffset && + NewEndOffset == NewAllocaEndOffset); + + // If the new lifetime marker would not differ from the old, just keep it. + if (&OldAI == &NewAI && EntireRange) + return true; + // Record this instruction for deletion. Pass.DeadInsts.insert(&II); @@ -3082,8 +3089,7 @@ private: // promoted, but PromoteMemToReg doesn't handle that case.) // FIXME: Check whether the alloca is promotable before dropping the // lifetime intrinsics? - if (NewBeginOffset != NewAllocaBeginOffset || - NewEndOffset != NewAllocaEndOffset) + if (!EntireRange) return true; ConstantInt *Size = diff --git a/llvm/test/Transforms/SROA/reuse_lifetime_markers.ll b/llvm/test/Transforms/SROA/reuse_lifetime_markers.ll new file mode 100644 index 0000000..0bfaf6e --- /dev/null +++ b/llvm/test/Transforms/SROA/reuse_lifetime_markers.ll @@ -0,0 +1,69 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -sroa -S | FileCheck %s +; +; Make sure we reuse the lifetime marker and do not create a new one that looks the same but without the call site attributes. +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0 + +define hidden void @old_markers() { +; +; CHECK-LABEL: define {{[^@]+}}@old_markers( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VV_SROA_4:%.*]] = alloca [3 x i32*] +; CHECK-NEXT: [[VV_SROA_4_0__SROA_CAST61:%.*]] = bitcast [3 x i32*]* [[VV_SROA_4]] to i8* +; CHECK-NEXT: [[VV_SROA_4_0__SROA_CAST94:%.*]] = bitcast [3 x i32*]* [[VV_SROA_4]] to i8* +; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull align 8 dereferenceable(24) [[VV_SROA_4_0__SROA_CAST94]]) +; CHECK-NEXT: br i1 undef, label [[DO_BODY:%.*]], label [[IF_END31:%.*]] +; CHECK: do.body: +; CHECK-NEXT: ret void +; CHECK: if.end31: +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nonnull align 8 dereferenceable(24) [[VV_SROA_4_0__SROA_CAST61]], i8* noalias nonnull align 8 undef, i64 24, i1 false) +; CHECK-NEXT: unreachable +; +entry: + %vv.sroa.4 = alloca [3 x i32*] + %vv.sroa.4.0..sroa_cast61 = bitcast [3 x i32*]* %vv.sroa.4 to i8* + %vv.sroa.4.0..sroa_cast94 = bitcast [3 x i32*]* %vv.sroa.4 to i8* + call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull align 8 dereferenceable(24) %vv.sroa.4.0..sroa_cast94) + br i1 undef, label %do.body, label %if.end31 + +do.body: ; preds = %entry + ret void + +if.end31: ; preds = %entry + call void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nonnull align 8 dereferenceable(24) %vv.sroa.4.0..sroa_cast61, i8* noalias nonnull align 8 undef, i64 24, i1 false) + unreachable +} + +define hidden void @new_markers() { +; +; CHECK-LABEL: define {{[^@]+}}@new_markers( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VV_SROA_4:%.*]] = alloca [3 x i32*] +; CHECK-NEXT: [[VV_SROA_4_0__SROA_CAST61:%.*]] = bitcast [3 x i32*]* [[VV_SROA_4]] to i8* +; CHECK-NEXT: br i1 undef, label [[DO_BODY:%.*]], label [[IF_END31:%.*]] +; CHECK: do.body: +; CHECK-NEXT: ret void +; CHECK: if.end31: +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nonnull align 8 dereferenceable(24) [[VV_SROA_4_0__SROA_CAST61]], i8* noalias nonnull align 8 undef, i64 24, i1 false) +; CHECK-NEXT: unreachable +; +entry: + %vv.sroa.4 = alloca [3 x i32*] + %vv.sroa.4.0..sroa_cast61 = bitcast [3 x i32*]* %vv.sroa.4 to i8* + %vv.sroa.4.0..sroa_cast94 = bitcast [3 x i32*]* %vv.sroa.4 to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull align 8 dereferenceable(24) %vv.sroa.4.0..sroa_cast94) + br i1 undef, label %do.body, label %if.end31 + +do.body: ; preds = %entry + ret void + +if.end31: ; preds = %entry + call void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nonnull align 8 dereferenceable(24) %vv.sroa.4.0..sroa_cast61, i8* noalias nonnull align 8 undef, i64 24, i1 false) + unreachable +} -- 2.7.4