diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/FunctionComparator.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/FunctionComparator.cpp | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp index 3fa61ec68cd3..8daeb92130ba 100644 --- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -157,16 +157,31 @@ int FunctionComparator::cmpAttrs(const AttributeList L, return 0; } -int FunctionComparator::cmpRangeMetadata(const MDNode *L, - const MDNode *R) const { +int FunctionComparator::cmpMetadata(const Metadata *L, + const Metadata *R) const { + // TODO: the following routine coerce the metadata contents into constants + // before comparison. + // It ignores any other cases, so that the metadata nodes are considered + // equal even though this is not correct. + // We should structurally compare the metadata nodes to be perfect here. + auto *CL = dyn_cast<ConstantAsMetadata>(L); + auto *CR = dyn_cast<ConstantAsMetadata>(R); + if (CL == CR) + return 0; + if (!CL) + return -1; + if (!CR) + return 1; + return cmpConstants(CL->getValue(), CR->getValue()); +} + +int FunctionComparator::cmpMDNode(const MDNode *L, const MDNode *R) const { 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 @@ -175,10 +190,30 @@ int FunctionComparator::cmpRangeMetadata(const MDNode *L, // function semantically. if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands())) return Res; - for (size_t I = 0; I < L->getNumOperands(); ++I) { - ConstantInt *LLow = mdconst::extract<ConstantInt>(L->getOperand(I)); - ConstantInt *RLow = mdconst::extract<ConstantInt>(R->getOperand(I)); - if (int Res = cmpAPInts(LLow->getValue(), RLow->getValue())) + for (size_t I = 0; I < L->getNumOperands(); ++I) + if (int Res = cmpMetadata(L->getOperand(I), R->getOperand(I))) + return Res; + return 0; +} + +int FunctionComparator::cmpInstMetadata(Instruction const *L, + Instruction const *R) const { + /// These metadata affects the other optimization passes by making assertions + /// or constraints. + /// Values that carry different expectations should be considered different. + SmallVector<std::pair<unsigned, MDNode *>> MDL, MDR; + L->getAllMetadataOtherThanDebugLoc(MDL); + R->getAllMetadataOtherThanDebugLoc(MDR); + if (MDL.size() > MDR.size()) + return 1; + else if (MDL.size() < MDR.size()) + return -1; + for (size_t I = 0, N = MDL.size(); I < N; ++I) { + auto const [KeyL, ML] = MDL[I]; + auto const [KeyR, MR] = MDR[I]; + if (int Res = cmpNumbers(KeyL, KeyR)) + return Res; + if (int Res = cmpMDNode(ML, MR)) return Res; } return 0; @@ -586,9 +621,7 @@ int FunctionComparator::cmpOperations(const Instruction *L, if (int Res = cmpNumbers(LI->getSyncScopeID(), cast<LoadInst>(R)->getSyncScopeID())) return Res; - return cmpRangeMetadata( - LI->getMetadata(LLVMContext::MD_range), - cast<LoadInst>(R)->getMetadata(LLVMContext::MD_range)); + return cmpInstMetadata(L, R); } if (const StoreInst *SI = dyn_cast<StoreInst>(L)) { if (int Res = @@ -616,8 +649,8 @@ int FunctionComparator::cmpOperations(const Instruction *L, if (int Res = cmpNumbers(CI->getTailCallKind(), cast<CallInst>(R)->getTailCallKind())) return Res; - return cmpRangeMetadata(L->getMetadata(LLVMContext::MD_range), - R->getMetadata(LLVMContext::MD_range)); + return cmpMDNode(L->getMetadata(LLVMContext::MD_range), + R->getMetadata(LLVMContext::MD_range)); } if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(L)) { ArrayRef<unsigned> LIndices = IVI->getIndices(); @@ -715,8 +748,8 @@ int FunctionComparator::cmpGEPs(const GEPOperator *GEPL, // When we have target data, we can reduce the GEP down to the value in bytes // added to the address. const DataLayout &DL = FnL->getParent()->getDataLayout(); - unsigned BitWidth = DL.getPointerSizeInBits(ASL); - APInt OffsetL(BitWidth, 0), OffsetR(BitWidth, 0); + unsigned OffsetBitWidth = DL.getIndexSizeInBits(ASL); + APInt OffsetL(OffsetBitWidth, 0), OffsetR(OffsetBitWidth, 0); if (GEPL->accumulateConstantOffset(DL, OffsetL) && GEPR->accumulateConstantOffset(DL, OffsetR)) return cmpAPInts(OffsetL, OffsetR); |