From df39028607ca751f0a3f50a76144464b825ff97a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Jan 2012 07:54:10 +0000 Subject: [PATCH] teach valuetracking about ConstantDataSequential git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148790 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constants.h | 12 +++++- lib/Analysis/ValueTracking.cpp | 78 ++++++++++++++++++++-------------- lib/VMCore/Constants.cpp | 18 ++++++++ 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index a7480d2a890..958ebb88c75 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -325,7 +325,11 @@ public: /// getElementValue - Return a zero of the right value for the specified GEP /// index. Constant *getElementValue(Constant *C); - + + /// getElementValue - Return a zero of the right value for the specified GEP + /// index. + Constant *getElementValue(unsigned Idx); + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const ConstantAggregateZero *) { return true; } @@ -1106,7 +1110,11 @@ public: /// getElementValue - Return an undef of the right value for the specified GEP /// index. UndefValue *getElementValue(Constant *C); - + + /// getElementValue - Return an undef of the right value for the specified GEP + /// index. + UndefValue *getElementValue(unsigned Idx); + virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 6cef42df9a2..753ec189944 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -100,6 +100,19 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, } return; } + if (ConstantDataSequential *CDS = dyn_cast(V)) { + // We know that CDS must be a vector of integers. Take the intersection of + // each element. + KnownZero.setAllBits(); KnownOne.setAllBits(); + APInt Elt(KnownZero.getBitWidth(), 0); + for (unsigned i = 0, e = CDS->getType()->getNumElements(); i != e; ++i) { + Elt = CDS->getElementAsInteger(i); + KnownZero &= ~Elt; + KnownOne &= Elt; + } + return; + } + // The address of an aligned GlobalValue has trailing zeros. if (GlobalValue *GV = dyn_cast(V)) { unsigned Align = GV->getAlignment(); @@ -1472,50 +1485,51 @@ static Value *BuildSubAggregate(Value *From, ArrayRef idx_range, Value *llvm::FindInsertedValue(Value *V, ArrayRef idx_range, Instruction *InsertBefore) { // Nothing to index? Just return V then (this is useful at the end of our - // recursion) + // recursion). if (idx_range.empty()) return V; - // We have indices, so V should have an indexable type - assert((V->getType()->isStructTy() || V->getType()->isArrayTy()) - && "Not looking at a struct or array?"); - assert(ExtractValueInst::getIndexedType(V->getType(), idx_range) - && "Invalid indices for type?"); + // We have indices, so V should have an indexable type. + assert((V->getType()->isStructTy() || V->getType()->isArrayTy()) && + "Not looking at a struct or array?"); + assert(ExtractValueInst::getIndexedType(V->getType(), idx_range) && + "Invalid indices for type?"); CompositeType *PTy = cast(V->getType()); if (isa(V)) - return UndefValue::get(ExtractValueInst::getIndexedType(PTy, - idx_range)); - else if (isa(V)) + return UndefValue::get(ExtractValueInst::getIndexedType(PTy, idx_range)); + if (isa(V)) return Constant::getNullValue(ExtractValueInst::getIndexedType(PTy, idx_range)); - else if (Constant *C = dyn_cast(V)) { - if (isa(C) || isa(C)) - // Recursively process this constant - return FindInsertedValue(C->getOperand(idx_range[0]), idx_range.slice(1), - InsertBefore); - } else if (InsertValueInst *I = dyn_cast(V)) { + if (isa(V) || isa(V)) + // Recursively process this constant + return FindInsertedValue(cast(V)->getOperand(idx_range[0]), + idx_range.slice(1), InsertBefore); + if (ConstantDataSequential *CDS = dyn_cast(V)) + return CDS->getElementAsConstant(idx_range[0]); + + if (InsertValueInst *I = dyn_cast(V)) { // Loop the indices for the insertvalue instruction in parallel with the // requested indices const unsigned *req_idx = idx_range.begin(); for (const unsigned *i = I->idx_begin(), *e = I->idx_end(); i != e; ++i, ++req_idx) { if (req_idx == idx_range.end()) { - if (InsertBefore) - // The requested index identifies a part of a nested aggregate. Handle - // this specially. For example, - // %A = insertvalue { i32, {i32, i32 } } undef, i32 10, 1, 0 - // %B = insertvalue { i32, {i32, i32 } } %A, i32 11, 1, 1 - // %C = extractvalue {i32, { i32, i32 } } %B, 1 - // This can be changed into - // %A = insertvalue {i32, i32 } undef, i32 10, 0 - // %C = insertvalue {i32, i32 } %A, i32 11, 1 - // which allows the unused 0,0 element from the nested struct to be - // removed. - return BuildSubAggregate(V, makeArrayRef(idx_range.begin(), req_idx), - InsertBefore); - else - // We can't handle this without inserting insertvalues + // We can't handle this without inserting insertvalues + if (!InsertBefore) return 0; + + // The requested index identifies a part of a nested aggregate. Handle + // this specially. For example, + // %A = insertvalue { i32, {i32, i32 } } undef, i32 10, 1, 0 + // %B = insertvalue { i32, {i32, i32 } } %A, i32 11, 1, 1 + // %C = extractvalue {i32, { i32, i32 } } %B, 1 + // This can be changed into + // %A = insertvalue {i32, i32 } undef, i32 10, 0 + // %C = insertvalue {i32, i32 } %A, i32 11, 1 + // which allows the unused 0,0 element from the nested struct to be + // removed. + return BuildSubAggregate(V, makeArrayRef(idx_range.begin(), req_idx), + InsertBefore); } // This insert value inserts something else than what we are looking for. @@ -1531,7 +1545,9 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef idx_range, return FindInsertedValue(I->getInsertedValueOperand(), makeArrayRef(req_idx, idx_range.end()), InsertBefore); - } else if (ExtractValueInst *I = dyn_cast(V)) { + } + + if (ExtractValueInst *I = dyn_cast(V)) { // If we're extracting a value from an aggregrate that was extracted from // something else, we can extract from that something else directly instead. // However, we will need to chain I's indices with the requested indices. diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index df98d758644..55b97ef7062 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -624,6 +624,15 @@ Constant *ConstantAggregateZero::getElementValue(Constant *C) { return getStructElement(cast(C)->getZExtValue()); } +/// getElementValue - Return a zero of the right value for the specified GEP +/// index. +Constant *ConstantAggregateZero::getElementValue(unsigned Idx) { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(Idx); +} + + //===----------------------------------------------------------------------===// // UndefValue Implementation //===----------------------------------------------------------------------===// @@ -648,6 +657,15 @@ UndefValue *UndefValue::getElementValue(Constant *C) { return getStructElement(cast(C)->getZExtValue()); } +/// getElementValue - Return an undef of the right value for the specified GEP +/// index. +UndefValue *UndefValue::getElementValue(unsigned Idx) { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(Idx); +} + + //===----------------------------------------------------------------------===// // ConstantXXX Classes