diff options
-rw-r--r-- | include/llvm/Instruction.h | 12 | ||||
-rw-r--r-- | lib/Transforms/Vectorize/BBVectorize.cpp | 25 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 21 |
3 files changed, 29 insertions, 29 deletions
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index a386d1de42..5512dcc9e6 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -281,6 +281,16 @@ public: /// ignores the SubclassOptionalData flags, which specify conditions /// under which the instruction's result is undefined. bool isIdenticalToWhenDefined(const Instruction *I) const; + + /// When checking for operation equivalence (using isSameOperationAs) it is + /// sometimes useful to ignore certain attributes. + enum OperationEquivalenceFlags { + /// Check for equivalence ignoring load/store alignment. + CompareIgnoringAlignment = 1<<0, + /// Check for equivalence treating a type and a vector of that type + /// as equivalent. + CompareUsingScalarTypes = 1<<1 + }; /// This function determines if the specified instruction executes the same /// operation as the current one. This means that the opcodes, type, operand @@ -290,7 +300,7 @@ public: /// @returns true if the specified instruction is the same operation as /// the current one. /// @brief Determine if one instruction is the same operation as another. - bool isSameOperationAs(const Instruction *I) const; + bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const; /// isUsedOutsideOfBlock - Return true if there are any uses of this /// instruction in blocks other than the specified block. Note that PHI nodes diff --git a/lib/Transforms/Vectorize/BBVectorize.cpp b/lib/Transforms/Vectorize/BBVectorize.cpp index 85187310dd..35e0d68b0a 100644 --- a/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/lib/Transforms/Vectorize/BBVectorize.cpp @@ -660,30 +660,9 @@ namespace { // Loads and stores can be merged if they have different alignments, // but are otherwise the same. - LoadInst *LI, *LJ; - StoreInst *SI, *SJ; - if ((LI = dyn_cast<LoadInst>(I)) && (LJ = dyn_cast<LoadInst>(J))) { - if (I->getType() != J->getType()) - return false; - - if (LI->getPointerOperand()->getType() != - LJ->getPointerOperand()->getType() || - LI->isVolatile() != LJ->isVolatile() || - LI->getOrdering() != LJ->getOrdering() || - LI->getSynchScope() != LJ->getSynchScope()) - return false; - } else if ((SI = dyn_cast<StoreInst>(I)) && (SJ = dyn_cast<StoreInst>(J))) { - if (SI->getValueOperand()->getType() != - SJ->getValueOperand()->getType() || - SI->getPointerOperand()->getType() != - SJ->getPointerOperand()->getType() || - SI->isVolatile() != SJ->isVolatile() || - SI->getOrdering() != SJ->getOrdering() || - SI->getSynchScope() != SJ->getSynchScope()) - return false; - } else if (!J->isSameOperationAs(I)) { + if (!J->isSameOperationAs(I, Instruction::CompareIgnoringAlignment)) return false; - } + // FIXME: handle addsub-type operations! if (IsSimpleLoadStore) { diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index faa99db4fc..66379a0493 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -240,27 +240,38 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { // isSameOperationAs // This should be kept in sync with isEquivalentOperation in // lib/Transforms/IPO/MergeFunctions.cpp. -bool Instruction::isSameOperationAs(const Instruction *I) const { +bool Instruction::isSameOperationAs(const Instruction *I, + unsigned flags) const { + bool IgnoreAlignment = flags & CompareIgnoringAlignment; + bool UseScalarTypes = flags & CompareUsingScalarTypes; + if (getOpcode() != I->getOpcode() || getNumOperands() != I->getNumOperands() || - getType() != I->getType()) + (UseScalarTypes ? + getType()->getScalarType() != I->getType()->getScalarType() : + getType() != I->getType())) return false; // We have two instructions of identical opcode and #operands. Check to see // if all operands are the same type for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i)->getType() != I->getOperand(i)->getType()) + if (UseScalarTypes ? + getOperand(i)->getType()->getScalarType() != + I->getOperand(i)->getType()->getScalarType() : + getOperand(i)->getType() != I->getOperand(i)->getType()) return false; // Check special state that is a part of some instructions. if (const LoadInst *LI = dyn_cast<LoadInst>(this)) return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() && - LI->getAlignment() == cast<LoadInst>(I)->getAlignment() && + (LI->getAlignment() == cast<LoadInst>(I)->getAlignment() || + IgnoreAlignment) && LI->getOrdering() == cast<LoadInst>(I)->getOrdering() && LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope(); if (const StoreInst *SI = dyn_cast<StoreInst>(this)) return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() && - SI->getAlignment() == cast<StoreInst>(I)->getAlignment() && + (SI->getAlignment() == cast<StoreInst>(I)->getAlignment() || + IgnoreAlignment) && SI->getOrdering() == cast<StoreInst>(I)->getOrdering() && SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope(); if (const CmpInst *CI = dyn_cast<CmpInst>(this)) |