diff options
Diffstat (limited to 'contrib/llvm/lib/IR/Value.cpp')
-rw-r--r-- | contrib/llvm/lib/IR/Value.cpp | 151 |
1 files changed, 92 insertions, 59 deletions
diff --git a/contrib/llvm/lib/IR/Value.cpp b/contrib/llvm/lib/IR/Value.cpp index 91a999b..51a7d42 100644 --- a/contrib/llvm/lib/IR/Value.cpp +++ b/contrib/llvm/lib/IR/Value.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DerivedUser.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" @@ -59,7 +60,7 @@ Value::Value(Type *ty, unsigned scid) (SubclassID < ConstantFirstVal || SubclassID > ConstantLastVal)) assert((VTy->isFirstClassType() || VTy->isVoidTy()) && "Cannot create non-first-class values except for constants!"); - static_assert(sizeof(Value) == 3 * sizeof(void *) + 2 * sizeof(unsigned), + static_assert(sizeof(Value) == 2 * sizeof(void *) + 2 * sizeof(unsigned), "Value too big"); } @@ -89,6 +90,32 @@ Value::~Value() { destroyValueName(); } +void Value::deleteValue() { + switch (getValueID()) { +#define HANDLE_VALUE(Name) \ + case Value::Name##Val: \ + delete static_cast<Name *>(this); \ + break; +#define HANDLE_MEMORY_VALUE(Name) \ + case Value::Name##Val: \ + static_cast<DerivedUser *>(this)->DeleteValue( \ + static_cast<DerivedUser *>(this)); \ + break; +#define HANDLE_INSTRUCTION(Name) /* nothing */ +#include "llvm/IR/Value.def" + +#define HANDLE_INST(N, OPC, CLASS) \ + case Value::InstructionVal + Instruction::OPC: \ + delete static_cast<CLASS *>(this); \ + break; +#define HANDLE_USER_INST(N, OPC, CLASS) +#include "llvm/IR/Instruction.def" + + default: + llvm_unreachable("attempting to delete unknown value kind"); + } +} + void Value::destroyValueName() { ValueName *Name = getValueName(); if (Name) @@ -320,7 +347,7 @@ void Value::takeName(Value *V) { ST->reinsertValue(this); } -void Value::assertModuleIsMaterialized() const { +void Value::assertModuleIsMaterializedImpl() const { #ifndef NDEBUG const GlobalValue *GV = dyn_cast<GlobalValue>(this); if (!GV) @@ -432,24 +459,26 @@ namespace { enum PointerStripKind { PSK_ZeroIndices, PSK_ZeroIndicesAndAliases, + PSK_ZeroIndicesAndAliasesAndBarriers, PSK_InBoundsConstantIndices, PSK_InBounds }; template <PointerStripKind StripKind> -static Value *stripPointerCastsAndOffsets(Value *V) { +static const Value *stripPointerCastsAndOffsets(const Value *V) { if (!V->getType()->isPointerTy()) return V; // Even though we don't look through PHI nodes, we could be called on an // instruction in an unreachable block, which may be on a cycle. - SmallPtrSet<Value *, 4> Visited; + SmallPtrSet<const Value *, 4> Visited; Visited.insert(V); do { - if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { + if (auto *GEP = dyn_cast<GEPOperator>(V)) { switch (StripKind) { case PSK_ZeroIndicesAndAliases: + case PSK_ZeroIndicesAndAliasesAndBarriers: case PSK_ZeroIndices: if (!GEP->hasAllZeroIndices()) return V; @@ -467,17 +496,25 @@ static Value *stripPointerCastsAndOffsets(Value *V) { } else if (Operator::getOpcode(V) == Instruction::BitCast || Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast<Operator>(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + } else if (auto *GA = dyn_cast<GlobalAlias>(V)) { if (StripKind == PSK_ZeroIndices || GA->isInterposable()) return V; V = GA->getAliasee(); } else { - if (auto CS = CallSite(V)) - if (Value *RV = CS.getReturnedArgOperand()) { + if (auto CS = ImmutableCallSite(V)) { + if (const Value *RV = CS.getReturnedArgOperand()) { V = RV; continue; } - + // The result of invariant.group.barrier must alias it's argument, + // but it can't be marked with returned attribute, that's why it needs + // special case. + if (StripKind == PSK_ZeroIndicesAndAliasesAndBarriers && + CS.getIntrinsicID() == Intrinsic::invariant_group_barrier) { + V = CS.getArgOperand(0); + continue; + } + } return V; } assert(V->getType()->isPointerTy() && "Unexpected operand type!"); @@ -487,20 +524,26 @@ static Value *stripPointerCastsAndOffsets(Value *V) { } } // end anonymous namespace -Value *Value::stripPointerCasts() { +const Value *Value::stripPointerCasts() const { return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this); } -Value *Value::stripPointerCastsNoFollowAliases() { +const Value *Value::stripPointerCastsNoFollowAliases() const { return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this); } -Value *Value::stripInBoundsConstantOffsets() { +const Value *Value::stripInBoundsConstantOffsets() const { return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this); } -Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, - APInt &Offset) { +const Value *Value::stripPointerCastsAndBarriers() const { + return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliasesAndBarriers>( + this); +} + +const Value * +Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, + APInt &Offset) const { if (!getType()->isPointerTy()) return this; @@ -510,11 +553,11 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, // Even though we don't look through PHI nodes, we could be called on an // instruction in an unreachable block, which may be on a cycle. - SmallPtrSet<Value *, 4> Visited; + SmallPtrSet<const Value *, 4> Visited; Visited.insert(this); - Value *V = this; + const Value *V = this; do { - if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { + if (auto *GEP = dyn_cast<GEPOperator>(V)) { if (!GEP->isInBounds()) return V; APInt GEPOffset(Offset); @@ -524,11 +567,11 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast) { V = cast<Operator>(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + } else if (auto *GA = dyn_cast<GlobalAlias>(V)) { V = GA->getAliasee(); } else { - if (auto CS = CallSite(V)) - if (Value *RV = CS.getReturnedArgOperand()) { + if (auto CS = ImmutableCallSite(V)) + if (const Value *RV = CS.getReturnedArgOperand()) { V = RV; continue; } @@ -541,7 +584,7 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, return V; } -Value *Value::stripInBoundsOffsets() { +const Value *Value::stripInBoundsOffsets() const { return stripPointerCastsAndOffsets<PSK_InBounds>(this); } @@ -562,9 +605,9 @@ unsigned Value::getPointerDereferenceableBytes(const DataLayout &DL, CanBeNull = true; } } else if (auto CS = ImmutableCallSite(this)) { - DerefBytes = CS.getDereferenceableBytes(0); + DerefBytes = CS.getDereferenceableBytes(AttributeList::ReturnIndex); if (DerefBytes == 0) { - DerefBytes = CS.getDereferenceableOrNullBytes(0); + DerefBytes = CS.getDereferenceableOrNullBytes(AttributeList::ReturnIndex); CanBeNull = true; } } else if (const LoadInst *LI = dyn_cast<LoadInst>(this)) { @@ -633,7 +676,7 @@ unsigned Value::getPointerAlignment(const DataLayout &DL) const { Align = DL.getPrefTypeAlignment(AllocatedType); } } else if (auto CS = ImmutableCallSite(this)) - Align = CS.getAttributes().getParamAlignment(AttributeSet::ReturnIndex); + Align = CS.getAttributes().getRetAlignment(); else if (const LoadInst *LI = dyn_cast<LoadInst>(this)) if (MDNode *MD = LI->getMetadata(LLVMContext::MD_align)) { ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0)); @@ -643,9 +686,9 @@ unsigned Value::getPointerAlignment(const DataLayout &DL) const { return Align; } -Value *Value::DoPHITranslation(const BasicBlock *CurBB, - const BasicBlock *PredBB) { - PHINode *PN = dyn_cast<PHINode>(this); +const Value *Value::DoPHITranslation(const BasicBlock *CurBB, + const BasicBlock *PredBB) const { + auto *PN = dyn_cast<PHINode>(this); if (PN && PN->getParent() == CurBB) return PN->getIncomingValueForBlock(PredBB); return this; @@ -695,7 +738,7 @@ void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { setPrevPtr(List); if (Next) { Next->setPrevPtr(&Next); - assert(V == Next->V && "Added to wrong list?"); + assert(getValPtr() == Next->getValPtr() && "Added to wrong list?"); } } @@ -710,14 +753,14 @@ void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) { } void ValueHandleBase::AddToUseList() { - assert(V && "Null pointer doesn't have a use list!"); + assert(getValPtr() && "Null pointer doesn't have a use list!"); - LLVMContextImpl *pImpl = V->getContext().pImpl; + LLVMContextImpl *pImpl = getValPtr()->getContext().pImpl; - if (V->HasValueHandle) { + if (getValPtr()->HasValueHandle) { // If this value already has a ValueHandle, then it must be in the // ValueHandles map already. - ValueHandleBase *&Entry = pImpl->ValueHandles[V]; + ValueHandleBase *&Entry = pImpl->ValueHandles[getValPtr()]; assert(Entry && "Value doesn't have any handles?"); AddToExistingUseList(&Entry); return; @@ -731,10 +774,10 @@ void ValueHandleBase::AddToUseList() { DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles; const void *OldBucketPtr = Handles.getPointerIntoBucketsArray(); - ValueHandleBase *&Entry = Handles[V]; + ValueHandleBase *&Entry = Handles[getValPtr()]; assert(!Entry && "Value really did already have handles?"); AddToExistingUseList(&Entry); - V->HasValueHandle = true; + getValPtr()->HasValueHandle = true; // If reallocation didn't happen or if this was the first insertion, don't // walk the table. @@ -746,14 +789,14 @@ void ValueHandleBase::AddToUseList() { // Okay, reallocation did happen. Fix the Prev Pointers. for (DenseMap<Value*, ValueHandleBase*>::iterator I = Handles.begin(), E = Handles.end(); I != E; ++I) { - assert(I->second && I->first == I->second->V && + assert(I->second && I->first == I->second->getValPtr() && "List invariant broken!"); I->second->setPrevPtr(&I->second); } } void ValueHandleBase::RemoveFromUseList() { - assert(V && V->HasValueHandle && + assert(getValPtr() && getValPtr()->HasValueHandle && "Pointer doesn't have a use list!"); // Unlink this from its use list. @@ -770,11 +813,11 @@ void ValueHandleBase::RemoveFromUseList() { // If the Next pointer was null, then it is possible that this was the last // ValueHandle watching VP. If so, delete its entry from the ValueHandles // map. - LLVMContextImpl *pImpl = V->getContext().pImpl; + LLVMContextImpl *pImpl = getValPtr()->getContext().pImpl; DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles; if (Handles.isPointerIntoBucketsArray(PrevPtr)) { - Handles.erase(V); - V->HasValueHandle = false; + Handles.erase(getValPtr()); + getValPtr()->HasValueHandle = false; } } @@ -804,13 +847,10 @@ void ValueHandleBase::ValueIsDeleted(Value *V) { switch (Entry->getKind()) { case Assert: break; - case Tracking: - // Mark that this value has been deleted by setting it to an invalid Value - // pointer. - Entry->operator=(DenseMapInfo<Value *>::getTombstoneKey()); - break; case Weak: - // Weak just goes to null, which will unlink it from the list. + case WeakTracking: + // WeakTracking and Weak just go to null, which unlinks them + // from the list. Entry->operator=(nullptr); break; case Callback: @@ -858,16 +898,10 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { switch (Entry->getKind()) { case Assert: - // Asserting handle does not follow RAUW implicitly. - break; - case Tracking: - // Tracking goes to new value like a WeakVH. Note that this may make it - // something incompatible with its templated type. We don't want to have a - // virtual (or inline) interface to handle this though, so instead we make - // the TrackingVH accessors guarantee that a client never sees this value. - - LLVM_FALLTHROUGH; case Weak: + // Asserting and Weak handles do not follow RAUW implicitly. + break; + case WeakTracking: // Weak goes to the new value, which will unlink it from Old's list. Entry->operator=(New); break; @@ -879,18 +913,17 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { } #ifndef NDEBUG - // If any new tracking or weak value handles were added while processing the + // If any new weak value handles were added while processing the // list, then complain about it now. if (Old->HasValueHandle) for (Entry = pImpl->ValueHandles[Old]; Entry; Entry = Entry->Next) switch (Entry->getKind()) { - case Tracking: - case Weak: + case WeakTracking: dbgs() << "After RAUW from " << *Old->getType() << " %" << Old->getName() << " to " << *New->getType() << " %" << New->getName() << "\n"; - llvm_unreachable("A tracking or weak value handle still pointed to the" - " old value!\n"); + llvm_unreachable( + "A weak tracking value handle still pointed to the old value!\n"); default: break; } |