Static Value-Flow Analysis
MemPartition.cpp
Go to the documentation of this file.
1 //===- MemPartition.cpp -- Memory region partition----------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * @file: DisMRGenerator.cpp
25  * @author: yesen
26  * @date: 07/12/2013
27  * @version: 1.0
28  *
29  * @section LICENSE
30  *
31  * @section DESCRIPTION
32  *
33  */
34 
35 #include "MSSA/MemPartition.h"
36 
37 using namespace SVF;
38 
43 {
44  for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end();
45  it!=eit; ++it)
46  {
47  const SVFFunction* fun = it->first;
49  NodeBS mergePts;
50  for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
51  {
52  const NodeBS& pts = *cit;
53  mergePts |= pts;
54  }
55  createDistinctMR(fun, mergePts);
56  }
57 }
58 
64 void DistinctMRG::createDistinctMR(const SVFFunction* func, const NodeBS& pts)
65 {
67 
68  NodeBS::iterator ptsIt = pts.begin();
69  NodeBS::iterator ptsEit = pts.end();
70  for (; ptsIt != ptsEit; ++ptsIt)
71  {
72  NodeID id = *ptsIt;
73  // create new conditional points-to set with this single element.
74  NodeBS newPts;
75  newPts.set(id);
76 
77  // set the rep cpts as itself.
78  cptsToRepCPtsMap[newPts] = newPts;
79 
80  // add memory region for this points-to target.
81  createMR(func, newPts);
82  }
83 }
84 
91 void DistinctMRG::getMRsForLoad(MRSet& mrs, const NodeBS& pts, const SVFFunction*)
92 {
94 
95  NodeBS::iterator ptsIt = pts.begin();
96  NodeBS::iterator ptsEit = pts.end();
97  for (; ptsIt != ptsEit; ++ptsIt)
98  {
99  NodeID id = *ptsIt;
100  // create new conditional points-to set with this single element.
101  NodeBS newPts;
102  newPts.set(id);
103 
104  MemRegion mr(newPts);
105  MRSet::iterator mit = memRegSet.find(&mr);
106  assert(mit!=memRegSet.end() && "memory region not found!!");
107  mrs.insert(*mit);
108  }
109 }
110 
115 void DistinctMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun)
116 {
117  getMRsForLoad(aliasMRs, cpts, fun);
118 }
119 
120 /*-----------------------------------------------------*/
121 
123 {
124  for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(),
125  eit = getFunToPointsToList().end(); it!=eit; ++it)
126  {
127  const SVFFunction* fun = it->first;
128 
129  for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end();
130  cit!=ecit; ++cit)
131  {
132  const NodeBS& cpts = *cit;
133 
134  PointsToList& inters = getIntersList(fun);
135  computeIntersections(cpts, inters);
136  }
137 
139  const PointsToList& inters = getIntersList(fun);
140  for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end();
141  interIt != interEit; ++interIt)
142  {
143  const NodeBS& inter = *interIt;
144  createDisjointMR(fun, inter);
145  }
146  }
147 }
148 
153 {
154  if (inters.find(cpts) != inters.end())
155  {
156  // Skip this cpts if it is already in the map.
157  return;
158  }
159  else if (cpts.count() == 1)
160  {
161  // If this cpts has only one element, it will not intersect with any cpts in inters,
162  // just add it into intersection set.
163  inters.insert(cpts);
164  return;
165  }
166  else
167  {
168  PointsToList toBeDeleted;
169  PointsToList newInters;
170 
171  NodeBS cpts_copy = cpts; // make a copy since cpts may be changed.
172 
173  // check intersections with existing cpts in subSetMap
174  for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end();
175  interIt != interEit; ++interIt)
176  {
177  const NodeBS& inter = *interIt;
178 
179  if (cpts_copy.intersects(inter))
180  {
181  // compute intersection between cpts and inter
182  NodeBS new_inter = inter;
183  new_inter &= cpts_copy;
184 
185  // remove old intersection and add new one if possible
186  if (new_inter != inter)
187  {
188  toBeDeleted.insert(inter);
189  newInters.insert(new_inter);
190 
191  // compute complement after intersection
192  NodeBS complement = inter;
193  complement.intersectWithComplement(new_inter);
194  if (complement.empty() == false)
195  {
196  newInters.insert(complement);
197  }
198  }
199 
200  cpts_copy.intersectWithComplement(new_inter);
201 
202  if (cpts_copy.empty())
203  break;
204  }
205  }
206 
207  // remove old intersections
208  for (PointsToList::const_iterator it = toBeDeleted.begin(), eit = toBeDeleted.end();
209  it != eit; ++it)
210  {
211  const NodeBS& temp_cpts = *it;
212  inters.erase(temp_cpts);
213  }
214 
215  // add new intersections
216  for (PointsToList::const_iterator it = newInters.begin(), eit = newInters.end();
217  it != eit; ++it)
218  {
219  const NodeBS& temp_cpts = *it;
220  inters.insert(temp_cpts);
221  }
222 
223  // add remaining set into inters
224  if (cpts_copy.empty() == false)
225  inters.insert(cpts_copy);
226  }
227 }
228 
233 {
234  // set the rep cpts as itself.
235  cptsToRepCPtsMap[cpts] = cpts;
236 
237  // add memory region for this points-to target.
238  createMR(func, cpts);
239 }
240 
242 {
243  PointsToList::const_iterator it = inters.begin();
244  PointsToList::const_iterator eit = inters.end();
245  for (; it != eit; ++it)
246  {
247  const NodeBS& inter = *it;
248  if (cpts.contains(inter))
249  {
250  MemRegion mr(inter);
251  MRSet::iterator mit = memRegSet.find(&mr);
252  assert(mit!=memRegSet.end() && "memory region not found!!");
253  mrs.insert(*mit);
254  }
255  }
256 }
257 
262 void IntraDisjointMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun)
263 {
264  getMRsForLoad(aliasMRs, cpts, fun);
265 }
266 
267 /*-----------------------------------------------------*/
268 
270 {
272  for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(),
273  eit = getFunToPointsToList().end(); it!=eit; ++it)
274  {
275  for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end();
276  cit!=ecit; ++cit)
277  {
278  const NodeBS& cpts = *cit;
279 
281  }
282  }
283 
285  for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(),
286  eit = getFunToPointsToList().end(); it!=eit; ++it)
287  {
288  const SVFFunction* fun = it->first;
289 
290  for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end();
291  cit!=ecit; ++cit)
292  {
293  const NodeBS& cpts = *cit;
294 
295  for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end();
296  interIt != interEit; ++interIt)
297  {
298  const NodeBS& inter = *interIt;
299  if (cpts.contains(inter))
300  createDisjointMR(fun, inter);
301  }
302  }
303  }
304 }
virtual void getMRsForLoad(MRSet &aliasMRs, const NodeBS &cpts, const SVFFunction *fun)
Get memory region at a load.
virtual void partitionMRs()
Partition regions.
virtual void getMRsForCallSiteRef(MRSet &aliasMRs, const NodeBS &cpts, const SVFFunction *fun)
Get memory regions to be inserted at a load statement.
void createDistinctMR(const SVFFunction *func, const NodeBS &cpts)
Create memory regions for each points-to target.
virtual void partitionMRs()
Partition regions.
void createDisjointMR(const SVFFunction *func, const NodeBS &cpts)
Create disjoint memory region.
virtual void partitionMRs()
Partition regions.
virtual void getMRsForCallSiteRef(MRSet &aliasMRs, const NodeBS &cpts, const SVFFunction *fun)
Get memory regions to be inserted at a load statement.
void getMRsForLoadFromInterList(MRSet &mrs, const NodeBS &cpts, const PointsToList &inters)
PointsToList & getIntersList(const SVFFunction *func)
Definition: MemPartition.h:120
void computeIntersections(const NodeBS &cpts, PointsToList &inters)
Compute intersections between cpts and computed cpts intersections before.
virtual void getMRsForLoad(MRSet &aliasMRs, const NodeBS &cpts, const SVFFunction *fun)
Definition: MemPartition.h:96
FunToPointsTosMap & getFunToPointsToList()
Definition: MemRegion.h:371
OrderedSet< NodeBS, SVFUtil::equalNodeBS > PointsToList
Definition: MemRegion.h:143
OrderedSet< const MemRegion *, MemRegion::equalMemRegion > MRSet
Get typedef from Pointer Analysis.
Definition: MemRegion.h:141
PtsToRepPtsSetMap cptsToRepCPtsMap
Map a condition pts to its rep conditional pts (super set points-to)
Definition: MemRegion.h:280
void createMR(const SVFFunction *fun, const NodeBS &cpts)
Generate a memory region and put in into functions which use it.
Definition: MemRegion.cpp:69
MRSet memRegSet
A set of All memory regions.
Definition: MemRegion.h:278
Memory Region class.
Definition: MemRegion.h:56
bool intersects(const SparseBitVector< ElementSize > *RHS) const
iterator end() const
void set(unsigned Idx)
bool intersectWithComplement(const SparseBitVector &RHS)
unsigned count() const
bool contains(const SparseBitVector< ElementSize > &RHS) const
iterator begin() const
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55