[llvm-commits] CVS: llvm/lib/VMCore/Globals.cpp

LLVM llvm at cs.uiuc.edu
Sat Jul 17 17:06:36 PDT 2004



Changes in directory llvm/lib/VMCore:

Globals.cpp added (r1.1)

---
Log message:

bug 122: http://llvm.cs.uiuc.edu/PR122 :
- Move these functions from other places
- Provide implementations of Constant class overrides in GlobalValue


---
Diffs of the changes:  (+139 -0)

Index: llvm/lib/VMCore/Globals.cpp
diff -c /dev/null llvm/lib/VMCore/Globals.cpp:1.1
*** /dev/null	Sat Jul 17 19:06:36 2004
--- llvm/lib/VMCore/Globals.cpp	Sat Jul 17 19:06:26 2004
***************
*** 0 ****
--- 1,139 ----
+ //===-- Globals.cpp - Implement the Global object classes -----------------===//
+ // 
+ //                     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 GlobalValue & GlobalVariable classes for the VMCore
+ // library.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/GlobalVariable.h"
+ #include "llvm/Module.h"
+ #include "llvm/SymbolTable.h"
+ #include "Support/LeakDetector.h"
+ 
+ using namespace llvm;
+ 
+ //===----------------------------------------------------------------------===//
+ //                            GlobalValue Class
+ //===----------------------------------------------------------------------===//
+ 
+ /// This could be named "SafeToDestroyGlobalValue". It just makes sure that 
+ /// there are no non-constant uses of this GlobalValue. If there aren't then
+ /// this and the transitive closure of the constants can be deleted. See the
+ /// destructor for details.
+ namespace {
+ bool removeDeadConstantUsers(Constant* C) {
+   while (!C->use_empty()) {
+     if (Constant *User = dyn_cast<Constant>(C->use_back())) {
+       if (!removeDeadConstantUsers(User)) 
+         return false; // Constant wasn't dead
+     } else {
+       return false; // Non-constant usage;
+     }
+   }
+   if (!isa<GlobalValue>(C))
+     C->destroyConstant();
+   return true;
+ }
+ }
+ 
+ /// 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.
+ ///
+ /// This function returns true if the global value is now dead.  If all 
+ /// users of this global are not dead, this method may return false and
+ /// leave some of them around.
+ bool GlobalValue::removeDeadConstantUsers() {
+   while(!use_empty()) {
+     if (Constant* User = dyn_cast<Constant>(use_back())) {
+       if (!::removeDeadConstantUsers(User))
+         return false; // Constant wasn't dead
+     } else {
+       return false; // Non-constant usage;
+     }
+   }
+   return true;
+ }
+ 
+ /// This virtual destructor is responsible for deleting any transitively dead
+ /// Constants that are using the GlobalValue.
+ GlobalValue::~GlobalValue() {
+   // Its an error to attempt destruction with non-constant uses remaining.
+   bool okay_to_destruct = removeDeadConstantUsers();
+   assert(okay_to_destruct && 
+          "Can't destroy GlobalValue with non-constant uses.");
+ }
+ 
+ /// 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() {
+   assert(0 && "You can't GV->destroyConstant()!");
+   abort();
+ }
+ //===----------------------------------------------------------------------===//
+ // GlobalVariable Implementation
+ //===----------------------------------------------------------------------===//
+ 
+ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
+                                Constant *Initializer,
+                                const std::string &Name, Module *ParentModule)
+   : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Link, Name),
+     isConstantGlobal(constant) {
+   if (Initializer) Operands.push_back(Use((Value*)Initializer, this));
+ 
+   LeakDetector::addGarbageObject(this);
+ 
+   if (ParentModule)
+     ParentModule->getGlobalList().push_back(this);
+ }
+ 
+ void GlobalVariable::setParent(Module *parent) {
+   if (getParent())
+     LeakDetector::addGarbageObject(this);
+   Parent = parent;
+   if (getParent())
+     LeakDetector::removeGarbageObject(this);
+ }
+ 
+ // Specialize setName to take care of symbol table majik
+ void GlobalVariable::setName(const std::string &name, SymbolTable *ST) {
+   Module *P;
+   assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
+          "Invalid symtab argument!");
+   if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
+   Value::setName(name);
+   if (P && hasName()) P->getSymbolTable().insert(this);
+ }
+ 
+ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
+                                                  bool DisableChecking )
+ {
+   // If you call this, then you better know this GVar has a constant
+   // initializer worth replacing. Enforce that here.
+   assert(getNumOperands() == 1 && 
+          "Attempt to replace uses of Constants on a GVar with no initializer");
+ 
+   // And, since you know it has an initializer, the From value better be
+   // the initializer :)
+   assert(getOperand(0) == From &&
+          "Attempt to replace wrong constant initializer in GVar");
+ 
+   // And, you better have a constant for the replacement value
+   assert(isa<Constant>(To) &&
+          "Attempt to replace GVar initializer with non-constant");
+   
+   // Okay, preconditions out of the way, replace the constant initializer.
+   this->setOperand(0,To);
+ }
+ 
+ // vim: sw=2 ai
+ 





More information about the llvm-commits mailing list