1139f7f9bSDimitry Andric //===-- Use.cpp - Implement the Use class ---------------------------------===//
2139f7f9bSDimitry Andric //
3139f7f9bSDimitry Andric // The LLVM Compiler Infrastructure
4139f7f9bSDimitry Andric //
5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details.
7139f7f9bSDimitry Andric //
8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
9139f7f9bSDimitry Andric
1091bc56edSDimitry Andric #include "llvm/IR/Use.h"
1191bc56edSDimitry Andric #include "llvm/IR/User.h"
12139f7f9bSDimitry Andric #include "llvm/IR/Value.h"
13139f7f9bSDimitry Andric #include <new>
14139f7f9bSDimitry Andric
15139f7f9bSDimitry Andric namespace llvm {
16139f7f9bSDimitry Andric
swap(Use & RHS)17139f7f9bSDimitry Andric void Use::swap(Use &RHS) {
1891bc56edSDimitry Andric if (Val == RHS.Val)
1991bc56edSDimitry Andric return;
2091bc56edSDimitry Andric
2191bc56edSDimitry Andric if (Val)
22139f7f9bSDimitry Andric removeFromList();
23139f7f9bSDimitry Andric
2491bc56edSDimitry Andric Value *OldVal = Val;
2591bc56edSDimitry Andric if (RHS.Val) {
26139f7f9bSDimitry Andric RHS.removeFromList();
2791bc56edSDimitry Andric Val = RHS.Val;
2891bc56edSDimitry Andric Val->addUse(*this);
29139f7f9bSDimitry Andric } else {
3091bc56edSDimitry Andric Val = nullptr;
31139f7f9bSDimitry Andric }
32139f7f9bSDimitry Andric
3391bc56edSDimitry Andric if (OldVal) {
3491bc56edSDimitry Andric RHS.Val = OldVal;
3591bc56edSDimitry Andric RHS.Val->addUse(RHS);
36139f7f9bSDimitry Andric } else {
3791bc56edSDimitry Andric RHS.Val = nullptr;
38139f7f9bSDimitry Andric }
39139f7f9bSDimitry Andric }
40139f7f9bSDimitry Andric
getUser() const4191bc56edSDimitry Andric User *Use::getUser() const {
4291bc56edSDimitry Andric const Use *End = getImpliedUser();
4391bc56edSDimitry Andric const UserRef *ref = reinterpret_cast<const UserRef *>(End);
4491bc56edSDimitry Andric return ref->getInt() ? ref->getPointer()
4591bc56edSDimitry Andric : reinterpret_cast<User *>(const_cast<Use *>(End));
4691bc56edSDimitry Andric }
4791bc56edSDimitry Andric
getOperandNo() const4891bc56edSDimitry Andric unsigned Use::getOperandNo() const {
4991bc56edSDimitry Andric return this - getUser()->op_begin();
5091bc56edSDimitry Andric }
5191bc56edSDimitry Andric
5291bc56edSDimitry Andric // Sets up the waymarking algorithm's tags for a series of Uses. See the
5391bc56edSDimitry Andric // algorithm details here:
5491bc56edSDimitry Andric //
55*39d628a0SDimitry Andric // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
5691bc56edSDimitry Andric //
initTags(Use * const Start,Use * Stop)5791bc56edSDimitry Andric Use *Use::initTags(Use *const Start, Use *Stop) {
5891bc56edSDimitry Andric ptrdiff_t Done = 0;
5991bc56edSDimitry Andric while (Done < 20) {
6091bc56edSDimitry Andric if (Start == Stop--)
6191bc56edSDimitry Andric return Start;
6291bc56edSDimitry Andric static const PrevPtrTag tags[20] = {
6391bc56edSDimitry Andric fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag,
6491bc56edSDimitry Andric stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag,
6591bc56edSDimitry Andric zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag,
6691bc56edSDimitry Andric oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag};
6791bc56edSDimitry Andric new (Stop) Use(tags[Done++]);
6891bc56edSDimitry Andric }
6991bc56edSDimitry Andric
7091bc56edSDimitry Andric ptrdiff_t Count = Done;
7191bc56edSDimitry Andric while (Start != Stop) {
7291bc56edSDimitry Andric --Stop;
7391bc56edSDimitry Andric if (!Count) {
7491bc56edSDimitry Andric new (Stop) Use(stopTag);
7591bc56edSDimitry Andric ++Done;
7691bc56edSDimitry Andric Count = Done;
7791bc56edSDimitry Andric } else {
7891bc56edSDimitry Andric new (Stop) Use(PrevPtrTag(Count & 1));
7991bc56edSDimitry Andric Count >>= 1;
8091bc56edSDimitry Andric ++Done;
8191bc56edSDimitry Andric }
8291bc56edSDimitry Andric }
8391bc56edSDimitry Andric
8491bc56edSDimitry Andric return Start;
8591bc56edSDimitry Andric }
8691bc56edSDimitry Andric
zap(Use * Start,const Use * Stop,bool del)8791bc56edSDimitry Andric void Use::zap(Use *Start, const Use *Stop, bool del) {
8891bc56edSDimitry Andric while (Start != Stop)
8991bc56edSDimitry Andric (--Stop)->~Use();
9091bc56edSDimitry Andric if (del)
9191bc56edSDimitry Andric ::operator delete(Start);
9291bc56edSDimitry Andric }
93139f7f9bSDimitry Andric
getImpliedUser() const94139f7f9bSDimitry Andric const Use *Use::getImpliedUser() const {
95139f7f9bSDimitry Andric const Use *Current = this;
96139f7f9bSDimitry Andric
97139f7f9bSDimitry Andric while (true) {
98139f7f9bSDimitry Andric unsigned Tag = (Current++)->Prev.getInt();
99139f7f9bSDimitry Andric switch (Tag) {
100139f7f9bSDimitry Andric case zeroDigitTag:
101139f7f9bSDimitry Andric case oneDigitTag:
102139f7f9bSDimitry Andric continue;
103139f7f9bSDimitry Andric
104139f7f9bSDimitry Andric case stopTag: {
105139f7f9bSDimitry Andric ++Current;
106139f7f9bSDimitry Andric ptrdiff_t Offset = 1;
107139f7f9bSDimitry Andric while (true) {
108139f7f9bSDimitry Andric unsigned Tag = Current->Prev.getInt();
109139f7f9bSDimitry Andric switch (Tag) {
110139f7f9bSDimitry Andric case zeroDigitTag:
111139f7f9bSDimitry Andric case oneDigitTag:
112139f7f9bSDimitry Andric ++Current;
113139f7f9bSDimitry Andric Offset = (Offset << 1) + Tag;
114139f7f9bSDimitry Andric continue;
115139f7f9bSDimitry Andric default:
116139f7f9bSDimitry Andric return Current + Offset;
117139f7f9bSDimitry Andric }
118139f7f9bSDimitry Andric }
119139f7f9bSDimitry Andric }
120139f7f9bSDimitry Andric
121139f7f9bSDimitry Andric case fullStopTag:
122139f7f9bSDimitry Andric return Current;
123139f7f9bSDimitry Andric }
124139f7f9bSDimitry Andric }
125139f7f9bSDimitry Andric }
126139f7f9bSDimitry Andric
127139f7f9bSDimitry Andric } // End llvm namespace
128