[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