1249259Sdim//===-- Use.cpp - Implement the Use class ---------------------------------===// 2249259Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6249259Sdim// 7249259Sdim//===----------------------------------------------------------------------===// 8249259Sdim 9276479Sdim#include "llvm/IR/Use.h" 10276479Sdim#include "llvm/IR/User.h" 11249259Sdim#include "llvm/IR/Value.h" 12249259Sdim#include <new> 13249259Sdim 14249259Sdimnamespace llvm { 15249259Sdim 16249259Sdimvoid Use::swap(Use &RHS) { 17276479Sdim if (Val == RHS.Val) 18276479Sdim return; 19249259Sdim 20276479Sdim if (Val) 21276479Sdim removeFromList(); 22249259Sdim 23276479Sdim Value *OldVal = Val; 24276479Sdim if (RHS.Val) { 25276479Sdim RHS.removeFromList(); 26276479Sdim Val = RHS.Val; 27276479Sdim Val->addUse(*this); 28276479Sdim } else { 29276479Sdim Val = nullptr; 30249259Sdim } 31276479Sdim 32276479Sdim if (OldVal) { 33276479Sdim RHS.Val = OldVal; 34276479Sdim RHS.Val->addUse(RHS); 35276479Sdim } else { 36276479Sdim RHS.Val = nullptr; 37276479Sdim } 38249259Sdim} 39249259Sdim 40276479SdimUser *Use::getUser() const { 41276479Sdim const Use *End = getImpliedUser(); 42276479Sdim const UserRef *ref = reinterpret_cast<const UserRef *>(End); 43276479Sdim return ref->getInt() ? ref->getPointer() 44276479Sdim : reinterpret_cast<User *>(const_cast<Use *>(End)); 45276479Sdim} 46249259Sdim 47276479Sdimunsigned Use::getOperandNo() const { 48276479Sdim return this - getUser()->op_begin(); 49249259Sdim} 50249259Sdim 51276479Sdim// Sets up the waymarking algorithm's tags for a series of Uses. See the 52276479Sdim// algorithm details here: 53276479Sdim// 54280031Sdim// http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm 55276479Sdim// 56276479SdimUse *Use::initTags(Use *const Start, Use *Stop) { 57249259Sdim ptrdiff_t Done = 0; 58249259Sdim while (Done < 20) { 59249259Sdim if (Start == Stop--) 60249259Sdim return Start; 61276479Sdim static const PrevPtrTag tags[20] = { 62276479Sdim fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag, 63276479Sdim stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag, 64276479Sdim zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag, 65276479Sdim oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag}; 66276479Sdim new (Stop) Use(tags[Done++]); 67249259Sdim } 68249259Sdim 69249259Sdim ptrdiff_t Count = Done; 70249259Sdim while (Start != Stop) { 71249259Sdim --Stop; 72249259Sdim if (!Count) { 73276479Sdim new (Stop) Use(stopTag); 74249259Sdim ++Done; 75249259Sdim Count = Done; 76249259Sdim } else { 77276479Sdim new (Stop) Use(PrevPtrTag(Count & 1)); 78249259Sdim Count >>= 1; 79249259Sdim ++Done; 80249259Sdim } 81249259Sdim } 82249259Sdim 83249259Sdim return Start; 84249259Sdim} 85249259Sdim 86249259Sdimvoid Use::zap(Use *Start, const Use *Stop, bool del) { 87249259Sdim while (Start != Stop) 88249259Sdim (--Stop)->~Use(); 89249259Sdim if (del) 90249259Sdim ::operator delete(Start); 91249259Sdim} 92249259Sdim 93276479Sdimconst Use *Use::getImpliedUser() const { 94276479Sdim const Use *Current = this; 95249259Sdim 96276479Sdim while (true) { 97276479Sdim unsigned Tag = (Current++)->Prev.getInt(); 98276479Sdim switch (Tag) { 99276479Sdim case zeroDigitTag: 100276479Sdim case oneDigitTag: 101276479Sdim continue; 102276479Sdim 103276479Sdim case stopTag: { 104276479Sdim ++Current; 105276479Sdim ptrdiff_t Offset = 1; 106276479Sdim while (true) { 107276479Sdim unsigned Tag = Current->Prev.getInt(); 108276479Sdim switch (Tag) { 109276479Sdim case zeroDigitTag: 110276479Sdim case oneDigitTag: 111276479Sdim ++Current; 112276479Sdim Offset = (Offset << 1) + Tag; 113276479Sdim continue; 114276479Sdim default: 115276479Sdim return Current + Offset; 116276479Sdim } 117276479Sdim } 118276479Sdim } 119276479Sdim 120276479Sdim case fullStopTag: 121276479Sdim return Current; 122276479Sdim } 123276479Sdim } 124249259Sdim} 125249259Sdim 126249259Sdim} // End llvm namespace 127