IR: MDNode => Value: Add Instruction::getMDNode()
[oota-llvm.git] / lib / IR / Use.cpp
index 0128adc3f776297addf313090a310c72b9ab94bb..cae845d99fe58fe3a943b4d38566f3339c7af805 100644 (file)
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This file implements the algorithm for finding the User of a Use.
-//
-//===----------------------------------------------------------------------===//
 
-#include "llvm/Value.h"
+#include "llvm/IR/Use.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
 #include <new>
 
 namespace llvm {
 
-//===----------------------------------------------------------------------===//
-//                         Use swap Implementation
-//===----------------------------------------------------------------------===//
-
 void Use::swap(Use &RHS) {
-  Value *V1(Val);
-  Value *V2(RHS.Val);
-  if (V1 != V2) {
-    if (V1) {
-      removeFromList();
-    }
-
-    if (V2) {
-      RHS.removeFromList();
-      Val = V2;
-      V2->addUse(*this);
-    } else {
-      Val = 0;
-    }
+  if (Val == RHS.Val)
+    return;
+
+  if (Val)
+    removeFromList();
+
+  Value *OldVal = Val;
+  if (RHS.Val) {
+    RHS.removeFromList();
+    Val = RHS.Val;
+    Val->addUse(*this);
+  } else {
+    Val = nullptr;
+  }
 
-    if (V1) {
-      RHS.Val = V1;
-      V1->addUse(RHS);
-    } else {
-      RHS.Val = 0;
-    }
+  if (OldVal) {
+    RHS.Val = OldVal;
+    RHS.Val->addUse(RHS);
+  } else {
+    RHS.Val = nullptr;
   }
 }
 
-//===----------------------------------------------------------------------===//
-//                         Use getImpliedUser Implementation
-//===----------------------------------------------------------------------===//
-
-const Use *Use::getImpliedUser() const {
-  const Use *Current = this;
-
-  while (true) {
-    unsigned Tag = (Current++)->Prev.getInt();
-    switch (Tag) {
-      case zeroDigitTag:
-      case oneDigitTag:
-        continue;
-
-      case stopTag: {
-        ++Current;
-        ptrdiff_t Offset = 1;
-        while (true) {
-          unsigned Tag = Current->Prev.getInt();
-          switch (Tag) {
-            case zeroDigitTag:
-            case oneDigitTag:
-              ++Current;
-              Offset = (Offset << 1) + Tag;
-              continue;
-            default:
-              return Current + Offset;
-          }
-        }
-      }
-
-      case fullStopTag:
-        return Current;
-    }
-  }
+User *Use::getUser() const {
+  const Use *End = getImpliedUser();
+  const UserRef *ref = reinterpret_cast<const UserRef *>(End);
+  return ref->getInt() ? ref->getPointer()
+                       : reinterpret_cast<User *>(const_cast<Use *>(End));
 }
 
-//===----------------------------------------------------------------------===//
-//                         Use initTags Implementation
-//===----------------------------------------------------------------------===//
+unsigned Use::getOperandNo() const {
+  return this - getUser()->op_begin();
+}
 
-Use *Use::initTags(Use * const Start, Use *Stop) {
+// Sets up the waymarking algorithm's tags for a series of Uses. See the
+// algorithm details here:
+//
+//   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
+//
+Use *Use::initTags(Use *const Start, Use *Stop) {
   ptrdiff_t Done = 0;
   while (Done < 20) {
     if (Start == Stop--)
       return Start;
-    static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag,
-                                         oneDigitTag, oneDigitTag, stopTag,
-                                         zeroDigitTag, oneDigitTag, oneDigitTag,
-                                         stopTag, zeroDigitTag, oneDigitTag,
-                                         zeroDigitTag, oneDigitTag, stopTag,
-                                         oneDigitTag, oneDigitTag, oneDigitTag,
-                                         oneDigitTag, stopTag
-                                       };
-    new(Stop) Use(tags[Done++]);
+    static const PrevPtrTag tags[20] = {
+        fullStopTag,  oneDigitTag,  stopTag,      oneDigitTag, oneDigitTag,
+        stopTag,      zeroDigitTag, oneDigitTag,  oneDigitTag, stopTag,
+        zeroDigitTag, oneDigitTag,  zeroDigitTag, oneDigitTag, stopTag,
+        oneDigitTag,  oneDigitTag,  oneDigitTag,  oneDigitTag, stopTag};
+    new (Stop) Use(tags[Done++]);
   }
 
   ptrdiff_t Count = Done;
   while (Start != Stop) {
     --Stop;
     if (!Count) {
-      new(Stop) Use(stopTag);
+      new (Stop) Use(stopTag);
       ++Done;
       Count = Done;
     } else {
-      new(Stop) Use(PrevPtrTag(Count & 1));
+      new (Stop) Use(PrevPtrTag(Count & 1));
       Count >>= 1;
       ++Done;
     }
@@ -119,10 +84,6 @@ Use *Use::initTags(Use * const Start, Use *Stop) {
   return Start;
 }
 
-//===----------------------------------------------------------------------===//
-//                         Use zap Implementation
-//===----------------------------------------------------------------------===//
-
 void Use::zap(Use *Start, const Use *Stop, bool del) {
   while (Start != Stop)
     (--Stop)->~Use();
@@ -130,16 +91,37 @@ void Use::zap(Use *Start, const Use *Stop, bool del) {
     ::operator delete(Start);
 }
 
-//===----------------------------------------------------------------------===//
-//                         Use getUser Implementation
-//===----------------------------------------------------------------------===//
+const Use *Use::getImpliedUser() const {
+  const Use *Current = this;
 
-User *Use::getUser() const {
-  const Use *End = getImpliedUser();
-  const UserRef *ref = reinterpret_cast<const UserRef*>(End);
-  return ref->getInt()
-    ? ref->getPointer()
-    : (User*)End;
+  while (true) {
+    unsigned Tag = (Current++)->Prev.getInt();
+    switch (Tag) {
+    case zeroDigitTag:
+    case oneDigitTag:
+      continue;
+
+    case stopTag: {
+      ++Current;
+      ptrdiff_t Offset = 1;
+      while (true) {
+        unsigned Tag = Current->Prev.getInt();
+        switch (Tag) {
+        case zeroDigitTag:
+        case oneDigitTag:
+          ++Current;
+          Offset = (Offset << 1) + Tag;
+          continue;
+        default:
+          return Current + Offset;
+        }
+      }
+    }
+
+    case fullStopTag:
+      return Current;
+    }
+  }
 }
 
 } // End llvm namespace