[PATCH] D133987: [WIP][IPO] Support whole program devirtualization for relative vtables
Leonard Chan via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 15 16:20:23 PDT 2022
leonardchan created this revision.
Herald added subscribers: abrachet, ormris, phosek, hiraditya, Prazek.
Herald added a project: All.
leonardchan requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D133987
Files:
llvm/lib/Analysis/TypeMetadataUtils.cpp
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll
Index: llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll
===================================================================
--- llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll
+++ llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll
@@ -4,31 +4,45 @@
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -stats %s 2>&1 | FileCheck %s
target datalayout = "e-p:64:64"
-target triple = "x86_64-unknown-linux-gnu"
+target triple = "x86_64-unknown-fuchsia"
; CHECK: remark: devirt-single.cc:30:32: single-impl: devirtualized a call to vf
; CHECK: remark: devirt-single.cc:13:0: devirtualized vf
; CHECK-NOT: devirtualized
- at vt1 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !8
- at vt2 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !8
+;@vt1 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !8
define void @vf(i8* %this) #0 !dbg !7 {
ret void
}
+declare i8* @llvm.load.relative.i32(i8*, i32) argmemonly nocallback nofree nosync nounwind readonly willreturn
+
+;%class.A = type { i32 (...)** }
+ at vt2 = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (void (i8*)* dso_local_equivalent @vf to i64), i64 ptrtoint (i32* getelementptr inbounds ([1 x i32], [1 x i32]* @vt2, i32 0, i32 0) to i64)) to i32)
+], align 4, !type !8
+;@vt2 = unnamed_addr alias { [3 x i32] }, { [3 x i32] }* @_ZTV1A.local
+;@vt2 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !8
+
; CHECK: define void @call
define void @call(i8* %obj) #1 !dbg !5 {
- %vtableptr = bitcast i8* %obj to [1 x i8*]**
- %vtable = load [1 x i8*]*, [1 x i8*]** %vtableptr
- %vtablei8 = bitcast [1 x i8*]* %vtable to i8*
- %p = call i1 @llvm.type.test(i8* %vtablei8, metadata !"typeid")
+ %vtableptr = bitcast i8* %obj to i8**
+ %vtable = load i8*, i8** %vtableptr, align 8
+ %p = call i1 @llvm.type.test(i8* %vtable, metadata !"typeid")
call void @llvm.assume(i1 %p)
- %fptrptr = getelementptr [1 x i8*], [1 x i8*]* %vtable, i32 0, i32 0
- %fptr = load i8*, i8** %fptrptr
+
+ %fptr = call i8* @llvm.load.relative.i32(i8* %vtable, i32 0)
%fptr_casted = bitcast i8* %fptr to void (i8*)*
; CHECK: call void @vf(
- call void %fptr_casted(i8* %obj), !dbg !6
+ call void %fptr_casted(i8* %obj)
+
+ ;%fptrptr = bitcast i8* %vtable to i8**
+ ;%fptr = load i8*, i8** %fptrptr
+ ;%fptr_casted = bitcast i8* %fptr to void (i8*)*
+ ;;call void @vf(
+ ;call void %fptr_casted(i8* %obj), !dbg !6
+
ret void
}
Index: llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1004,10 +1004,15 @@
return false;
Constant *Ptr = getPointerAtOffset(TM.Bits->GV->getInitializer(),
- TM.Offset + ByteOffset, M);
+ TM.Offset + ByteOffset, M,
+ TM.Bits->GV);
if (!Ptr)
return false;
+ if (auto *Equiv = dyn_cast<DSOLocalEquivalent>(Ptr)) {
+ Ptr = Equiv->getGlobalValue();
+ }
+
auto Fn = dyn_cast<Function>(Ptr->stripPointerCasts());
if (!Fn)
return false;
Index: llvm/lib/Analysis/TypeMetadataUtils.cpp
===================================================================
--- llvm/lib/Analysis/TypeMetadataUtils.cpp
+++ llvm/lib/Analysis/TypeMetadataUtils.cpp
@@ -67,6 +67,10 @@
findLoadCallsAtConstantOffset(M, DevirtCalls, User, Offset + GEPOffset,
CI, DT);
}
+ } else if (auto *Call = dyn_cast<CallInst>(User)) {
+ if (Call->getIntrinsicID() == llvm::Intrinsic::load_relative) {
+ findCallsAtConstantOffset(DevirtCalls, nullptr, User, Offset, CI, DT);
+ }
}
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133987.460536.patch
Type: text/x-patch
Size: 3944 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220915/0d7a65fc/attachment.bin>
More information about the llvm-commits
mailing list