Skip to content

Commit 08b9470

Browse files
committed
Fixing array legth inference performance issue
1 parent 713c272 commit 08b9470

File tree

3 files changed

+51
-43
lines changed

3 files changed

+51
-43
lines changed

clang/include/clang/CConv/AVarBoundsInfo.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ class AvarBoundsInference {
119119
AVarGraph &BKGraph,
120120
bool CheckImmediate = false);
121121

122-
bool intersectBounds(std::set<ProgramVar *> &ProgVars,
123-
ABounds::BoundsKind BK,
124-
std::set<ABounds *> &CurrB);
125-
126122
// Check if bounds specified by Bnds are declared bounds of K.
127123
bool areDeclaredBounds(BoundsKey K,
128124
const std::pair<ABounds::BoundsKind,
@@ -192,7 +188,6 @@ class AVarBoundsInfo {
192188
BoundsKey getVariable(clang::FieldDecl *FD);
193189
BoundsKey getVariable(clang::FunctionDecl *FD);
194190
BoundsKey getConstKey(uint64_t value);
195-
bool fetchAllConstKeys(uint64_t value, std::set<BoundsKey> &AllKeys);
196191

197192
// Generate a random bounds key to be used for inference.
198193
BoundsKey getRandomBKey();
@@ -270,8 +265,8 @@ class AVarBoundsInfo {
270265
BoundsKey BCount;
271266
// Map of VarKeys and corresponding program variables.
272267
std::map<BoundsKey, ProgramVar *> PVarInfo;
273-
// Map of APSInt (constants) and set of BoundKeys that correspond to it.
274-
std::map<uint64_t, std::set<BoundsKey>> ConstVarKeys;
268+
// Map of APSInt (constants) and a BoundKey that correspond to it.
269+
std::map<uint64_t, BoundsKey> ConstVarKeys;
275270
// Map of BoundsKey and corresponding prioritized bounds information.
276271
// Note that although each PSL could have multiple ConstraintKeys Ex: **p.
277272
// Only the outer most pointer can have bounds.

clang/include/clang/CConv/ConstraintsGraph.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,17 @@ class DataGraph :
137137
invalidateBFSCache();
138138
}
139139

140-
bool getNeighbors(Data D, std::set<Data> &DataSet, bool Succ){
140+
void addUniqueEdge(Data L, Data R) {
141+
NodeType *BL = this->findOrCreateNode(L);
142+
NodeType *BR = this->findOrCreateNode(R);
143+
llvm::SmallVector<EdgeType*, 10> Edges;
144+
BL->findEdgesTo(*BR, Edges);
145+
if (Edges.empty()) {
146+
addEdge(L, R);
147+
}
148+
}
149+
150+
bool getNeighbors(Data D, std::set<Data> &DataSet, bool Succ) {
141151
auto *N = this->findNode(NodeType(D));
142152
if (N == this->end())
143153
return false;

clang/lib/CConv/AVarBoundsInfo.cpp

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,12 @@ bool AVarBoundsInfo::addAssignment(BoundsKey L, BoundsKey R) {
400400
// dependency and never will be able to find the bounds for the return
401401
// value.
402402
if (L != R)
403-
ProgVarGraph.addEdge(R, L);
403+
ProgVarGraph.addUniqueEdge(R, L);
404404
} else {
405-
ProgVarGraph.addEdge(L, R);
406-
ProgVarGraph.addEdge(R, L);
405+
ProgVarGraph.addUniqueEdge(R, L);
406+
ProgramVar *PV = getProgramVar(R);
407+
if (!(PV && PV->IsNumConstant()))
408+
ProgVarGraph.addUniqueEdge(L, R);
407409
}
408410
return true;
409411
}
@@ -512,25 +514,18 @@ BoundsKey AVarBoundsInfo::getVarKey(PersistentSourceLoc &PSL) {
512514
}
513515

514516
BoundsKey AVarBoundsInfo::getConstKey(uint64_t value) {
515-
BoundsKey NK = ++BCount;
516-
std::string ConsString = std::to_string(value);
517-
ProgramVar *NPV =
518-
ProgramVar::createNewProgramVar(NK,
519-
ConsString,
520-
GlobalScope::getGlobalScope(),
521-
true);
522-
insertProgramVar(NK, NPV);
523-
ConstVarKeys[value].insert(NK);
524-
return NK;
525-
}
526-
527-
bool AVarBoundsInfo::fetchAllConstKeys(uint64_t value,
528-
std::set<BoundsKey> &AllKeys) {
529-
if (ConstVarKeys.find(value) != ConstVarKeys.end()) {
530-
AllKeys.insert(ConstVarKeys[value].begin(), ConstVarKeys[value].end());
531-
return true;
517+
if (ConstVarKeys.find(value) == ConstVarKeys.end()) {
518+
BoundsKey NK = ++BCount;
519+
std::string ConsString = std::to_string(value);
520+
ProgramVar *NPV =
521+
ProgramVar::createNewProgramVar(NK,
522+
ConsString,
523+
GlobalScope::getGlobalScope(),
524+
true);
525+
insertProgramVar(NK, NPV);
526+
ConstVarKeys[value] = NK;
532527
}
533-
return false;
528+
return ConstVarKeys[value];
534529
}
535530

536531
BoundsKey AVarBoundsInfo::getVarKey(llvm::APSInt &API) {
@@ -712,15 +707,6 @@ bool AvarBoundsInference::getReachableBoundKeys(const ProgramVarScope *DstScope,
712707
AllFKeys.clear();
713708
AllFKeys.insert(FromVarK);
714709

715-
// If this is a constant? Then get all bounds keys that
716-
// correspond to the same constant
717-
if (SBVar->IsNumConstant()) {
718-
uint64_t ConsVal;
719-
std::istringstream IS(SBVar->getVarName());
720-
IS >> ConsVal;
721-
BI->fetchAllConstKeys(ConsVal, AllFKeys);
722-
}
723-
724710
for (auto CurrVarK : AllFKeys) {
725711
// Find all the in scope variables reachable from the CurrVarK
726712
// bounds variable.
@@ -731,6 +717,24 @@ bool AvarBoundsInference::getReachableBoundKeys(const ProgramVarScope *DstScope,
731717
});
732718
}
733719

720+
// This is to get all the constants that are assigned to the variables
721+
// reachable from FromVarK.
722+
if (!SBVar->IsNumConstant()) {
723+
std::set<BoundsKey> ReachableCons;
724+
std::set<BoundsKey> Pre;
725+
for (auto CK : PotK) {
726+
Pre.clear();
727+
BKGraph.getPredecessors(CK, Pre);
728+
for (auto T : Pre) {
729+
auto *TVar = BI->getProgramVar(T);
730+
if (TVar->IsNumConstant()) {
731+
ReachableCons.insert(T);
732+
}
733+
}
734+
}
735+
PotK.insert(ReachableCons.begin(), ReachableCons.end());
736+
}
737+
734738
return !PotK.empty();
735739
}
736740

@@ -1229,11 +1233,10 @@ bool AVarBoundsInfo::performFlowAnalysis(ProgramInfo *PI) {
12291233
// Any thing changed? which means bounds of a variable changed
12301234
// Which means we need to recompute the flow based bounds for
12311235
// all arrays that have flow based bounds.
1232-
if (keepHighestPriorityBounds(ArrPointerBoundsKey)) {
1233-
// Remove flow inferred bounds, if exist for all the array pointers.
1234-
for (auto TBK : ArrPointerBoundsKey)
1235-
removeBounds(TBK, FlowInferred);
1236-
}
1236+
keepHighestPriorityBounds(ArrPointerBoundsKey);
1237+
// Remove flow inferred bounds, if exist for all the array pointers.
1238+
for (auto TBK : ArrPointerBoundsKey)
1239+
removeBounds(TBK, FlowInferred);
12371240

12381241
std::set<BoundsKey> ArrNeededBounds, ArrNeededBoundsNew;
12391242
ArrNeededBounds.clear();

0 commit comments

Comments
 (0)