#include "Support/LeakDetector.h"
#include "SymbolTableListTraitsImpl.h"
#include <algorithm>
+#include <cstdarg>
#include <map>
Function *ilist_traits<Function>::createNode() {
};
-Module::Module() {
+Module::Module(const std::string &MID)
+ : ModuleID(MID), Endian(AnyEndianness), PtrSize(AnyPointerSize) {
FunctionList.setItemParent(this);
FunctionList.setParent(this);
GlobalList.setItemParent(this);
}
}
+// getOrInsertFunction - Look up the specified function in the module symbol
+// table. If it does not exist, add a prototype for the function and return it.
+// This version of the method takes a null terminated list of function
+// arguments, which makes it easier for clients to use.
+//
+Function *Module::getOrInsertFunction(const std::string &Name,
+ const Type *RetTy, ...) {
+ va_list Args;
+ va_start(Args, RetTy);
+
+ // Build the list of argument types...
+ std::vector<const Type*> ArgTys;
+ while (const Type *ArgTy = va_arg(Args, const Type*))
+ ArgTys.push_back(ArgTy);
+
+ va_end(Args);
+
+ // Build the function type and chain to the other getOrInsertFunction...
+ return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false));
+}
+
+
+
// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
///
Function *Module::getNamedFunction(const std::string &Name) {
// Loop over all of the functions, looking for the function desired
+ Function *Found = 0;
for (iterator I = begin(), E = end(); I != E; ++I)
if (I->getName() == Name)
- return I;
- return 0; // function not found...
+ if (I->isExternal())
+ Found = I;
+ else
+ return I;
+ return Found; // Non-external function not found...
}
}
void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) {
+ assert(OldGV != NewGV && "Cannot mutate to the same global!");
GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV);
assert(I != GVRefMap->Map.end() &&
"mutateConstantPointerRef; OldGV not in table!");
// Remove the old entry...
GVRefMap->Map.erase(I);
- // Insert the new entry...
- GVRefMap->Map.insert(std::make_pair(NewGV, Ref));
+ // Check to see if a CPR already exists for NewGV
+ I = GVRefMap->Map.lower_bound(NewGV);
+
+ if (I == GVRefMap->Map.end() || I->first != NewGV) {
+ // Insert the new entry...
+ GVRefMap->Map.insert(I, std::make_pair(NewGV, Ref));
+ } else {
+ // Otherwise, an entry already exists for the current global value.
+ // Completely replace the old CPR with the existing one...
+ Ref->replaceAllUsesWith(I->second);
+ delete Ref;
+ }
}