X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FValue.cpp;h=e41c7fd1366f5b0ffccefe12664681f4cf5fa60d;hb=068758e518f0fe4ab67490f2eec0fd3b376a4d2c;hp=95670f398262776d75501397a60bfac4a3b901de;hpb=4e84e7720c333112da24bd4e9d4c7bfb4d446016;p=oota-llvm.git diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 95670f39826..e41c7fd1366 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -1,4 +1,11 @@ //===-- Value.cpp - Implement the Value class -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file implements the Value and User classes. // @@ -8,8 +15,11 @@ #include "llvm/SymbolTable.h" #include "llvm/DerivedTypes.h" #include "llvm/Constant.h" +#include "llvm/GlobalValue.h" #include "Support/LeakDetector.h" #include +#include +using namespace llvm; //===----------------------------------------------------------------------===// // Value Class @@ -20,9 +30,14 @@ static inline const Type *checkType(const Type *Ty) { return Ty; } -Value::Value(const Type *ty, ValueTy vty, const std::string &name) - : Name(name), Ty(checkType(ty)) { - VTy = vty; +Value::Value(const Type *ty, unsigned scid, const std::string &name) + : SubclassID(scid), Ty(checkType(ty)), Name(name) { + if (!isa(this) && !isa(this)) + assert((Ty->isFirstClassType() || Ty == Type::VoidTy || + isa(ty)) && + "Cannot create non-first-class values except for constants!"); + if (ty == Type::VoidTy) + assert(name.empty() && "Cannot have named void values!"); } Value::~Value() { @@ -35,7 +50,7 @@ Value::~Value() { // if (Uses.begin() != Uses.end()) { std::cerr << "While deleting: " << *Ty << "%" << Name << "\n"; - for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I) + for (use_const_iterator I = Uses.begin(), E = Uses.end(); I != E; ++I) std::cerr << "Use still stuck around after Def is destroyed:" << **I << "\n"; } @@ -47,25 +62,6 @@ Value::~Value() { } - - -void Value::replaceAllUsesWith(Value *New) { - assert(New && "Value::replaceAllUsesWith() is invalid!"); - assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); - assert(New->getType() == getType() && - "replaceAllUses of value with new value of different type!"); - while (!Uses.empty()) { - User *Use = Uses.back(); - // Must handle Constants specially, we cannot call replaceUsesOfWith on a - // constant! - if (Constant *C = dyn_cast(Use)) { - C->replaceUsesOfWithOnConstant(this, New); - } else { - Use->replaceUsesOfWith(this, New); - } - } -} - // uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith, // except that it doesn't have all of the asserts. The asserts fail because we // are half-way done resolving types, which causes some types to exist as two @@ -74,48 +70,40 @@ void Value::replaceAllUsesWith(Value *New) { // void Value::uncheckedReplaceAllUsesWith(Value *New) { while (!Uses.empty()) { - User *Use = Uses.back(); + Use &U = Uses.back(); // Must handle Constants specially, we cannot call replaceUsesOfWith on a // constant! - if (Constant *C = dyn_cast(Use)) { - C->replaceUsesOfWithOnConstant(this, New, true); + if (Constant *C = dyn_cast(U.getUser())) { + if (!isa(C)) + C->replaceUsesOfWithOnConstant(this, New, true); + else + U.set(New); } else { - Use->replaceUsesOfWith(this, New); + U.set(New); } } } +void Value::replaceAllUsesWith(Value *New) { + assert(New && "Value::replaceAllUsesWith() is invalid!"); + assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); + assert(New->getType() == getType() && + "replaceAllUses of value with new value of different type!"); -void Value::killUse(User *U) { - assert(U != 0 && "Null users are not allowed!"); - unsigned i; - - // Scan backwards through the uses list looking for the user. We do this - // because vectors like to be accessed on the end. This is incredibly - // important from a performance perspective. - for (i = Uses.size()-1; Uses[i] != U; --i) - /* empty */; - - assert(i < Uses.size() && "Use not in uses list!!"); - Uses[i] = Uses.back(); - Uses.pop_back(); + uncheckedReplaceAllUsesWith(New); } //===----------------------------------------------------------------------===// // User Class //===----------------------------------------------------------------------===// -User::User(const Type *Ty, ValueTy vty, const std::string &name) - : Value(Ty, vty, name) { -} - // replaceUsesOfWith - Replaces all references to the "From" definition with // references to the "To" definition. // void User::replaceUsesOfWith(Value *From, Value *To) { if (From == To) return; // Duh what? - assert(!isa(this) && + assert(!isa(this) || isa(this) && "Cannot call User::replaceUsesofWith on a constant!"); for (unsigned i = 0, E = getNumOperands(); i != E; ++i) @@ -126,3 +114,4 @@ void User::replaceUsesOfWith(Value *From, Value *To) { setOperand(i, To); // Fix it now... } } +