Skip to content

Commit 1bad10b

Browse files
authored
Merge pull request #2025 from vedantk/eng/PR-70560161
Revert "[CodeExtractor] Don't create bitcasts when inserting lifetime markers (NFCI)"
2 parents 986e88d + d5be1aa commit 1bad10b

File tree

6 files changed

+92
-21
lines changed

6 files changed

+92
-21
lines changed

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,31 +1023,50 @@ static void insertLifetimeMarkersSurroundingCall(
10231023
Module *M, ArrayRef<Value *> LifetimesStart, ArrayRef<Value *> LifetimesEnd,
10241024
CallInst *TheCall) {
10251025
LLVMContext &Ctx = M->getContext();
1026+
auto Int8PtrTy = Type::getInt8PtrTy(Ctx);
10261027
auto NegativeOne = ConstantInt::getSigned(Type::getInt64Ty(Ctx), -1);
10271028
Instruction *Term = TheCall->getParent()->getTerminator();
10281029

1030+
// The memory argument to a lifetime marker must be a i8*. Cache any bitcasts
1031+
// needed to satisfy this requirement so they may be reused.
1032+
DenseMap<Value *, Value *> Bitcasts;
1033+
10291034
// Emit lifetime markers for the pointers given in \p Objects. Insert the
10301035
// markers before the call if \p InsertBefore, and after the call otherwise.
1031-
auto insertMarkers = [&](Intrinsic::ID IID, ArrayRef<Value *> Objects,
1036+
auto insertMarkers = [&](Function *MarkerFunc, ArrayRef<Value *> Objects,
10321037
bool InsertBefore) {
10331038
for (Value *Mem : Objects) {
10341039
assert((!isa<Instruction>(Mem) || cast<Instruction>(Mem)->getFunction() ==
10351040
TheCall->getFunction()) &&
10361041
"Input memory not defined in original function");
1037-
assert(Mem->getType()->isPointerTy() && "Expected pointer to memory");
1038-
Function *MarkerFunc =
1039-
llvm::Intrinsic::getDeclaration(M, IID, Mem->getType());
1040-
auto Marker = CallInst::Create(MarkerFunc, {NegativeOne, Mem});
1042+
Value *&MemAsI8Ptr = Bitcasts[Mem];
1043+
if (!MemAsI8Ptr) {
1044+
if (Mem->getType() == Int8PtrTy)
1045+
MemAsI8Ptr = Mem;
1046+
else
1047+
MemAsI8Ptr =
1048+
CastInst::CreatePointerCast(Mem, Int8PtrTy, "lt.cast", TheCall);
1049+
}
1050+
1051+
auto Marker = CallInst::Create(MarkerFunc, {NegativeOne, MemAsI8Ptr});
10411052
if (InsertBefore)
10421053
Marker->insertBefore(TheCall);
10431054
else
10441055
Marker->insertBefore(Term);
10451056
}
10461057
};
10471058

1048-
insertMarkers(Intrinsic::lifetime_start, LifetimesStart,
1049-
/*InsertBefore=*/true);
1050-
insertMarkers(Intrinsic::lifetime_end, LifetimesEnd, /*InsertBefore=*/false);
1059+
if (!LifetimesStart.empty()) {
1060+
auto StartFn = llvm::Intrinsic::getDeclaration(
1061+
M, llvm::Intrinsic::lifetime_start, Int8PtrTy);
1062+
insertMarkers(StartFn, LifetimesStart, /*InsertBefore=*/true);
1063+
}
1064+
1065+
if (!LifetimesEnd.empty()) {
1066+
auto EndFn = llvm::Intrinsic::getDeclaration(
1067+
M, llvm::Intrinsic::lifetime_end, Int8PtrTy);
1068+
insertMarkers(EndFn, LifetimesEnd, /*InsertBefore=*/false);
1069+
}
10511070
}
10521071

10531072
/// emitCallAndSwitchStatement - This method sets up the caller side by adding

llvm/test/Transforms/CodeExtractor/PartialInlineInvokeProducesOutVal.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ bb5: ; preds = %bb4, %bb1, %bb
2626
; CHECK-LABEL: bb:
2727
; CHECK-NEXT: [[CALL26LOC:%.*]] = alloca i8*
2828
; CHECK-LABEL: codeRepl.i:
29-
; CHECK-NEXT: call void @llvm.lifetime.start.p0p0i8(i64 -1, i8** [[CALL26LOC]])
29+
; CHECK-NEXT: %lt.cast.i = bitcast i8** [[CALL26LOC]] to i8*
30+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast.i)
3031
; CHECK-NEXT: call void @bar.1.bb1(i8** [[CALL26LOC]])
3132
; CHECK-NEXT: %call26.reload.i = load i8*, i8** [[CALL26LOC]]
32-
; CHECK-NEXT: call void @llvm.lifetime.end.p0p0i8(i64 -1, i8** [[CALL26LOC]])
33+
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* %lt.cast.i)
3334
define i8* @dummy_caller(i32 %arg) {
3435
bb:
3536
%tmp = tail call i8* @bar(i32 %arg)

llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ normalPath:
2929
ret void
3030

3131
; CHECK-LABEL: codeRepl:
32-
; CHECK: call void @llvm.lifetime.start.p0i256(i64 -1, i256* %local1)
33-
; CHECK-NEXT: call void @llvm.lifetime.start.p0i256(i64 -1, i256* %local2)
32+
; CHECK: [[local1_cast:%.*]] = bitcast i256* %local1 to i8*
33+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local1_cast]])
34+
; CHECK-NEXT: [[local2_cast:%.*]] = bitcast i256* %local2 to i8*
35+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local2_cast]])
3436
; CHECK-NEXT: call i1 @foo.cold.1(i8* %local1_cast, i8* %local2_cast)
3537
; CHECK-NEXT: br i1
3638

