diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -174,6 +174,14 @@ return static_cast(Instruction::getOpcode()); } + // Function to introduce total ordering between two UnaryOperator + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in UnaryOperator class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const UnaryOperator *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->isUnaryOp(); @@ -403,6 +411,14 @@ /// bool swapOperands(); + // Function to introduce total ordering between two BinaryOperator + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in BinaryOperator class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const BinaryOperator *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->isBinaryOp(); @@ -955,6 +971,14 @@ /// operands. static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2); + // Function to introduce total ordering between two Cmp Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CmpInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CmpInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp || diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -645,6 +645,15 @@ /// Instruction *clone() const; + /// Function to introduce total ordering between two Instructions + /// based on their special state. + /// Returns -1 (this instruction < I1) + /// +1 (this instruction > I1) + /// 0 (this instruction = I1) + /// This checks whether instruction specific properties for instructions + /// which have the same Opcode and same number of operands. + int compareSpecialState(const Instruction *I1, unsigned flags = 0) const; + /// Return true if the specified instruction is exactly identical to the /// current one. This means that all operands match and any extra information /// (e.g. load is volatile) agree. @@ -659,10 +668,12 @@ /// sometimes useful to ignore certain attributes. enum OperationEquivalenceFlags { /// Check for equivalence ignoring load/store alignment. - CompareIgnoringAlignment = 1<<0, + CompareIgnoringAlignment = 1 << 0, + /// Check for equivalence ignoring MetaData. + CompareIgnoringMetaData = 1 << 1, /// Check for equivalence treating a type and a vector of that type /// as equivalent. - CompareUsingScalarTypes = 1<<1 + CompareUsingScalarTypes = 1 << 2 }; /// This function determines if the specified instruction executes the same diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -142,6 +142,15 @@ (V ? 64 : 0)); } + // Function to introduce total ordering between two Alloca Instructions. + // Returns -1 (this instruction < AI) + // +1 (this instruction > AI) + // 0 (this instruction = AI) + // Any addition of operands in AllocaInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const AllocaInst *AI, + bool IgnoreAlignment = false) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Alloca); @@ -262,6 +271,16 @@ return getPointerOperandType()->getPointerAddressSpace(); } + // Function to introduce total ordering between two Load Instructions. + // Returns -1 (this instruction < LI) + // +1 (this instruction > LI) + // 0 (this instruction = LI) + // Any addition of operands in LoadInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const LoadInst *LI, + bool IgnoreAlignment = false, + bool IgnoreMetaData = false) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; @@ -391,6 +410,15 @@ return getPointerOperandType()->getPointerAddressSpace(); } + // Function to introduce total ordering between two Store Instructions. + // Returns -1 (this instruction < SI) + // +1 (this instruction > SI) + // 0 (this instruction = SI) + // Any addition of operands in StoreInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const StoreInst *SI, + bool IgnoreAlignment = false) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; @@ -468,6 +496,14 @@ this->SSID = SSID; } + // Function to introduce total ordering between two Fence Instructions. + // Returns -1 (this instruction < FI) + // +1 (this instruction > FI) + // 0 (this instruction = FI) + // Any addition of operands in FenceInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FenceInst *FI) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Fence; @@ -626,6 +662,14 @@ } } + // Function to introduce total ordering between two AtomicCmpXchg + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in AtomicCmpXchgInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const AtomicCmpXchgInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; @@ -798,6 +842,14 @@ return isFPOperation(getOperation()); } + // Function to introduce total ordering between two AtomicRMW Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in AtomicRMWInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const AtomicRMWInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; @@ -1065,6 +1117,14 @@ /// the base GEP pointer. bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; + // Function to introduce total ordering between two GetElementPtr + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in GetElementPtrInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const GetElementPtrInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); @@ -1581,6 +1641,15 @@ addAttribute(AttributeList::FunctionIndex, Attribute::ReturnsTwice); } + // Function to introduce total ordering between two Call Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CallInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CallInst *I, + bool IgnoreMetaData) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; @@ -1701,6 +1770,14 @@ return static_cast(Instruction::getOpcode()); } + // Function to introduce total ordering between two Select Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in SelectInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const SelectInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Select; @@ -1747,6 +1824,14 @@ const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } + // Function to introduce total ordering between two VAArg Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in VAArgInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const VAArgInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == VAArg; @@ -1804,6 +1889,14 @@ /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Function to introduce total ordering between two ExtractElement + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ExtractElementInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ExtractElementInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractElement; @@ -1867,6 +1960,14 @@ /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Function to introduce total ordering between two InsertElement + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in InsertElementInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const InsertElementInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertElement; @@ -2197,6 +2298,14 @@ } } + // Function to introduce total ordering between two ShuffleVector + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ShuffleVectorInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ShuffleVectorInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; @@ -2292,9 +2401,15 @@ return (unsigned)Indices.size(); } - bool hasIndices() const { - return true; - } + bool hasIndices() const { return true; } + + // Function to introduce total ordering between two ExtractValue Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ExtractValueInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ExtractValueInst *I) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { @@ -2423,9 +2538,15 @@ return (unsigned)Indices.size(); } - bool hasIndices() const { - return true; - } + bool hasIndices() const { return true; } + + // Function to introduce total ordering between two InsertValue Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in InsertValueInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const InsertValueInst *I) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { @@ -2684,6 +2805,14 @@ /// non-undef value. bool hasConstantOrUndefValue() const; + // Function to introduce total ordering between two PHI Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in PHINode class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const PHINode *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::PHI; @@ -2793,6 +2922,14 @@ /// number of clauses. void reserveClauses(unsigned Size) { growOperands(Size); } + // Function to introduce total ordering between two LandingPad Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in LandingPadInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const LandingPadInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::LandingPad; @@ -2867,6 +3004,14 @@ unsigned getNumSuccessors() const { return 0; } + // Function to introduce total ordering between two Return Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ReturnInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ReturnInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Ret); @@ -3020,6 +3165,14 @@ const_succ_op_iterator(value_op_end())); } + // Function to introduce total ordering between two Branch Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in BranchInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const BranchInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); @@ -3377,6 +3530,14 @@ setOperand(idx * 2 + 1, NewSucc); } + // Function to introduce total ordering between two Switch Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in SwitchInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const SwitchInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Switch; @@ -3557,6 +3718,14 @@ const_succ_op_iterator(value_op_end())); } + // Function to introduce total ordering between two IndirectBr Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in IndirectBrInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const IndirectBrInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; @@ -3743,6 +3912,15 @@ unsigned getNumSuccessors() const { return 2; } + // Function to introduce total ordering between two Invoke Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in InvokeInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const InvokeInst *I, + bool IgnoreMetaData = false) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); @@ -3983,6 +4161,15 @@ unsigned getNumSuccessors() const { return getNumIndirectDests() + 1; } + // Function to introduce total ordering between two CallBr Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CallBrInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CallBrInst *I, + bool IgnoreMetaData = false) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CallBr); @@ -4058,6 +4245,14 @@ unsigned getNumSuccessors() const { return 0; } + // Function to introduce total ordering between two Resume Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ResumeInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ResumeInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Resume; @@ -4243,6 +4438,14 @@ setOperand(Idx + 1, NewSucc); } + // Function to introduce total ordering between two CatchSwitch Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CatchSwitchInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CatchSwitchInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchSwitch; @@ -4289,6 +4492,14 @@ CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); } + // Function to introduce total ordering between two CleanupPad Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CleanupPadInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CleanupPadInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CleanupPad; @@ -4339,6 +4550,14 @@ Op<-1>() = CatchSwitch; } + // Function to introduce total ordering between two CatchPad Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CatchPadInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + bool compareInstSpecificProperties(const CatchPadInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchPad; @@ -4403,6 +4622,14 @@ return getCatchPad()->getCatchSwitch()->getParentPad(); } + // Function to introduce total ordering between two CatchReturn Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CatchReturnInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CatchReturnInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CatchRet); @@ -4497,6 +4724,14 @@ Op<1>() = NewDest; } + // Function to introduce total ordering between two CleanupReturn + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in CleanupReturnInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const CleanupReturnInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CleanupRet); @@ -4556,6 +4791,14 @@ unsigned getNumSuccessors() const { return 0; } + // Function to introduce total ordering between two Unreachable Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in UnreachableInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const UnreachableInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Unreachable; @@ -4598,12 +4841,20 @@ /// Constructor with insert-at-end-of-block semantics TruncInst( - Value *S, ///< The value to be truncated - Type *Ty, ///< The (smaller) type to truncate to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be truncated + Type *Ty, ///< The (smaller) type to truncate to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two Trunc Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in TruncInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const TruncInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Trunc; @@ -4636,13 +4887,20 @@ ); /// Constructor with insert-at-end semantics. - ZExtInst( - Value *S, ///< The value to be zero extended - Type *Ty, ///< The type to zero extend to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ZExtInst(Value *S, ///< The value to be zero extended + Type *Ty, ///< The type to zero extend to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two ZExt Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in ZExtInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const ZExtInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == ZExt; @@ -4675,13 +4933,20 @@ ); /// Constructor with insert-at-end-of-block semantics - SExtInst( - Value *S, ///< The value to be sign extended - Type *Ty, ///< The type to sign extend to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + SExtInst(Value *S, ///< The value to be sign extended + Type *Ty, ///< The type to sign extend to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two SExt Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in SExtInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const SExtInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == SExt; @@ -4715,12 +4980,20 @@ /// Constructor with insert-before-instruction semantics FPTruncInst( - Value *S, ///< The value to be truncated - Type *Ty, ///< The type to truncate to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be truncated + Type *Ty, ///< The type to truncate to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two FPTrunc Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in FPTruncInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FPTruncInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPTrunc; @@ -4754,12 +5027,20 @@ /// Constructor with insert-at-end-of-block semantics FPExtInst( - Value *S, ///< The value to be extended - Type *Ty, ///< The type to extend to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be extended + Type *Ty, ///< The type to extend to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two FPExt Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in FPExtInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FPExtInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPExt; @@ -4793,12 +5074,20 @@ /// Constructor with insert-at-end-of-block semantics UIToFPInst( - Value *S, ///< The value to be converted - Type *Ty, ///< The type to convert to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two UIToFP Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in UIToFPInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const UIToFPInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == UIToFP; @@ -4832,12 +5121,20 @@ /// Constructor with insert-at-end-of-block semantics SIToFPInst( - Value *S, ///< The value to be converted - Type *Ty, ///< The type to convert to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two SIToFP Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in SIToFPInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const SIToFPInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == SIToFP; @@ -4870,13 +5167,20 @@ ); /// Constructor with insert-at-end-of-block semantics - FPToUIInst( - Value *S, ///< The value to be converted - Type *Ty, ///< The type to convert to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< Where to insert the new instruction + FPToUIInst(Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); + // Function to introduce total ordering between two FPToUI Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in FPToUIInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FPToUIInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPToUI; @@ -4910,12 +5214,20 @@ /// Constructor with insert-at-end-of-block semantics FPToSIInst( - Value *S, ///< The value to be converted - Type *Ty, ///< The type to convert to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two FPToSI Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in FPToSIInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FPToSIInst *I) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPToSI; @@ -4959,6 +5271,14 @@ return getType()->getPointerAddressSpace(); } + // Function to introduce total ordering between two IntToPtr Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in IntToPtrInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const IntToPtrInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == IntToPtr; @@ -5010,6 +5330,14 @@ return getPointerOperand()->getType()->getPointerAddressSpace(); } + // Function to introduce total ordering between two PtrToInt Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in PtrToIntInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const PtrToIntInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == PtrToInt; @@ -5043,12 +5371,20 @@ /// Constructor with insert-at-end-of-block semantics BitCastInst( - Value *S, ///< The value to be casted - Type *Ty, ///< The type to casted to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be casted + Type *Ty, ///< The type to casted to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two BitCast Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in BitCastInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const BitCastInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == BitCast; @@ -5083,12 +5419,20 @@ /// Constructor with insert-at-end-of-block semantics AddrSpaceCastInst( - Value *S, ///< The value to be casted - Type *Ty, ///< The type to casted to - const Twine &NameStr, ///< A name for the new instruction - BasicBlock *InsertAtEnd ///< The block to insert the instruction into + Value *S, ///< The value to be casted + Type *Ty, ///< The type to casted to + const Twine &NameStr, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Function to introduce total ordering between two AddrSpaceCast + // Instructions. Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in AddrSpaceCastInst class need to be reflected + // here so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const AddrSpaceCastInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == AddrSpaceCast; @@ -5189,6 +5533,14 @@ Instruction *InsertBefore = nullptr); FreezeInst(Value *S, const Twine &NameStr, BasicBlock *InsertAtEnd); + // Function to introduce total ordering between two Freeze Instructions. + // Returns -1 (this instruction < I) + // +1 (this instruction > I) + // 0 (this instruction = I) + // Any addition of operands in FreezeInst class need to be reflected here + // so that the IR comparators stay in sync with the changes to IR. + int compareInstSpecificProperties(const FreezeInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Freeze; diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -401,71 +401,243 @@ } } -/// Return true if both instructions have the same special state. This must be -/// kept in sync with FunctionComparator::cmpOperations in -/// lib/Transforms/IPO/MergeFunctions.cpp. -static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2, - bool IgnoreAlignment = false) { - assert(I1->getOpcode() == I2->getOpcode() && +/// Function to introduce total ordering between two Instructions +/// based on the special state. +/// Returns -1 (this instruction < I) +/// +1 (this instruction > I) +/// 0 (this instruction = I) +/// This is used by FunctionComparator::cmpOperations in +/// lib/Transforms/Utils/FunctionComparator.cpp. +int Instruction::compareSpecialState(const Instruction *I1, + unsigned flags) const { + assert(getOpcode() == I2->getOpcode() && "Can not compare special state of different instructions"); + assert(getNumOperands() == I2->getNumOperands() && + "Can not compare special state of instructions with different number " + "of operands"); - if (const AllocaInst *AI = dyn_cast(I1)) - return AI->getAllocatedType() == cast(I2)->getAllocatedType() && - (AI->getAlignment() == cast(I2)->getAlignment() || - IgnoreAlignment); - if (const LoadInst *LI = dyn_cast(I1)) - return LI->isVolatile() == cast(I2)->isVolatile() && - (LI->getAlignment() == cast(I2)->getAlignment() || - IgnoreAlignment) && - LI->getOrdering() == cast(I2)->getOrdering() && - LI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const StoreInst *SI = dyn_cast(I1)) - return SI->isVolatile() == cast(I2)->isVolatile() && - (SI->getAlignment() == cast(I2)->getAlignment() || - IgnoreAlignment) && - SI->getOrdering() == cast(I2)->getOrdering() && - SI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const CmpInst *CI = dyn_cast(I1)) - return CI->getPredicate() == cast(I2)->getPredicate(); - if (const CallInst *CI = dyn_cast(I1)) - return CI->isTailCall() == cast(I2)->isTailCall() && - CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes() && - CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const InvokeInst *CI = dyn_cast(I1)) - return CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes() && - CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const CallBrInst *CI = dyn_cast(I1)) - return CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes() && - CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const InsertValueInst *IVI = dyn_cast(I1)) - return IVI->getIndices() == cast(I2)->getIndices(); - if (const ExtractValueInst *EVI = dyn_cast(I1)) - return EVI->getIndices() == cast(I2)->getIndices(); - if (const FenceInst *FI = dyn_cast(I1)) - return FI->getOrdering() == cast(I2)->getOrdering() && - FI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const AtomicCmpXchgInst *CXI = dyn_cast(I1)) - return CXI->isVolatile() == cast(I2)->isVolatile() && - CXI->isWeak() == cast(I2)->isWeak() && - CXI->getSuccessOrdering() == - cast(I2)->getSuccessOrdering() && - CXI->getFailureOrdering() == - cast(I2)->getFailureOrdering() && - CXI->getSyncScopeID() == - cast(I2)->getSyncScopeID(); - if (const AtomicRMWInst *RMWI = dyn_cast(I1)) - return RMWI->getOperation() == cast(I2)->getOperation() && - RMWI->isVolatile() == cast(I2)->isVolatile() && - RMWI->getOrdering() == cast(I2)->getOrdering() && - RMWI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const ShuffleVectorInst *SVI = dyn_cast(I1)) - return SVI->getShuffleMask() == - cast(I2)->getShuffleMask(); - - return true; + bool IgnoreAlignment = flags & CompareIgnoringAlignment; + bool IgnoreMetaData = flags & CompareIgnoringMetaData; + + switch (getOpcode()) { + default: + // Trying to compare an instruction whose Opcode is unknown to this + // function. This leads to failure when new instructions are added + // but this function is not updated. + llvm_unreachable("Instruction to compare are unknown"); + case Instruction::Alloca: { + const AllocaInst *AI = cast(this); + return AI->compareInstSpecificProperties(cast(I1), + IgnoreAlignment); + } + case Instruction::Load: { + const LoadInst *LI = cast(this); + return LI->compareInstSpecificProperties(cast(I1), + IgnoreAlignment, IgnoreMetaData); + } + case Instruction::Store: { + const StoreInst *SI = cast(this); + return SI->compareInstSpecificProperties(cast(I1), + IgnoreAlignment); + } + case Instruction::ICmp: + case Instruction::FCmp: { + const CmpInst *C = cast(this); + return C->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Call: { + const CallInst *CI = cast(this); + return CI->compareInstSpecificProperties(cast(I1), + IgnoreMetaData); + } + case Instruction::Invoke: { + const InvokeInst *II = cast(this); + return II->compareInstSpecificProperties(cast(I1), + IgnoreMetaData); + } + case Instruction::CallBr: { + const CallBrInst *CBI = cast(this); + return CBI->compareInstSpecificProperties(cast(I1), + IgnoreMetaData); + } + case Instruction::InsertValue: { + const InsertValueInst *IVI = cast(this); + return IVI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::ExtractValue: { + const ExtractValueInst *EVI = cast(this); + return EVI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Fence: { + const FenceInst *FI = cast(this); + return FI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::AtomicCmpXchg: { + const AtomicCmpXchgInst *CXI = cast(this); + return CXI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::AtomicRMW: { + const AtomicRMWInst *RMWI = cast(this); + return RMWI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::ShuffleVector: { + const ShuffleVectorInst *SVI = cast(this); + return SVI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Ret: { + const ReturnInst *RI = cast(this); + return RI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Br: { + const BranchInst *BI = cast(this); + return BI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Switch: { + const SwitchInst *SI = cast(this); + return SI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::IndirectBr: { + const IndirectBrInst *IBI = cast(this); + return IBI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Resume: { + const ResumeInst *RI = cast(this); + return RI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::CatchSwitch: { + const CatchSwitchInst *CSI = cast(this); + return CSI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::CatchRet: { + const CatchReturnInst *CRI = cast(this); + return CRI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::CleanupRet: { + const CleanupReturnInst *CRI = cast(this); + return CRI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Unreachable: { + const UnreachableInst *UI = cast(this); + return UI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::FNeg: { + const UnaryOperator *UOP = cast(this); + return UOP->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Add: + case Instruction::FAdd: + case Instruction::Sub: + case Instruction::FSub: + case Instruction::Mul: + case Instruction::FMul: + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: { + const BinaryOperator *BOP = cast(this); + return BOP->compareInstSpecificProperties(cast(I1)); + } + case Instruction::GetElementPtr: { + const GetElementPtrInst *GEP = cast(this); + return GEP->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Trunc: { + const TruncInst *TI = cast(this); + return TI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::ZExt: { + const ZExtInst *ZEI = cast(this); + return ZEI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::SExt: { + const SExtInst *SEI = cast(this); + return SEI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::FPToUI: { + const FPToUIInst *FUI = cast(this); + return FUI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::FPToSI: { + const FPToSIInst *FSI = cast(this); + return FSI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::UIToFP: { + const UIToFPInst *UFI = cast(this); + return UFI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::SIToFP: { + const SIToFPInst *SFI = cast(this); + return SFI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::FPTrunc: { + const FPTruncInst *FTI = cast(this); + return FTI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::FPExt: { + const FPExtInst *FEI = cast(this); + return FEI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::PtrToInt: { + const PtrToIntInst *PII = cast(this); + return PII->compareInstSpecificProperties(cast(I1)); + } + case Instruction::IntToPtr: { + const IntToPtrInst *IPI = cast(this); + return IPI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::BitCast: { + const BitCastInst *BI = cast(this); + return BI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::AddrSpaceCast: { + const AddrSpaceCastInst *ACI = cast(this); + return ACI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::CleanupPad: { + const CleanupPadInst *CPI = cast(this); + return CPI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::CatchPad: { + const CatchPadInst *CPI = cast(this); + return CPI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::PHI: { + const PHINode *PI = cast(this); + return PI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Select: { + const SelectInst *SI = cast(this); + return SI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::VAArg: { + const VAArgInst *VAI = cast(this); + return VAI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::ExtractElement: { + const ExtractElementInst *EEI = cast(this); + return EEI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::InsertElement: { + const InsertElementInst *IEI = cast(this); + return IEI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::LandingPad: { + const LandingPadInst *LPI = cast(this); + return LPI->compareInstSpecificProperties(cast(I1)); + } + case Instruction::Freeze: { + const FreezeInst *FI = cast(this); + return FI->compareInstSpecificProperties(cast(I1)); + } + } } bool Instruction::isIdenticalTo(const Instruction *I) const { @@ -475,13 +647,12 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { if (getOpcode() != I->getOpcode() || - getNumOperands() != I->getNumOperands() || - getType() != I->getType()) + getNumOperands() != I->getNumOperands() || getType() != I->getType()) return false; // If both instructions have no operands, they are identical. if (getNumOperands() == 0 && I->getNumOperands() == 0) - return haveSameSpecialState(this, I); + return compareSpecialState(I, CompareIgnoringMetaData) == 0; // We have two instructions of identical opcode and #operands. Check to see // if all operands are the same. @@ -494,14 +665,13 @@ otherPHI->block_begin()); } - return haveSameSpecialState(this, I); + return compareSpecialState(I, CompareIgnoringMetaData) == 0; } // Keep this in sync with FunctionComparator::cmpOperations in // lib/Transforms/IPO/MergeFunctions.cpp. bool Instruction::isSameOperationAs(const Instruction *I, unsigned flags) const { - bool IgnoreAlignment = flags & CompareIgnoringAlignment; bool UseScalarTypes = flags & CompareUsingScalarTypes; if (getOpcode() != I->getOpcode() || @@ -514,13 +684,13 @@ // 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 (UseScalarTypes ? - getOperand(i)->getType()->getScalarType() != - I->getOperand(i)->getType()->getScalarType() : - 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; - return haveSameSpecialState(this, I, IgnoreAlignment); + return compareSpecialState(I, flags | CompareIgnoringMetaData) == 0; } bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -45,6 +45,218 @@ using namespace llvm; +// Functions for comparision of basic types used for +// introducing total ordering between IR instructions. +static int compareIntegers(uint64_t L, uint64_t R) { + if (L < R) + return -1; + if (L > R) + return 1; + return 0; +} + +static int compareBools(bool L, bool R) { + if ((int)L < (int)R) + return -1; + if ((int)L > (int)R) + return 1; + return 0; +} + +static int compareOrderings(AtomicOrdering L, AtomicOrdering R) { + if ((int)L < (int)R) + return -1; + if ((int)L > (int)R) + return 1; + return 0; +} + +static int compareAPInts(const APInt &L, const APInt &R) { + if (int Res = compareIntegers(L.getBitWidth(), R.getBitWidth())) + return Res; + if (L.ugt(R)) + return 1; + if (R.ugt(L)) + return -1; + return 0; +} + +static int compareRangeMetadata(const MDNode *L, const MDNode *R) { + if (L == R) + return 0; + if (!L) + return -1; + if (!R) + return 1; + // Range metadata is a sequence of numbers. Make sure they are the same + // sequence. + // TODO: Note that as this is metadata, it is possible to drop and/or merge + // this data when considering functions to merge. Thus this comparison would + // return 0 (i.e. equivalent), but merging would become more complicated + // because the ranges would need to be unioned. It is not likely that + // functions differ ONLY in this metadata if they are actually the same + // function semantically. + if (int Res = compareIntegers(L->getNumOperands(), R->getNumOperands())) + return Res; + for (size_t I = 0; I < L->getNumOperands(); ++I) { + ConstantInt *LLow = mdconst::extract(L->getOperand(I)); + ConstantInt *RLow = mdconst::extract(R->getOperand(I)); + if (int Res = compareAPInts(LLow->getValue(), RLow->getValue())) + return Res; + } + return 0; +} + +static int compareOperandBundlesSchema(const CallBase &LCS, + const CallBase &RCS) { + assert(LCS.getOpcode() == RCS.getOpcode() && "Can't compare otherwise!"); + + if (int Res = compareIntegers(LCS.getNumOperandBundles(), + RCS.getNumOperandBundles())) + return Res; + + for (unsigned I = 0, E = LCS.getNumOperandBundles(); I != E; ++I) { + auto OBL = LCS.getOperandBundleAt(I); + auto OBR = RCS.getOperandBundleAt(I); + + if (int Res = OBL.getTagName().compare(OBR.getTagName())) + return Res; + + if (int Res = compareIntegers(OBL.Inputs.size(), OBR.Inputs.size())) + return Res; + } + + return 0; +} + +static int compareTypes(Type *TyL, Type *TyR) { + PointerType *PTyL = dyn_cast(TyL); + PointerType *PTyR = dyn_cast(TyR); + + if (TyL == TyR) + return 0; + + if (int Res = compareIntegers(TyL->getTypeID(), TyR->getTypeID())) + return Res; + + switch (TyL->getTypeID()) { + default: + llvm_unreachable("Unknown type!"); + case Type::IntegerTyID: + return compareIntegers(cast(TyL)->getBitWidth(), + cast(TyR)->getBitWidth()); + // TyL == TyR would have returned true earlier, because types are uniqued. + case Type::VoidTyID: + case Type::FloatTyID: + case Type::DoubleTyID: + case Type::X86_FP80TyID: + case Type::FP128TyID: + case Type::PPC_FP128TyID: + case Type::LabelTyID: + case Type::MetadataTyID: + case Type::TokenTyID: + return 0; + + case Type::PointerTyID: + assert(PTyL && PTyR && "Both types must be pointers here."); + return compareIntegers(PTyL->getAddressSpace(), PTyR->getAddressSpace()); + + case Type::StructTyID: { + StructType *STyL = cast(TyL); + StructType *STyR = cast(TyR); + if (STyL->getNumElements() != STyR->getNumElements()) + return compareIntegers(STyL->getNumElements(), STyR->getNumElements()); + + if (STyL->isPacked() != STyR->isPacked()) + return compareIntegers(STyL->isPacked(), STyR->isPacked()); + + for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) { + if (int Res = + compareTypes(STyL->getElementType(i), STyR->getElementType(i))) + return Res; + } + return 0; + } + + case Type::FunctionTyID: { + FunctionType *FTyL = cast(TyL); + FunctionType *FTyR = cast(TyR); + if (FTyL->getNumParams() != FTyR->getNumParams()) + return compareIntegers(FTyL->getNumParams(), FTyR->getNumParams()); + + if (FTyL->isVarArg() != FTyR->isVarArg()) + return compareIntegers(FTyL->isVarArg(), FTyR->isVarArg()); + + if (int Res = compareTypes(FTyL->getReturnType(), FTyR->getReturnType())) + return Res; + + for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) { + if (int Res = compareTypes(FTyL->getParamType(i), FTyR->getParamType(i))) + return Res; + } + return 0; + } + + case Type::ArrayTyID: { + auto *STyL = cast(TyL); + auto *STyR = cast(TyR); + if (STyL->getNumElements() != STyR->getNumElements()) + return compareIntegers(STyL->getNumElements(), STyR->getNumElements()); + return compareTypes(STyL->getElementType(), STyR->getElementType()); + } + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { + auto *STyL = cast(TyL); + auto *STyR = cast(TyR); + if (STyL->getElementCount().Scalable != STyR->getElementCount().Scalable) + return compareIntegers(STyL->getElementCount().Scalable, + STyR->getElementCount().Scalable); + if (STyL->getElementCount().Min != STyR->getElementCount().Min) + return compareIntegers(STyL->getElementCount().Min, + STyR->getElementCount().Min); + return compareTypes(STyL->getElementType(), STyR->getElementType()); + } + } +} + +int compareAttrs(const AttributeList L, const AttributeList R) { + if (int Res = compareIntegers(L.getNumAttrSets(), R.getNumAttrSets())) + return Res; + + for (unsigned i = L.index_begin(), e = L.index_end(); i != e; ++i) { + AttributeSet LAS = L.getAttributes(i); + AttributeSet RAS = R.getAttributes(i); + AttributeSet::iterator LI = LAS.begin(), LE = LAS.end(); + AttributeSet::iterator RI = RAS.begin(), RE = RAS.end(); + for (; LI != LE && RI != RE; ++LI, ++RI) { + Attribute LA = *LI; + Attribute RA = *RI; + if (LA.isTypeAttribute() && RA.isTypeAttribute()) { + if (LA.getKindAsEnum() != RA.getKindAsEnum()) + return compareIntegers(LA.getKindAsEnum(), RA.getKindAsEnum()); + + Type *TyL = LA.getValueAsType(); + Type *TyR = RA.getValueAsType(); + if (TyL && TyR) + return compareTypes(TyL, TyR); + + // Two pointers, at least one null, so the comparison result is + // independent of the value of a real pointer. + return compareIntegers((uint64_t)TyL, (uint64_t)TyR); + } + if (LA < RA) + return -1; + if (RA < LA) + return 1; + } + if (LI != LE) + return 1; + if (RI != RE) + return -1; + } + return 0; +} + //===----------------------------------------------------------------------===// // AllocaInst Class //===----------------------------------------------------------------------===// @@ -90,6 +302,16 @@ return nullptr; } +// Function to introduce total ordering between two Select Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in SelectInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int SelectInst::compareInstSpecificProperties(const SelectInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -177,6 +399,14 @@ return true; } +// Function to introduce total ordering between two PHI Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in PHINode class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int PHINode::compareInstSpecificProperties(const PHINode *I) const { return 0; } + //===----------------------------------------------------------------------===// // LandingPadInst Implementation //===----------------------------------------------------------------------===// @@ -243,6 +473,17 @@ getOperandList()[OpNo] = Val; } +// Function to introduce total ordering between two LandingPad Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in LandingPadInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int LandingPadInst::compareInstSpecificProperties( + const LandingPadInst *I) const { + return compareBools(isCleanup(), I->isCleanup()); +} + //===----------------------------------------------------------------------===// // CallBase Implementation //===----------------------------------------------------------------------===// @@ -750,6 +991,27 @@ return FreeCall; } +// Function to introduce total ordering between two Call Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CallInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CallInst::compareInstSpecificProperties(const CallInst *I, + bool IgnoreMetaData) const { + if (int Res = compareIntegers(getCallingConv(), I->getCallingConv())) + return Res; + if (int Res = compareAttrs(getAttributes(), I->getAttributes())) + return Res; + if (int Res = compareOperandBundlesSchema(*this, *I)) + return Res; + if (!IgnoreMetaData) + if (int Res = compareRangeMetadata(getMetadata(LLVMContext::MD_range), + I->getMetadata(LLVMContext::MD_range))) + return Res; + return compareIntegers(getTailCallKind(), I->getTailCallKind()); +} + //===----------------------------------------------------------------------===// // InvokeInst Implementation //===----------------------------------------------------------------------===// @@ -812,11 +1074,29 @@ return NewII; } - LandingPadInst *InvokeInst::getLandingPadInst() const { return cast(getUnwindDest()->getFirstNonPHI()); } +// Function to introduce total ordering between two Invoke Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in InvokeInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int InvokeInst::compareInstSpecificProperties(const InvokeInst *I, + bool IgnoreMetaData) const { + if (int Res = compareIntegers(getCallingConv(), I->getCallingConv())) + return Res; + if (int Res = compareAttrs(getAttributes(), I->getAttributes())) + return Res; + if (!IgnoreMetaData) + if (int Res = compareRangeMetadata(getMetadata(LLVMContext::MD_range), + I->getMetadata(LLVMContext::MD_range))) + return Res; + return compareOperandBundlesSchema(*this, *I); +} + //===----------------------------------------------------------------------===// // CallBrInst Implementation //===----------------------------------------------------------------------===// @@ -896,6 +1176,25 @@ return NewCBI; } +// Function to introduce total ordering between two CallBr Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CallBrInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CallBrInst::compareInstSpecificProperties(const CallBrInst *I, + bool IgnoreMetaData) const { + if (int Res = compareIntegers(getCallingConv(), I->getCallingConv())) + return Res; + if (int Res = compareAttrs(getAttributes(), I->getAttributes())) + return Res; + if (!IgnoreMetaData) + if (int Res = compareRangeMetadata(getMetadata(LLVMContext::MD_range), + I->getMetadata(LLVMContext::MD_range))) + return Res; + return compareOperandBundlesSchema(*this, *I); +} + //===----------------------------------------------------------------------===// // ReturnInst Implementation //===----------------------------------------------------------------------===// @@ -929,6 +1228,16 @@ : Instruction(Type::getVoidTy(Context), Instruction::Ret, OperandTraits::op_end(this), 0, InsertAtEnd) {} +// Function to introduce total ordering between two Return Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ReturnInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int ReturnInst::compareInstSpecificProperties(const ReturnInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // ResumeInst Implementation //===----------------------------------------------------------------------===// @@ -951,6 +1260,16 @@ Op<0>() = Exn; } +// Function to introduce total ordering between two Resume Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ResumeInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int ResumeInst::compareInstSpecificProperties(const ResumeInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // CleanupReturnInst Implementation //===----------------------------------------------------------------------===// @@ -993,6 +1312,17 @@ init(CleanupPad, UnwindBB); } +// Function to introduce total ordering between two CleanupReturn Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CleanupReturnInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CleanupReturnInst::compareInstSpecificProperties( + const CleanupReturnInst *I) const { + return compareBools(unwindsToCaller(), I->unwindsToCaller()); +} + //===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// @@ -1024,6 +1354,17 @@ init(CatchPad, BB); } +// Function to introduce total ordering between two CatchReturn Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CatchReturnInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CatchReturnInst::compareInstSpecificProperties( + const CatchReturnInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // CatchSwitchInst Implementation //===----------------------------------------------------------------------===// @@ -1107,6 +1448,17 @@ setNumHungOffUseOperands(getNumOperands() - 1); } +// Function to introduce total ordering between two CatchSwitch Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CatchSwitchInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CatchSwitchInst::compareInstSpecificProperties( + const CatchSwitchInst *I) const { + return compareBools(unwindsToCaller(), I->unwindsToCaller()); +} + //===----------------------------------------------------------------------===// // FuncletPadInst Implementation //===----------------------------------------------------------------------===// @@ -1157,6 +1509,17 @@ : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr, 0, InsertAtEnd) {} +// Function to introduce total ordering between two Unreachable Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in UnreachableInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int UnreachableInst::compareInstSpecificProperties( + const UnreachableInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // BranchInst Implementation //===----------------------------------------------------------------------===// @@ -1230,6 +1593,16 @@ swapProfMetadata(); } +// Function to introduce total ordering between two Branch Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in BranchInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int BranchInst::compareInstSpecificProperties(const BranchInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // AllocaInst Implementation //===----------------------------------------------------------------------===// @@ -1315,13 +1688,28 @@ /// into the prolog/epilog code, so it is basically free. bool AllocaInst::isStaticAlloca() const { // Must be constant size. - if (!isa(getArraySize())) return false; + if (!isa(getArraySize())) + return false; // Must be in the entry block. const BasicBlock *Parent = getParent(); return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca(); } +// Function to introduce total ordering between two Alloca Instructions. +// Returns -1 (this instruction < AI) +// +1 (this instruction > AI) +// 0 (this instruction = AI) +// Any addition of operands in AllocaInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int AllocaInst::compareInstSpecificProperties(const AllocaInst *AI, + bool IgnoreAlignment) const { + if (!IgnoreAlignment) + if (int Res = compareIntegers(getAlignment(), AI->getAlignment())) + return Res; + return compareTypes(getAllocatedType(), AI->getAllocatedType()); +} + //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// @@ -1402,6 +1790,29 @@ assert(getAlign() == Align && "Alignment representation error!"); } +// Function to introduce total ordering between two Load Instructions. +// Returns -1 (this instruction < LI) +// +1 (this instruction > LI) +// 0 (this instruction = LI) +// Any addition of operands in LoadInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int LoadInst::compareInstSpecificProperties(const LoadInst *LI, + bool IgnoreAlignment, + bool IgnoreMetaData) const { + if (int Res = compareIntegers(isVolatile(), LI->isVolatile())) + return Res; + if (!IgnoreAlignment) + if (int Res = compareIntegers(getAlignment(), LI->getAlignment())) + return Res; + if (int Res = compareOrderings(getOrdering(), LI->getOrdering())) + return Res; + if (!IgnoreMetaData) + if (int Res = compareRangeMetadata(getMetadata(LLVMContext::MD_range), + LI->getMetadata(LLVMContext::MD_range))) + return Res; + return compareIntegers(getSyncScopeID(), LI->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// @@ -1481,6 +1892,24 @@ assert(getAlign() == Alignment && "Alignment representation error!"); } +// Function to introduce total ordering between two Store Instructions. +// Returns -1 (this instruction < SI) +// +1 (this instruction > SI) +// 0 (this instruction = SI) +// Any addition of operands in StoreInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int StoreInst::compareInstSpecificProperties(const StoreInst *SI, + bool IgnoreAlignment) const { + if (int Res = compareIntegers(isVolatile(), SI->isVolatile())) + return Res; + if (!IgnoreAlignment) + if (int Res = compareIntegers(getAlignment(), SI->getAlignment())) + return Res; + if (int Res = compareOrderings(getOrdering(), SI->getOrdering())) + return Res; + return compareIntegers(getSyncScopeID(), SI->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // AtomicCmpXchgInst Implementation //===----------------------------------------------------------------------===// @@ -1542,6 +1971,25 @@ Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SSID); } +// Function to introduce total ordering between two AtomicCmpXchg Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in AtomicCmpXchgInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int AtomicCmpXchgInst::compareInstSpecificProperties( + const AtomicCmpXchgInst *I) const { + if (int Res = compareIntegers(isVolatile(), I->isVolatile())) + return Res; + if (int Res = compareIntegers(isWeak(), I->isWeak())) + return Res; + if (int Res = compareOrderings(getSuccessOrdering(), I->getSuccessOrdering())) + return Res; + if (int Res = compareOrderings(getFailureOrdering(), I->getFailureOrdering())) + return Res; + return compareIntegers(getSyncScopeID(), I->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // AtomicRMWInst Implementation //===----------------------------------------------------------------------===// @@ -1623,26 +2071,52 @@ llvm_unreachable("invalid atomicrmw operation"); } +// Function to introduce total ordering between two AtomicRMW Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in AtomicRMWInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int AtomicRMWInst::compareInstSpecificProperties(const AtomicRMWInst *I) const { + if (int Res = compareIntegers(getOperation(), I->getOperation())) + return Res; + if (int Res = compareIntegers(isVolatile(), I->isVolatile())) + return Res; + if (int Res = compareOrderings(getOrdering(), I->getOrdering())) + return Res; + return compareIntegers(getSyncScopeID(), I->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // FenceInst Implementation //===----------------------------------------------------------------------===// FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, - SyncScope::ID SSID, - Instruction *InsertBefore) - : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) { + SyncScope::ID SSID, Instruction *InsertBefore) + : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) { setOrdering(Ordering); setSyncScopeID(SSID); } FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, - SyncScope::ID SSID, - BasicBlock *InsertAtEnd) - : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertAtEnd) { + SyncScope::ID SSID, BasicBlock *InsertAtEnd) + : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertAtEnd) { setOrdering(Ordering); setSyncScopeID(SSID); } +// Function to introduce total ordering between two Fence Instructions. +// Returns -1 (this instruction < FI) +// +1 (this instruction > FI) +// 0 (this instruction = FI) +// Any addition of operands in FenceInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FenceInst::compareInstSpecificProperties(const FenceInst *FI) const { + if (int Res = compareOrderings(getOrdering(), FI->getOrdering())) + return Res; + return compareIntegers(getSyncScopeID(), FI->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// @@ -1759,6 +2233,17 @@ return cast(this)->accumulateConstantOffset(DL, Offset); } +// Function to introduce total ordering between two GetElementPtr Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in GetElementPtrInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int GetElementPtrInst::compareInstSpecificProperties( + const GetElementPtrInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // ExtractElementInst Implementation //===----------------------------------------------------------------------===// @@ -1778,12 +2263,10 @@ } ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, - const Twine &Name, - BasicBlock *InsertAE) - : Instruction(cast(Val->getType())->getElementType(), - ExtractElement, - OperandTraits::op_begin(this), - 2, InsertAE) { + const Twine &Name, BasicBlock *InsertAE) + : Instruction( + cast(Val->getType())->getElementType(), ExtractElement, + OperandTraits::op_begin(this), 2, InsertAE) { assert(isValidOperands(Val, Index) && "Invalid extractelement instruction operands!"); @@ -1798,6 +2281,17 @@ return true; } +// Function to introduce total ordering between two ExtractElement Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ExtractElementInst class need to be reflected +// here so that the IR comparators stay in sync with the changes to IR. +int ExtractElementInst::compareInstSpecificProperties( + const ExtractElementInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // InsertElementInst Implementation //===----------------------------------------------------------------------===// @@ -1834,7 +2328,7 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, const Value *Index) { if (!Vec->getType()->isVectorTy()) - return false; // First operand of insertelement must be vector type. + return false; // First operand of insertelement must be vector type. if (Elt->getType() != cast(Vec->getType())->getElementType()) return false;// Second operand of insertelement must be vector element type. @@ -1844,6 +2338,17 @@ return true; } +// Function to introduce total ordering between two InsertElement Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in InsertElementInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int InsertElementInst::compareInstSpecificProperties( + const InsertElementInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // ShuffleVectorInst Implementation //===----------------------------------------------------------------------===// @@ -2226,6 +2731,25 @@ return isIdentityMaskImpl(getShuffleMask(), NumMaskElts); } +// Function to introduce total ordering between two ShuffleVector Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ShuffleVectorInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int ShuffleVectorInst::compareInstSpecificProperties( + const ShuffleVectorInst *I) const { + ArrayRef LMask = getShuffleMask(); + ArrayRef RMask = I->getShuffleMask(); + if (int Res = compareIntegers(LMask.size(), RMask.size())) + return Res; + for (size_t i = 0, e = LMask.size(); i != e; ++i) { + if (int Res = compareIntegers(LMask[i], RMask[i])) + return Res; + } + return 0; +} + //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// @@ -2241,7 +2765,8 @@ assert(!Idxs.empty() && "InsertValueInst must have at least one index"); assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == - Val->getType() && "Inserted value must match indexed type!"); + Val->getType() && + "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; @@ -2250,14 +2775,33 @@ } InsertValueInst::InsertValueInst(const InsertValueInst &IVI) - : Instruction(IVI.getType(), InsertValue, - OperandTraits::op_begin(this), 2), - Indices(IVI.Indices) { + : Instruction(IVI.getType(), InsertValue, + OperandTraits::op_begin(this), 2), + Indices(IVI.Indices) { Op<0>() = IVI.getOperand(0); Op<1>() = IVI.getOperand(1); SubclassOptionalData = IVI.SubclassOptionalData; } +// Function to introduce total ordering between two InsertValue Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in InsertValueInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int InsertValueInst::compareInstSpecificProperties( + const InsertValueInst *I) const { + ArrayRef LIndices = getIndices(); + ArrayRef RIndices = I->getIndices(); + if (int Res = compareIntegers(LIndices.size(), RIndices.size())) + return Res; + for (size_t i = 0, e = LIndices.size(); i != e; ++i) { + if (int Res = compareIntegers(LIndices[i], RIndices[i])) + return Res; + } + return 0; +} + //===----------------------------------------------------------------------===// // ExtractValueInst Class //===----------------------------------------------------------------------===// @@ -2307,7 +2851,26 @@ return nullptr; } } - return const_cast(Agg); + return const_cast(Agg); +} + +// Function to introduce total ordering between two ExtractValue Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ExtractValueInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int ExtractValueInst::compareInstSpecificProperties( + const ExtractValueInst *I) const { + ArrayRef LIndices = getIndices(); + ArrayRef RIndices = I->getIndices(); + if (int Res = compareIntegers(LIndices.size(), RIndices.size())) + return Res; + for (size_t i = 0, e = LIndices.size(); i != e; ++i) { + if (int Res = compareIntegers(LIndices[i], RIndices[i])) + return Res; + } + return 0; } //===----------------------------------------------------------------------===// @@ -2363,6 +2926,16 @@ #endif } +// Function to introduce total ordering between two UnaryOperator Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in UnaryOperator class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int UnaryOperator::compareInstSpecificProperties(const UnaryOperator *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -2520,15 +3093,15 @@ BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, Instruction *InsertBefore) { Constant *C = Constant::getAllOnesValue(Op->getType()); - return new BinaryOperator(Instruction::Xor, Op, C, - Op->getType(), Name, InsertBefore); + return new BinaryOperator(Instruction::Xor, Op, C, Op->getType(), Name, + InsertBefore); } BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Constant *AllOnes = Constant::getAllOnesValue(Op->getType()); - return new BinaryOperator(Instruction::Xor, Op, AllOnes, - Op->getType(), Name, InsertAtEnd); + return new BinaryOperator(Instruction::Xor, Op, AllOnes, Op->getType(), Name, + InsertAtEnd); } // Exchange the two operands to this instruction. This instruction is safe to @@ -2542,6 +3115,17 @@ return false; } +// Function to introduce total ordering between two BinaryOperator Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in BinaryOperator class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int BinaryOperator::compareInstSpecificProperties( + const BinaryOperator *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // FPMathOperator Class //===----------------------------------------------------------------------===// @@ -3413,68 +3997,129 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); } +// Function to introduce total ordering between two Trunc Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in TruncInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int TruncInst::compareInstSpecificProperties(const TruncInst *I) const { + return 0; +} + ZExtInst::ZExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, ZExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } -ZExtInst::ZExtInst( - Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd -) : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { +ZExtInst::ZExtInst(Value *S, Type *Ty, const Twine &Name, + BasicBlock *InsertAtEnd) + : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } + +// Function to introduce total ordering between two ZExt Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in ZExtInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int ZExtInst::compareInstSpecificProperties(const ZExtInst *I) const { + return 0; +} + SExtInst::SExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } -SExtInst::SExtInst( - Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd -) : CastInst(Ty, SExt, S, Name, InsertAtEnd) { +SExtInst::SExtInst(Value *S, Type *Ty, const Twine &Name, + BasicBlock *InsertAtEnd) + : CastInst(Ty, SExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } +// Function to introduce total ordering between two SExt Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in SExtInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int SExtInst::compareInstSpecificProperties(const SExtInst *I) const { + return 0; +} + FPTruncInst::FPTruncInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } -FPTruncInst::FPTruncInst( - Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd -) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { +FPTruncInst::FPTruncInst(Value *S, Type *Ty, const Twine &Name, + BasicBlock *InsertAtEnd) + : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } -FPExtInst::FPExtInst( - Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore -) : CastInst(Ty, FPExt, S, Name, InsertBefore) { +// Function to introduce total ordering between two FPTrunc Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in FPTruncInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FPTruncInst::compareInstSpecificProperties(const FPTruncInst *I) const { + return 0; +} + +FPExtInst::FPExtInst(Value *S, Type *Ty, const Twine &Name, + Instruction *InsertBefore) + : CastInst(Ty, FPExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } -FPExtInst::FPExtInst( - Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd -) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { +FPExtInst::FPExtInst(Value *S, Type *Ty, const Twine &Name, + BasicBlock *InsertAtEnd) + : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } -UIToFPInst::UIToFPInst( - Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore -) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { +// Function to introduce total ordering between two FPExt Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in FPExtInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FPExtInst::compareInstSpecificProperties(const FPExtInst *I) const { + return 0; +} + +UIToFPInst::UIToFPInst(Value *S, Type *Ty, const Twine &Name, + Instruction *InsertBefore) + : CastInst(Ty, UIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } -UIToFPInst::UIToFPInst( - Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd -) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { +UIToFPInst::UIToFPInst(Value *S, Type *Ty, const Twine &Name, + BasicBlock *InsertAtEnd) + : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } -SIToFPInst::SIToFPInst( - Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore -) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { +// Function to introduce total ordering between two UIToFP Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in UIToFPInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int UIToFPInst::compareInstSpecificProperties(const UIToFPInst *I) const { + return 0; +} + +SIToFPInst::SIToFPInst(Value *S, Type *Ty, const Twine &Name, + Instruction *InsertBefore) + : CastInst(Ty, SIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } @@ -3484,9 +4129,19 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } -FPToUIInst::FPToUIInst( - Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore -) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { +// Function to introduce total ordering between two SIToFP Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in SIToFPInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int SIToFPInst::compareInstSpecificProperties(const SIToFPInst *I) const { + return 0; +} + +FPToUIInst::FPToUIInst(Value *S, Type *Ty, const Twine &Name, + Instruction *InsertBefore) + : CastInst(Ty, FPToUI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } @@ -3496,9 +4151,19 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } -FPToSIInst::FPToSIInst( - Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore -) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { +// Function to introduce total ordering between two FPToUI Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in FPToUIInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FPToUIInst::compareInstSpecificProperties(const FPToUIInst *I) const { + return 0; +} + +FPToSIInst::FPToSIInst(Value *S, Type *Ty, const Twine &Name, + Instruction *InsertBefore) + : CastInst(Ty, FPToSI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } @@ -3508,6 +4173,16 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } +// Function to introduce total ordering between two FPToSI Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in FPToSIInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FPToSIInst::compareInstSpecificProperties(const FPToSIInst *I) const { + return 0; +} + PtrToIntInst::PtrToIntInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { @@ -3520,6 +4195,16 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } +// Function to introduce total ordering between two PtrToInt Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in PtrToIntInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int PtrToIntInst::compareInstSpecificProperties(const PtrToIntInst *I) const { + return 0; +} + IntToPtrInst::IntToPtrInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { @@ -3532,6 +4217,16 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); } +// Function to introduce total ordering between two IntToPtr Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in IntToPtrInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int IntToPtrInst::compareInstSpecificProperties(const IntToPtrInst *I) const { + return 0; +} + BitCastInst::BitCastInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, BitCast, S, Name, InsertBefore) { @@ -3544,6 +4239,16 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } +// Function to introduce total ordering between two BitCast Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in BitCastInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int BitCastInst::compareInstSpecificProperties(const BitCastInst *I) const { + return 0; +} + AddrSpaceCastInst::AddrSpaceCastInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) { @@ -3556,6 +4261,17 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); } +// Function to introduce total ordering between two AddrSpaceCast Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in AddrSpaceCastInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int AddrSpaceCastInst::compareInstSpecificProperties( + const AddrSpaceCastInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // CmpInst Classes //===----------------------------------------------------------------------===// @@ -3847,10 +4563,19 @@ } bool CmpInst::isTrueWhenEqual(Predicate predicate) { - switch(predicate) { - default: return false; - case ICMP_EQ: case ICMP_UGE: case ICMP_ULE: case ICMP_SGE: case ICMP_SLE: - case FCMP_TRUE: case FCMP_UEQ: case FCMP_UGE: case FCMP_ULE: return true; + switch (predicate) { + default: + return false; + case ICMP_EQ: + case ICMP_UGE: + case ICMP_ULE: + case ICMP_SGE: + case ICMP_SLE: + case FCMP_TRUE: + case FCMP_UEQ: + case FCMP_UGE: + case FCMP_ULE: + return true; } } @@ -3891,6 +4616,16 @@ return isImpliedTrueByMatchingCmp(Pred1, getInversePredicate(Pred2)); } +// Function to introduce total ordering between two Cmp Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CmpInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CmpInst::compareInstSpecificProperties(const CmpInst *I) const { + return compareIntegers(getPredicate(), I->getPredicate()); +} + //===----------------------------------------------------------------------===// // SwitchInst Implementation //===----------------------------------------------------------------------===// @@ -4114,6 +4849,16 @@ return None; } +// Function to introduce total ordering between two Switch Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in SwitchInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int SwitchInst::compareInstSpecificProperties(const SwitchInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // IndirectBrInst Implementation //===----------------------------------------------------------------------===// @@ -4170,45 +4915,108 @@ void IndirectBrInst::addDestination(BasicBlock *DestBB) { unsigned OpNo = getNumOperands(); if (OpNo+1 > ReservedSpace) - growOperands(); // Get more space! + growOperands(); // Get more space! // Initialize some new operands. assert(OpNo < ReservedSpace && "Growing didn't work!"); - setNumHungOffUseOperands(OpNo+1); + setNumHungOffUseOperands(OpNo + 1); getOperandList()[OpNo] = DestBB; } /// removeDestination - This method removes the specified successor from the /// indirectbr instruction. void IndirectBrInst::removeDestination(unsigned idx) { - assert(idx < getNumOperands()-1 && "Successor index out of range!"); + assert(idx < getNumOperands() - 1 && "Successor index out of range!"); unsigned NumOps = getNumOperands(); Use *OL = getOperandList(); // Replace this value with the last one. - OL[idx+1] = OL[NumOps-1]; + OL[idx + 1] = OL[NumOps - 1]; // Nuke the last value. - OL[NumOps-1].set(nullptr); - setNumHungOffUseOperands(NumOps-1); + OL[NumOps - 1].set(nullptr); + setNumHungOffUseOperands(NumOps - 1); +} + +// Function to introduce total ordering between two IndirectBr Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in IndirectBrInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int IndirectBrInst::compareInstSpecificProperties( + const IndirectBrInst *I) const { + return 0; } //===----------------------------------------------------------------------===// // FreezeInst Implementation //===----------------------------------------------------------------------===// -FreezeInst::FreezeInst(Value *S, - const Twine &Name, Instruction *InsertBefore) +FreezeInst::FreezeInst(Value *S, const Twine &Name, Instruction *InsertBefore) : UnaryInstruction(S->getType(), Freeze, S, InsertBefore) { setName(Name); } -FreezeInst::FreezeInst(Value *S, - const Twine &Name, BasicBlock *InsertAtEnd) +FreezeInst::FreezeInst(Value *S, const Twine &Name, BasicBlock *InsertAtEnd) : UnaryInstruction(S->getType(), Freeze, S, InsertAtEnd) { setName(Name); } +// Function to introduce total ordering between two Freeze Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in FreezeInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int FreezeInst::compareInstSpecificProperties(const FreezeInst *I) const { + return 0; +} + +//===----------------------------------------------------------------------===// +// VAArgInst class +//===----------------------------------------------------------------------===// + +// Function to introduce total ordering between two VAArg Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in VAArgInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int VAArgInst::compareInstSpecificProperties(const VAArgInst *I) const { + return 0; +} + +//===----------------------------------------------------------------------===// +// CleanupPadInst class +//===----------------------------------------------------------------------===// + +// Function to introduce total ordering between two CleanupPad Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CleanupPadInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +int CleanupPadInst::compareInstSpecificProperties( + const CleanupPadInst *I) const { + return 0; +} + +//===----------------------------------------------------------------------===// +// CatchPadInst class +//===----------------------------------------------------------------------===// + +// Function to introduce total ordering between two CatchPad Instructions. +// Returns -1 (this instruction < I) +// +1 (this instruction > I) +// 0 (this instruction = I) +// Any addition of operands in CatchPadInst class need to be reflected here +// so that the IR comparators stay in sync with the changes to IR. +bool CatchPadInst::compareInstSpecificProperties(const CatchPadInst *I) const { + const CatchSwitchInst *CSI = getCatchSwitch(); + return CSI->compareInstSpecificProperties(I->getCatchSwitch()); +} + //===----------------------------------------------------------------------===// // cloneImpl() implementations //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp --- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -545,127 +545,6 @@ } // Check special state that is a part of some instructions. - if (const AllocaInst *AI = dyn_cast(L)) { - if (int Res = cmpTypes(AI->getAllocatedType(), - cast(R)->getAllocatedType())) - return Res; - return cmpNumbers(AI->getAlignment(), cast(R)->getAlignment()); - } - if (const LoadInst *LI = dyn_cast(L)) { - if (int Res = cmpNumbers(LI->isVolatile(), cast(R)->isVolatile())) - return Res; - if (int Res = - cmpNumbers(LI->getAlignment(), cast(R)->getAlignment())) - return Res; - if (int Res = - cmpOrderings(LI->getOrdering(), cast(R)->getOrdering())) - return Res; - if (int Res = cmpNumbers(LI->getSyncScopeID(), - cast(R)->getSyncScopeID())) - return Res; - return cmpRangeMetadata( - LI->getMetadata(LLVMContext::MD_range), - cast(R)->getMetadata(LLVMContext::MD_range)); - } - if (const StoreInst *SI = dyn_cast(L)) { - if (int Res = - cmpNumbers(SI->isVolatile(), cast(R)->isVolatile())) - return Res; - if (int Res = - cmpNumbers(SI->getAlignment(), cast(R)->getAlignment())) - return Res; - if (int Res = - cmpOrderings(SI->getOrdering(), cast(R)->getOrdering())) - return Res; - return cmpNumbers(SI->getSyncScopeID(), - cast(R)->getSyncScopeID()); - } - if (const CmpInst *CI = dyn_cast(L)) - return cmpNumbers(CI->getPredicate(), cast(R)->getPredicate()); - if (auto *CBL = dyn_cast(L)) { - auto *CBR = cast(R); - if (int Res = cmpNumbers(CBL->getCallingConv(), CBR->getCallingConv())) - return Res; - if (int Res = cmpAttrs(CBL->getAttributes(), CBR->getAttributes())) - return Res; - if (int Res = cmpOperandBundlesSchema(*CBL, *CBR)) - return Res; - if (const CallInst *CI = dyn_cast(L)) - if (int Res = cmpNumbers(CI->getTailCallKind(), - cast(R)->getTailCallKind())) - return Res; - return cmpRangeMetadata(L->getMetadata(LLVMContext::MD_range), - R->getMetadata(LLVMContext::MD_range)); - } - if (const InsertValueInst *IVI = dyn_cast(L)) { - ArrayRef LIndices = IVI->getIndices(); - ArrayRef RIndices = cast(R)->getIndices(); - if (int Res = cmpNumbers(LIndices.size(), RIndices.size())) - return Res; - for (size_t i = 0, e = LIndices.size(); i != e; ++i) { - if (int Res = cmpNumbers(LIndices[i], RIndices[i])) - return Res; - } - return 0; - } - if (const ExtractValueInst *EVI = dyn_cast(L)) { - ArrayRef LIndices = EVI->getIndices(); - ArrayRef RIndices = cast(R)->getIndices(); - if (int Res = cmpNumbers(LIndices.size(), RIndices.size())) - return Res; - for (size_t i = 0, e = LIndices.size(); i != e; ++i) { - if (int Res = cmpNumbers(LIndices[i], RIndices[i])) - return Res; - } - } - if (const FenceInst *FI = dyn_cast(L)) { - if (int Res = - cmpOrderings(FI->getOrdering(), cast(R)->getOrdering())) - return Res; - return cmpNumbers(FI->getSyncScopeID(), - cast(R)->getSyncScopeID()); - } - if (const AtomicCmpXchgInst *CXI = dyn_cast(L)) { - if (int Res = cmpNumbers(CXI->isVolatile(), - cast(R)->isVolatile())) - return Res; - if (int Res = - cmpNumbers(CXI->isWeak(), cast(R)->isWeak())) - return Res; - if (int Res = - cmpOrderings(CXI->getSuccessOrdering(), - cast(R)->getSuccessOrdering())) - return Res; - if (int Res = - cmpOrderings(CXI->getFailureOrdering(), - cast(R)->getFailureOrdering())) - return Res; - return cmpNumbers(CXI->getSyncScopeID(), - cast(R)->getSyncScopeID()); - } - if (const AtomicRMWInst *RMWI = dyn_cast(L)) { - if (int Res = cmpNumbers(RMWI->getOperation(), - cast(R)->getOperation())) - return Res; - if (int Res = cmpNumbers(RMWI->isVolatile(), - cast(R)->isVolatile())) - return Res; - if (int Res = cmpOrderings(RMWI->getOrdering(), - cast(R)->getOrdering())) - return Res; - return cmpNumbers(RMWI->getSyncScopeID(), - cast(R)->getSyncScopeID()); - } - if (const ShuffleVectorInst *SVI = dyn_cast(L)) { - ArrayRef LMask = SVI->getShuffleMask(); - ArrayRef RMask = cast(R)->getShuffleMask(); - if (int Res = cmpNumbers(LMask.size(), RMask.size())) - return Res; - for (size_t i = 0, e = LMask.size(); i != e; ++i) { - if (int Res = cmpNumbers(LMask[i], RMask[i])) - return Res; - } - } if (const PHINode *PNL = dyn_cast(L)) { const PHINode *PNR = cast(R); // Ensure that in addition to the incoming values being identical @@ -677,7 +556,7 @@ return Res; } } - return 0; + return L->compareSpecialState(R); } // Determine whether two GEP operations perform the same underlying arithmetic.