//===-- 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.
//
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
+#include "llvm/GlobalValue.h"
#include "Support/LeakDetector.h"
#include <algorithm>
+#include <iostream>
+using namespace llvm;
//===----------------------------------------------------------------------===//
// Value Class
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<Constant>(this) && !isa<BasicBlock>(this))
+ assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
+ isa<OpaqueType>(ty)) &&
+ "Cannot create non-first-class values except for constants!");
+ if (ty == Type::VoidTy)
+ assert(name.empty() && "Cannot have named void values!");
}
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";
}
}
-
-
-void Value::replaceAllUsesWith(Value *New) {
- assert(New && "Value::replaceAllUsesWith(<null>) 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<Constant>(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
//
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<Constant>(Use)) {
- C->replaceUsesOfWithOnConstant(this, New, true);
+ if (Constant *C = dyn_cast<Constant>(U.getUser())) {
+ if (!isa<GlobalValue>(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(<null>) 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<Constant>(this) &&
+ assert(!isa<Constant>(this) || isa<GlobalValue>(this) &&
"Cannot call User::replaceUsesofWith on a constant!");
for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
setOperand(i, To); // Fix it now...
}
}
+