diff options
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
| -rw-r--r-- | llvm/lib/IR/Constants.cpp | 57 | 
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.  //  | 
