hoist GlobalValue::removeDeadConstantUsers up to being a method on Constant.

llvm-svn: 125828
This commit is contained in:
Chris Lattner 2011-02-18 04:41:42 +00:00
parent 4a14fbc50c
commit 8488640da7
4 changed files with 62 additions and 58 deletions

View File

@ -141,16 +141,22 @@ public:
assert(0 && "Constants that do not have operands cannot be using 'From'!");
}
static Constant* getNullValue(const Type* Ty);
static Constant *getNullValue(const Type* Ty);
/// @returns the value for an integer constant of the given type that has all
/// its bits set to true.
/// @brief Get the all ones value
static Constant* getAllOnesValue(const Type* Ty);
static Constant *getAllOnesValue(const Type* Ty);
/// getIntegerValue - Return the value for an integer or pointer constant,
/// or a vector thereof, with the given scalar value.
static Constant* getIntegerValue(const Type* Ty, const APInt &V);
static Constant *getIntegerValue(const Type* Ty, const APInt &V);
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this constant, remove them. This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void removeDeadConstantUsers() const;
};
} // End llvm namespace

View File

@ -282,12 +282,6 @@ public:
inline Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; }
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this global value, remove them. This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void removeDeadConstantUsers() const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalValue *) { return true; }
static inline bool classof(const Value *V) {

View File

@ -262,6 +262,59 @@ void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
}
/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
/// it. This involves recursively eliminating any dead users of the
/// constantexpr.
static bool removeDeadUsersOfConstant(const Constant *C) {
if (isa<GlobalValue>(C)) return false; // Cannot remove this
while (!C->use_empty()) {
const Constant *User = dyn_cast<Constant>(C->use_back());
if (!User) return false; // Non-constant usage;
if (!removeDeadUsersOfConstant(User))
return false; // Constant wasn't dead
}
const_cast<Constant*>(C)->destroyConstant();
return true;
}
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this constant, remove them. This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void Constant::removeDeadConstantUsers() const {
Value::const_use_iterator I = use_begin(), E = use_end();
Value::const_use_iterator LastNonDeadUser = E;
while (I != E) {
const Constant *User = dyn_cast<Constant>(*I);
if (User == 0) {
LastNonDeadUser = I;
++I;
continue;
}
if (!removeDeadUsersOfConstant(User)) {
// If the constant wasn't dead, remember that this was the last live use
// and move on to the next constant.
LastNonDeadUser = I;
++I;
continue;
}
// If the constant was dead, then the iterator is invalidated.
if (LastNonDeadUser == E) {
I = use_begin();
if (I == E) break;
} else {
I = LastNonDeadUser;
++I;
}
}
}
//===----------------------------------------------------------------------===//
// ConstantInt

View File

@ -26,23 +26,6 @@ using namespace llvm;
// GlobalValue Class
//===----------------------------------------------------------------------===//
/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
/// it. This involves recursively eliminating any dead users of the
/// constantexpr.
static bool removeDeadUsersOfConstant(const Constant *C) {
if (isa<GlobalValue>(C)) return false; // Cannot remove this
while (!C->use_empty()) {
const Constant *User = dyn_cast<Constant>(C->use_back());
if (!User) return false; // Non-constant usage;
if (!removeDeadUsersOfConstant(User))
return false; // Constant wasn't dead
}
const_cast<Constant*>(C)->destroyConstant();
return true;
}
bool GlobalValue::isMaterializable() const {
return getParent() && getParent()->isMaterializable(this);
}
@ -56,38 +39,6 @@ void GlobalValue::Dematerialize() {
getParent()->Dematerialize(this);
}
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this global value, remove them. This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void GlobalValue::removeDeadConstantUsers() const {
Value::const_use_iterator I = use_begin(), E = use_end();
Value::const_use_iterator LastNonDeadUser = E;
while (I != E) {
if (const Constant *User = dyn_cast<Constant>(*I)) {
if (!removeDeadUsersOfConstant(User)) {
// If the constant wasn't dead, remember that this was the last live use
// and move on to the next constant.
LastNonDeadUser = I;
++I;
} else {
// If the constant was dead, then the iterator is invalidated.
if (LastNonDeadUser == E) {
I = use_begin();
if (I == E) break;
} else {
I = LastNonDeadUser;
++I;
}
}
} else {
LastNonDeadUser = I;
++I;
}
}
}
/// Override destroyConstant to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
void GlobalValue::destroyConstant() {