1249259Sdim//===-- User.cpp - Implement the User class -------------------------------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim
10249259Sdim#include "llvm/IR/User.h"
11249259Sdim#include "llvm/IR/Constant.h"
12249259Sdim#include "llvm/IR/GlobalValue.h"
13249259Sdim#include "llvm/IR/Operator.h"
14249259Sdim
15249259Sdimnamespace llvm {
16249259Sdim
17249259Sdim//===----------------------------------------------------------------------===//
18249259Sdim//                                 User Class
19249259Sdim//===----------------------------------------------------------------------===//
20249259Sdim
21249259Sdimvoid User::anchor() {}
22249259Sdim
23249259Sdim// replaceUsesOfWith - Replaces all references to the "From" definition with
24249259Sdim// references to the "To" definition.
25249259Sdim//
26249259Sdimvoid User::replaceUsesOfWith(Value *From, Value *To) {
27249259Sdim  if (From == To) return;   // Duh what?
28249259Sdim
29249259Sdim  assert((!isa<Constant>(this) || isa<GlobalValue>(this)) &&
30249259Sdim         "Cannot call User::replaceUsesOfWith on a constant!");
31249259Sdim
32249259Sdim  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
33249259Sdim    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
34249259Sdim      // The side effects of this setOperand call include linking to
35249259Sdim      // "To", adding "this" to the uses list of To, and
36249259Sdim      // most importantly, removing "this" from the use list of "From".
37249259Sdim      setOperand(i, To); // Fix it now...
38249259Sdim    }
39249259Sdim}
40249259Sdim
41249259Sdim//===----------------------------------------------------------------------===//
42249259Sdim//                         User allocHungoffUses Implementation
43249259Sdim//===----------------------------------------------------------------------===//
44249259Sdim
45249259SdimUse *User::allocHungoffUses(unsigned N) const {
46249259Sdim  // Allocate the array of Uses, followed by a pointer (with bottom bit set) to
47249259Sdim  // the User.
48249259Sdim  size_t size = N * sizeof(Use) + sizeof(Use::UserRef);
49249259Sdim  Use *Begin = static_cast<Use*>(::operator new(size));
50249259Sdim  Use *End = Begin + N;
51249259Sdim  (void) new(End) Use::UserRef(const_cast<User*>(this), 1);
52249259Sdim  return Use::initTags(Begin, End);
53249259Sdim}
54249259Sdim
55249259Sdim//===----------------------------------------------------------------------===//
56249259Sdim//                         User operator new Implementations
57249259Sdim//===----------------------------------------------------------------------===//
58249259Sdim
59249259Sdimvoid *User::operator new(size_t s, unsigned Us) {
60249259Sdim  void *Storage = ::operator new(s + sizeof(Use) * Us);
61249259Sdim  Use *Start = static_cast<Use*>(Storage);
62249259Sdim  Use *End = Start + Us;
63249259Sdim  User *Obj = reinterpret_cast<User*>(End);
64249259Sdim  Obj->OperandList = Start;
65249259Sdim  Obj->NumOperands = Us;
66249259Sdim  Use::initTags(Start, End);
67249259Sdim  return Obj;
68249259Sdim}
69249259Sdim
70249259Sdim//===----------------------------------------------------------------------===//
71249259Sdim//                         User operator delete Implementation
72249259Sdim//===----------------------------------------------------------------------===//
73249259Sdim
74249259Sdimvoid User::operator delete(void *Usr) {
75249259Sdim  User *Start = static_cast<User*>(Usr);
76249259Sdim  Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands;
77249259Sdim  // If there were hung-off uses, they will have been freed already and
78249259Sdim  // NumOperands reset to 0, so here we just free the User itself.
79249259Sdim  ::operator delete(Storage);
80249259Sdim}
81249259Sdim
82249259Sdim//===----------------------------------------------------------------------===//
83249259Sdim//                             Operator Class
84249259Sdim//===----------------------------------------------------------------------===//
85249259Sdim
86249259SdimOperator::~Operator() {
87249259Sdim  llvm_unreachable("should never destroy an Operator");
88249259Sdim}
89249259Sdim
90249259Sdim} // End llvm namespace
91