diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Instruction.h | 12 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/BBVectorize.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Instruction.cpp | 21 | 
3 files changed, 29 insertions, 29 deletions
diff --git a/llvm/include/llvm/Instruction.h b/llvm/include/llvm/Instruction.h index a386d1de42f..5512dcc9e6b 100644 --- a/llvm/include/llvm/Instruction.h +++ b/llvm/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/llvm/lib/Transforms/Vectorize/BBVectorize.cpp b/llvm/lib/Transforms/Vectorize/BBVectorize.cpp index 85187310dd8..35e0d68b0af 100644 --- a/llvm/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/llvm/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/llvm/lib/VMCore/Instruction.cpp b/llvm/lib/VMCore/Instruction.cpp index faa99db4fcb..66379a04931 100644 --- a/llvm/lib/VMCore/Instruction.cpp +++ b/llvm/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))  | 

