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 hasSamePropertiesAs(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 hasSamePropertiesAs(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 hasSamePropertiesAs(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,17 @@ /// 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. + /// The IgnoreAlignment is used to whether or not consider alignment + /// during comparision. + int haveSameSpecialState(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 +670,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 hasSamePropertiesAs(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,15 @@ 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 hasSamePropertiesAs(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 +409,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 hasSamePropertiesAs(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 +495,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 hasSamePropertiesAs(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 +661,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 hasSamePropertiesAs(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 +841,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 hasSamePropertiesAs(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 +1116,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 hasSamePropertiesAs(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 +1640,14 @@ 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 hasSamePropertiesAs(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 +1768,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 hasSamePropertiesAs(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 +1822,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 hasSamePropertiesAs(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 +1887,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 hasSamePropertiesAs(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 +1958,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 hasSamePropertiesAs(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 +2296,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 hasSamePropertiesAs(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; @@ -2296,6 +2403,14 @@ 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 hasSamePropertiesAs(const ExtractValueInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractValue; @@ -2427,6 +2542,14 @@ 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 hasSamePropertiesAs(const InsertValueInst *I) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertValue; @@ -2684,6 +2807,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 hasSamePropertiesAs(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 +2924,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 hasSamePropertiesAs(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 +3006,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 hasSamePropertiesAs(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 +3167,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 hasSamePropertiesAs(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 +3532,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 hasSamePropertiesAs(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 +3720,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 hasSamePropertiesAs(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 +3914,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 hasSamePropertiesAs(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 +4163,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 hasSamePropertiesAs(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 +4247,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 hasSamePropertiesAs(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 +4440,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 hasSamePropertiesAs(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 +4494,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 hasSamePropertiesAs(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 +4552,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 hasSamePropertiesAs(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 +4624,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 hasSamePropertiesAs(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 +4726,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 hasSamePropertiesAs(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 +4793,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 hasSamePropertiesAs(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; @@ -4604,6 +4849,14 @@ 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 hasSamePropertiesAs(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; @@ -4643,6 +4896,14 @@ 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 hasSamePropertiesAs(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; @@ -4682,6 +4943,14 @@ 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 hasSamePropertiesAs(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; @@ -4721,6 +4990,14 @@ 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 hasSamePropertiesAs(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; @@ -4760,6 +5037,14 @@ 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 hasSamePropertiesAs(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; @@ -4799,6 +5084,14 @@ 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 hasSamePropertiesAs(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; @@ -4838,6 +5131,14 @@ 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 hasSamePropertiesAs(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; @@ -4877,6 +5178,14 @@ 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 hasSamePropertiesAs(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; @@ -4916,6 +5225,14 @@ 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 hasSamePropertiesAs(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 +5276,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 hasSamePropertiesAs(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 +5335,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 hasSamePropertiesAs(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; @@ -5049,6 +5382,14 @@ 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 hasSamePropertiesAs(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; @@ -5089,6 +5430,14 @@ 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 hasSamePropertiesAs(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 +5538,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 hasSamePropertiesAs(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,238 @@ } } -/// 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 must be kept in sync with FunctionComparator::cmpOperations +/// in lib/Transforms/IPO/MergeFunctions.cpp. +int Instruction::haveSameSpecialState(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->hasSamePropertiesAs(cast(I1), IgnoreAlignment); + } + case Instruction::Load: { + const LoadInst *LI = cast(this); + return LI->hasSamePropertiesAs(cast(I1), IgnoreAlignment, + IgnoreMetaData); + } + case Instruction::Store: { + const StoreInst *SI = cast(this); + return SI->hasSamePropertiesAs(cast(I1), IgnoreAlignment); + } + case Instruction::ICmp: + case Instruction::FCmp: { + const CmpInst *C = cast(this); + return C->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Call: { + const CallInst *CI = cast(this); + return CI->hasSamePropertiesAs(cast(I1), IgnoreMetaData); + } + case Instruction::Invoke: { + const InvokeInst *II = cast(this); + return II->hasSamePropertiesAs(cast(I1), IgnoreMetaData); + } + case Instruction::CallBr: { + const CallBrInst *CBI = cast(this); + return CBI->hasSamePropertiesAs(cast(I1), IgnoreMetaData); + } + case Instruction::InsertValue: { + const InsertValueInst *IVI = cast(this); + return IVI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::ExtractValue: { + const ExtractValueInst *EVI = cast(this); + return EVI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Fence: { + const FenceInst *FI = cast(this); + return FI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::AtomicCmpXchg: { + const AtomicCmpXchgInst *CXI = cast(this); + return CXI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::AtomicRMW: { + const AtomicRMWInst *RMWI = cast(this); + return RMWI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::ShuffleVector: { + const ShuffleVectorInst *SVI = cast(this); + return SVI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Ret: { + const ReturnInst *RI = cast(this); + return RI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Br: { + const BranchInst *BI = cast(this); + return BI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Switch: { + const SwitchInst *SI = cast(this); + return SI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::IndirectBr: { + const IndirectBrInst *IBI = cast(this); + return IBI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Resume: { + const ResumeInst *RI = cast(this); + return RI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::CatchSwitch: { + const CatchSwitchInst *CSI = cast(this); + return CSI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::CatchRet: { + const CatchReturnInst *CRI = cast(this); + return CRI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::CleanupRet: { + const CleanupReturnInst *CRI = cast(this); + return CRI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Unreachable: { + const UnreachableInst *UI = cast(this); + return UI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::FNeg: { + const UnaryOperator *UOP = cast(this); + return UOP->hasSamePropertiesAs(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->hasSamePropertiesAs(cast(I1)); + } + case Instruction::GetElementPtr: { + const GetElementPtrInst *GEP = cast(this); + return GEP->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Trunc: { + const TruncInst *TI = cast(this); + return TI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::ZExt: { + const ZExtInst *ZEI = cast(this); + return ZEI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::SExt: { + const SExtInst *SEI = cast(this); + return SEI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::FPToUI: { + const FPToUIInst *FUI = cast(this); + return FUI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::FPToSI: { + const FPToSIInst *FSI = cast(this); + return FSI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::UIToFP: { + const UIToFPInst *UFI = cast(this); + return UFI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::SIToFP: { + const SIToFPInst *SFI = cast(this); + return SFI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::FPTrunc: { + const FPTruncInst *FTI = cast(this); + return FTI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::FPExt: { + const FPExtInst *FEI = cast(this); + return FEI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::PtrToInt: { + const PtrToIntInst *PII = cast(this); + return PII->hasSamePropertiesAs(cast(I1)); + } + case Instruction::IntToPtr: { + const IntToPtrInst *IPI = cast(this); + return IPI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::BitCast: { + const BitCastInst *BI = cast(this); + return BI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::AddrSpaceCast: { + const AddrSpaceCastInst *ACI = cast(this); + return ACI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::CleanupPad: { + const CleanupPadInst *CPI = cast(this); + return CPI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::CatchPad: { + const CatchPadInst *CPI = cast(this); + return CPI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::PHI: { + const PHINode *PI = cast(this); + return PI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Select: { + const SelectInst *SI = cast(this); + return SI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::VAArg: { + const VAArgInst *VAI = cast(this); + return VAI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::ExtractElement: { + const ExtractElementInst *EEI = cast(this); + return EEI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::InsertElement: { + const InsertElementInst *IEI = cast(this); + return IEI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::LandingPad: { + const LandingPadInst *LPI = cast(this); + return LPI->hasSamePropertiesAs(cast(I1)); + } + case Instruction::Freeze: { + const FreezeInst *FI = cast(this); + return FI->hasSamePropertiesAs(cast(I1)); + } + } } bool Instruction::isIdenticalTo(const Instruction *I) const { @@ -481,7 +648,7 @@ // If both instructions have no operands, they are identical. if (getNumOperands() == 0 && I->getNumOperands() == 0) - return haveSameSpecialState(this, I); + return haveSameSpecialState(I, CompareIgnoringMetaData) == 0; // We have two instructions of identical opcode and #operands. Check to see // if all operands are the same. @@ -494,14 +661,13 @@ otherPHI->block_begin()); } - return haveSameSpecialState(this, I); + return haveSameSpecialState(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() || @@ -520,7 +686,7 @@ getOperand(i)->getType() != I->getOperand(i)->getType()) return false; - return haveSameSpecialState(this, I, IgnoreAlignment); + return haveSameSpecialState(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,225 @@ 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); + + /* + const DataLayout &DL = FnL->getParent()->getDataLayout(); + if (PTyL && PTyL->getAddressSpace() == 0) + TyL = DL.getIntPtrType(TyL); + if (PTyR && PTyR->getAddressSpace() == 0) + TyR = DL.getIntPtrType(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 +309,14 @@ 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::hasSamePropertiesAs(const SelectInst *I) const { return 0; } + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -177,6 +404,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::hasSamePropertiesAs(const PHINode *I) const { return 0; } + //===----------------------------------------------------------------------===// // LandingPadInst Implementation //===----------------------------------------------------------------------===// @@ -243,6 +478,16 @@ 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::hasSamePropertiesAs(const LandingPadInst *I) const { + return compareBools(isCleanup(), I->isCleanup()); +} + //===----------------------------------------------------------------------===// // CallBase Implementation //===----------------------------------------------------------------------===// @@ -750,6 +995,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::hasSamePropertiesAs(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 +1078,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::hasSamePropertiesAs(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 +1180,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::hasSamePropertiesAs(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 +1232,14 @@ : 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::hasSamePropertiesAs(const ReturnInst *I) const { return 0; } + //===----------------------------------------------------------------------===// // ResumeInst Implementation //===----------------------------------------------------------------------===// @@ -951,6 +1262,14 @@ 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::hasSamePropertiesAs(const ResumeInst *I) const { return 0; } + //===----------------------------------------------------------------------===// // CleanupReturnInst Implementation //===----------------------------------------------------------------------===// @@ -993,6 +1312,16 @@ 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::hasSamePropertiesAs(const CleanupReturnInst *I) const { + return compareBools(unwindsToCaller(), I->unwindsToCaller()); +} + //===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// @@ -1024,6 +1353,16 @@ 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::hasSamePropertiesAs(const CatchReturnInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // CatchSwitchInst Implementation //===----------------------------------------------------------------------===// @@ -1107,6 +1446,16 @@ 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::hasSamePropertiesAs(const CatchSwitchInst *I) const { + return compareBools(unwindsToCaller(), I->unwindsToCaller()); +} + //===----------------------------------------------------------------------===// // FuncletPadInst Implementation //===----------------------------------------------------------------------===// @@ -1157,6 +1506,16 @@ : 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::hasSamePropertiesAs(const UnreachableInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // BranchInst Implementation //===----------------------------------------------------------------------===// @@ -1230,6 +1589,14 @@ 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::hasSamePropertiesAs(const BranchInst *I) const { return 0; } + //===----------------------------------------------------------------------===// // AllocaInst Implementation //===----------------------------------------------------------------------===// @@ -1322,6 +1689,20 @@ 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::hasSamePropertiesAs(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 +1783,28 @@ 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::hasSamePropertiesAs(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 +1884,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::hasSamePropertiesAs(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 +1963,24 @@ 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::hasSamePropertiesAs(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,6 +2062,22 @@ 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::hasSamePropertiesAs(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 //===----------------------------------------------------------------------===// @@ -1643,6 +2098,18 @@ 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::hasSamePropertiesAs(const FenceInst *FI) const { + if (int Res = compareOrderings(getOrdering(), FI->getOrdering())) + return Res; + return compareIntegers(getSyncScopeID(), FI->getSyncScopeID()); +} + //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// @@ -1759,6 +2226,16 @@ 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::hasSamePropertiesAs(const GetElementPtrInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // ExtractElementInst Implementation //===----------------------------------------------------------------------===// @@ -1798,6 +2275,16 @@ 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::hasSamePropertiesAs(const ExtractElementInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // InsertElementInst Implementation //===----------------------------------------------------------------------===// @@ -1844,6 +2331,16 @@ 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::hasSamePropertiesAs(const InsertElementInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // ShuffleVectorInst Implementation //===----------------------------------------------------------------------===// @@ -2226,6 +2723,24 @@ 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::hasSamePropertiesAs(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 //===----------------------------------------------------------------------===// @@ -2258,6 +2773,24 @@ 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::hasSamePropertiesAs(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 //===----------------------------------------------------------------------===// @@ -2310,6 +2843,24 @@ 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::hasSamePropertiesAs(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; +} + //===----------------------------------------------------------------------===// // UnaryOperator Class //===----------------------------------------------------------------------===// @@ -2363,6 +2914,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::hasSamePropertiesAs(const UnaryOperator *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -2542,6 +3103,16 @@ 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::hasSamePropertiesAs(const BinaryOperator *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // FPMathOperator Class //===----------------------------------------------------------------------===// @@ -3413,6 +3984,14 @@ 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::hasSamePropertiesAs(const TruncInst *I) const { return 0; } + ZExtInst::ZExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, ZExt, S, Name, InsertBefore) { @@ -3424,6 +4003,15 @@ ) : 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::hasSamePropertiesAs(const ZExtInst *I) const { return 0; } + SExtInst::SExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SExt, S, Name, InsertBefore) { @@ -3436,6 +4024,14 @@ 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::hasSamePropertiesAs(const SExtInst *I) const { return 0; } + FPTruncInst::FPTruncInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { @@ -3448,6 +4044,14 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } +// 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::hasSamePropertiesAs(const FPTruncInst *I) const { return 0; } + FPExtInst::FPExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPExt, S, Name, InsertBefore) { @@ -3460,6 +4064,14 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } +// 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::hasSamePropertiesAs(const FPExtInst *I) const { return 0; } + UIToFPInst::UIToFPInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { @@ -3472,6 +4084,14 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } +// 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::hasSamePropertiesAs(const UIToFPInst *I) const { return 0; } + SIToFPInst::SIToFPInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { @@ -3484,6 +4104,14 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } +// 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::hasSamePropertiesAs(const SIToFPInst *I) const { return 0; } + FPToUIInst::FPToUIInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { @@ -3496,6 +4124,14 @@ assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } +// 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::hasSamePropertiesAs(const FPToUIInst *I) const { return 0; } + FPToSIInst::FPToSIInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { @@ -3508,6 +4144,14 @@ 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::hasSamePropertiesAs(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 +4164,14 @@ 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::hasSamePropertiesAs(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 +4184,14 @@ 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::hasSamePropertiesAs(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 +4204,14 @@ 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::hasSamePropertiesAs(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 +4224,16 @@ 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::hasSamePropertiesAs(const AddrSpaceCastInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // CmpInst Classes //===----------------------------------------------------------------------===// @@ -3891,6 +4569,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::hasSamePropertiesAs(const CmpInst *I) const { + return compareIntegers(getPredicate(), I->getPredicate()); +} + //===----------------------------------------------------------------------===// // SwitchInst Implementation //===----------------------------------------------------------------------===// @@ -4114,6 +4802,14 @@ 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::hasSamePropertiesAs(const SwitchInst *I) const { return 0; } + //===----------------------------------------------------------------------===// // IndirectBrInst Implementation //===----------------------------------------------------------------------===// @@ -4193,6 +4889,16 @@ 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::hasSamePropertiesAs(const IndirectBrInst *I) const { + return 0; +} + //===----------------------------------------------------------------------===// // FreezeInst Implementation //===----------------------------------------------------------------------===// @@ -4209,6 +4915,55 @@ 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::hasSamePropertiesAs(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::hasSamePropertiesAs(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::hasSamePropertiesAs(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::hasSamePropertiesAs(const CatchPadInst *I) const { + const CatchSwitchInst *CSI = getCatchSwitch(); + return CSI->hasSamePropertiesAs(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,6 +545,20 @@ } // Check special state that is a part of some instructions. + + if (const PHINode *PNL = dyn_cast(L)) { + const PHINode *PNR = cast(R); + // Ensure that in addition to the incoming values being identical + // (checked by the caller of this function), the incoming blocks + // are also identical. + for (unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) { + if (int Res = + cmpValues(PNL->getIncomingBlock(i), PNR->getIncomingBlock(i))) + return Res; + } + } + return L->haveSameSpecialState(R); + /* if (const AllocaInst *AI = dyn_cast(L)) { if (int Res = cmpTypes(AI->getAllocatedType(), cast(R)->getAllocatedType())) @@ -678,6 +692,7 @@ } } return 0; + */ } // Determine whether two GEP operations perform the same underlying arithmetic.