@@ -59,4 +61,4 @@ outlinedPathExit:
5961
}
6062

6163
; CHECK-LABEL: define {{.*}}@foo.cold.1(
62-
; CHECK-NOT: call void @llvm.lifetime
64+
; CHECK-NOT: @llvm.lifetime

llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ declare void @use(i8*)
3737
define void @only_lifetime_start_is_cold() {
3838
; CHECK-LABEL: @only_lifetime_start_is_cold(
3939
; CHECK-NEXT: entry:
40-
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8
40+
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
4141
; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
4242
; CHECK-NEXT: br i1 undef, label [[CODEREPL:%.*]], label [[NO_EXTRACT1:%.*]]
4343
; CHECK: codeRepl:
44-
; CHECK-NEXT: call void @llvm.lifetime.start.p0i256(i64 -1, i256* [[LOCAL1]])
45-
; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3:#.*]]
44+
; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
45+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]])
46+
; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3
4647
; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[NO_EXTRACT1]], label [[EXIT:%.*]]
4748
; CHECK: no-extract1:
4849
; CHECK-NEXT: br label [[EXIT]]
@@ -97,15 +98,15 @@ exit:
9798
define void @only_lifetime_end_is_cold() {
9899
; CHECK-LABEL: @only_lifetime_end_is_cold(
99100
; CHECK-NEXT: entry:
100-
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8
101+
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
101102
; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
102103
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]])
103104
; CHECK-NEXT: br i1 undef, label [[NO_EXTRACT1:%.*]], label [[CODEREPL:%.*]]
104105
; CHECK: no-extract1:
105106
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[LOCAL1_CAST]])
106107
; CHECK-NEXT: br label [[EXIT:%.*]]
107108
; CHECK: codeRepl:
108-
; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3]]
109+
; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3
109110
; CHECK-NEXT: br label [[EXIT]]
110111
; CHECK: exit:
111112
; CHECK-NEXT: ret void
@@ -137,15 +138,15 @@ exit:
137138
define void @do_not_lift_lifetime_end() {
138139
; CHECK-LABEL: @do_not_lift_lifetime_end(
139140
; CHECK-NEXT: entry:
140-
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8
141+
; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
141142
; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
142143
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]])
143144
; CHECK-NEXT: br label [[HEADER:%.*]]
144145
; CHECK: header:
145146
; CHECK-NEXT: call void @use(i8* [[LOCAL1_CAST]])
146147
; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[CODEREPL:%.*]]
147148
; CHECK: codeRepl:
148-
; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3]]
149+
; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) #3
149150
; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[HEADER]], label [[EXIT]]
150151
; CHECK: exit:
151152
; CHECK-NEXT: ret void
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; RUN: opt -S -hotcoldsplit -hotcoldsplit-threshold=0 < %s 2>&1 | FileCheck %s
2+
3+
%type1 = type opaque
4+
%type2 = type opaque
5+
6+
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
7+
8+
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
9+
10+
declare void @use(%type1**, %type2**)
11+
12+
declare void @use2(%type1**, %type2**) cold
13+
14+
; CHECK-LABEL: define {{.*}}@foo(
15+
define void @foo() {
16+
entry:
17+
%local1 = alloca %type1*
18+
%local2 = alloca %type2*
19+
%local1_cast = bitcast %type1** %local1 to i8*
20+
%local2_cast = bitcast %type2** %local2 to i8*
21+
br i1 undef, label %normalPath, label %outlinedPath
22+
23+
normalPath:
24+
call void @use(%type1** %local1, %type2** %local2)
25+
ret void
26+
27+
; CHECK-LABEL: codeRepl:
28+
; CHECK: [[local1_cast:%.*]] = bitcast %type1** %local1 to i8*
29+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local1_cast]])
30+
; CHECK-NEXT: [[local2_cast:%.*]] = bitcast %type2** %local2 to i8*
31+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local2_cast]])
32+
; CHECK-NEXT: call void @foo.cold.1(i8* %local1_cast, i8* %local2_cast
33+
34+
outlinedPath:
35+
call void @llvm.lifetime.start.p0i8(i64 1, i8* %local1_cast)
36+
call void @llvm.lifetime.start.p0i8(i64 1, i8* %local2_cast)
37+
call void @use2(%type1** %local1, %type2** %local2)
38+
call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast)
39+
call void @llvm.lifetime.end.p0i8(i64 1, i8* %local2_cast)
40+
br label %outlinedPathExit
41+
42+
outlinedPathExit:
43+
ret void
44+
}
45+
46+
; CHECK-LABEL: define {{.*}}@foo.cold.1(
47+
; CHECK-NOT: @llvm.lifetime

llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ target triple = "x86_64-apple-macosx10.14.0"
1212
; CHECK-NEXT: ]
1313
;
1414
; CHECK: codeRepl:
15-
; CHECK: lifetime.start
15+
; CHECK-NEXT: bitcast
16+
; CHECK-NEXT: lifetime.start
1617
; CHECK-NEXT: call void @pluto.cold.1(i1* %tmp8.ce.loc)
1718
; CHECK-NEXT: %tmp8.ce.reload = load i1, i1* %tmp8.ce.loc
1819
; CHECK-NEXT: lifetime.end

0 commit comments

Comments
 (0)