X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FConstants.cpp;h=0898bf645385131761b5b4d40823d99a91c4be2b;hb=ff65de018b6bb5bc4da3e923bbc0f55c5ca8e039;hp=b598c2807ceb4f49371a88d1ba7a4cc6f5ec9b5a;hpb=ad80c2d9ed1a348deaacdf11aa17c40382a97ac7;p=oota-llvm.git diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index b598c2807ce..0898bf64538 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -53,6 +53,11 @@ bool Constant::isNegativeZeroValue() const { if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative()) return true; + if (const ConstantVector *CV = dyn_cast(this)) + if (ConstantFP *SplatCFP = dyn_cast_or_null(CV->getSplatValue())) + if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative()) + return true; + // We've already handled true FP case; any other FP vectors can't represent -0.0. if (getType()->isFPOrFPVectorTy()) return false; @@ -68,6 +73,17 @@ bool Constant::isZeroValue() const { if (const ConstantFP *CFP = dyn_cast(this)) return CFP->isZero(); + // Equivalent for a vector of -0.0's. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (ConstantFP *SplatCFP = dyn_cast_or_null(CV->getSplatValue())) + if (SplatCFP && SplatCFP->isZero()) + return true; + + if (const ConstantVector *CV = dyn_cast(this)) + if (ConstantFP *SplatCFP = dyn_cast_or_null(CV->getSplatValue())) + if (SplatCFP && SplatCFP->isZero()) + return true; + // Otherwise, just use +0.0. return isNullValue(); } @@ -81,8 +97,10 @@ bool Constant::isNullValue() const { if (const ConstantFP *CFP = dyn_cast(this)) return CFP->isZero() && !CFP->isNegative(); - // constant zero is zero for aggregates and cpnull is null for pointers. - return isa(this) || isa(this); + // constant zero is zero for aggregates, cpnull is null for pointers, none for + // tokens. + return isa(this) || isa(this) || + isa(this); } bool Constant::isAllOnesValue() const { @@ -204,6 +222,8 @@ Constant *Constant::getNullValue(Type *Ty) { case Type::ArrayTyID: case Type::VectorTyID: return ConstantAggregateZero::get(Ty); + case Type::TokenTyID: + return ConstantTokenNone::get(Ty->getContext()); default: // Function, Label, or Opaque type? llvm_unreachable("Cannot create a null constant of that type!"); @@ -276,8 +296,19 @@ Constant *Constant::getAggregateElement(Constant *Elt) const { return nullptr; } +void Constant::destroyConstant() { + /// First call destroyConstantImpl on the subclass. This gives the subclass + /// a chance to remove the constant from any maps/pools it's contained in. + switch (getValueID()) { + default: + llvm_unreachable("Not a constant!"); +#define HANDLE_CONSTANT(Name) \ + case Value::Name##Val: \ + cast(this)->destroyConstantImpl(); \ + break; +#include "llvm/IR/Value.def" + } -void Constant::destroyConstantImpl() { // When a Constant is destroyed, there may be lingering // references to the constant by other constants in the constant pool. These // constants are implicitly dependent on the module that is being deleted, @@ -287,11 +318,11 @@ void Constant::destroyConstantImpl() { // while (!use_empty()) { Value *V = user_back(); -#ifndef NDEBUG // Only in -g mode... +#ifndef NDEBUG // Only in -g mode... if (!isa(V)) { dbgs() << "While deleting: " << *this - << "\n\nUse still stuck around after Def is destroyed: " - << *V << "\n\n"; + << "\n\nUse still stuck around after Def is destroyed: " << *V + << "\n\n"; } #endif assert(isa(V) && "References remain to Constant being destroyed"); @@ -399,32 +430,13 @@ bool Constant::isConstantUsed() const { return false; } +bool Constant::needsRelocation() const { + if (isa(this)) + return true; // Global reference. - -/// getRelocationInfo - This method classifies the entry according to -/// whether or not it may generate a relocation entry. This must be -/// conservative, so if it might codegen to a relocatable entry, it should say -/// so. The return values are: -/// -/// NoRelocation: This constant pool entry is guaranteed to never have a -/// relocation applied to it (because it holds a simple constant like -/// '4'). -/// LocalRelocation: This entry has relocations, but the entries are -/// guaranteed to be resolvable by the static linker, so the dynamic -/// linker will never see them. -/// GlobalRelocations: This entry may have arbitrary relocations. -/// -/// FIXME: This really should not be in IR. -Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { - if (const GlobalValue *GV = dyn_cast(this)) { - if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) - return LocalRelocation; // Local to this file/library. - return GlobalRelocations; // Global reference. - } - if (const BlockAddress *BA = dyn_cast(this)) - return BA->getFunction()->getRelocationInfo(); - + return BA->getFunction()->needsRelocation(); + // While raw uses of blockaddress need to be relocated, differences between // two of them don't when they are for labels in the same function. This is a // common idiom when creating a table for the indirect goto extension, so we @@ -433,20 +445,18 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { if (CE->getOpcode() == Instruction::Sub) { ConstantExpr *LHS = dyn_cast(CE->getOperand(0)); ConstantExpr *RHS = dyn_cast(CE->getOperand(1)); - if (LHS && RHS && - LHS->getOpcode() == Instruction::PtrToInt && + if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt && RHS->getOpcode() == Instruction::PtrToInt && isa(LHS->getOperand(0)) && isa(RHS->getOperand(0)) && cast(LHS->getOperand(0))->getFunction() == - cast(RHS->getOperand(0))->getFunction()) - return NoRelocation; + cast(RHS->getOperand(0))->getFunction()) + return false; } - PossibleRelocationsTy Result = NoRelocation; + bool Result = false; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - Result = std::max(Result, - cast(getOperand(i))->getRelocationInfo()); + Result |= cast(getOperand(i))->needsRelocation(); return Result; } @@ -608,6 +618,11 @@ ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); } +/// Remove the constant from the constant table. +void ConstantInt::destroyConstantImpl() { + llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!"); +} + //===----------------------------------------------------------------------===// // ConstantFP //===----------------------------------------------------------------------===// @@ -743,6 +758,11 @@ bool ConstantFP::isExactlyValue(const APFloat &V) const { return Val.bitwiseIsEqual(V); } +/// Remove the constant from the constant table. +void ConstantFP::destroyConstantImpl() { + llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!"); +} + //===----------------------------------------------------------------------===// // ConstantAggregateZero Implementation //===----------------------------------------------------------------------===// @@ -776,10 +796,10 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { } unsigned ConstantAggregateZero::getNumElements() const { - const Type *Ty = getType(); - if (const auto *AT = dyn_cast(Ty)) + Type *Ty = getType(); + if (auto *AT = dyn_cast(Ty)) return AT->getNumElements(); - if (const auto *VT = dyn_cast(Ty)) + if (auto *VT = dyn_cast(Ty)) return VT->getNumElements(); return Ty->getStructNumElements(); } @@ -817,10 +837,10 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const { } unsigned UndefValue::getNumElements() const { - const Type *Ty = getType(); - if (const auto *AT = dyn_cast(Ty)) + Type *Ty = getType(); + if (auto *AT = dyn_cast(Ty)) return AT->getNumElements(); - if (const auto *VT = dyn_cast(Ty)) + if (auto *VT = dyn_cast(Ty)) return VT->getNumElements(); return Ty->getStructNumElements(); } @@ -837,6 +857,59 @@ static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) { return true; } +template +static Constant *getIntSequenceIfElementsMatch(ArrayRef V) { + assert(!V.empty() && "Cannot get empty int sequence."); + + SmallVector Elts; + for (Constant *C : V) + if (auto *CI = dyn_cast(C)) + Elts.push_back(CI->getZExtValue()); + else + return nullptr; + return SequentialTy::get(V[0]->getContext(), Elts); +} + +template +static Constant *getFPSequenceIfElementsMatch(ArrayRef V) { + assert(!V.empty() && "Cannot get empty FP sequence."); + + SmallVector Elts; + for (Constant *C : V) + if (auto *CFP = dyn_cast(C)) + Elts.push_back(CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); + else + return nullptr; + return SequentialTy::getFP(V[0]->getContext(), Elts); +} + +template +static Constant *getSequenceIfElementsMatch(Constant *C, + ArrayRef V) { + // We speculatively build the elements here even if it turns out that there is + // a constantexpr or something else weird, since it is so uncommon for that to + // happen. + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getType()->isIntegerTy(8)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(16)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(32)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(64)) + return getIntSequenceIfElementsMatch(V); + } else if (ConstantFP *CFP = dyn_cast(C)) { + if (CFP->getType()->isHalfTy()) + return getFPSequenceIfElementsMatch(V); + else if (CFP->getType()->isFloatTy()) + return getFPSequenceIfElementsMatch(V); + else if (CFP->getType()->isDoubleTy()) + return getFPSequenceIfElementsMatch(V); + } + + return nullptr; +} + ConstantArray::ConstantArray(ArrayType *T, ArrayRef V) : Constant(T, ConstantArrayVal, OperandTraits::op_end(this) - V.size(), @@ -854,6 +927,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { return C; return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V); } + Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef V) { // Empty arrays are canonicalized to ConstantAggregateZero. if (V.empty()) @@ -876,74 +950,8 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef V) { // Check to see if all of the elements are ConstantFP or ConstantInt and if // the element type is compatible with ConstantDataVector. If so, use it. - if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { - // We speculatively build the elements here even if it turns out that there - // is a constantexpr or something else weird in the array, since it is so - // uncommon for that to happen. - if (ConstantInt *CI = dyn_cast(C)) { - if (CI->getType()->isIntegerTy(8)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(16)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(32)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(64)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } - } - - if (ConstantFP *CFP = dyn_cast(C)) { - if (CFP->getType()->isFloatTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back( - CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::getFP(C->getContext(), Elts); - } else if (CFP->getType()->isDoubleTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back( - CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::getFP(C->getContext(), Elts); - } - } - } + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) + return getSequenceIfElementsMatch(C, V); // Otherwise, we really do want to create a ConstantArray. return nullptr; @@ -1039,6 +1047,7 @@ Constant *ConstantVector::get(ArrayRef V) { VectorType *Ty = VectorType::get(V.front()->getType(), V.size()); return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V); } + Constant *ConstantVector::getImpl(ArrayRef V) { assert(!V.empty() && "Vectors can't be empty"); VectorType *T = VectorType::get(V.front()->getType(), V.size()); @@ -1064,74 +1073,8 @@ Constant *ConstantVector::getImpl(ArrayRef V) { // Check to see if all of the elements are ConstantFP or ConstantInt and if // the element type is compatible with ConstantDataVector. If so, use it. - if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { - // We speculatively build the elements here even if it turns out that there - // is a constantexpr or something else weird in the array, since it is so - // uncommon for that to happen. - if (ConstantInt *CI = dyn_cast(C)) { - if (CI->getType()->isIntegerTy(8)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(16)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(32)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(64)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); - } - } - - if (ConstantFP *CFP = dyn_cast(C)) { - if (CFP->getType()->isFloatTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back( - CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::getFP(C->getContext(), Elts); - } else if (CFP->getType()->isDoubleTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back( - CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataVector::getFP(C->getContext(), Elts); - } - } - } + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) + return getSequenceIfElementsMatch(C, V); // Otherwise, the element type isn't compatible with ConstantDataVector, or // the operand list constants a ConstantExpr or something else strange. @@ -1149,6 +1092,17 @@ Constant *ConstantVector::getSplat(unsigned NumElts, Constant *V) { return get(Elts); } +ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) { + LLVMContextImpl *pImpl = Context.pImpl; + if (!pImpl->TheNoneToken) + pImpl->TheNoneToken.reset(new ConstantTokenNone(Context)); + return pImpl->TheNoneToken.get(); +} + +/// Remove the constant from the constant table. +void ConstantTokenNone::destroyConstantImpl() { + llvm_unreachable("You can't ConstantTokenNone->destroyConstantImpl()!"); +} // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into @@ -1200,8 +1154,7 @@ ArrayRef ConstantExpr::getIndices() const { } unsigned ConstantExpr::getPredicate() const { - assert(isCompare()); - return ((const CompareConstantExpr*)this)->predicate; + return cast(this)->predicate; } /// getWithOperandReplaced - Return a constant expression identical to this @@ -1224,7 +1177,7 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { /// operands replaced with the specified values. The specified array must /// have the same number of operands as our current one. Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, - bool OnlyIfReduced) const { + bool OnlyIfReduced, Type *SrcTy) const { assert(Ops.size() == getNumOperands() && "Operand count mismatch!"); // If no operands changed return self. @@ -1262,10 +1215,13 @@ Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2], OnlyIfReducedTy); - case Instruction::GetElementPtr: - return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1), - cast(this)->isInBounds(), - OnlyIfReducedTy); + case Instruction::GetElementPtr: { + auto *GEPO = cast(this); + assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType())); + return ConstantExpr::getGetElementPtr( + SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1), + GEPO->isInBounds(), OnlyIfReducedTy); + } case Instruction::ICmp: case Instruction::FCmp: return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1], @@ -1366,16 +1322,14 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { /// destroyConstant - Remove the constant from the constant table. /// -void ConstantAggregateZero::destroyConstant() { +void ConstantAggregateZero::destroyConstantImpl() { getContext().pImpl->CAZConstants.erase(getType()); - destroyConstantImpl(); } /// destroyConstant - Remove the constant from the constant table... /// -void ConstantArray::destroyConstant() { +void ConstantArray::destroyConstantImpl() { getType()->getContext().pImpl->ArrayConstants.remove(this); - destroyConstantImpl(); } @@ -1384,16 +1338,14 @@ void ConstantArray::destroyConstant() { // destroyConstant - Remove the constant from the constant table... // -void ConstantStruct::destroyConstant() { +void ConstantStruct::destroyConstantImpl() { getType()->getContext().pImpl->StructConstants.remove(this); - destroyConstantImpl(); } // destroyConstant - Remove the constant from the constant table... // -void ConstantVector::destroyConstant() { +void ConstantVector::destroyConstantImpl() { getType()->getContext().pImpl->VectorConstants.remove(this); - destroyConstantImpl(); } /// getSplatValue - If this is a splat vector constant, meaning that all of @@ -1432,7 +1384,6 @@ const APInt &Constant::getUniqueInteger() const { return cast(C)->getValue(); } - //---- ConstantPointerNull::get() implementation. // @@ -1446,10 +1397,8 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { // destroyConstant - Remove the constant from the constant table... // -void ConstantPointerNull::destroyConstant() { +void ConstantPointerNull::destroyConstantImpl() { getContext().pImpl->CPNConstants.erase(getType()); - // Free the constant and any dangling references to it. - destroyConstantImpl(); } @@ -1466,10 +1415,9 @@ UndefValue *UndefValue::get(Type *Ty) { // destroyConstant - Remove the constant from the constant table. // -void UndefValue::destroyConstant() { +void UndefValue::destroyConstantImpl() { // Free the constant and any dangling references to it. getContext().pImpl->UVConstants.erase(getType()); - destroyConstantImpl(); } //---- BlockAddress::get() implementation. @@ -1512,14 +1460,13 @@ BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { // destroyConstant - Remove the constant from the constant table. // -void BlockAddress::destroyConstant() { +void BlockAddress::destroyConstantImpl() { getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); getBasicBlock()->AdjustBlockAddressRefCount(-1); - destroyConstantImpl(); } -void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { +Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To, Use *U) { // This could be replacing either the Basic Block or the Function. In either // case, we have to remove the map entry. Function *NewF = getFunction(); @@ -1534,10 +1481,8 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { // and return early. BlockAddress *&NewBA = getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)]; - if (NewBA) { - replaceUsesOfWithOnConstantImpl(NewBA); - return; - } + if (NewBA) + return NewBA; getBasicBlock()->AdjustBlockAddressRefCount(-1); @@ -1549,6 +1494,10 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { setOperand(0, NewF); setOperand(1, NewBB); getBasicBlock()->AdjustBlockAddressRefCount(1); + + // If we just want to keep the existing value, then return null. + // Callers know that this means we shouldn't delete this value. + return nullptr; } //---- ConstantExpr::get() implementations. @@ -2050,7 +1999,8 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, ArgVec.push_back(cast(Idxs[i])); } const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - InBounds ? GEPOperator::IsInBounds : 0); + InBounds ? GEPOperator::IsInBounds : 0, None, + Ty); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); @@ -2371,28 +2321,31 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { // destroyConstant - Remove the constant from the constant table... // -void ConstantExpr::destroyConstant() { +void ConstantExpr::destroyConstantImpl() { getType()->getContext().pImpl->ExprConstants.remove(this); - destroyConstantImpl(); } const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - - -GetElementPtrConstantExpr:: -GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, - Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - OperandTraits::op_end(this) - - (IdxList.size()+1), IdxList.size()+1) { - OperandList[0] = C; +GetElementPtrConstantExpr::GetElementPtrConstantExpr( + Type *SrcElementTy, Constant *C, ArrayRef IdxList, Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + OperandTraits::op_end(this) - + (IdxList.size() + 1), + IdxList.size() + 1), + SrcElementTy(SrcElementTy) { + Op<0>() = C; + Use *OperandList = getOperandList(); for (unsigned i = 0, E = IdxList.size(); i != E; ++i) OperandList[i+1] = IdxList[i]; } +Type *GetElementPtrConstantExpr::getSourceElementType() const { + return SrcElementTy; +} + //===----------------------------------------------------------------------===// // ConstantData* implementations @@ -2412,9 +2365,9 @@ StringRef ConstantDataSequential::getRawDataValues() const { /// formed with a vector or array of the specified element type. /// ConstantDataArray only works with normal float and int types that are /// stored densely in memory, not with things like i42 or x86_f80. -bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) { - if (Ty->isFloatTy() || Ty->isDoubleTy()) return true; - if (const IntegerType *IT = dyn_cast(Ty)) { +bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) { + if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) return true; + if (auto *IT = dyn_cast(Ty)) { switch (IT->getBitWidth()) { case 8: case 16: @@ -2491,7 +2444,7 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { return *Entry = new ConstantDataVector(Ty, Slot.first().data()); } -void ConstantDataSequential::destroyConstant() { +void ConstantDataSequential::destroyConstantImpl() { // Remove the constant from the StringMap. StringMap &CDSConstants = getType()->getContext().pImpl->CDSConstants; @@ -2526,9 +2479,6 @@ void ConstantDataSequential::destroyConstant() { // If we were part of a list, make sure that we don't delete the list that is // still owned by the uniquing map. Next = nullptr; - - // Finally, actually delete it. - destroyConstantImpl(); } /// get() constructors - Return a constant with array type with an element @@ -2572,7 +2522,7 @@ Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { /// object. Constant *ConstantDataArray::getFP(LLVMContext &Context, ArrayRef Elts) { - Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size()); + Type *Ty = ArrayType::get(Type::getHalfTy(Context), Elts.size()); const char *Data = reinterpret_cast(Elts.data()); return getImpl(StringRef(const_cast(Data), Elts.size() * 2), Ty); } @@ -2688,6 +2638,11 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) { } if (ConstantFP *CFP = dyn_cast(V)) { + if (CFP->getType()->isHalfTy()) { + SmallVector Elts( + NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); + return getFP(V->getContext(), Elts); + } if (CFP->getType()->isFloatTy()) { SmallVector Elts( NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); @@ -2733,6 +2688,10 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const { switch (getElementType()->getTypeID()) { default: llvm_unreachable("Accessor can only be used when element is float/double!"); + case Type::HalfTyID: { + auto EltVal = *reinterpret_cast(EltPtr); + return APFloat(APFloat::IEEEhalf, APInt(16, EltVal)); + } case Type::FloatTyID: { auto EltVal = *reinterpret_cast(EltPtr); return APFloat(APFloat::IEEEsingle, APInt(32, EltVal)); @@ -2767,7 +2726,8 @@ double ConstantDataSequential::getElementAsDouble(unsigned Elt) const { /// Note that this has to compute a new constant to return, so it isn't as /// efficient as getElementAsInteger/Float/Double. Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const { - if (getElementType()->isFloatTy() || getElementType()->isDoubleTy()) + if (getElementType()->isHalfTy() || getElementType()->isFloatTy() || + getElementType()->isDoubleTy()) return ConstantFP::get(getContext(), getElementAsAPFloat(Elt)); return ConstantInt::get(getElementType(), getElementAsInteger(Elt)); @@ -2809,20 +2769,36 @@ Constant *ConstantDataVector::getSplatValue() const { } //===----------------------------------------------------------------------===// -// replaceUsesOfWithOnConstant implementations +// handleOperandChange implementations -/// replaceUsesOfWithOnConstant - Update this constant array to change uses of +/// Update this constant array to change uses of /// 'From' to be uses of 'To'. This must update the uniquing data structures /// etc. /// /// Note that we intentionally replace all uses of From with To here. Consider /// a large array that uses 'From' 1000 times. By handling this case all here, -/// ConstantArray::replaceUsesOfWithOnConstant is only invoked once, and that +/// ConstantArray::handleOperandChange is only invoked once, and that /// single invocation handles all 1000 uses. Handling them one at a time would /// work, but would be really slow because it would have to unique each updated /// array instance. /// -void Constant::replaceUsesOfWithOnConstantImpl(Constant *Replacement) { +void Constant::handleOperandChange(Value *From, Value *To, Use *U) { + Value *Replacement = nullptr; + switch (getValueID()) { + default: + llvm_unreachable("Not a constant!"); +#define HANDLE_CONSTANT(Name) \ + case Value::Name##Val: \ + Replacement = cast(this)->handleOperandChangeImpl(From, To, U); \ + break; +#include "llvm/IR/Value.def" + } + + // If handleOperandChangeImpl returned nullptr, then it handled + // replacing itself and we don't want to delete or replace anything else here. + if (!Replacement) + return; + // I do need to replace this with an existing value. assert(Replacement != this && "I didn't contain From!"); @@ -2833,8 +2809,39 @@ void Constant::replaceUsesOfWithOnConstantImpl(Constant *Replacement) { destroyConstant(); } -void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +Value *ConstantInt::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantFP::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantTokenNone::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *UndefValue::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantPointerNull::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantAggregateZero::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantDataSequential::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); @@ -2847,6 +2854,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, // Keep track of whether all the values in the array are "ToC". bool AllSame = true; + Use *OperandList = getOperandList(); for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { Constant *Val = cast(O->get()); if (Val == From) { @@ -2857,32 +2865,26 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, AllSame &= Val == ToC; } - if (AllSame && ToC->isNullValue()) { - replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType())); - return; - } - if (AllSame && isa(ToC)) { - replaceUsesOfWithOnConstantImpl(UndefValue::get(getType())); - return; - } + if (AllSame && ToC->isNullValue()) + return ConstantAggregateZero::get(getType()); + + if (AllSame && isa(ToC)) + return UndefValue::get(getType()); // Check for any other type of constant-folding. - if (Constant *C = getImpl(getType(), Values)) { - replaceUsesOfWithOnConstantImpl(C); - return; - } + if (Constant *C = getImpl(getType(), Values)) + return C; // Update to the new value. - if (Constant *C = getContext().pImpl->ArrayConstants.replaceOperandsInPlace( - Values, this, From, ToC, NumUpdated, U - OperandList)) - replaceUsesOfWithOnConstantImpl(C); + return getContext().pImpl->ArrayConstants.replaceOperandsInPlace( + Values, this, From, ToC, NumUpdated, U - OperandList); } -void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); + Use *OperandList = getOperandList(); unsigned OperandToUpdate = U-OperandList; assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); @@ -2913,23 +2915,18 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - if (isAllZeros) { - replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType())); - return; - } - if (isAllUndef) { - replaceUsesOfWithOnConstantImpl(UndefValue::get(getType())); - return; - } + if (isAllZeros) + return ConstantAggregateZero::get(getType()); + + if (isAllUndef) + return UndefValue::get(getType()); // Update to the new value. - if (Constant *C = getContext().pImpl->StructConstants.replaceOperandsInPlace( - Values, this, From, ToC)) - replaceUsesOfWithOnConstantImpl(C); + return getContext().pImpl->StructConstants.replaceOperandsInPlace( + Values, this, From, ToC); } -void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); @@ -2945,19 +2942,16 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Values.push_back(Val); } - if (Constant *C = getImpl(Values)) { - replaceUsesOfWithOnConstantImpl(C); - return; - } + if (Constant *C = getImpl(Values)) + return C; // Update to the new value. - if (Constant *C = getContext().pImpl->VectorConstants.replaceOperandsInPlace( - Values, this, From, ToC, NumUpdated, U - OperandList)) - replaceUsesOfWithOnConstantImpl(C); + Use *OperandList = getOperandList(); + return getContext().pImpl->VectorConstants.replaceOperandsInPlace( + Values, this, From, ToC, NumUpdated, U - OperandList); } -void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, - Use *U) { +Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV, Use *U) { assert(isa(ToV) && "Cannot make Constant refer to non-constant!"); Constant *To = cast(ToV); @@ -2973,15 +2967,13 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, } assert(NumUpdated && "I didn't contain From!"); - if (Constant *C = getWithOperands(NewOps, getType(), true)) { - replaceUsesOfWithOnConstantImpl(C); - return; - } + if (Constant *C = getWithOperands(NewOps, getType(), true)) + return C; // Update to the new value. - if (Constant *C = getContext().pImpl->ExprConstants.replaceOperandsInPlace( - NewOps, this, From, To, NumUpdated, U - OperandList)) - replaceUsesOfWithOnConstantImpl(C); + Use *OperandList = getOperandList(); + return getContext().pImpl->ExprConstants.replaceOperandsInPlace( + NewOps, this, From, To, NumUpdated, U - OperandList); } Instruction *ConstantExpr::getAsInstruction() { @@ -3028,7 +3020,7 @@ Instruction *ConstantExpr::getAsInstruction() { case Instruction::ICmp: case Instruction::FCmp: return CmpInst::Create((Instruction::OtherOps)getOpcode(), - getPredicate(), Ops[0], Ops[1]); + (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1]); default: assert(getNumOperands() == 2 && "Must be binary operator?");