summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-12-05 06:43:27 +0000
committerChris Lattner <sabre@nondot.org>2004-12-05 06:43:27 +0000
commitb392d307612043ffaadc7ed1c54b5a31faf11c66 (patch)
treeb93786e123e2956bd84cf24b120c8a1cdb8f41af /llvm
parent0ba8f4e19177bab7e1cfc2b62c4cfebddbb3b2b8 (diff)
downloadbcm5719-llvm-b392d307612043ffaadc7ed1c54b5a31faf11c66.tar.gz
bcm5719-llvm-b392d307612043ffaadc7ed1c54b5a31faf11c66.zip
Add a new method
llvm-svn: 18531
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Function.h7
-rw-r--r--llvm/lib/VMCore/Function.cpp41
2 files changed, 48 insertions, 0 deletions
diff --git a/llvm/include/llvm/Function.h b/llvm/include/llvm/Function.h
index e67ef01a56b..a540ee3f743 100644
--- a/llvm/include/llvm/Function.h
+++ b/llvm/include/llvm/Function.h
@@ -106,6 +106,13 @@ public:
unsigned getIntrinsicID() const;
bool isIntrinsic() const { return getIntrinsicID() != 0; }
+ /// renameLocalSymbols - This method goes through the Function's symbol table
+ /// and renames any symbols that conflict with symbols at global scope. This
+ /// is required before printing out to a textual form, to ensure that there is
+ /// no ambiguity when parsing.
+ void renameLocalSymbols();
+
+
/// deleteBody - This method deletes the body of the function, and converts
/// the linkage to external.
///
diff --git a/llvm/lib/VMCore/Function.cpp b/llvm/lib/VMCore/Function.cpp
index 46cb4c23d43..a35a55b4bb4 100644
--- a/llvm/lib/VMCore/Function.cpp
+++ b/llvm/lib/VMCore/Function.cpp
@@ -17,6 +17,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Support/LeakDetector.h"
#include "SymbolTableListTraitsImpl.h"
+#include "llvm/ADT/StringExtras.h"
using namespace llvm;
BasicBlock *ilist_traits<BasicBlock>::createNode() {
@@ -153,6 +154,46 @@ void Function::eraseFromParent() {
getParent()->getFunctionList().erase(this);
}
+
+/// renameLocalSymbols - This method goes through the Function's symbol table
+/// and renames any symbols that conflict with symbols at global scope. This is
+/// required before printing out to a textual form, to ensure that there is no
+/// ambiguity when parsing.
+void Function::renameLocalSymbols() {
+ SymbolTable &LST = getSymbolTable(); // Local Symtab
+ SymbolTable &GST = getParent()->getSymbolTable(); // Global Symtab
+
+ for (SymbolTable::plane_iterator LPI = LST.plane_begin(), E = LST.plane_end();
+ LPI != E; ++LPI)
+ // All global symbols are of pointer type, ignore any non-pointer planes.
+ if (isa<PointerType>(LPI->first)) {
+ // Only check if the global plane has any symbols of this type.
+ SymbolTable::plane_iterator GPI = GST.find(LPI->first);
+ if (GPI != GST.plane_end()) {
+ SymbolTable::ValueMap &LVM = LPI->second;
+ const SymbolTable::ValueMap &GVM = GPI->second;
+
+ // Loop over all local symbols, renaming those that are in the global
+ // symbol table already.
+ for (SymbolTable::value_iterator VI = LVM.begin(), E = LVM.end();
+ VI != E;) {
+ Value *V = VI->second;
+ const std::string &Name = VI->first;
+ ++VI;
+ if (GVM.count(Name)) {
+ static unsigned UniqueNum = 0;
+ // Find a name that does not conflict!
+ while (GVM.count(Name + "_" + utostr(++UniqueNum)) ||
+ LVM.count(Name + "_" + utostr(UniqueNum)))
+ /* scan for UniqueNum that works */;
+ V->setName(Name + "_" + utostr(UniqueNum));
+ }
+ }
+ }
+ }
+}
+
+
// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular
OpenPOWER on IntegriCloud