From 3f44bcbdcb271f8fd57a345b9bb5968b92b834a1 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sat, 4 Mar 2017 01:34:53 +0000 Subject: [PATCH] WholeProgramDevirt: Implement exporting for uniform ret val opt. Differential Revision: https://reviews.llvm.org/D29846 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296948 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/WholeProgramDevirt.cpp | 25 +++++++++---- .../export-uniform-ret-val.ll | 36 +++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 test/Transforms/WholeProgramDevirt/export-uniform-ret-val.ll diff --git a/lib/Transforms/IPO/WholeProgramDevirt.cpp b/lib/Transforms/IPO/WholeProgramDevirt.cpp index bbf0a925bfc..843bd69fbd6 100644 --- a/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -428,7 +428,8 @@ struct DevirtModule { void applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName, uint64_t TheRetVal); bool tryUniformRetValOpt(MutableArrayRef TargetsForSlot, - CallSiteInfo &CSInfo); + CallSiteInfo &CSInfo, + WholeProgramDevirtResolution::ByArg *Res); void applyUniqueRetValOpt(CallSiteInfo &CSInfo, StringRef FnName, bool IsOne, Constant *UniqueMemberAddr); @@ -439,7 +440,8 @@ struct DevirtModule { void applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName, Constant *Byte, Constant *Bit); bool tryVirtualConstProp(MutableArrayRef TargetsForSlot, - VTableSlotInfo &SlotInfo); + VTableSlotInfo &SlotInfo, + WholeProgramDevirtResolution *Res); void rebuildGlobal(VTableBits &B); @@ -727,10 +729,12 @@ void DevirtModule::applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName, Call.replaceAndErase( "uniform-ret-val", FnName, RemarksEnabled, ConstantInt::get(cast(Call.CS.getType()), TheRetVal)); + CSInfo.TypeCheckedLoadUsers.clear(); } bool DevirtModule::tryUniformRetValOpt( - MutableArrayRef TargetsForSlot, CallSiteInfo &CSInfo) { + MutableArrayRef TargetsForSlot, CallSiteInfo &CSInfo, + WholeProgramDevirtResolution::ByArg *Res) { // Uniform return value optimization. If all functions return the same // constant, replace all calls with that constant. uint64_t TheRetVal = TargetsForSlot[0].RetVal; @@ -738,6 +742,11 @@ bool DevirtModule::tryUniformRetValOpt( if (Target.RetVal != TheRetVal) return false; + if (CSInfo.isExported()) { + Res->TheKind = WholeProgramDevirtResolution::ByArg::UniformRetVal; + Res->Info = TheRetVal; + } + applyUniformRetValOpt(CSInfo, TargetsForSlot[0].Fn->getName(), TheRetVal); if (RemarksEnabled) for (auto &&Target : TargetsForSlot) @@ -824,7 +833,7 @@ void DevirtModule::applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName, bool DevirtModule::tryVirtualConstProp( MutableArrayRef TargetsForSlot, - VTableSlotInfo &SlotInfo) { + VTableSlotInfo &SlotInfo, WholeProgramDevirtResolution *Res) { // This only works if the function returns an integer. auto RetType = dyn_cast(TargetsForSlot[0].Fn->getReturnType()); if (!RetType) @@ -856,7 +865,11 @@ bool DevirtModule::tryVirtualConstProp( if (!tryEvaluateFunctionsWithArgs(TargetsForSlot, CSByConstantArg.first)) continue; - if (tryUniformRetValOpt(TargetsForSlot, CSByConstantArg.second)) + WholeProgramDevirtResolution::ByArg *ResByArg = nullptr; + if (Res) + ResByArg = &Res->ResByArg[CSByConstantArg.first]; + + if (tryUniformRetValOpt(TargetsForSlot, CSByConstantArg.second, ResByArg)) continue; if (tryUniqueRetValOpt(BitWidth, TargetsForSlot, CSByConstantArg.second)) @@ -1175,7 +1188,7 @@ bool DevirtModule::run() { .WPDRes[S.first.ByteOffset]; if (!trySingleImplDevirt(TargetsForSlot, S.second, Res) && - tryVirtualConstProp(TargetsForSlot, S.second)) + tryVirtualConstProp(TargetsForSlot, S.second, Res)) DidVirtualConstProp = true; // Collect functions devirtualized at least for one call site for stats. diff --git a/test/Transforms/WholeProgramDevirt/export-uniform-ret-val.ll b/test/Transforms/WholeProgramDevirt/export-uniform-ret-val.ll new file mode 100644 index 00000000000..1d7030c41fd --- /dev/null +++ b/test/Transforms/WholeProgramDevirt/export-uniform-ret-val.ll @@ -0,0 +1,36 @@ +; RUN: opt -wholeprogramdevirt -wholeprogramdevirt-summary-action=export -wholeprogramdevirt-read-summary=%S/Inputs/export.yaml -wholeprogramdevirt-write-summary=%t -S -o - %s | FileCheck %s +; RUN: FileCheck --check-prefix=SUMMARY %s < %t + +; SUMMARY: - TypeTests: +; SUMMARY-NEXT: TypeTestAssumeVCalls: + +; SUMMARY: TypeIdMap: +; SUMMARY-NEXT: typeid4: +; SUMMARY-NEXT: TTRes: +; SUMMARY-NEXT: Kind: Unsat +; SUMMARY-NEXT: SizeM1BitWidth: 0 +; SUMMARY-NEXT: WPDRes: +; SUMMARY-NEXT: 0: +; SUMMARY-NEXT: Kind: Indir +; SUMMARY-NEXT: SingleImplName: '' +; SUMMARY-NEXT: ResByArg: +; SUMMARY-NEXT: 24,12: +; SUMMARY-NEXT: Kind: UniformRetVal +; SUMMARY-NEXT: Info: 36 + +; CHECK: @vt4a = constant i32 (i8*, i32, i32)* @vf4a +@vt4a = constant i32 (i8*, i32, i32)* @vf4a, !type !0 + +; CHECK: @vt4b = constant i32 (i8*, i32, i32)* @vf4b +@vt4b = constant i32 (i8*, i32, i32)* @vf4b, !type !0 + +define i32 @vf4a(i8*, i32 %x, i32 %y) { + %z = add i32 %x, %y + ret i32 %z +} + +define i32 @vf4b(i8*, i32 %x, i32 %y) { + ret i32 36 +} + +!0 = !{i32 0, !"typeid4"} -- 2.50.1