aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-10-03 22:51:37 +0000
committerChris Lattner <sabre@nondot.org>2005-10-03 22:51:37 +0000
commitcea141f1d1f85997c4c657009994bdacbc3a3dbf (patch)
treeb0905030996259f2fdaec8372f5fd76b39bce1cb /lib
parent5cbade9f8340f5266d9f9ba401d494e636b7c42f (diff)
downloadexternal_llvm-cea141f1d1f85997c4c657009994bdacbc3a3dbf.zip
external_llvm-cea141f1d1f85997c4c657009994bdacbc3a3dbf.tar.gz
external_llvm-cea141f1d1f85997c4c657009994bdacbc3a3dbf.tar.bz2
Change ConstantArray::replaceUsesOfWithOnConstant to attempt to update
constant arrays in place instead of reallocating them and replaceAllUsesOf'ing the result. This speeds up a release build of the bcreader from: 136.987u 120.866s 4:24.38 to 49.790u 49.890s 1:40.14 ... a 2.6x speedup parsing a large python bc file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23614 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/VMCore/Constants.cpp66
1 files changed, 58 insertions, 8 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 7471a60..6728fc4 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -515,9 +515,11 @@ namespace llvm {
namespace {
template<class ValType, class TypeClass, class ConstantClass>
class ValueMap : public AbstractTypeUser {
+ public:
typedef std::pair<const TypeClass*, ValType> MapKey;
typedef std::map<MapKey, ConstantClass *> MapTy;
typedef typename MapTy::iterator MapIterator;
+ private:
MapTy Map;
typedef std::map<const TypeClass*, MapIterator> AbstractTypeMapTy;
@@ -533,8 +535,22 @@ namespace {
}
public:
- // getOrCreate - Return the specified constant from the map, creating it if
- // necessary.
+ MapIterator map_end() { return Map.end(); }
+
+ /// InsertOrGetItem - Return an iterator for the specified element.
+ /// If the element exists in the map, the returned iterator points to the
+ /// entry and Exists=true. If not, the iterator points to the newly
+ /// inserted entry and returns Exists=false. Newly inserted entries have
+ /// I->second == 0, and should be filled in.
+ MapIterator InsertOrGetItem(std::pair<MapKey, ConstantClass *> &InsertVal,
+ bool &Exists) {
+ std::pair<MapIterator, bool> IP = Map.insert(InsertVal);
+ Exists = !IP.second;
+ return IP.first;
+ }
+
+ /// getOrCreate - Return the specified constant from the map, creating it if
+ /// necessary.
ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
MapKey Lookup(Ty, V);
MapIterator I = Map.lower_bound(Lookup);
@@ -545,7 +561,6 @@ namespace {
ConstantClass *Result =
ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
-
/// FIXME: why does this assert fail when loading 176.gcc?
//assert(Result->getType() == Ty && "Type specified is not correct!");
I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));
@@ -784,8 +799,9 @@ static std::vector<Constant*> getValType(ConstantArray *CA) {
return Elements;
}
-static ValueMap<std::vector<Constant*>, ArrayType,
- ConstantArray> ArrayConstants;
+typedef ValueMap<std::vector<Constant*>, ArrayType,
+ ConstantArray> ArrayConstantsTy;
+static ArrayConstantsTy ArrayConstants;
Constant *ConstantArray::get(const ArrayType *Ty,
const std::vector<Constant*> &V) {
@@ -1331,15 +1347,49 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
bool DisableChecking) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
- std::vector<Constant*> Values;
- Values.reserve(getNumOperands()); // Build replacement array...
+ std::pair<ArrayConstantsTy::MapKey, ConstantArray*> Lookup;
+ Lookup.first.first = getType();
+ Lookup.second = this;
+ std::vector<Constant*> &Values = Lookup.first.second;
+ Values.reserve(getNumOperands()); // Build replacement array.
+
+ bool isAllZeros = false; // Does this turn into an all-zeros array?
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
Constant *Val = getOperand(i);
if (Val == From) Val = cast<Constant>(To);
Values.push_back(Val);
+ if (isAllZeros) isAllZeros = Val->isNullValue();
}
- Constant *Replacement = ConstantArray::get(getType(), Values);
+ Constant *Replacement = 0;
+ if (isAllZeros) {
+ Replacement = ConstantAggregateZero::get(getType());
+ } else {
+ // Check to see if we have this array type already.
+ bool Exists;
+ ArrayConstantsTy::MapIterator I =
+ ArrayConstants.InsertOrGetItem(Lookup, Exists);
+
+ if (Exists) {
+ Replacement = I->second;
+ } else {
+ // Okay, the new shape doesn't exist in the system yet. Instead of
+ // creating a new constant array, inserting it, replaceallusesof'ing the
+ // old with the new, then deleting the old... just update the current one
+ // in place!
+ if (I != ArrayConstants.map_end() && I->second == this)
+ ++I; // Do not invalidate iterator!
+ ArrayConstants.remove(this); // Remove old shape from the map.
+
+ // Update to the new values.
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (getOperand(i) == From)
+ setOperand(i, cast<Constant>(To));
+ return;
+ }
+ }
+
+ // Otherwise, I do need to replace this with an existing value.
assert(Replacement != this && "I didn't contain From!");
// Everyone using this now uses the replacement...