if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
return true;
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(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;
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero();
+ // Equivalent for a vector of -0.0's.
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero())
+ return true;
+
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero())
+ return true;
+
// Otherwise, just use +0.0.
return isNullValue();
}
return false;
}
+bool Constant::needsRelocation() const {
+ if (isa<GlobalValue>(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<GlobalValue>(this)) {
- if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
- return LocalRelocation; // Local to this file/library.
- return GlobalRelocations; // Global reference.
- }
-
if (const BlockAddress *BA = dyn_cast<BlockAddress>(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
if (CE->getOpcode() == Instruction::Sub) {
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
- if (LHS && RHS &&
- LHS->getOpcode() == Instruction::PtrToInt &&
+ if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
RHS->getOpcode() == Instruction::PtrToInt &&
isa<BlockAddress>(LHS->getOperand(0)) &&
isa<BlockAddress>(RHS->getOperand(0)) &&
cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
- cast<BlockAddress>(RHS->getOperand(0))->getFunction())
- return NoRelocation;
+ cast<BlockAddress>(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<Constant>(getOperand(i))->getRelocationInfo());
+ Result |= cast<Constant>(getOperand(i))->needsRelocation();
return Result;
}
return true;
}
+template <typename SequentialTy, typename ElementTy>
+static Constant *getIntSequenceIfElementsMatch(ArrayRef<Constant *> V) {
+ assert(!V.empty() && "Cannot get empty int sequence.");
+
+ SmallVector<ElementTy, 16> Elts;
+ for (Constant *C : V)
+ if (auto *CI = dyn_cast<ConstantInt>(C))
+ Elts.push_back(CI->getZExtValue());
+ else
+ return nullptr;
+ return SequentialTy::get(V[0]->getContext(), Elts);
+}
+
+template <typename SequentialTy, typename ElementTy>
+static Constant *getFPSequenceIfElementsMatch(ArrayRef<Constant *> V) {
+ assert(!V.empty() && "Cannot get empty FP sequence.");
+
+ SmallVector<ElementTy, 16> Elts;
+ for (Constant *C : V)
+ if (auto *CFP = dyn_cast<ConstantFP>(C))
+ Elts.push_back(CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ else
+ return nullptr;
+ return SequentialTy::getFP(V[0]->getContext(), Elts);
+}
+
+template <typename SequenceTy>
+static Constant *getSequenceIfElementsMatch(Constant *C,
+ ArrayRef<Constant *> 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<ConstantInt>(C)) {
+ if (CI->getType()->isIntegerTy(8))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint8_t>(V);
+ else if (CI->getType()->isIntegerTy(16))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
+ else if (CI->getType()->isIntegerTy(32))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
+ else if (CI->getType()->isIntegerTy(64))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
+ } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ if (CFP->getType()->isHalfTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
+ else if (CFP->getType()->isFloatTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
+ else if (CFP->getType()->isDoubleTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
+ }
+
+ return nullptr;
+}
+
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
: Constant(T, ConstantArrayVal,
OperandTraits<ConstantArray>::op_end(this) - V.size(),
return C;
return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V);
}
+
Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
// Empty arrays are canonicalized to ConstantAggregateZero.
if (V.empty())
// 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<ConstantInt>(C)) {
- if (CI->getType()->isIntegerTy(8)) {
- SmallVector<uint8_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint16_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<ConstantFP>(C)) {
- if (CFP->getType()->isFloatTy()) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(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<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(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<ConstantDataArray>(C, V);
// Otherwise, we really do want to create a ConstantArray.
return nullptr;
VectorType *Ty = VectorType::get(V.front()->getType(), V.size());
return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V);
}
+
Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
assert(!V.empty() && "Vectors can't be empty");
VectorType *T = VectorType::get(V.front()->getType(), V.size());
// 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<ConstantInt>(C)) {
- if (CI->getType()->isIntegerTy(8)) {
- SmallVector<uint8_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint16_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(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<ConstantFP>(C)) {
- if (CFP->getType()->isFloatTy()) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(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<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(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<ConstantDataVector>(C, V);
// Otherwise, the element type isn't compatible with ConstantDataVector, or
// the operand list constants a ConstantExpr or something else strange.
ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {
LLVMContextImpl *pImpl = Context.pImpl;
if (!pImpl->TheNoneToken)
- pImpl->TheNoneToken = new ConstantTokenNone(Context);
- return pImpl->TheNoneToken;
+ pImpl->TheNoneToken.reset(new ConstantTokenNone(Context));
+ return pImpl->TheNoneToken.get();
}
/// Remove the constant from the constant table.
}
unsigned ConstantExpr::getPredicate() const {
- assert(isCompare());
- return ((const CompareConstantExpr*)this)->predicate;
+ return cast<CompareConstantExpr>(this)->predicate;
}
/// getWithOperandReplaced - Return a constant expression identical to this
/// 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(Type *Ty) {
- if (Ty->isFloatTy() || Ty->isDoubleTy()) return true;
+ if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) return true;
if (auto *IT = dyn_cast<IntegerType>(Ty)) {
switch (IT->getBitWidth()) {
case 8:
/// object.
Constant *ConstantDataArray::getFP(LLVMContext &Context,
ArrayRef<uint16_t> Elts) {
- Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size());
+ Type *Ty = ArrayType::get(Type::getHalfTy(Context), Elts.size());
const char *Data = reinterpret_cast<const char *>(Elts.data());
return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 2), Ty);
}
}
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
+ if (CFP->getType()->isHalfTy()) {
+ SmallVector<uint16_t, 16> Elts(
+ NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ return getFP(V->getContext(), Elts);
+ }
if (CFP->getType()->isFloatTy()) {
SmallVector<uint32_t, 16> Elts(
NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
switch (getElementType()->getTypeID()) {
default:
llvm_unreachable("Accessor can only be used when element is float/double!");
+ case Type::HalfTyID: {
+ auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
+ return APFloat(APFloat::IEEEhalf, APInt(16, EltVal));
+ }
case Type::FloatTyID: {
auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
return APFloat(APFloat::IEEEsingle, APInt(32, EltVal));
/// 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));
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?");