diff options
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 33 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstructionCombining.cpp | 24 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 15 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 47 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 449 |
5 files changed, 149 insertions, 419 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 6e8b434..4a98b3b 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2176,21 +2176,9 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, std::vector<Constant*> Elts; if (StructType *STy = dyn_cast<StructType>(Init->getType())) { - // Break up the constant into its elements. - if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Init)) { - for (User::op_iterator i = CS->op_begin(), e = CS->op_end(); i != e; ++i) - Elts.push_back(cast<Constant>(*i)); - } else if (isa<ConstantAggregateZero>(Init)) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) - Elts.push_back(Constant::getNullValue(STy->getElementType(i))); - } else if (isa<UndefValue>(Init)) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) - Elts.push_back(UndefValue::get(STy->getElementType(i))); - } else { - llvm_unreachable("This code is out of sync with " - " ConstantFoldLoadThroughGEPConstantExpr"); - } + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + Elts.push_back(Init->getAggregateElement(i)); // Replace the element that we are supposed to. ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo)); @@ -2209,22 +2197,11 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, if (ArrayType *ATy = dyn_cast<ArrayType>(InitTy)) NumElts = ATy->getNumElements(); else - NumElts = cast<VectorType>(InitTy)->getNumElements(); + NumElts = InitTy->getVectorNumElements(); // Break up the array into elements. - if (ConstantArray *CA = dyn_cast<ConstantArray>(Init)) { - for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) - Elts.push_back(cast<Constant>(*i)); - } else if (ConstantVector *CV = dyn_cast<ConstantVector>(Init)) { - for (User::op_iterator i = CV->op_begin(), e = CV->op_end(); i != e; ++i) - Elts.push_back(cast<Constant>(*i)); - } else if (isa<ConstantAggregateZero>(Init)) { - Elts.assign(NumElts, Constant::getNullValue(InitTy->getElementType())); - } else { - assert(isa<UndefValue>(Init) && "This code is out of sync with " - " ConstantFoldLoadThroughGEPConstantExpr"); - Elts.assign(NumElts, UndefValue::get(InitTy->getElementType())); - } + for (uint64_t i = 0, e = NumElts; i != e; ++i) + Elts.push_back(Init->getAggregateElement(i)); assert(CI->getZExtValue() < NumElts); Elts[CI->getZExtValue()] = diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index af065cd..86e491b 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1270,24 +1270,16 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) { return ReplaceInstUsesWith(EV, Agg); if (Constant *C = dyn_cast<Constant>(Agg)) { - if (isa<UndefValue>(C)) - return ReplaceInstUsesWith(EV, UndefValue::get(EV.getType())); - - if (isa<ConstantAggregateZero>(C)) - return ReplaceInstUsesWith(EV, Constant::getNullValue(EV.getType())); - - if (isa<ConstantArray>(C) || isa<ConstantStruct>(C)) { - // Extract the element indexed by the first index out of the constant - Value *V = C->getOperand(*EV.idx_begin()); - if (EV.getNumIndices() > 1) - // Extract the remaining indices out of the constant indexed by the - // first index - return ExtractValueInst::Create(V, EV.getIndices().slice(1)); - else - return ReplaceInstUsesWith(EV, V); + if (Constant *C2 = C->getAggregateElement(*EV.idx_begin())) { + if (EV.getNumIndices() == 0) + return ReplaceInstUsesWith(EV, C2); + // Extract the remaining indices out of the constant indexed by the + // first index + return ExtractValueInst::Create(C2, EV.getIndices().slice(1)); } return 0; // Can't handle other constants - } + } + if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) { // We're extracting from an insertvalue instruction, compare the indices const unsigned *exti, *exte, *insi, *inse; diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index c4fc38a..1f8f452 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -408,15 +408,14 @@ private: return LV; // Common case, already in the map. if (Constant *C = dyn_cast<Constant>(V)) { - if (isa<UndefValue>(C)) - ; // Undef values remain undefined. - else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) - LV.markConstant(CS->getOperand(i)); // Constants are constant. - else if (isa<ConstantAggregateZero>(C)) { - Type *FieldTy = cast<StructType>(V->getType())->getElementType(i); - LV.markConstant(Constant::getNullValue(FieldTy)); - } else + Constant *Elt = C->getAggregateElement(i); + + if (Elt == 0) LV.markOverdefined(); // Unknown sort of constant. + else if (isa<UndefValue>(Elt)) + ; // Undef values remain undefined. + else + LV.markConstant(Elt); // Constants are constant. } // All others are underdefined by default. diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 0eb45c5..4d5e7a5 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -855,6 +855,37 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } return; } + + if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) { + // As a special case, print the array as a string if it is an array of + // i8 with ConstantInt values. + if (CA->isString()) { + Out << "c\""; + PrintEscapedString(CA->getAsString(), Out); + Out << '"'; + return; + } + + Type *ETy = CA->getType()->getElementType(); + Out << '['; + if (CA->getNumOperands()) { + TypePrinter.print(ETy, Out); + Out << ' '; + WriteAsOperandInternal(Out, CA->getElementAsConstant(0), + &TypePrinter, Machine, + Context); + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { + Out << ", "; + TypePrinter.print(ETy, Out); + Out << ' '; + WriteAsOperandInternal(Out, CA->getElementAsConstant(i), &TypePrinter, + Machine, Context); + } + Out << ']'; + } + return; + } + if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) { if (CS->getType()->isPacked()) @@ -886,21 +917,19 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } - if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { - Type *ETy = CP->getType()->getElementType(); - assert(CP->getNumOperands() > 0 && - "Number of operands for a PackedConst must be > 0"); + if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) { + Type *ETy = CV->getType()->getVectorElementType(); Out << '<'; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine, - Context); - for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { + WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter, + Machine, Context); + for (unsigned i = 1, e = CV->getType()->getVectorNumElements(); i != e;++i){ Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine, - Context); + WriteAsOperandInternal(Out, CV->getAggregateElement(i), &TypePrinter, + Machine, Context); } Out << '>'; return; diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 81ad205..9a3a991 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -38,11 +38,10 @@ using namespace llvm; // ConstantFold*Instruction Implementations //===----------------------------------------------------------------------===// -/// BitCastConstantVector - Convert the specified ConstantVector node to the +/// BitCastConstantVector - Convert the specified vector Constant node to the /// specified vector type. At this point, we know that the elements of the /// input vector constant are all simple integer or FP values. -static Constant *BitCastConstantVector(ConstantVector *CV, - VectorType *DstTy) { +static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) { if (CV->isAllOnesValue()) return Constant::getAllOnesValue(DstTy); if (CV->isNullValue()) return Constant::getNullValue(DstTy); @@ -51,22 +50,21 @@ static Constant *BitCastConstantVector(ConstantVector *CV, // doing so requires endianness information. This should be handled by // Analysis/ConstantFolding.cpp unsigned NumElts = DstTy->getNumElements(); - if (NumElts != CV->getNumOperands()) + if (NumElts != CV->getType()->getVectorNumElements()) return 0; + + Type *DstEltTy = DstTy->getElementType(); // Check to verify that all elements of the input are simple. + SmallVector<Constant*, 16> Result; for (unsigned i = 0; i != NumElts; ++i) { - if (!isa<ConstantInt>(CV->getOperand(i)) && - !isa<ConstantFP>(CV->getOperand(i))) - return 0; + Constant *C = CV->getAggregateElement(i); + if (C == 0) return 0; + C = ConstantExpr::getBitCast(C, DstEltTy); + if (isa<ConstantExpr>(C)) return 0; + Result.push_back(C); } - // Bitcast each element now. - std::vector<Constant*> Result; - Type *DstEltTy = DstTy->getElementType(); - for (unsigned i = 0; i != NumElts; ++i) - Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), - DstEltTy)); return ConstantVector::get(Result); } @@ -142,8 +140,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { if (isa<ConstantAggregateZero>(V)) return Constant::getNullValue(DestTy); - if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) - return BitCastConstantVector(CV, DestPTy); + // Handle ConstantVector and ConstantAggregateVector. + return BitCastConstantVector(V, DestPTy); } // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts @@ -692,42 +690,26 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2) { - if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) - return CB->getZExtValue() ? V1 : V2; - - // Check for zero aggregate and ConstantVector of zeros + // Check for i1 and vector true/false conditions. if (Cond->isNullValue()) return V2; - - if (ConstantVector* CondV = dyn_cast<ConstantVector>(Cond)) { - - if (CondV->isAllOnesValue()) return V1; - - VectorType *VTy = cast<VectorType>(V1->getType()); - ConstantVector *CP1 = dyn_cast<ConstantVector>(V1); - ConstantVector *CP2 = dyn_cast<ConstantVector>(V2); - - if ((CP1 || isa<ConstantAggregateZero>(V1)) && - (CP2 || isa<ConstantAggregateZero>(V2))) { - - // Find the element type of the returned vector - Type *EltTy = VTy->getElementType(); - unsigned NumElem = VTy->getNumElements(); - std::vector<Constant*> Res(NumElem); - - bool Valid = true; - for (unsigned i = 0; i < NumElem; ++i) { - ConstantInt* c = dyn_cast<ConstantInt>(CondV->getOperand(i)); - if (!c) { - Valid = false; - break; - } - Constant *C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - Constant *C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res[i] = c->getZExtValue() ? C1 : C2; - } - // If we were able to build the vector, return it - if (Valid) return ConstantVector::get(Res); + if (Cond->isAllOnesValue()) return V1; + + // FIXME: CDV Condition. + // If the condition is a vector constant, fold the result elementwise. + if (ConstantVector *CondV = dyn_cast<ConstantVector>(Cond)) { + SmallVector<Constant*, 16> Result; + for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){ + ConstantInt *Cond = dyn_cast<ConstantInt>(CondV->getOperand(i)); + if (Cond == 0) break; + + Constant *Res = (Cond->getZExtValue() ? V2 : V1)->getAggregateElement(i); + if (Res == 0) break; + Result.push_back(Res); } + + // If we were able to build the vector, return it. + if (Result.size() == V1->getType()->getVectorNumElements()) + return ConstantVector::get(Result); } @@ -781,70 +763,22 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, Constant *Idx) { ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); if (!CIdx) return 0; - APInt idxVal = CIdx->getValue(); - if (isa<UndefValue>(Val)) { - // Insertion of scalar constant into vector undef - // Optimize away insertion of undef - if (isa<UndefValue>(Elt)) - return Val; - // Otherwise break the aggregate undef into multiple undefs and do - // the insertion - unsigned numOps = - cast<VectorType>(Val->getType())->getNumElements(); - std::vector<Constant*> Ops; - Ops.reserve(numOps); - for (unsigned i = 0; i < numOps; ++i) { - Constant *Op = - (idxVal == i) ? Elt : UndefValue::get(Elt->getType()); - Ops.push_back(Op); - } - return ConstantVector::get(Ops); - } - if (isa<ConstantAggregateZero>(Val)) { - // Insertion of scalar constant into vector aggregate zero - // Optimize away insertion of zero - if (Elt->isNullValue()) - return Val; - // Otherwise break the aggregate zero into multiple zeros and do - // the insertion - unsigned numOps = - cast<VectorType>(Val->getType())->getNumElements(); - std::vector<Constant*> Ops; - Ops.reserve(numOps); - for (unsigned i = 0; i < numOps; ++i) { - Constant *Op = - (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType()); - Ops.push_back(Op); - } - return ConstantVector::get(Ops); - } - if (ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) { - // Insertion of scalar constant into vector constant - std::vector<Constant*> Ops; - Ops.reserve(CVal->getNumOperands()); - for (unsigned i = 0; i < CVal->getNumOperands(); ++i) { - Constant *Op = - (idxVal == i) ? Elt : cast<Constant>(CVal->getOperand(i)); - Ops.push_back(Op); + const APInt &IdxVal = CIdx->getValue(); + + SmallVector<Constant*, 16> Result; + for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){ + if (i == IdxVal) { + Result.push_back(Elt); + continue; } - return ConstantVector::get(Ops); + + if (Constant *C = Val->getAggregateElement(i)) + Result.push_back(C); + else + return 0; } - - return 0; -} - -/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef -/// return the specified element value. Otherwise return null. -static Constant *GetVectorElement(Constant *C, unsigned EltNo) { - if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) - return CV->getOperand(EltNo); - - Type *EltTy = cast<VectorType>(C->getType())->getElementType(); - if (isa<ConstantAggregateZero>(C)) - return Constant::getNullValue(EltTy); - if (isa<UndefValue>(C)) - return UndefValue::get(EltTy); - return 0; + + return ConstantVector::get(Result); } Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, @@ -860,24 +794,21 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, // Loop over the shuffle mask, evaluating each element. SmallVector<Constant*, 32> Result; for (unsigned i = 0; i != MaskNumElts; ++i) { - Constant *InElt = GetVectorElement(Mask, i); + Constant *InElt = Mask->getAggregateElement(i); if (InElt == 0) return 0; - if (isa<UndefValue>(InElt)) - InElt = UndefValue::get(EltTy); - else if (ConstantInt *CI = dyn_cast<ConstantInt>(InElt)) { - unsigned Elt = CI->getZExtValue(); - if (Elt >= SrcNumElts*2) - InElt = UndefValue::get(EltTy); - else if (Elt >= SrcNumElts) - InElt = GetVectorElement(V2, Elt - SrcNumElts); - else - InElt = GetVectorElement(V1, Elt); - if (InElt == 0) return 0; - } else { - // Unknown value. - return 0; + if (isa<UndefValue>(InElt)) { + Result.push_back(UndefValue::get(EltTy)); + continue; } + unsigned Elt = cast<ConstantInt>(InElt)->getZExtValue(); + if (Elt >= SrcNumElts*2) + InElt = UndefValue::get(EltTy); + else if (Elt >= SrcNumElts) + InElt = V2->getAggregateElement(Elt - SrcNumElts); + else + InElt = V1->getAggregateElement(Elt); + if (InElt == 0) return 0; Result.push_back(InElt); } @@ -890,26 +821,10 @@ Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg, if (Idxs.empty()) return Agg; - if (isa<UndefValue>(Agg)) // ev(undef, x) -> undef - return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(), - Idxs)); - - if (isa<ConstantAggregateZero>(Agg)) // ev(0, x) -> 0 - return - Constant::getNullValue(ExtractValueInst::getIndexedType(Agg->getType(), - Idxs)); - - // Otherwise recurse. - if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg)) - return ConstantFoldExtractValueInstruction(CS->getOperand(Idxs[0]), - Idxs.slice(1)); - - if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg)) - return ConstantFoldExtractValueInstruction(CA->getOperand(Idxs[0]), - Idxs.slice(1)); - ConstantVector *CV = cast<ConstantVector>(Agg); - return ConstantFoldExtractValueInstruction(CV->getOperand(Idxs[0]), - Idxs.slice(1)); + if (Constant *C = Agg->getAggregateElement(Idxs[0])) + return ConstantFoldExtractValueInstruction(C, Idxs.slice(1)); + + return 0; } Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, @@ -919,84 +834,30 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, if (Idxs.empty()) return Val; - if (isa<UndefValue>(Agg)) { - // Insertion of constant into aggregate undef - // Optimize away insertion of undef. - if (isa<UndefValue>(Val)) - return Agg; - - // Otherwise break the aggregate undef into multiple undefs and do - // the insertion. - CompositeType *AggTy = cast<CompositeType>(Agg->getType()); - unsigned numOps; - if (ArrayType *AR = dyn_cast<ArrayType>(AggTy)) - numOps = AR->getNumElements(); - else - numOps = cast<StructType>(AggTy)->getNumElements(); - - std::vector<Constant*> Ops(numOps); - for (unsigned i = 0; i < numOps; ++i) { - Type *MemberTy = AggTy->getTypeAtIndex(i); - Constant *Op = - (Idxs[0] == i) ? - ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy), - Val, Idxs.slice(1)) : - UndefValue::get(MemberTy); - Ops[i] = Op; - } - - if (StructType* ST = dyn_cast<StructType>(AggTy)) - return ConstantStruct::get(ST, Ops); - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); - } + unsigned NumElts; + if (StructType *ST = dyn_cast<StructType>(Agg->getType())) + NumElts = ST->getNumElements(); + else if (ArrayType *AT = dyn_cast<ArrayType>(Agg->getType())) + NumElts = AT->getNumElements(); + else + NumElts = AT->getVectorNumElements(); - if (isa<ConstantAggregateZero>(Agg)) { - // Insertion of constant into aggregate zero - // Optimize away insertion of zero. - if (Val->isNullValue()) - return Agg; - - // Otherwise break the aggregate zero into multiple zeros and do - // the insertion. - CompositeType *AggTy = cast<CompositeType>(Agg->getType()); - unsigned numOps; - if (ArrayType *AR = dyn_cast<ArrayType>(AggTy)) - numOps = AR->getNumElements(); - else - numOps = cast<StructType>(AggTy)->getNumElements(); + SmallVector<Constant*, 32> Result; + for (unsigned i = 0; i != NumElts; ++i) { + Constant *C = Agg->getAggregateElement(i); + if (C == 0) return 0; - std::vector<Constant*> Ops(numOps); - for (unsigned i = 0; i < numOps; ++i) { - Type *MemberTy = AggTy->getTypeAtIndex(i); - Constant *Op = - (Idxs[0] == i) ? - ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy), - Val, Idxs.slice(1)) : - Constant::getNullValue(MemberTy); - Ops[i] = Op; - } + if (Idxs[0] == i) + C = ConstantFoldInsertValueInstruction(C, Val, Idxs.slice(1)); - if (StructType *ST = dyn_cast<StructType>(AggTy)) - return ConstantStruct::get(ST, Ops); - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); + Result.push_back(C); } - if (isa<ConstantStruct>(Agg) || isa<ConstantArray>(Agg)) { - // Insertion of constant into aggregate constant. - std::vector<Constant*> Ops(Agg->getNumOperands()); - for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { - Constant *Op = cast<Constant>(Agg->getOperand(i)); - if (Idxs[0] == i) - Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs.slice(1)); - Ops[i] = Op; - } - - if (StructType* ST = dyn_cast<StructType>(Agg->getType())) - return ConstantStruct::get(ST, Ops); - return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); - } - - return 0; + if (StructType *ST = dyn_cast<StructType>(Agg->getType())) + return ConstantStruct::get(ST, Result); + if (ArrayType *AT = dyn_cast<ArrayType>(Agg->getType())) + return ConstantArray::get(AT, Result); + return ConstantVector::get(Result); } @@ -1174,7 +1035,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // At this point we know neither constant is an UndefValue. if (ConstantInt *CI1 = dyn_cast<ConstantInt>(C1)) { if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) { - using namespace APIntOps; const APInt &C1V = CI1->getValue(); const APInt &C2V = CI2->getValue(); switch (Opcode) { @@ -1271,145 +1131,18 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } } } else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) { - ConstantVector *CP1 = dyn_cast<ConstantVector>(C1); - ConstantVector *CP2 = dyn_cast<ConstantVector>(C2); - if ((CP1 != NULL || isa<ConstantAggregateZero>(C1)) && - (CP2 != NULL || isa<ConstantAggregateZero>(C2))) { - std::vector<Constant*> Res; - Type* EltTy = VTy->getElementType(); - Constant *C1 = 0; - Constant *C2 = 0; - switch (Opcode) { - default: - break; - case Instruction::Add: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getAdd(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::FAdd: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getFAdd(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::Sub: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getSub(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::FSub: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getFSub(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::Mul: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getMul(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::FMul: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getFMul(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::UDiv: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getUDiv(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::SDiv: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getSDiv(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::FDiv: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getFDiv(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::URem: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getURem(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::SRem: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getSRem(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::FRem: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getFRem(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::And: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getAnd(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::Or: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getOr(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::Xor: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getXor(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::LShr: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getLShr(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::AShr: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getAShr(C1, C2)); - } - return ConstantVector::get(Res); - case Instruction::Shl: - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); - C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(ConstantExpr::getShl(C1, C2)); - } - return ConstantVector::get(Res); - } + // Perform elementwise folding. + SmallVector<Constant*, 16> Result; + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + Constant *LHS = C1->getAggregateElement(i); + Constant *RHS = C2->getAggregateElement(i); + if (LHS == 0 || RHS == 0) break; + + Result.push_back(ConstantExpr::get(Opcode, LHS, RHS)); } + + if (Result.size() == VTy->getNumElements()) + return ConstantVector::get(Result); } if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { |