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