llvm.org GIT mirror llvm / e150e2d
Add a ConstantDataVector::getSplatValue() method, for parity with ConstantVector. Fix some outright bugs in the implementation of ConstantArray and Constant struct, which would cause us to not make one big UndefValue when asking for an array/struct with all undef elements. Enhance Constant::isAllOnesValue to work with ConstantDataVector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149021 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 7 years ago
2 changed file(s) with 92 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
765765 /// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
766766 static Constant *getSplat(unsigned NumElts, Constant *Elt);
767767
768 /// getSplatValue - If this is a splat constant, meaning that all of the
769 /// elements have the same value, return that value. Otherwise return NULL.
770 Constant *getSplatValue() const;
771
768772 /// getType - Specialize the getType() method to always return a VectorType,
769773 /// which reduces the amount of casting needed in parts of the compiler.
770774 ///
7474
7575 // Check for constant vectors which are splats of -1 values.
7676 if (const ConstantVector *CV = dyn_cast(this))
77 if (Constant *Splat = CV->getSplatValue())
78 return Splat->isAllOnesValue();
79
80 // Check for constant vectors which are splats of -1 values.
81 if (const ConstantDataVector *CV = dyn_cast(this))
7782 if (Constant *Splat = CV->getSplatValue())
7883 return Splat->isAllOnesValue();
7984
710715 }
711716 LLVMContextImpl *pImpl = Ty->getContext().pImpl;
712717 // If this is an all-zero array, return a ConstantAggregateZero object
718 bool isAllZero = true;
719 bool isUndef = false;
713720 if (!V.empty()) {
714721 Constant *C = V[0];
715 if (!C->isNullValue())
716 return pImpl->ArrayConstants.getOrCreate(Ty, V);
717
718 for (unsigned i = 1, e = V.size(); i != e; ++i)
719 if (V[i] != C)
720 return pImpl->ArrayConstants.getOrCreate(Ty, V);
721 }
722
723 return ConstantAggregateZero::get(Ty);
722 isAllZero = C->isNullValue();
723 isUndef = isa(C);
724
725 if (isAllZero || isUndef)
726 for (unsigned i = 1, e = V.size(); i != e; ++i)
727 if (V[i] != C) {
728 isAllZero = false;
729 isUndef = false;
730 break;
731 }
732 }
733
734 if (isAllZero)
735 return ConstantAggregateZero::get(Ty);
736 if (isUndef)
737 return UndefValue::get(Ty);
738 return pImpl->ArrayConstants.getOrCreate(Ty, V);
724739 }
725740
726741 /// ConstantArray::get(const string&) - Return an array that is initialized to
779794
780795 // ConstantStruct accessors.
781796 Constant *ConstantStruct::get(StructType *ST, ArrayRef V) {
782 // Create a ConstantAggregateZero value if all elements are zeros.
783 for (unsigned i = 0, e = V.size(); i != e; ++i)
784 if (!V[i]->isNullValue())
785 return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
786
787797 assert((ST->isOpaque() || ST->getNumElements() == V.size()) &&
788798 "Incorrect # elements specified to ConstantStruct::get");
789 return ConstantAggregateZero::get(ST);
799
800 // Create a ConstantAggregateZero value if all elements are zeros.
801 bool isZero = true;
802 bool isUndef = false;
803
804 if (!V.empty()) {
805 isUndef = isa(V[0]);
806 isZero = V[0]->isNullValue();
807 if (isUndef || isZero) {
808 for (unsigned i = 0, e = V.size(); i != e; ++i) {
809 if (!V[i]->isNullValue())
810 isZero = false;
811 if (!isa(V[i]))
812 isUndef = false;
813 }
814 }
815 }
816 if (isZero)
817 return ConstantAggregateZero::get(ST);
818 if (isUndef)
819 return UndefValue::get(ST);
820
821 return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
790822 }
791823
792824 Constant *ConstantStruct::get(StructType *T, ...) {
23282360 return Str.drop_back().find(0) == StringRef::npos;
23292361 }
23302362
2363 /// getSplatValue - If this is a splat constant, meaning that all of the
2364 /// elements have the same value, return that value. Otherwise return NULL.
2365 Constant *ConstantDataVector::getSplatValue() const {
2366 const char *Base = getRawDataValues().data();
2367
2368 // Compare elements 1+ to the 0'th element.
2369 unsigned EltSize = getElementByteSize();
2370 for (unsigned i = 1, e = getNumElements(); i != e; ++i)
2371 if (memcmp(Base, Base+i*EltSize, EltSize))
2372 return 0;
2373
2374 // If they're all the same, return the 0th one as a representative.
2375 return getElementAsConstant(0);
2376 }
23312377
23322378 //===----------------------------------------------------------------------===//
23332379 // replaceUsesOfWithOnConstant implementations
23592405
23602406 // Fill values with the modified operands of the constant array. Also,
23612407 // compute whether this turns into an all-zeros array.
2362 bool isAllZeros = false;
23632408 unsigned NumUpdated = 0;
2364 if (!ToC->isNullValue()) {
2365 for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
2366 Constant *Val = cast(O->get());
2367 if (Val == From) {
2368 Val = ToC;
2369 ++NumUpdated;
2370 }
2371 Values.push_back(Val);
2409
2410 // Keep track of whether all the values in the array are "ToC".
2411 bool AllSame = true;
2412 for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
2413 Constant *Val = cast(O->get());
2414 if (Val == From) {
2415 Val = ToC;
2416 ++NumUpdated;
23722417 }
2373 } else {
2374 isAllZeros = true;
2375 for (Use *O = OperandList, *E = OperandList+getNumOperands();O != E; ++O) {
2376 Constant *Val = cast(O->get());
2377 if (Val == From) {
2378 Val = ToC;
2379 ++NumUpdated;
2380 }
2381 Values.push_back(Val);
2382 if (isAllZeros) isAllZeros = Val->isNullValue();
2383 }
2418 Values.push_back(Val);
2419 AllSame = Val == ToC;
23842420 }
23852421
23862422 Constant *Replacement = 0;
2387 if (isAllZeros) {
2423 if (AllSame && ToC->isNullValue()) {
23882424 Replacement = ConstantAggregateZero::get(getType());
2425 } else if (AllSame && isa(ToC)) {
2426 Replacement = UndefValue::get(getType());
23892427 } else {
23902428 // Check to see if we have this array type already.
23912429 bool Exists;
24452483 // Fill values with the modified operands of the constant struct. Also,
24462484 // compute whether this turns into an all-zeros struct.
24472485 bool isAllZeros = false;
2448 if (!ToC->isNullValue()) {
2449 for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O)
2450 Values.push_back(cast(O->get()));
2451 } else {
2486 bool isAllUndef = false;
2487 if (ToC->isNullValue()) {
24522488 isAllZeros = true;
24532489 for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
24542490 Constant *Val = cast(O->get());
24552491 Values.push_back(Val);
24562492 if (isAllZeros) isAllZeros = Val->isNullValue();
24572493 }
2494 } else if (isa(ToC)) {
2495 isAllUndef = true;
2496 for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
2497 Constant *Val = cast(O->get());
2498 Values.push_back(Val);
2499 if (isAllUndef) isAllUndef = isa(Val);
2500 }
2501 } else {
2502 for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O)
2503 Values.push_back(cast(O->get()));
24582504 }
24592505 Values[OperandToUpdate] = ToC;
24602506
24632509 Constant *Replacement = 0;
24642510 if (isAllZeros) {
24652511 Replacement = ConstantAggregateZero::get(getType());
2512 } else if (isAllUndef) {
2513 Replacement = UndefValue::get(getType());
24662514 } else {
24672515 // Check to see if we have this struct type already.
24682516 bool Exists;