Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -948,111 +948,17 @@ canEmitInitWithFewStoresAfterBZero(Init, StoreBudget); } -/// A byte pattern. -/// -/// Can be "any" pattern if the value was padding or known to be undef. -/// Can be "none" pattern if a sequence doesn't exist. -class BytePattern { - uint8_t Val; - enum class ValueType : uint8_t { Specific, Any, None } Type; - BytePattern(ValueType Type) : Type(Type) {} - -public: - BytePattern(uint8_t Value) : Val(Value), Type(ValueType::Specific) {} - static BytePattern Any() { return BytePattern(ValueType::Any); } - static BytePattern None() { return BytePattern(ValueType::None); } - bool isAny() const { return Type == ValueType::Any; } - bool isNone() const { return Type == ValueType::None; } - bool isValued() const { return Type == ValueType::Specific; } - uint8_t getValue() const { - assert(isValued()); - return Val; - } - BytePattern merge(const BytePattern Other) const { - if (isNone() || Other.isNone()) - return None(); - if (isAny()) - return Other; - if (Other.isAny()) - return *this; - if (getValue() == Other.getValue()) - return *this; - return None(); - } -}; - -/// Figures out whether the constant can be initialized with memset. -static BytePattern constantIsRepeatedBytePattern(llvm::Constant *C) { - if (isa(C) || isa(C)) - return BytePattern(0x00); - if (isa(C)) - return BytePattern::Any(); - - if (isa(C)) { - auto *Int = cast(C); - if (Int->getBitWidth() % 8 != 0) - return BytePattern::None(); - const llvm::APInt &Value = Int->getValue(); - if (Value.isSplat(8)) - return BytePattern(Value.getLoBits(8).getLimitedValue()); - return BytePattern::None(); - } - - if (isa(C)) { - auto *FP = cast(C); - llvm::APInt Bits = FP->getValueAPF().bitcastToAPInt(); - if (Bits.getBitWidth() % 8 != 0) - return BytePattern::None(); - if (!Bits.isSplat(8)) - return BytePattern::None(); - return BytePattern(Bits.getLimitedValue() & 0xFF); - } - - if (isa(C)) { - llvm::Constant *Splat = cast(C)->getSplatValue(); - if (Splat) - return constantIsRepeatedBytePattern(Splat); - return BytePattern::None(); - } - - if (isa(C) || isa(C)) { - BytePattern Pattern(BytePattern::Any()); - for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) { - llvm::Constant *Elt = cast(C->getOperand(I)); - Pattern = Pattern.merge(constantIsRepeatedBytePattern(Elt)); - if (Pattern.isNone()) - return Pattern; - } - return Pattern; - } - - if (llvm::ConstantDataSequential *CDS = - dyn_cast(C)) { - BytePattern Pattern(BytePattern::Any()); - for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { - llvm::Constant *Elt = CDS->getElementAsConstant(I); - Pattern = Pattern.merge(constantIsRepeatedBytePattern(Elt)); - if (Pattern.isNone()) - return Pattern; - } - return Pattern; - } - - // BlockAddress, ConstantExpr, and everything else is scary. - return BytePattern::None(); -} - /// Decide whether we should use memset to initialize a local variable instead /// of using a memcpy from a constant global. Assumes we've already decided to /// not user bzero. /// FIXME We could be more clever, as we are for bzero above, and generate /// memset followed by stores. It's unclear that's worth the effort. -static BytePattern shouldUseMemSetToInitialize(llvm::Constant *Init, - uint64_t GlobalSize) { +static llvm::Constant::BytePattern +shouldUseMemSetToInitialize(llvm::Constant *Init, uint64_t GlobalSize) { uint64_t SizeLimit = 32; if (GlobalSize <= SizeLimit) - return BytePattern::None(); - return constantIsRepeatedBytePattern(Init); + return llvm::Constant::BytePattern::None(); + return Init->isRepeatedBytePattern(); } static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, @@ -1081,7 +987,8 @@ return; } - BytePattern Pattern = shouldUseMemSetToInitialize(constant, ConstantSize); + llvm::Constant::BytePattern Pattern = + shouldUseMemSetToInitialize(constant, ConstantSize); if (!Pattern.isNone()) { uint8_t Value = Pattern.isAny() ? 0x00 : Pattern.getValue(); Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, Value), SizeVal,