@@ -601,11 +601,13 @@ void AvarBoundsInference::mergeReachableProgramVars(
601
601
if (!TmpB->isNumConstant ()) {
602
602
// We give preference to non-constant lengths.
603
603
BVar = TmpB;
604
- } else if (!this ->BI ->areSameProgramVar (BVar->getKey (),
605
- TmpB->getKey ())) {
606
- // If both are different constants?
607
- BVar = nullptr ;
608
- break ;
604
+ } else {
605
+ // If we need to merge two constants? Pick the lesser value.
606
+ int CVal = std::stoi (BVar->getVarName ());
607
+ int TmpVal = std::stoi (TmpB->getVarName ());
608
+ if (TmpVal < CVal) {
609
+ BVar = TmpB;
610
+ }
609
611
}
610
612
} else if (!TmpB->isNumConstant () && BVar->getKey () != TmpB->getKey ()) {
611
613
// If they are different variables?
@@ -737,22 +739,6 @@ bool AvarBoundsInference::getRelevantBounds(BoundsKey BK,
737
739
return HasBounds;
738
740
}
739
741
740
- // Variable comparison. Comparator implementation: where given two BoundsKey
741
- // they are checked to see if they correspond to the same program variable.
742
- struct BVarCmp {
743
- public:
744
- BVarCmp (AVarBoundsInfo *ABI) { this ->ABInfo = ABI; }
745
- bool operator ()(BoundsKey A, BoundsKey B) const {
746
- if (this ->ABInfo != nullptr && this ->ABInfo ->areSameProgramVar (A, B)) {
747
- return false ;
748
- }
749
- return A < B;
750
- };
751
-
752
- private:
753
- AVarBoundsInfo *ABInfo;
754
- };
755
-
756
742
bool AvarBoundsInference::areDeclaredBounds (
757
743
BoundsKey K,
758
744
const std::pair<ABounds::BoundsKind, std::set<BoundsKey>> &Bnds) {
@@ -827,7 +813,7 @@ bool AvarBoundsInference::predictBounds(BoundsKey K,
827
813
if (!InferredNBnds.empty ()) {
828
814
// All the possible inferred bounds for K
829
815
InferredKBnds.clear ();
830
- std::set<BoundsKey> TmpBKeys;
816
+ std::set<BoundsKey> TmpBKeys, AllKeys ;
831
817
// TODO: Figure out if there is a discrepency and try to implement
832
818
// root-cause analysis.
833
819
@@ -838,16 +824,23 @@ bool AvarBoundsInference::predictBounds(BoundsKey K,
838
824
InferredKBnds[INB.first ] = INB.second ;
839
825
} else {
840
826
TmpBKeys.clear ();
841
- // Here, we should use intersection by taking care of comparing
842
- // bounds key that correspond to the same constant.
843
- // Note, DO NOT use findIntersection here, as we need to take
844
- // care of comparing bounds key that correspond to the same
845
- // constant.
827
+ AllKeys.clear ();
828
+ // Find intersection between the current bounds and the
829
+ // bounds propagated from current neighbour, i.e., INB.first.
846
830
auto &S1 = InferredKBnds[INB.first ];
847
831
auto &S2 = INB.second ;
848
- std::set_intersection (S1.begin (), S1.end (), S2.begin (), S2.end (),
849
- std::inserter (TmpBKeys, TmpBKeys.begin ()),
850
- BVarCmp (this ->BI ));
832
+ // Find intersection of bounds propagated from all neighbours.
833
+ findIntersection (S1, S2, TmpBKeys);
834
+
835
+ AllKeys = S1;
836
+ AllKeys.insert (S2.begin (), S2.end ());
837
+ // Also, add all constants as potential bounds so that we can pick
838
+ // a constant with least value later.
839
+ for (auto CK: AllKeys) {
840
+ auto *CKVar = this ->BI ->getProgramVar (CK);
841
+ if (CKVar != nullptr && CKVar->isNumConstant ())
842
+ TmpBKeys.insert (CK);
843
+ }
851
844
InferredKBnds[INB.first ] = TmpBKeys;
852
845
}
853
846
}
@@ -1132,20 +1125,18 @@ void AVarBoundsInfo::computerArrPointers(ProgramInfo *PI,
1132
1125
// counterparts.
1133
1126
std::set<BoundsKey> CtxSensBKeys;
1134
1127
CtxSensBKeys.clear ();
1135
- std::set<BoundsKey> TmpBKeys, TmpBKeysF ;
1128
+ std::set<BoundsKey> TmpBKeys;
1136
1129
for (auto BK : ArrPointers) {
1137
- TmpBKeys.clear ();
1138
- ProgVarGraph.getPredecessors (BK, TmpBKeys);
1139
- TmpBKeysF.insert (TmpBKeys.begin (), TmpBKeys.end ());
1140
- TmpBKeys.clear ();
1141
- ProgVarGraph.getSuccessors (BK, TmpBKeys);
1142
- TmpBKeysF.insert (TmpBKeys.begin (), TmpBKeys.end ());
1143
- for (auto TBK : TmpBKeysF) {
1144
- ProgramVar *TmpPVar = getProgramVar (TBK);
1145
- if (TmpPVar != nullptr ) {
1146
- if (isa<CtxFunctionArgScope>(TmpPVar->getScope ())) {
1147
- CtxSensBKeys.insert (TBK);
1148
- }
1130
+ CtxSensProgVarGraph.getSuccessors (BK, TmpBKeys, true );
1131
+ CtxSensProgVarGraph.getPredecessors (BK, TmpBKeys, true );
1132
+ RevCtxSensProgVarGraph.getSuccessors (BK, TmpBKeys, true );
1133
+ RevCtxSensProgVarGraph.getPredecessors (BK, TmpBKeys, true );
1134
+ }
1135
+ for (auto TBK : TmpBKeys) {
1136
+ ProgramVar *TmpPVar = getProgramVar (TBK);
1137
+ if (TmpPVar != nullptr ) {
1138
+ if (isa<CtxFunctionArgScope>(TmpPVar->getScope ())) {
1139
+ CtxSensBKeys.insert (TBK);
1149
1140
}
1150
1141
}
1151
1142
}
@@ -1193,6 +1184,10 @@ bool AVarBoundsInfo::performFlowAnalysis(ProgramInfo *PI) {
1193
1184
// Repopulate array bounds key.
1194
1185
ArrPointerBoundsKey.clear ();
1195
1186
ArrPointerBoundsKey.insert (ArrPointers.begin (), ArrPointers.end ());
1187
+ // All BoundsKey that has bounds are also array pointers.
1188
+ for (auto &T : this ->BInfo ) {
1189
+ ArrPointerBoundsKey.insert (T.first );
1190
+ }
1196
1191
1197
1192
// Keep only highest priority bounds.
1198
1193
// Any thing changed? which means bounds of a variable changed
0 commit comments