aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/FunctionComparator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/FunctionComparator.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/FunctionComparator.cpp63
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);