Type *VTy;
Use *UseList;
- friend class ValueAsMetadata; // Allow access to NameAndIsUsedByMD.
+ friend class ValueAsMetadata; // Allow access to IsUsedByMD.
friend class ValueHandleBase;
- PointerIntPair<ValueName *, 1> NameAndIsUsedByMD;
const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast)
unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
/// This is stored here to save space in User on 64-bit hosts. Since most
/// instances of Value have operands, 32-bit hosts aren't significantly
/// affected.
- unsigned NumOperands;
+ unsigned NumOperands : 30;
+
+ bool IsUsedByMD : 1;
+ bool HasName : 1;
private:
template <typename UseT> // UseT == 'Use' or 'const Use'
LLVMContext &getContext() const;
// \brief All values can potentially be named.
- bool hasName() const { return getValueName() != nullptr; }
- ValueName *getValueName() const { return NameAndIsUsedByMD.getPointer(); }
- void setValueName(ValueName *VN) { NameAndIsUsedByMD.setPointer(VN); }
+ bool hasName() const { return HasName; }
+ ValueName *getValueName() const;
+ void setValueName(ValueName *VN);
private:
void destroyValueName();
bool hasValueHandle() const { return HasValueHandle; }
/// \brief Return true if there is metadata referencing this value.
- bool isUsedByMetadata() const { return NameAndIsUsedByMD.getInt(); }
+ bool isUsedByMetadata() const { return IsUsedByMD; }
/// \brief Strip off pointer casts, all-zero GEPs, and aliases.
///
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
+ DenseMap<const Value*, ValueName*> ValueNames;
+
#define HANDLE_MDNODE_LEAF(CLASS) DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"
if (!Entry) {
assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) &&
"Expected constant or function-local value");
- assert(!V->NameAndIsUsedByMD.getInt() &&
+ assert(!V->IsUsedByMD &&
"Expected this to be the only metadata use");
- V->NameAndIsUsedByMD.setInt(true);
+ V->IsUsedByMD = true;
if (auto *C = dyn_cast<Constant>(V))
Entry = new ConstantAsMetadata(C);
else
auto &Store = Context.pImpl->ValuesAsMetadata;
auto I = Store.find(From);
if (I == Store.end()) {
- assert(!From->NameAndIsUsedByMD.getInt() &&
+ assert(!From->IsUsedByMD &&
"Expected From not to be used by metadata");
return;
}
// Remove old entry from the map.
- assert(From->NameAndIsUsedByMD.getInt() &&
+ assert(From->IsUsedByMD &&
"Expected From to be used by metadata");
- From->NameAndIsUsedByMD.setInt(false);
+ From->IsUsedByMD = false;
ValueAsMetadata *MD = I->second;
assert(MD && "Expected valid metadata");
assert(MD->getValue() == From && "Expected valid mapping");
}
// Update MD in place (and update the map entry).
- assert(!To->NameAndIsUsedByMD.getInt() &&
+ assert(!To->IsUsedByMD &&
"Expected this to be the only metadata use");
- To->NameAndIsUsedByMD.setInt(true);
+ To->IsUsedByMD = true;
MD->V = To;
Entry = MD;
}
}
Value::Value(Type *ty, unsigned scid)
- : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid), HasValueHandle(0),
- SubclassOptionalData(0), SubclassData(0), NumOperands(0) {
+ : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid),
+ HasValueHandle(0), SubclassOptionalData(0), SubclassData(0),
+ NumOperands(0), IsUsedByMD(false), HasName(false) {
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
// constructed.
return false;
}
+ValueName *Value::getValueName() const {
+ if (!HasName) return nullptr;
+
+ LLVMContext &Ctx = getContext();
+ auto I = Ctx.pImpl->ValueNames.find(this);
+ assert(I != Ctx.pImpl->ValueNames.end() &&
+ "No name entry found!");
+
+ return I->second;
+}
+
+void Value::setValueName(ValueName *VN) {
+ LLVMContext &Ctx = getContext();
+
+ assert(HasName == Ctx.pImpl->ValueNames.count(this) &&
+ "HasName bit out of sync!");
+
+ if (!VN) {
+ if (HasName)
+ Ctx.pImpl->ValueNames.erase(this);
+ HasName = false;
+ return;
+ }
+
+ HasName = true;
+ Ctx.pImpl->ValueNames[this] = VN;
+}
+
StringRef Value::getName() const {
// Make sure the empty string is still a C string. For historical reasons,
// some clients want to call .data() on the result and expect it to be null
// terminated.
- if (!getValueName())
+ if (!hasName())
return StringRef("", 0);
return getValueName()->getKey();
}