From fc16153e104c53dcfd54e79eee6549820a8a12f4 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Tue, 1 Dec 2015 20:20:49 +0000 Subject: [PATCH] IR: Clean up some duplicated code in ConstantDataSequential creation. NFC ConstantDataArray::getImpl and ConstantDataVector::getImpl had a lot of copy pasta in how they handled sequences of constants. Break that out into a couple of simple functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254456 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Constants.cpp | 193 +++++++++++++------------------------------ 1 file changed, 57 insertions(+), 136 deletions(-) diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index d79fb3e7b0b..b4a07a1b6b4 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -857,6 +857,57 @@ static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) { return true; } +template +static Constant *getIntSequenceIfElementsMatch(ArrayRef V) { + assert(!V.empty() && "Cannot get empty int sequence."); + + SmallVector Elts; + for (Constant *C : V) + if (auto *CI = dyn_cast(C)) + Elts.push_back(CI->getZExtValue()); + else + return nullptr; + return SequentialTy::get(V[0]->getContext(), Elts); +} + +template +static Constant *getFPSequenceIfElementsMatch(ArrayRef V) { + assert(!V.empty() && "Cannot get empty FP sequence."); + + SmallVector Elts; + for (Constant *C : V) + if (auto *CFP = dyn_cast(C)) + Elts.push_back(CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); + else + return nullptr; + return SequentialTy::getFP(V[0]->getContext(), Elts); +} + +template +static Constant *getSequenceIfElementsMatch(Constant *C, + ArrayRef 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(C)) { + if (CI->getType()->isIntegerTy(8)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(16)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(32)) + return getIntSequenceIfElementsMatch(V); + else if (CI->getType()->isIntegerTy(64)) + return getIntSequenceIfElementsMatch(V); + } else if (ConstantFP *CFP = dyn_cast(C)) { + if (CFP->getType()->isFloatTy()) + return getFPSequenceIfElementsMatch(V); + else if (CFP->getType()->isDoubleTy()) + return getFPSequenceIfElementsMatch(V); + } + + return nullptr; +} + ConstantArray::ConstantArray(ArrayType *T, ArrayRef V) : Constant(T, ConstantArrayVal, OperandTraits::op_end(this) - V.size(), @@ -874,6 +925,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { return C; return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V); } + Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef V) { // Empty arrays are canonicalized to ConstantAggregateZero. if (V.empty()) @@ -896,74 +948,8 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef V) { // 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(C)) { - if (CI->getType()->isIntegerTy(8)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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(C)) { - if (CFP->getType()->isFloatTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(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(C, V); // Otherwise, we really do want to create a ConstantArray. return nullptr; @@ -1059,6 +1045,7 @@ Constant *ConstantVector::get(ArrayRef V) { VectorType *Ty = VectorType::get(V.front()->getType(), V.size()); return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V); } + Constant *ConstantVector::getImpl(ArrayRef V) { assert(!V.empty() && "Vectors can't be empty"); VectorType *T = VectorType::get(V.front()->getType(), V.size()); @@ -1084,74 +1071,8 @@ Constant *ConstantVector::getImpl(ArrayRef V) { // 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(C)) { - if (CI->getType()->isIntegerTy(8)) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(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(C)) { - if (CFP->getType()->isFloatTy()) { - SmallVector Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(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 Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast(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(C, V); // Otherwise, the element type isn't compatible with ConstantDataVector, or // the operand list constants a ConstantExpr or something else strange. -- 2.34.1