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 10*91bc56edSDimitry Andric #include "llvm/IR/Use.h" 11*91bc56edSDimitry 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 17139f7f9bSDimitry Andric void Use::swap(Use &RHS) { 18*91bc56edSDimitry Andric if (Val == RHS.Val) 19*91bc56edSDimitry Andric return; 20*91bc56edSDimitry Andric 21*91bc56edSDimitry Andric if (Val) 22139f7f9bSDimitry Andric removeFromList(); 23139f7f9bSDimitry Andric 24*91bc56edSDimitry Andric Value *OldVal = Val; 25*91bc56edSDimitry Andric if (RHS.Val) { 26139f7f9bSDimitry Andric RHS.removeFromList(); 27*91bc56edSDimitry Andric Val = RHS.Val; 28*91bc56edSDimitry Andric Val->addUse(*this); 29139f7f9bSDimitry Andric } else { 30*91bc56edSDimitry Andric Val = nullptr; 31139f7f9bSDimitry Andric } 32139f7f9bSDimitry Andric 33*91bc56edSDimitry Andric if (OldVal) { 34*91bc56edSDimitry Andric RHS.Val = OldVal; 35*91bc56edSDimitry Andric RHS.Val->addUse(RHS); 36139f7f9bSDimitry Andric } else { 37*91bc56edSDimitry Andric RHS.Val = nullptr; 38139f7f9bSDimitry Andric } 39139f7f9bSDimitry Andric } 40139f7f9bSDimitry Andric 41*91bc56edSDimitry Andric User *Use::getUser() const { 42*91bc56edSDimitry Andric const Use *End = getImpliedUser(); 43*91bc56edSDimitry Andric const UserRef *ref = reinterpret_cast<const UserRef *>(End); 44*91bc56edSDimitry Andric return ref->getInt() ? ref->getPointer() 45*91bc56edSDimitry Andric : reinterpret_cast<User *>(const_cast<Use *>(End)); 46*91bc56edSDimitry Andric } 47*91bc56edSDimitry Andric 48*91bc56edSDimitry Andric unsigned Use::getOperandNo() const { 49*91bc56edSDimitry Andric return this - getUser()->op_begin(); 50*91bc56edSDimitry Andric } 51*91bc56edSDimitry Andric 52*91bc56edSDimitry Andric // Sets up the waymarking algorithm's tags for a series of Uses. See the 53*91bc56edSDimitry Andric // algorithm details here: 54*91bc56edSDimitry Andric // 55*91bc56edSDimitry Andric // http://www.llvm.org/docs/ProgrammersManual.html#UserLayout 56*91bc56edSDimitry Andric // 57*91bc56edSDimitry Andric Use *Use::initTags(Use *const Start, Use *Stop) { 58*91bc56edSDimitry Andric ptrdiff_t Done = 0; 59*91bc56edSDimitry Andric while (Done < 20) { 60*91bc56edSDimitry Andric if (Start == Stop--) 61*91bc56edSDimitry Andric return Start; 62*91bc56edSDimitry Andric static const PrevPtrTag tags[20] = { 63*91bc56edSDimitry Andric fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag, 64*91bc56edSDimitry Andric stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag, 65*91bc56edSDimitry Andric zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag, 66*91bc56edSDimitry Andric oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag}; 67*91bc56edSDimitry Andric new (Stop) Use(tags[Done++]); 68*91bc56edSDimitry Andric } 69*91bc56edSDimitry Andric 70*91bc56edSDimitry Andric ptrdiff_t Count = Done; 71*91bc56edSDimitry Andric while (Start != Stop) { 72*91bc56edSDimitry Andric --Stop; 73*91bc56edSDimitry Andric if (!Count) { 74*91bc56edSDimitry Andric new (Stop) Use(stopTag); 75*91bc56edSDimitry Andric ++Done; 76*91bc56edSDimitry Andric Count = Done; 77*91bc56edSDimitry Andric } else { 78*91bc56edSDimitry Andric new (Stop) Use(PrevPtrTag(Count & 1)); 79*91bc56edSDimitry Andric Count >>= 1; 80*91bc56edSDimitry Andric ++Done; 81*91bc56edSDimitry Andric } 82*91bc56edSDimitry Andric } 83*91bc56edSDimitry Andric 84*91bc56edSDimitry Andric return Start; 85*91bc56edSDimitry Andric } 86*91bc56edSDimitry Andric 87*91bc56edSDimitry Andric void Use::zap(Use *Start, const Use *Stop, bool del) { 88*91bc56edSDimitry Andric while (Start != Stop) 89*91bc56edSDimitry Andric (--Stop)->~Use(); 90*91bc56edSDimitry Andric if (del) 91*91bc56edSDimitry Andric ::operator delete(Start); 92*91bc56edSDimitry Andric } 93139f7f9bSDimitry Andric 94139f7f9bSDimitry 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