Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

588 lines
17 KiB

  1. //===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. /// @file
  11. /// IntegersSubsetMapping is mapping from A to B, where
  12. /// Items in A is subsets of integers,
  13. /// Items in B some pointers (Successors).
  14. /// If user which to add another subset for successor that is already
  15. /// exists in mapping, IntegersSubsetMapping merges existing subset with
  16. /// added one.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
  20. #define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
  21. #include "llvm/Support/IntegersSubset.h"
  22. #include <list>
  23. #include <map>
  24. #include <vector>
  25. namespace llvm {
  26. template <class SuccessorClass,
  27. class IntegersSubsetTy = IntegersSubset,
  28. class IntTy = IntItem>
  29. class IntegersSubsetMapping {
  30. // FIXME: To much similar iterators typedefs, similar names.
  31. // - Rename RangeIterator to the cluster iterator.
  32. // - Remove unused "add" methods.
  33. // - Class contents needs cleaning.
  34. public:
  35. typedef IntRange<IntTy> RangeTy;
  36. struct RangeEx : public RangeTy {
  37. RangeEx() : Weight(1) {}
  38. RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
  39. RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
  40. RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
  41. RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
  42. RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
  43. RangeTy(L, H), Weight(W) {}
  44. unsigned Weight;
  45. };
  46. typedef std::pair<RangeEx, SuccessorClass*> Cluster;
  47. typedef std::list<RangeTy> RangesCollection;
  48. typedef typename RangesCollection::iterator RangesCollectionIt;
  49. typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
  50. typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
  51. protected:
  52. typedef std::list<Cluster> CaseItems;
  53. typedef typename CaseItems::iterator CaseItemIt;
  54. typedef typename CaseItems::const_iterator CaseItemConstIt;
  55. // TODO: Change unclean CRS prefixes to SubsetMap for example.
  56. typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
  57. typedef typename CRSMap::iterator CRSMapIt;
  58. struct ClustersCmp {
  59. bool operator()(const Cluster &C1, const Cluster &C2) {
  60. return C1.first < C2.first;
  61. }
  62. };
  63. CaseItems Items;
  64. bool Sorted;
  65. bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
  66. return LItem->first.getHigh() >= RItem->first.getLow();
  67. }
  68. bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
  69. if (LItem->second != RItem->second) {
  70. assert(!isIntersected(LItem, RItem) &&
  71. "Intersected items with different successors!");
  72. return false;
  73. }
  74. APInt RLow = RItem->first.getLow();
  75. if (RLow != APInt::getNullValue(RLow.getBitWidth()))
  76. --RLow;
  77. return LItem->first.getHigh() >= RLow;
  78. }
  79. void sort() {
  80. if (!Sorted) {
  81. std::vector<Cluster> clustersVector;
  82. clustersVector.reserve(Items.size());
  83. clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
  84. std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
  85. Items.clear();
  86. Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
  87. Sorted = true;
  88. }
  89. }
  90. enum DiffProcessState {
  91. L_OPENED,
  92. INTERSECT_OPENED,
  93. R_OPENED,
  94. ALL_IS_CLOSED
  95. };
  96. class DiffStateMachine {
  97. DiffProcessState State;
  98. IntTy OpenPt;
  99. SuccessorClass *CurrentLSuccessor;
  100. SuccessorClass *CurrentRSuccessor;
  101. self *LeftMapping;
  102. self *IntersectionMapping;
  103. self *RightMapping;
  104. public:
  105. typedef
  106. IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
  107. DiffStateMachine(MappingTy *L,
  108. MappingTy *Intersection,
  109. MappingTy *R) :
  110. State(ALL_IS_CLOSED),
  111. LeftMapping(L),
  112. IntersectionMapping(Intersection),
  113. RightMapping(R)
  114. {}
  115. void onLOpen(const IntTy &Pt, SuccessorClass *S) {
  116. switch (State) {
  117. case R_OPENED:
  118. if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
  119. RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
  120. State = INTERSECT_OPENED;
  121. break;
  122. case ALL_IS_CLOSED:
  123. State = L_OPENED;
  124. break;
  125. default:
  126. assert(0 && "Got unexpected point.");
  127. break;
  128. }
  129. CurrentLSuccessor = S;
  130. OpenPt = Pt;
  131. }
  132. void onLClose(const IntTy &Pt) {
  133. switch (State) {
  134. case L_OPENED:
  135. assert(Pt >= OpenPt &&
  136. "Subset is not sorted or contains overlapped ranges");
  137. if (LeftMapping)
  138. LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
  139. State = ALL_IS_CLOSED;
  140. break;
  141. case INTERSECT_OPENED:
  142. if (IntersectionMapping)
  143. IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
  144. OpenPt = Pt + 1;
  145. State = R_OPENED;
  146. break;
  147. default:
  148. assert(0 && "Got unexpected point.");
  149. break;
  150. }
  151. }
  152. void onROpen(const IntTy &Pt, SuccessorClass *S) {
  153. switch (State) {
  154. case L_OPENED:
  155. if (Pt > OpenPt && LeftMapping)
  156. LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
  157. State = INTERSECT_OPENED;
  158. break;
  159. case ALL_IS_CLOSED:
  160. State = R_OPENED;
  161. break;
  162. default:
  163. assert(0 && "Got unexpected point.");
  164. break;
  165. }
  166. CurrentRSuccessor = S;
  167. OpenPt = Pt;
  168. }
  169. void onRClose(const IntTy &Pt) {
  170. switch (State) {
  171. case R_OPENED:
  172. assert(Pt >= OpenPt &&
  173. "Subset is not sorted or contains overlapped ranges");
  174. if (RightMapping)
  175. RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
  176. State = ALL_IS_CLOSED;
  177. break;
  178. case INTERSECT_OPENED:
  179. if (IntersectionMapping)
  180. IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
  181. OpenPt = Pt + 1;
  182. State = L_OPENED;
  183. break;
  184. default:
  185. assert(0 && "Got unexpected point.");
  186. break;
  187. }
  188. }
  189. void onLROpen(const IntTy &Pt,
  190. SuccessorClass *LS,
  191. SuccessorClass *RS) {
  192. switch (State) {
  193. case ALL_IS_CLOSED:
  194. State = INTERSECT_OPENED;
  195. break;
  196. default:
  197. assert(0 && "Got unexpected point.");
  198. break;
  199. }
  200. CurrentLSuccessor = LS;
  201. CurrentRSuccessor = RS;
  202. OpenPt = Pt;
  203. }
  204. void onLRClose(const IntTy &Pt) {
  205. switch (State) {
  206. case INTERSECT_OPENED:
  207. if (IntersectionMapping)
  208. IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
  209. State = ALL_IS_CLOSED;
  210. break;
  211. default:
  212. assert(0 && "Got unexpected point.");
  213. break;
  214. }
  215. }
  216. bool isLOpened() { return State == L_OPENED; }
  217. bool isROpened() { return State == R_OPENED; }
  218. };
  219. public:
  220. // Don't public CaseItems itself. Don't allow edit the Items directly.
  221. // Just present the user way to iterate over the internal collection
  222. // sharing iterator, begin() and end(). Editing should be controlled by
  223. // factory.
  224. typedef CaseItemIt RangeIterator;
  225. typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
  226. typedef std::list<Case> Cases;
  227. typedef typename Cases::iterator CasesIt;
  228. IntegersSubsetMapping() {
  229. Sorted = false;
  230. }
  231. bool verify() {
  232. RangeIterator DummyErrItem;
  233. return verify(DummyErrItem);
  234. }
  235. bool verify(RangeIterator& errItem) {
  236. if (Items.empty())
  237. return true;
  238. sort();
  239. for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
  240. j != e; i = j++) {
  241. if (isIntersected(i, j) && i->second != j->second) {
  242. errItem = j;
  243. return false;
  244. }
  245. }
  246. return true;
  247. }
  248. bool isOverlapped(self &RHS) {
  249. if (Items.empty() || RHS.empty())
  250. return true;
  251. for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
  252. el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
  253. const RangeTy &LRange = L->first;
  254. const RangeTy &RRange = R->first;
  255. if (LRange.getLow() > RRange.getLow()) {
  256. if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
  257. ++R;
  258. else
  259. return true;
  260. } else if (LRange.getLow() < RRange.getLow()) {
  261. if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
  262. ++L;
  263. else
  264. return true;
  265. } else // iRange.getLow() == jRange.getLow()
  266. return true;
  267. }
  268. return false;
  269. }
  270. void optimize() {
  271. if (Items.size() < 2)
  272. return;
  273. sort();
  274. CaseItems OldItems = Items;
  275. Items.clear();
  276. const IntTy *Low = &OldItems.begin()->first.getLow();
  277. const IntTy *High = &OldItems.begin()->first.getHigh();
  278. unsigned Weight = OldItems.begin()->first.Weight;
  279. SuccessorClass *Successor = OldItems.begin()->second;
  280. for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
  281. j != e; i = j++) {
  282. if (isJoinable(i, j)) {
  283. const IntTy *CurHigh = &j->first.getHigh();
  284. Weight += j->first.Weight;
  285. if (*CurHigh > *High)
  286. High = CurHigh;
  287. } else {
  288. RangeEx R(*Low, *High, Weight);
  289. add(R, Successor);
  290. Low = &j->first.getLow();
  291. High = &j->first.getHigh();
  292. Weight = j->first.Weight;
  293. Successor = j->second;
  294. }
  295. }
  296. RangeEx R(*Low, *High, Weight);
  297. add(R, Successor);
  298. // We recollected the Items, but we kept it sorted.
  299. Sorted = true;
  300. }
  301. /// Adds a constant value.
  302. void add(const IntTy &C, SuccessorClass *S = 0) {
  303. RangeTy R(C);
  304. add(R, S);
  305. }
  306. /// Adds a range.
  307. void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
  308. RangeTy R(Low, High);
  309. add(R, S);
  310. }
  311. void add(const RangeTy &R, SuccessorClass *S = 0) {
  312. RangeEx REx = R;
  313. add(REx, S);
  314. }
  315. void add(const RangeEx &R, SuccessorClass *S = 0) {
  316. Items.push_back(std::make_pair(R, S));
  317. Sorted = false;
  318. }
  319. /// Adds all ranges and values from given ranges set to the current
  320. /// mapping.
  321. void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
  322. unsigned Weight = 0) {
  323. unsigned ItemWeight = 1;
  324. if (Weight)
  325. // Weight is associated with CRS, for now we perform a division to
  326. // get the weight for each item.
  327. ItemWeight = Weight / CRS.getNumItems();
  328. for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
  329. RangeTy R = CRS.getItem(i);
  330. RangeEx REx(R, ItemWeight);
  331. add(REx, S);
  332. }
  333. }
  334. void add(self& RHS) {
  335. Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
  336. }
  337. void add(self& RHS, SuccessorClass *S) {
  338. for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
  339. add(i->first, S);
  340. }
  341. void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
  342. for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
  343. add(*i, S);
  344. }
  345. /// Removes items from set.
  346. void removeItem(RangeIterator i) { Items.erase(i); }
  347. /// Moves whole case from current mapping to the NewMapping object.
  348. void detachCase(self& NewMapping, SuccessorClass *Succ) {
  349. for (CaseItemIt i = Items.begin(); i != Items.end();)
  350. if (i->second == Succ) {
  351. NewMapping.add(i->first, i->second);
  352. Items.erase(i++);
  353. } else
  354. ++i;
  355. }
  356. /// Removes all clusters for given successor.
  357. void removeCase(SuccessorClass *Succ) {
  358. for (CaseItemIt i = Items.begin(); i != Items.end();)
  359. if (i->second == Succ) {
  360. Items.erase(i++);
  361. } else
  362. ++i;
  363. }
  364. /// Find successor that satisfies given value.
  365. SuccessorClass *findSuccessor(const IntTy& Val) {
  366. for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
  367. if (i->first.isInRange(Val))
  368. return i->second;
  369. }
  370. return 0;
  371. }
  372. /// Calculates the difference between this mapping and RHS.
  373. /// THIS without RHS is placed into LExclude,
  374. /// RHS without THIS is placed into RExclude,
  375. /// THIS intersect RHS is placed into Intersection.
  376. void diff(self *LExclude, self *Intersection, self *RExclude,
  377. const self& RHS) {
  378. DiffStateMachine Machine(LExclude, Intersection, RExclude);
  379. CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
  380. while (L != Items.end() && R != RHS.Items.end()) {
  381. const Cluster &LCluster = *L;
  382. const RangeEx &LRange = LCluster.first;
  383. const Cluster &RCluster = *R;
  384. const RangeEx &RRange = RCluster.first;
  385. if (LRange.getHigh() < RRange.getLow()) {
  386. Machine.onLOpen(LRange.getLow(), LCluster.second);
  387. Machine.onLClose(LRange.getHigh());
  388. ++L;
  389. continue;
  390. }
  391. if (LRange.getLow() > RRange.getHigh()) {
  392. Machine.onROpen(RRange.getLow(), RCluster.second);
  393. Machine.onRClose(RRange.getHigh());
  394. ++R;
  395. continue;
  396. }
  397. if (LRange.getLow() < RRange.getLow()) {
  398. // May be opened in previous iteration.
  399. if (!Machine.isLOpened())
  400. Machine.onLOpen(LRange.getLow(), LCluster.second);
  401. Machine.onROpen(RRange.getLow(), RCluster.second);
  402. }
  403. else if (RRange.getLow() < LRange.getLow()) {
  404. if (!Machine.isROpened())
  405. Machine.onROpen(RRange.getLow(), RCluster.second);
  406. Machine.onLOpen(LRange.getLow(), LCluster.second);
  407. }
  408. else
  409. Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
  410. if (LRange.getHigh() < RRange.getHigh()) {
  411. Machine.onLClose(LRange.getHigh());
  412. ++L;
  413. while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
  414. Machine.onLOpen(L->first.getLow(), L->second);
  415. Machine.onLClose(L->first.getHigh());
  416. ++L;
  417. }
  418. }
  419. else if (RRange.getHigh() < LRange.getHigh()) {
  420. Machine.onRClose(RRange.getHigh());
  421. ++R;
  422. while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
  423. Machine.onROpen(R->first.getLow(), R->second);
  424. Machine.onRClose(R->first.getHigh());
  425. ++R;
  426. }
  427. }
  428. else {
  429. Machine.onLRClose(LRange.getHigh());
  430. ++L;
  431. ++R;
  432. }
  433. }
  434. if (L != Items.end()) {
  435. if (Machine.isLOpened()) {
  436. Machine.onLClose(L->first.getHigh());
  437. ++L;
  438. }
  439. if (LExclude)
  440. while (L != Items.end()) {
  441. LExclude->add(L->first, L->second);
  442. ++L;
  443. }
  444. } else if (R != RHS.Items.end()) {
  445. if (Machine.isROpened()) {
  446. Machine.onRClose(R->first.getHigh());
  447. ++R;
  448. }
  449. if (RExclude)
  450. while (R != RHS.Items.end()) {
  451. RExclude->add(R->first, R->second);
  452. ++R;
  453. }
  454. }
  455. }
  456. /// Builds the finalized case objects.
  457. void getCases(Cases& TheCases, bool PreventMerging = false) {
  458. //FIXME: PreventMerging is a temporary parameter.
  459. //Currently a set of passes is still knows nothing about
  460. //switches with case ranges, and if these passes meet switch
  461. //with complex case that crashs the application.
  462. if (PreventMerging) {
  463. for (RangeIterator i = this->begin(); i != this->end(); ++i) {
  464. RangesCollection SingleRange;
  465. SingleRange.push_back(i->first);
  466. TheCases.push_back(std::make_pair(i->second,
  467. IntegersSubsetTy(SingleRange)));
  468. }
  469. return;
  470. }
  471. CRSMap TheCRSMap;
  472. for (RangeIterator i = this->begin(); i != this->end(); ++i)
  473. TheCRSMap[i->second].push_back(i->first);
  474. for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
  475. TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
  476. }
  477. /// Builds the finalized case objects ignoring successor values, as though
  478. /// all ranges belongs to the same successor.
  479. IntegersSubsetTy getCase() {
  480. RangesCollection Ranges;
  481. for (RangeIterator i = this->begin(); i != this->end(); ++i)
  482. Ranges.push_back(i->first);
  483. return IntegersSubsetTy(Ranges);
  484. }
  485. /// Returns pointer to value of case if it is single-numbered or 0
  486. /// in another case.
  487. const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
  488. const IntTy* Res = 0;
  489. for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
  490. if (i->second == Succ) {
  491. if (!i->first.isSingleNumber())
  492. return 0;
  493. if (Res)
  494. return 0;
  495. else
  496. Res = &(i->first.getLow());
  497. }
  498. return Res;
  499. }
  500. /// Returns true if there is no ranges and values inside.
  501. bool empty() const { return Items.empty(); }
  502. void clear() {
  503. Items.clear();
  504. // Don't reset Sorted flag:
  505. // 1. For empty mapping it matters nothing.
  506. // 2. After first item will added Sorted flag will cleared.
  507. }
  508. // Returns number of clusters
  509. unsigned size() const {
  510. return Items.size();
  511. }
  512. RangeIterator begin() { return Items.begin(); }
  513. RangeIterator end() { return Items.end(); }
  514. };
  515. class BasicBlock;
  516. typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
  517. }
  518. #endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */