[llvm] 798eb71 - [NFC][StackSafety] Dedup callees
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 01:15:07 PDT 2020
Author: Vitaly Buka
Date: 2020-08-14T01:14:52-07:00
New Revision: 798eb71c3a5a43f592b006e1b41620c54cacb721
URL: https://github.com/llvm/llvm-project/commit/798eb71c3a5a43f592b006e1b41620c54cacb721
DIFF: https://github.com/llvm/llvm-project/commit/798eb71c3a5a43f592b006e1b41620c54cacb721.diff
LOG: [NFC][StackSafety] Dedup callees
Added:
Modified:
llvm/lib/Analysis/StackSafetyAnalysis.cpp
llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
llvm/test/Bitcode/thinlto-function-summary-paramaccess.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
index db3eb0bc49a5..0baf0c2d54b2 100644
--- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp
+++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
@@ -95,20 +95,16 @@ template <typename CalleeTy> struct CallInfo {
const CalleeTy *Callee = nullptr;
/// Index of argument which pass address.
size_t ParamNo = 0;
- // Offset range of address from base address (alloca or calling function
- // argument).
- // Range should never set to empty-set, that is an invalid access range
- // that can cause empty-set to be propagated with ConstantRange::add
- ConstantRange Offset;
- CallInfo(const CalleeTy *Callee, size_t ParamNo, const ConstantRange &Offset)
- : Callee(Callee), ParamNo(ParamNo), Offset(Offset) {}
-};
-template <typename CalleeTy>
-raw_ostream &operator<<(raw_ostream &OS, const CallInfo<CalleeTy> &P) {
- return OS << "@" << P.Callee->getName() << "(arg" << P.ParamNo << ", "
- << P.Offset << ")";
-}
+ CallInfo(const CalleeTy *Callee, size_t ParamNo)
+ : Callee(Callee), ParamNo(ParamNo) {}
+
+ struct Less {
+ bool operator()(const CallInfo &L, const CallInfo &R) const {
+ return std::tie(L.Callee, L.ParamNo) < std::tie(R.Callee, R.ParamNo);
+ }
+ };
+};
/// Describe uses of address (alloca or parameter) inside of the function.
template <typename CalleeTy> struct UseInfo {
@@ -117,7 +113,12 @@ template <typename CalleeTy> struct UseInfo {
ConstantRange Range;
// List of calls which pass address as an argument.
- SmallVector<CallInfo<CalleeTy>, 4> Calls;
+ // Value is offset range of address from base address (alloca or calling
+ // function argument). Range should never set to empty-set, that is an invalid
+ // access range that can cause empty-set to be propagated with
+ // ConstantRange::add
+ std::map<CallInfo<CalleeTy>, ConstantRange, typename CallInfo<CalleeTy>::Less>
+ Calls;
UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
@@ -128,7 +129,9 @@ template <typename CalleeTy>
raw_ostream &operator<<(raw_ostream &OS, const UseInfo<CalleeTy> &U) {
OS << U.Range;
for (auto &Call : U.Calls)
- OS << ", " << Call;
+ OS << ", "
+ << "@" << Call.first.Callee->getName() << "(arg" << Call.first.ParamNo
+ << ", " << Call.second << ")";
return OS;
}
@@ -410,7 +413,11 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
}
assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
- US.Calls.emplace_back(Callee, ArgNo, offsetFrom(UI, Ptr));
+ ConstantRange Offsets = offsetFrom(UI, Ptr);
+ auto Insert =
+ US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
+ if (!Insert.second)
+ Insert.first->second = Insert.first->second.unionWith(Offsets);
break;
}
@@ -516,12 +523,12 @@ template <typename CalleeTy>
bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
bool UpdateToFullSet) {
bool Changed = false;
- for (auto &CS : US.Calls) {
- assert(!CS.Offset.isEmptySet() &&
+ for (auto &KV : US.Calls) {
+ assert(!KV.second.isEmptySet() &&
"Param range can't be empty-set, invalid offset range");
ConstantRange CalleeRange =
- getArgumentAccessRange(CS.Callee, CS.ParamNo, CS.Offset);
+ getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
if (!US.Range.contains(CalleeRange)) {
Changed = true;
if (UpdateToFullSet)
@@ -561,7 +568,7 @@ void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
auto &FS = F.second;
for (auto &KV : FS.Params)
for (auto &CS : KV.second.Calls)
- Callees.push_back(CS.Callee);
+ Callees.push_back(CS.first.Callee);
llvm::sort(Callees);
Callees.erase(std::unique(Callees.begin(), Callees.end()), Callees.end());
@@ -650,16 +657,18 @@ const ConstantRange *findParamAccess(const FunctionSummary &FS,
void resolveAllCalls(UseInfo<GlobalValue> &Use,
const ModuleSummaryIndex *Index) {
ConstantRange FullSet(Use.Range.getBitWidth(), true);
- for (auto &C : Use.Calls) {
- const Function *F = findCalleeInModule(C.Callee);
+ auto TmpCalls = std::move(Use.Calls);
+ for (const auto &C : TmpCalls) {
+ const Function *F = findCalleeInModule(C.first.Callee);
if (F) {
- C.Callee = F;
+ Use.Calls.emplace(CallInfo<GlobalValue>(F, C.first.ParamNo), C.second);
continue;
}
if (!Index)
return Use.updateRange(FullSet);
- GlobalValueSummary *GVS = getGlobalValueSummary(Index, C.Callee->getGUID());
+ GlobalValueSummary *GVS =
+ getGlobalValueSummary(Index, C.first.Callee->getGUID());
FunctionSummary *FS = resolveCallee(GVS);
++NumModuleCalleeLookupTotal;
@@ -667,18 +676,13 @@ void resolveAllCalls(UseInfo<GlobalValue> &Use,
++NumModuleCalleeLookupFailed;
return Use.updateRange(FullSet);
}
- const ConstantRange *Found = findParamAccess(*FS, C.ParamNo);
+ const ConstantRange *Found = findParamAccess(*FS, C.first.ParamNo);
if (!Found || Found->isFullSet())
return Use.updateRange(FullSet);
ConstantRange Access = Found->sextOrTrunc(Use.Range.getBitWidth());
if (!Access.isEmptySet())
- Use.updateRange(addOverflowNever(Access, C.Offset));
- C.Callee = nullptr;
+ Use.updateRange(addOverflowNever(Access, C.second));
}
-
- Use.Calls.erase(std::remove_if(Use.Calls.begin(), Use.Calls.end(),
- [](auto &T) { return !T.Callee; }),
- Use.Calls.end());
}
GVToSSI createGlobalStackSafetyInfo(
@@ -692,8 +696,11 @@ GVToSSI createGlobalStackSafetyInfo(
auto Copy = Functions;
for (auto &FnKV : Copy)
- for (auto &KV : FnKV.second.Params)
+ for (auto &KV : FnKV.second.Params) {
resolveAllCalls(KV.second, Index);
+ if (KV.second.Range.isFullSet())
+ KV.second.Calls.clear();
+ }
uint32_t PointerSize = Copy.begin()
->first->getParent()
@@ -708,8 +715,8 @@ GVToSSI createGlobalStackSafetyInfo(
auto &A = KV.second;
resolveAllCalls(A, Index);
for (auto &C : A.Calls) {
- A.updateRange(
- SSDFA.getArgumentAccessRange(C.Callee, C.ParamNo, C.Offset));
+ A.updateRange(SSDFA.getArgumentAccessRange(C.first.Callee,
+ C.first.ParamNo, C.second));
}
// FIXME: This is needed only to preserve calls in print() results.
A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
@@ -799,11 +806,16 @@ StackSafetyInfo::getParamAccesses() const {
// will make ParamAccess::Range as FullSet anyway. So we can drop the
// entire parameter like we did above.
// TODO(vitalybuka): Return already filtered parameters from getInfo().
- if (C.Offset.isFullSet()) {
+ if (C.second.isFullSet()) {
ParamAccesses.pop_back();
break;
}
- Param.Calls.emplace_back(C.ParamNo, C.Callee->getGUID(), C.Offset);
+ Param.Calls.emplace_back(C.first.ParamNo, C.first.Callee->getGUID(),
+ C.second);
+ llvm::sort(Param.Calls, [](const FunctionSummary::ParamAccess::Call &L,
+ const FunctionSummary::ParamAccess::Call &R) {
+ return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
+ });
}
}
return ParamAccesses;
@@ -992,7 +1004,8 @@ void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
US.Calls.clear();
break;
}
- US.Calls.emplace_back(S, Call.ParamNo, Call.Offsets);
+ US.Calls.emplace(CallInfo<FunctionSummary>(S, Call.ParamNo),
+ Call.Offsets);
}
}
Functions.emplace(FS, std::move(FI));
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll b/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
index 8cb875b8a9aa..6be426f6bbd3 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
@@ -354,8 +354,8 @@ define void @TwoArguments() #0 {
; CHECK-LABEL: @TwoArguments dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
-; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg1, [0,1)), @Write4_2(arg0, [4,5)){{$}}
-; GLOBAL-NEXT: x[8]: [0,8), @Write4_2(arg1, [0,1)), @Write4_2(arg0, [4,5)){{$}}
+; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}
+; GLOBAL-NEXT: x[8]: [0,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}
; CHECK-EMPTY:
entry:
%x = alloca i64, align 4
@@ -369,8 +369,8 @@ define void @TwoArgumentsOOBOne() #0 {
; CHECK-LABEL: @TwoArgumentsOOBOne dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
-; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg1, [0,1)), @Write4_2(arg0, [5,6)){{$}}
-; GLOBAL-NEXT: x[8]: [0,9), @Write4_2(arg1, [0,1)), @Write4_2(arg0, [5,6)){{$}}
+; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}
+; GLOBAL-NEXT: x[8]: [0,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}
; CHECK-EMPTY:
entry:
%x = alloca i64, align 4
@@ -384,8 +384,8 @@ define void @TwoArgumentsOOBOther() #0 {
; CHECK-LABEL: @TwoArgumentsOOBOther dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
-; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg1, [-1,0)), @Write4_2(arg0, [4,5)){{$}}
-; GLOBAL-NEXT: x[8]: [-1,8), @Write4_2(arg1, [-1,0)), @Write4_2(arg0, [4,5)){{$}}
+; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}
+; GLOBAL-NEXT: x[8]: [-1,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}
; CHECK-EMPTY:
entry:
%x = alloca i64, align 4
@@ -400,8 +400,8 @@ define void @TwoArgumentsOOBBoth() #0 {
; CHECK-LABEL: @TwoArgumentsOOBBoth dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
-; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg1, [-1,0)), @Write4_2(arg0, [5,6)){{$}}
-; GLOBAL-NEXT: x[8]: [-1,9), @Write4_2(arg1, [-1,0)), @Write4_2(arg0, [5,6)){{$}}
+; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}
+; GLOBAL-NEXT: x[8]: [-1,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}
; CHECK-EMPTY:
entry:
%x = alloca i64, align 4
diff --git a/llvm/test/Bitcode/thinlto-function-summary-paramaccess.ll b/llvm/test/Bitcode/thinlto-function-summary-paramaccess.ll
index e52dda708161..1757173ec52b 100644
--- a/llvm/test/Bitcode/thinlto-function-summary-paramaccess.ll
+++ b/llvm/test/Bitcode/thinlto-function-summary-paramaccess.ll
@@ -210,11 +210,11 @@ entry:
}
; SSI-LABEL: for function 'CallMany'
-; SSI: p[]: empty-set, @Callee(arg0, [-715,-714)), @Callee(arg0, [-33,-32)), @Callee(arg0, [124,125))
-; BC-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=3 op4=0 op5=[[CALLEE]] op6=1431 op7=1429 op8=0 op9=[[CALLEE]] op10=67 op11=65 op12=0 op13=[[CALLEE]] op14=248 op15=250/>
+; SSI: p[]: empty-set, @Callee(arg0, [-715,125))
+; BC-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=1 op4=0 op5=[[CALLEE]] op6=1431 op7=250/>
; BC-NEXT: <PERMODULE
-; DIS-DAG: = gv: (name: "CallMany", summaries: {{.*}} calls: ((callee: ^{{.*}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{.*}}, param: 0, offset: [-715, -715]), (callee: ^{{.*}}, param: 0, offset: [-33, -33]), (callee: ^{{.*}}, param: 0, offset: [124, 124]))))))) ; guid = 17150418543861409076
-; DCO-DAG: = gv: (guid: 17150418543861409076, summaries: (function: (module: ^0, flags: ({{[^()]+}}), insts: 7, funcFlags: ({{[^()]+}}), calls: ((callee: ^[[CALLEE:.]])), params: ((param: 0, offset: [0, -1], calls: ((callee: ^[[CALLEE]], param: 0, offset: [-715, -715]), (callee: ^[[CALLEE]], param: 0, offset: [-33, -33]), (callee: ^[[CALLEE]], param: 0, offset: [124, 124]))))))){{$}}
+; DIS-DAG: = gv: (name: "CallMany", summaries: {{.*}} calls: ((callee: ^{{.*}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{.*}}, param: 0, offset: [-715, 124]))))))) ; guid = 17150418543861409076
+; DCO-DAG: = gv: (guid: 17150418543861409076, summaries: (function: (module: ^0, flags: ({{[^()]+}}), insts: 7, funcFlags: ({{[^()]+}}), calls: ((callee: ^[[CALLEE:.]])), params: ((param: 0, offset: [0, -1], calls: ((callee: ^[[CALLEE]], param: 0, offset: [-715, 124]))))))){{$}}
define void @CallMany(i8* %p) #0 {
entry:
%p0 = getelementptr i8, i8* %p, i64 -715
@@ -230,11 +230,11 @@ entry:
}
; SSI-LABEL: for function 'CallMany2'
-; SSI: p[]: empty-set, @Callee(arg0, [-715,-714)), @Callee2(arg1, [-33,-32)), @Callee(arg0, [124,125))
-; BC-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=3 op4=0 op5=[[CALLEE]] op6=1431 op7=1429 op8=1 op9=[[CALLEE2:-?[0-9]+]] op10=67 op11=65 op12=0 op13=[[CALLEE]] op14=248 op15=250/>
+; SSI: p[]: empty-set, @Callee(arg0, [-715,125))
+; BC-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=2 op4=0 op5=[[CALLEE]] op6=1431 op7=250 op8=1 op9=[[CALLEE2:-?[0-9]+]] op10=67 op11=65/>
; BC-NEXT: <PERMODULE
-; DIS-DAG: = gv: (name: "CallMany2", summaries: {{.*}} calls: ((callee: ^{{.*}}), (callee: ^{{.*}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{.*}}, param: 0, offset: [-715, -715]), (callee: ^{{.*}}, param: 1, offset: [-33, -33]), (callee: ^{{.*}}, param: 0, offset: [124, 124]))))))) ; guid = 16654048340802466690
-; DCO-DAG: = gv: (guid: 16654048340802466690, summaries: (function: (module: ^0, flags: ({{[^()]+}}), insts: 7, funcFlags: ({{[^()]+}}), calls: ((callee: ^{{[0-9]+}}), (callee: ^{{[0-9]+}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{[0-9]+}}, param: 0, offset: [-715, -715]), (callee: ^{{[0-9]+}}, param: 1, offset: [-33, -33]), (callee: ^{{[0-9]+}}, param: 0, offset: [124, 124]))))))){{$}}
+; DIS-DAG: = gv: (name: "CallMany2", summaries: {{.*}} calls: ((callee: ^{{.*}}), (callee: ^{{.*}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{.*}}, param: 0, offset: [-715, 124]), (callee: ^{{.*}}, param: 1, offset: [-33, -33]))))))) ; guid = 16654048340802466690
+; DCO-DAG: = gv: (guid: 16654048340802466690, summaries: (function: (module: ^0, flags: ({{[^()]+}}), insts: 7, funcFlags: ({{[^()]+}}), calls: ((callee: ^{{[0-9]+}}), (callee: ^{{[0-9]+}})), params: ((param: 0, offset: [0, -1], calls: ((callee: ^{{[0-9]+}}, param: 0, offset: [-715, 124]), (callee: ^{{[0-9]+}}, param: 1, offset: [-33, -33]))))))){{$}}
define void @CallMany2(i8* %p) #0 {
entry:
%p0 = getelementptr i8, i8* %p, i64 -715
@@ -250,7 +250,7 @@ entry:
}
; SSI-LABEL: for function 'CallManyUnsafe'
-; SSI: p[]: full-set, @Callee(arg0, [-715,-714)), @Callee(arg0, [-33,-32)), @Callee(arg0, [124,125))
+; SSI: p[]: full-set, @Callee(arg0, [-715,125))
; BC-NEXT: <PERMODULE
; DIS-DAG: = gv: (name: "CallManyUnsafe", summaries: {{.*}} calls: ((callee: ^{{.*}}))))) ; guid = 15696680128757863301
; DCO-DAG: = gv: (guid: 15696680128757863301, summaries: (function: (module: ^0, flags: ({{[^()]+}}), insts: 9, funcFlags: ({{[^()]+}}), calls: ((callee: ^[[CALLEE:.]]))))){{$}}
@@ -334,8 +334,8 @@ entry:
; COMBINED-NEXT: <COMBINED abbrevid=4 op0=16
; COMBINED-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=1 op4=0 op5=[[CALLEE2]] op6=1431 op7=1429/>
; COMBINED-NEXT: <COMBINED abbrevid=4 op0=17
-; COMBINED-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=3 op4=0 op5=[[CALLEE2]] op6=1431 op7=1429 op8=1 op9=[[CALLEE1]] op10=67 op11=65 op12=0 op13=[[CALLEE2]] op14=248 op15=250/>
+; COMBINED-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=2 op4=0 op5=[[CALLEE2]] op6=1431 op7=250 op8=1 op9=[[CALLEE1]] op10=67 op11=65/>
; COMBINED-NEXT: <COMBINED abbrevid=4 op0=18
-; COMBINED-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=3 op4=0 op5=[[CALLEE2]] op6=1431 op7=1429 op8=0 op9=[[CALLEE2]] op10=67 op11=65 op12=0 op13=[[CALLEE2]] op14=248 op15=250/>
+; COMBINED-NEXT: <PARAM_ACCESS op0=0 op1=0 op2=0 op3=1 op4=0 op5=[[CALLEE2]] op6=1431 op7=250/>
; COMBINED-NEXT: <COMBINED abbrevid=4 op0=19
; COMBINED-NEXT: <BLOCK_COUNT op0=19/>
\ No newline at end of file
More information about the llvm-commits
mailing list