aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp57
1 files changed, 51 insertions, 6 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index c66cfb6e9ac1..837be910f6d8 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -535,6 +535,9 @@ void llvm::deleteConstant(Constant *C) {
case Constant::DSOLocalEquivalentVal:
delete static_cast<DSOLocalEquivalent *>(C);
break;
+ case Constant::NoCFIValueVal:
+ delete static_cast<NoCFIValue *>(C);
+ break;
case Constant::UndefValueVal:
delete static_cast<UndefValue *>(C);
break;
@@ -1296,9 +1299,10 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
if (V.empty())
return ConstantAggregateZero::get(Ty);
- for (unsigned i = 0, e = V.size(); i != e; ++i) {
- assert(V[i]->getType() == Ty->getElementType() &&
+ for (Constant *C : V) {
+ assert(C->getType() == Ty->getElementType() &&
"Wrong type in array element initializer");
+ (void)C;
}
// If this is an all-zero array, return a ConstantAggregateZero object. If
@@ -1364,12 +1368,12 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
isZero = V[0]->isNullValue();
// PoisonValue inherits UndefValue, so its check is not necessary.
if (isUndef || isZero) {
- for (unsigned i = 0, e = V.size(); i != e; ++i) {
- if (!V[i]->isNullValue())
+ for (Constant *C : V) {
+ if (!C->isNullValue())
isZero = false;
- if (!isa<PoisonValue>(V[i]))
+ if (!isa<PoisonValue>(C))
isPoison = false;
- if (isa<PoisonValue>(V[i]) || !isa<UndefValue>(V[i]))
+ if (isa<PoisonValue>(C) || !isa<UndefValue>(C))
isUndef = false;
}
}
@@ -1962,6 +1966,47 @@ Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {
return nullptr;
}
+NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
+ NoCFIValue *&NC = GV->getContext().pImpl->NoCFIValues[GV];
+ if (!NC)
+ NC = new NoCFIValue(GV);
+
+ assert(NC->getGlobalValue() == GV &&
+ "NoCFIValue does not match the expected global value");
+ return NC;
+}
+
+NoCFIValue::NoCFIValue(GlobalValue *GV)
+ : Constant(GV->getType(), Value::NoCFIValueVal, &Op<0>(), 1) {
+ setOperand(0, GV);
+}
+
+/// Remove the constant from the constant table.
+void NoCFIValue::destroyConstantImpl() {
+ const GlobalValue *GV = getGlobalValue();
+ GV->getContext().pImpl->NoCFIValues.erase(GV);
+}
+
+Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {
+ assert(From == getGlobalValue() && "Changing value does not match operand.");
+
+ GlobalValue *GV = dyn_cast<GlobalValue>(To->stripPointerCasts());
+ assert(GV && "Can only replace the operands with a global value");
+
+ NoCFIValue *&NewNC = getContext().pImpl->NoCFIValues[GV];
+ if (NewNC)
+ return llvm::ConstantExpr::getBitCast(NewNC, getType());
+
+ getContext().pImpl->NoCFIValues.erase(getGlobalValue());
+ NewNC = this;
+ setOperand(0, GV);
+
+ if (GV->getType() != getType())
+ mutateType(GV->getType());
+
+ return nullptr;
+}
+
//---- ConstantExpr::get() implementations.
//