blob: b6720e5676496789b8eed104663387965daf4d3f [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) {
Gabor Greif715b9d22008-09-19 15:13:20 +000017 Value *V1(Val);
18 Value *V2(RHS.Val);
Gabor Greif5ef74042008-05-13 22:51:52 +000019 if (V1 != V2) {
20 if (V1) {
21 removeFromList();
22 }
23
24 if (V2) {
25 RHS.removeFromList();
Gabor Greif715b9d22008-09-19 15:13:20 +000026 Val = V2;
Gabor Greif5ef74042008-05-13 22:51:52 +000027 V2->addUse(*this);
28 } else {
Gabor Greif715b9d22008-09-19 15:13:20 +000029 Val = 0;
Gabor Greif5ef74042008-05-13 22:51:52 +000030 }
31
32 if (V1) {
Gabor Greif715b9d22008-09-19 15:13:20 +000033 RHS.Val = V1;
Gabor Greif5ef74042008-05-13 22:51:52 +000034 V1->addUse(RHS);
35 } else {
Gabor Greif715b9d22008-09-19 15:13:20 +000036 RHS.Val = 0;
Gabor Greif5ef74042008-05-13 22:51:52 +000037 }
38 }
39}
40
Chandler Carruth06d49182014-03-04 08:51:00 +000041User *Use::getUser() const {
42 const Use *End = getImpliedUser();
Chandler Carruth618bd1b2014-03-04 08:53:41 +000043 const UserRef *ref = reinterpret_cast<const UserRef *>(End);
44 return ref->getInt() ? ref->getPointer()
45 : reinterpret_cast<User *>(const_cast<Use *>(End));
Gabor Greiff6caff662008-05-10 08:32:32 +000046}
47
Chandler Carruth06d49182014-03-04 08:51:00 +000048// Sets up the waymarking algoritm's tags for a series of Uses. See the
49// algorithm details here:
50//
51// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
52//
Chandler Carruth618bd1b2014-03-04 08:53:41 +000053Use *Use::initTags(Use *const Start, Use *Stop) {
Jay Foadbbb91f22011-01-16 15:30:52 +000054 ptrdiff_t Done = 0;
Gabor Greif39c06b32010-07-19 14:48:15 +000055 while (Done < 20) {
Gabor Greiffee4daf2010-07-16 20:35:19 +000056 if (Start == Stop--)
57 return Start;
Chandler Carruth618bd1b2014-03-04 08:53:41 +000058 static const PrevPtrTag tags[20] = {
59 fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag,
60 stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag,
61 zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag,
62 oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag};
63 new (Stop) Use(tags[Done++]);
Gabor Greiffee4daf2010-07-16 20:35:19 +000064 }
65
Gabor Greiff6caff662008-05-10 08:32:32 +000066 ptrdiff_t Count = Done;
67 while (Start != Stop) {
68 --Stop;
Gabor Greiff6caff662008-05-10 08:32:32 +000069 if (!Count) {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000070 new (Stop) Use(stopTag);
Gabor Greiff6caff662008-05-10 08:32:32 +000071 ++Done;
72 Count = Done;
73 } else {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000074 new (Stop) Use(PrevPtrTag(Count & 1));
Gabor Greiff6caff662008-05-10 08:32:32 +000075 Count >>= 1;
76 ++Done;
77 }
78 }
79
80 return Start;
81}
82
Gabor Greiff6caff662008-05-10 08:32:32 +000083void Use::zap(Use *Start, const Use *Stop, bool del) {
Jay Foadbbb91f22011-01-16 15:30:52 +000084 while (Start != Stop)
85 (--Stop)->~Use();
86 if (del)
Gabor Greiff6caff662008-05-10 08:32:32 +000087 ::operator delete(Start);
Gabor Greiff6caff662008-05-10 08:32:32 +000088}
89
Chandler Carruth06d49182014-03-04 08:51:00 +000090const Use *Use::getImpliedUser() const {
91 const Use *Current = this;
Gabor Greiff6caff662008-05-10 08:32:32 +000092
Chandler Carruth06d49182014-03-04 08:51:00 +000093 while (true) {
94 unsigned Tag = (Current++)->Prev.getInt();
95 switch (Tag) {
Chandler Carruth618bd1b2014-03-04 08:53:41 +000096 case zeroDigitTag:
97 case oneDigitTag:
98 continue;
Chandler Carruth06d49182014-03-04 08:51:00 +000099
Chandler Carruth618bd1b2014-03-04 08:53:41 +0000100 case stopTag: {
101 ++Current;
102 ptrdiff_t Offset = 1;
103 while (true) {
104 unsigned Tag = Current->Prev.getInt();
105 switch (Tag) {
106 case zeroDigitTag:
107 case oneDigitTag:
108 ++Current;
109 Offset = (Offset << 1) + Tag;
110 continue;
111 default:
112 return Current + Offset;
Chandler Carruth06d49182014-03-04 08:51:00 +0000113 }
114 }
Chandler Carruth618bd1b2014-03-04 08:53:41 +0000115 }
Chandler Carruth06d49182014-03-04 08:51:00 +0000116
Chandler Carruth618bd1b2014-03-04 08:53:41 +0000117 case fullStopTag:
118 return Current;
Chandler Carruth06d49182014-03-04 08:51:00 +0000119 }
120 }
Gabor Greiff6caff662008-05-10 08:32:32 +0000121}
122
Gabor Greiff6caff662008-05-10 08:32:32 +0000123} // End llvm namespace