Line data Source code
1 : //===-- Use.cpp - Implement the Use class ---------------------------------===//
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 : #include "llvm/IR/Use.h"
11 : #include "llvm/IR/User.h"
12 : #include "llvm/IR/Value.h"
13 : #include <new>
14 :
15 : namespace llvm {
16 :
17 121538 : void Use::swap(Use &RHS) {
18 121538 : if (Val == RHS.Val)
19 : return;
20 :
21 121538 : if (Val)
22 : removeFromList();
23 :
24 : Value *OldVal = Val;
25 121538 : if (RHS.Val) {
26 : RHS.removeFromList();
27 121538 : Val = RHS.Val;
28 : Val->addUse(*this);
29 : } else {
30 0 : Val = nullptr;
31 : }
32 :
33 121538 : if (OldVal) {
34 121538 : RHS.Val = OldVal;
35 : RHS.Val->addUse(RHS);
36 : } else {
37 0 : RHS.Val = nullptr;
38 : }
39 : }
40 :
41 255651617 : User *Use::getUser() const {
42 255651617 : const Use *End = getImpliedUser();
43 : const UserRef *ref = reinterpret_cast<const UserRef *>(End);
44 511303234 : return ref->getInt() ? ref->getPointer()
45 255651617 : : reinterpret_cast<User *>(const_cast<Use *>(End));
46 : }
47 :
48 885813 : unsigned Use::getOperandNo() const {
49 885813 : return this - getUser()->op_begin();
50 : }
51 :
52 : // Sets up the waymarking algorithm's tags for a series of Uses. See the
53 : // algorithm details here:
54 : //
55 : // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
56 : //
57 72137594 : Use *Use::initTags(Use *const Start, Use *Stop) {
58 : ptrdiff_t Done = 0;
59 188176557 : while (Done < 20) {
60 188162094 : if (Start == Stop--)
61 : return Start;
62 : static const PrevPtrTag tags[20] = {
63 : fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag,
64 : stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag,
65 : zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag,
66 : oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag};
67 116038963 : new (Stop) Use(tags[Done++]);
68 : }
69 :
70 : ptrdiff_t Count = Done;
71 329197 : while (Start != Stop) {
72 314734 : --Stop;
73 314734 : if (!Count) {
74 : new (Stop) Use(stopTag);
75 34368 : ++Done;
76 : Count = Done;
77 : } else {
78 280366 : new (Stop) Use(PrevPtrTag(Count & 1));
79 280366 : Count >>= 1;
80 280366 : ++Done;
81 : }
82 : }
83 :
84 : return Start;
85 : }
86 :
87 35699491 : void Use::zap(Use *Start, const Use *Stop, bool del) {
88 89261788 : while (Start != Stop)
89 53562297 : (--Stop)->~Use();
90 35699491 : if (del)
91 2002863 : ::operator delete(Start);
92 35699491 : }
93 :
94 255651617 : const Use *Use::getImpliedUser() const {
95 : const Use *Current = this;
96 :
97 : while (true) {
98 370770123 : unsigned Tag = (Current++)->Prev.getInt();
99 370770123 : switch (Tag) {
100 : case zeroDigitTag:
101 : case oneDigitTag:
102 : continue;
103 :
104 36256776 : case stopTag: {
105 36256776 : ++Current;
106 : ptrdiff_t Offset = 1;
107 : while (true) {
108 49312038 : unsigned Tag = Current->Prev.getInt();
109 49312038 : switch (Tag) {
110 13055262 : case zeroDigitTag:
111 : case oneDigitTag:
112 13055262 : ++Current;
113 13055262 : Offset = (Offset << 1) + Tag;
114 : continue;
115 36256776 : default:
116 36256776 : return Current + Offset;
117 : }
118 13055262 : }
119 : }
120 :
121 : case fullStopTag:
122 : return Current;
123 : }
124 : }
125 : }
126 :
127 : } // End llvm namespace
|