diff options
| author | Stephen Tozer <Stephen.Tozer@Sony.com> | 2021-05-20 20:17:33 +0100 |
|---|---|---|
| committer | Stephen Tozer <Stephen.Tozer@Sony.com> | 2021-05-21 11:06:20 +0100 |
| commit | 36ec97f76ac0d8be76fb16ac521f55126766267d (patch) | |
| tree | 9d3136fa7fa260f6def0c6545b7cb1967b3fc76a /llvm/lib/IR/Operator.cpp | |
| parent | 5a476987f7d653eb7ce2d8ba0ddf0125f481117e (diff) | |
3rd Reapply "[DebugInfo] Use variadic debug values to salvage BinOps and GEP instrs with non-const operands"
This reapplies c0f3dfb9, which was reverted following the discovery of
crashes on linux kernel and chromium builds - these issues have since
been fixed, allowing this patch to re-land.
This reverts commit 4397b7095d640f9b9426c4d0135e999c5a1de1c5.
Diffstat (limited to 'llvm/lib/IR/Operator.cpp')
| -rw-r--r-- | llvm/lib/IR/Operator.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp index 69181f35827b..e030cb552275 100644 --- a/llvm/lib/IR/Operator.cpp +++ b/llvm/lib/IR/Operator.cpp @@ -142,4 +142,61 @@ bool GEPOperator::accumulateConstantOffset( } return true; } + +bool GEPOperator::collectOffset( + const DataLayout &DL, unsigned BitWidth, + SmallDenseMap<Value *, APInt, 8> &VariableOffsets, + APInt &ConstantOffset) const { + assert(BitWidth == DL.getIndexSizeInBits(getPointerAddressSpace()) && + "The offset bit width does not match DL specification."); + + auto CollectConstantOffset = [&](APInt Index, uint64_t Size) { + Index = Index.sextOrTrunc(BitWidth); + APInt IndexedSize = APInt(BitWidth, Size); + ConstantOffset += Index * IndexedSize; + }; + + for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); + GTI != GTE; ++GTI) { + // Scalable vectors are multiplied by a runtime constant. + bool ScalableType = isa<ScalableVectorType>(GTI.getIndexedType()); + + Value *V = GTI.getOperand(); + StructType *STy = GTI.getStructTypeOrNull(); + // Handle ConstantInt if possible. + if (auto ConstOffset = dyn_cast<ConstantInt>(V)) { + if (ConstOffset->isZero()) + continue; + // If the type is scalable and the constant is not zero (vscale * n * 0 = + // 0) bailout. + // TODO: If the runtime value is accessible at any point before DWARF + // emission, then we could potentially keep a forward reference to it + // in the debug value to be filled in later. + if (ScalableType) + return false; + // Handle a struct index, which adds its field offset to the pointer. + if (STy) { + unsigned ElementIdx = ConstOffset->getZExtValue(); + const StructLayout *SL = DL.getStructLayout(STy); + // Element offset is in bytes. + CollectConstantOffset(APInt(BitWidth, SL->getElementOffset(ElementIdx)), + 1); + continue; + } + CollectConstantOffset(ConstOffset->getValue(), + DL.getTypeAllocSize(GTI.getIndexedType())); + continue; + } + + if (STy || ScalableType) + return false; + // Insert an initial offset of 0 for V iff none exists already, then + // increment the offset by IndexedSize. + VariableOffsets.try_emplace(V, BitWidth, 0); + APInt IndexedSize = + APInt(BitWidth, DL.getTypeAllocSize(GTI.getIndexedType())); + VariableOffsets[V] += IndexedSize; + } + return true; +} } // namespace llvm |
