summaryrefslogtreecommitdiff
path: root/lib/IR/ConstantsContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/ConstantsContext.h')
-rw-r--r--lib/IR/ConstantsContext.h71
1 files changed, 34 insertions, 37 deletions
diff --git a/lib/IR/ConstantsContext.h b/lib/IR/ConstantsContext.h
index 13fcbd2ece10a..7db87edff010a 100644
--- a/lib/IR/ConstantsContext.h
+++ b/lib/IR/ConstantsContext.h
@@ -15,7 +15,7 @@
#ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
#define LLVM_LIB_IR_CONSTANTSCONTEXT_H
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
@@ -23,8 +23,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include <map>
-#include <tuple>
#define DEBUG_TYPE "ir"
@@ -225,19 +223,12 @@ public:
/// used behind the scenes to implement getelementpr constant exprs.
class GetElementPtrConstantExpr : public ConstantExpr {
Type *SrcElementTy;
+ Type *ResElementTy;
void anchor() override;
GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
ArrayRef<Constant *> IdxList, Type *DestTy);
public:
- static GetElementPtrConstantExpr *Create(Constant *C,
- ArrayRef<Constant*> IdxList,
- Type *DestTy,
- unsigned Flags) {
- return Create(
- cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
- IdxList, DestTy, Flags);
- }
static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
ArrayRef<Constant *> IdxList,
Type *DestTy, unsigned Flags) {
@@ -247,6 +238,7 @@ public:
return Result;
}
Type *getSourceElementType() const;
+ Type *getResultElementType() const;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -552,6 +544,9 @@ public:
typedef typename ConstantInfo<ConstantClass>::TypeClass TypeClass;
typedef std::pair<TypeClass *, ValType> LookupKey;
+ /// Key and hash together, so that we compute the hash only once and reuse it.
+ typedef std::pair<unsigned, LookupKey> LookupKeyHashed;
+
private:
struct MapInfo {
typedef DenseMapInfo<ConstantClass *> ConstantClassInfo;
@@ -562,7 +557,7 @@ private:
return ConstantClassInfo::getTombstoneKey();
}
static unsigned getHashValue(const ConstantClass *CP) {
- SmallVector<Constant *, 8> Storage;
+ SmallVector<Constant *, 32> Storage;
return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
}
static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
@@ -571,6 +566,9 @@ private:
static unsigned getHashValue(const LookupKey &Val) {
return hash_combine(Val.first, Val.second.getHash());
}
+ static unsigned getHashValue(const LookupKeyHashed &Val) {
+ return Val.first;
+ }
static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
return false;
@@ -578,30 +576,31 @@ private:
return false;
return LHS.second == RHS;
}
+ static bool isEqual(const LookupKeyHashed &LHS, const ConstantClass *RHS) {
+ return isEqual(LHS.second, RHS);
+ }
};
public:
- typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
+ typedef DenseSet<ConstantClass *, MapInfo> MapTy;
private:
MapTy Map;
public:
- typename MapTy::iterator map_begin() { return Map.begin(); }
- typename MapTy::iterator map_end() { return Map.end(); }
+ typename MapTy::iterator begin() { return Map.begin(); }
+ typename MapTy::iterator end() { return Map.end(); }
void freeConstants() {
for (auto &I : Map)
- // Asserts that use_empty().
- delete I.first;
+ delete I; // Asserts that use_empty().
}
-
private:
- ConstantClass *create(TypeClass *Ty, ValType V) {
+ ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
ConstantClass *Result = V.create(Ty);
assert(Result->getType() == Ty && "Type specified is not correct!");
- insert(Result);
+ Map.insert_as(Result, HashKey);
return Result;
}
@@ -609,32 +608,27 @@ private:
public:
/// Return the specified constant from the map, creating it if necessary.
ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
- LookupKey Lookup(Ty, V);
+ LookupKey Key(Ty, V);
+ /// Hash once, and reuse it for the lookup and the insertion if needed.
+ LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
+
ConstantClass *Result = nullptr;
- auto I = find(Lookup);
+ auto I = Map.find_as(Lookup);
if (I == Map.end())
- Result = create(Ty, V);
+ Result = create(Ty, V, Lookup);
else
- Result = I->first;
+ Result = *I;
assert(Result && "Unexpected nullptr");
return Result;
}
- /// Find the constant by lookup key.
- typename MapTy::iterator find(LookupKey Lookup) {
- return Map.find_as(Lookup);
- }
-
- /// Insert the constant into its proper slot.
- void insert(ConstantClass *CP) { Map[CP] = '\0'; }
-
/// Remove this constant from the map
void remove(ConstantClass *CP) {
typename MapTy::iterator I = Map.find(CP);
assert(I != Map.end() && "Constant not found in constant table!");
- assert(I->first == CP && "Didn't find correct element?");
+ assert(*I == CP && "Didn't find correct element?");
Map.erase(I);
}
@@ -642,10 +636,13 @@ public:
ConstantClass *CP, Value *From,
Constant *To, unsigned NumUpdated = 0,
unsigned OperandNo = ~0u) {
- LookupKey Lookup(CP->getType(), ValType(Operands, CP));
- auto I = find(Lookup);
+ LookupKey Key(CP->getType(), ValType(Operands, CP));
+ /// Hash once, and reuse it for the lookup and the insertion if needed.
+ LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
+
+ auto I = Map.find_as(Lookup);
if (I != Map.end())
- return I->first;
+ return *I;
// Update to the new value. Optimize for the case when we have a single
// operand that we're changing, but handle bulk updates efficiently.
@@ -659,7 +656,7 @@ public:
if (CP->getOperand(I) == From)
CP->setOperand(I, To);
}
- insert(CP);
+ Map.insert_as(CP, Lookup);
return nullptr;
}