[CodeExtractor] Replace uses of extracted bitcasts in out-of-region lifetime markers
CodeExtractor handles bitcasts in the extracted region that have
lifetime markers users in the outer region as outputs. That
creates unnecessary alloca/reload instructions and extra lifetime
markers. The patch identifies those cases, and replaces uses in
out-of-region lifetime markers with new bitcasts in the outer region.
**Example**
```
define void @foo() {
entry:
%0 = alloca i32
br label %extract
extract:
%1 = bitcast i32* %0 to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
call void @use(i32* %0)
br label %exit
exit:
call void @use(i32* %0)
call void @llvm.lifetime.end.p0i8(i64 4, i8* %1)
ret void
}
```
**Current extraction**
```
define void @foo() {
entry:
%.loc = alloca i8*, align 8
%0 = alloca i32, align 4
br label %codeRepl
codeRepl: ; preds = %entry
%lt.cast = bitcast i8** %.loc to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast)
%lt.cast1 = bitcast i32* %0 to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast1)
call void @foo.extract(i32* %0, i8** %.loc)
%.reload = load i8*, i8** %.loc, align 8
call void @llvm.lifetime.end.p0i8(i64 -1, i8* %lt.cast)
br label %exit
exit: ; preds = %codeRepl
call void @use(i32* %0)
call void @llvm.lifetime.end.p0i8(i64 4, i8* %.reload)
ret void
}
define internal void @foo.extract(i32* %0, i8** %.out) {
newFuncRoot:
br label %extract
exit.exitStub: ; preds = %extract
ret void
extract: ; preds = %newFuncRoot
%1 = bitcast i32* %0 to i8*
store i8* %1, i8** %.out, align 8
call void @use(i32* %0)
br label %exit.exitStub
}
```
**Extraction with patch**
```
define void @foo() {
entry:
%0 = alloca i32, align 4
br label %codeRepl
codeRepl: ; preds = %entry
%lt.cast1 = bitcast i32* %0 to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast1)
call void @foo.extract(i32* %0)
br label %exit
exit: ; preds = %codeRepl
call void @use(i32* %0)
%lt.cast = bitcast i32* %0 to i8*
call void @llvm.lifetime.end.p0i8(i64 4, i8* %lt.cast)
ret void
}
define internal void @foo.extract(i32* %0) {
newFuncRoot:
br label %extract
exit.exitStub: ; preds = %extract
ret void
extract: ; preds = %newFuncRoot
%1 = bitcast i32* %0 to i8*
call void @use(i32* %0)
br label %exit.exitStub
}
```
Reviewed By: vsk
Differential Revision: https://reviews.llvm.org/D90689