Skip to content

Commit f86da78

Browse files
authored
Merge pull request #309 from correctcomputation/arrbndsdebug
Fixing array length inference performance issue
2 parents 04ccde0 + 8cce9d9 commit f86da78

File tree

3 files changed

+64
-17
lines changed

3 files changed

+64
-17
lines changed

clang/include/clang/CConv/AVarBoundsInfo.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,10 @@ class AvarBoundsInference {
103103
AVarGraph &BKGraph,
104104
std::set<ABounds *> &EB);
105105

106-
bool intersectBounds(std::set<ProgramVar *> &ProgVars,
107-
ABounds::BoundsKind BK,
108-
std::set<ABounds *> &CurrB);
109-
110-
bool getRelevantBounds(std::set<BoundsKey> &RBKeys,
111-
std::set<ABounds *> &ResBounds);
106+
// Check if bounds specified by Bnds are declared bounds of K.
107+
bool areDeclaredBounds(BoundsKey K,
108+
const std::pair<ABounds::BoundsKind,
109+
std::set<BoundsKey>> &Bnds);
112110

113111
bool predictBounds(BoundsKey K, std::set<BoundsKey> &Neighbours,
114112
AVarGraph &BKGraph,
@@ -238,7 +236,7 @@ class AVarBoundsInfo {
238236
BoundsKey BCount;
239237
// Map of VarKeys and corresponding program variables.
240238
std::map<BoundsKey, ProgramVar *> PVarInfo;
241-
// Map of APSInt (constants) and corresponding VarKeys.
239+
// Map of APSInt (constants) and a BoundKey that correspond to it.
242240
std::map<uint64_t, BoundsKey> ConstVarKeys;
243241
// Map of BoundsKey and corresponding prioritized bounds information.
244242
// Note that although each PSL could have multiple ConstraintKeys Ex: **p.

clang/include/clang/CConv/ConstraintsGraph.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,17 @@ class DataGraph :
134134
BL->connectTo(*BR);
135135
}
136136

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

clang/lib/CConv/AVarBoundsInfo.cpp

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,12 @@ bool AVarBoundsInfo::addAssignment(BoundsKey L, BoundsKey R) {
393393
// dependency and never will be able to find the bounds for the return
394394
// value.
395395
if (L != R)
396-
ProgVarGraph.addEdge(R, L);
396+
ProgVarGraph.addUniqueEdge(R, L);
397397
} else {
398-
ProgVarGraph.addEdge(L, R);
399-
ProgVarGraph.addEdge(R, L);
398+
ProgVarGraph.addUniqueEdge(R, L);
399+
ProgramVar *PV = getProgramVar(R);
400+
if (!(PV && PV->IsNumConstant()))
401+
ProgVarGraph.addUniqueEdge(L, R);
400402
}
401403
return true;
402404
}
@@ -712,7 +714,45 @@ bool AvarBoundsInference::inferPossibleBounds(BoundsKey K, ABounds *SB,
712714
}
713715
}
714716

715-
return RetVal;
717+
// All constants are reachable!
718+
if (SBVar->IsNumConstant()) {
719+
PotK.insert(FromVarK);
720+
}
721+
722+
// Get all bounds key that are equivalent to FromVarK
723+
std::set<BoundsKey> AllFKeys;
724+
AllFKeys.clear();
725+
AllFKeys.insert(FromVarK);
726+
727+
for (auto CurrVarK : AllFKeys) {
728+
// Find all the in scope variables reachable from the CurrVarK
729+
// bounds variable.
730+
ScopeVisitor TV(DstScope, PotK, BI->PVarInfo,
731+
BI->PointerBoundsKey);
732+
BKGraph.visitBreadthFirst(CurrVarK, [&TV](BoundsKey BK) {
733+
TV.visitBoundsKey(BK);
734+
});
735+
}
736+
737+
// This is to get all the constants that are assigned to the variables
738+
// reachable from FromVarK.
739+
if (!SBVar->IsNumConstant()) {
740+
std::set<BoundsKey> ReachableCons;
741+
std::set<BoundsKey> Pre;
742+
for (auto CK : PotK) {
743+
Pre.clear();
744+
BKGraph.getPredecessors(CK, Pre);
745+
for (auto T : Pre) {
746+
auto *TVar = BI->getProgramVar(T);
747+
if (TVar->IsNumConstant()) {
748+
ReachableCons.insert(T);
749+
}
750+
}
751+
}
752+
PotK.insert(ReachableCons.begin(), ReachableCons.end());
753+
}
754+
755+
return !PotK.empty();
716756
}
717757

718758
bool AvarBoundsInference::getRelevantBounds(std::set<BoundsKey> &RBKeys,
@@ -1065,11 +1105,10 @@ bool AVarBoundsInfo::performFlowAnalysis(ProgramInfo *PI) {
10651105
// Any thing changed? which means bounds of a variable changed
10661106
// Which means we need to recompute the flow based bounds for
10671107
// all arrays that have flow based bounds.
1068-
if (keepHighestPriorityBounds(ArrPointerBoundsKey)) {
1069-
// Remove flow inferred bounds, if exist for all the array pointers.
1070-
for (auto TBK : ArrPointerBoundsKey)
1071-
removeBounds(TBK, FlowInferred);
1072-
}
1108+
keepHighestPriorityBounds(ArrPointerBoundsKey);
1109+
// Remove flow inferred bounds, if exist for all the array pointers.
1110+
for (auto TBK : ArrPointerBoundsKey)
1111+
removeBounds(TBK, FlowInferred);
10731112

10741113
// Next, get the ARR pointers that has bounds.
10751114
// These are pointers with bounds.

0 commit comments

Comments
 (0)