blob: 5f01e238e04f711e74ac6db6cf9a275dbed5ef21 [file] [log] [blame]
Gabor Greif697e94c2008-05-15 10:04:30 +00001//===-- Use.cpp - Implement the Use class ---------------------------------===//
Gabor Greiff6caff662008-05-10 08:32:32 +00002//
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//===----------------------------------------------------------------------===//
Gabor Greiff6caff662008-05-10 08:32:32 +00009
Chandler Carruth06d49182014-03-04 08:51:00 +000010#include "llvm/IR/Use.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000011#include "llvm/IR/Value.h"
Douglas Gregorc0f63802012-03-26 14:04:17 +000012#include <new>
Gabor Greiff6caff662008-05-10 08:32:32 +000013
14namespace llvm {
15
Gabor Greif5ef74042008-05-13 22:51:52 +000016void Use::swap(Use &RHS) {
Chandler Carruth4ffd9d22014-03-04 09:00:15 +000017 if (Val == RHS.Val)
18 return;
Gabor Greif5ef74042008-05-13 22:51:52 +000019
Chandler Carruth4ffd9d22014-03-04 09:00:15 +000020 if (Val)
21 removeFromList();
Gabor Greif5ef74042008-05-13 22:51:52 +000022
Chandler Carruth4ffd9d22014-03-04 09:00:15 +000023 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;
Gabor Greif5ef74042008-05-13 22:51:52 +000037 }
38}
39
Chandler Carruth06d49182014-03-04 08:51:00 +000040User *Use::getUser() const {
41 const Use *End = getImpliedUser();
Chandler Carruth618bd1b2014-03-04 08:53:41 +000042 const UserRef *ref = reinterpret_cast<const UserRef *>(End);
43 return ref->getInt() ? ref->getPointer()
44 : reinterpret_cast<User *>(const_cast<Use *>(End));
Gabor Greiff6caff662008-05-10 08:32:32 +000045}
46
Chandler Carruth06d49182014-03-04 08:51:00 +000047// 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//
Chandler Carruth618bd1b2014-03-04 08:53:41 +000052Use *Use::initTags(Use *const Start, Use *Stop) {
Jay Foadbbb91f22011-01-16 15:30:52 +000053 ptrdiff_t Done = 0;
Gabor Greif39c06b32010-07-19 14:48:15 +000054 while (Done < 20) {
Gabor Greiffee4daf2010-07-16 20:35:19 +000055 if (Start == Stop--)
56 return Start;
Chandler Carruth618bd1b2014-03-04 08:53:41 +000057 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++]);
Gabor Greiffee4daf2010-07-16 20:35:19 +000063 }
64
Gabor Greiff6caff662008-05-10 08:32:32 +000065 ptrdiff_t Count = Done;
66 while (Start != Stop) {
67 --Stop;
Gabor Greiff6caff662008-05-10 08:32:32 +000068 if (!Count) {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000069 new (Stop) Use(stopTag);
Gabor Greiff6caff662008-05-10 08:32:32 +000070 ++Done;
71 Count = Done;
72 } else {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000073 new (Stop) Use(PrevPtrTag(Count & 1));
Gabor Greiff6caff662008-05-10 08:32:32 +000074 Count >>= 1;
75 ++Done;
76 }
77 }
78
79 return Start;
80}
81
Gabor Greiff6caff662008-05-10 08:32:32 +000082void Use::zap(Use *Start, const Use *Stop, bool del) {
Jay Foadbbb91f22011-01-16 15:30:52 +000083 while (Start != Stop)
84 (--Stop)->~Use();
85 if (del)
Gabor Greiff6caff662008-05-10 08:32:32 +000086 ::operator delete(Start);
Gabor Greiff6caff662008-05-10 08:32:32 +000087}
88
Chandler Carruth06d49182014-03-04 08:51:00 +000089const Use *Use::getImpliedUser() const {
90 const Use *Current = this;
Gabor Greiff6caff662008-05-10 08:32:32 +000091
Chandler Carruth06d49182014-03-04 08:51:00 +000092 while (true) {
93 unsigned Tag = (Current++)->Prev.getInt();
94 switch (Tag) {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000095 case zeroDigitTag:
96 case oneDigitTag:
97 continue;
Chandler Carruth06d49182014-03-04 08:51:00 +000098
Chandler Carruth618bd1b2014-03-04 08:53:41 +000099 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;
Chandler Carruth06d49182014-03-04 08:51:00 +0000112 }
113 }
Chandler Carruth618bd1b2014-03-04 08:53:41 +0000114 }
Chandler Carruth06d49182014-03-04 08:51:00 +0000115
Chandler Carruth618bd1b2014-03-04 08:53:41 +0000116 case fullStopTag:
117 return Current;
Chandler Carruth06d49182014-03-04 08:51:00 +0000118 }
119 }
Gabor Greiff6caff662008-05-10 08:32:32 +0000120}
121
Gabor Greiff6caff662008-05-10 08:32:32 +0000122} // End llvm namespace