@@ -1864,177 +1864,52 @@ void at::deleteAll(Function *F) {
1864
1864
DVR->eraseFromParent ();
1865
1865
}
1866
1866
1867
- // / Get the FragmentInfo for the variable if it exists, otherwise return a
1868
- // / FragmentInfo that covers the entire variable if the variable size is
1869
- // / known, otherwise return a zero-sized fragment.
1870
- static DIExpression::FragmentInfo
1871
- getFragmentOrEntireVariable (const DbgVariableRecord *DVR) {
1872
- DIExpression::FragmentInfo VariableSlice (0 , 0 );
1873
- // Get the fragment or variable size, or zero.
1874
- if (auto Sz = DVR->getFragmentSizeInBits ())
1875
- VariableSlice.SizeInBits = *Sz;
1876
- if (auto Frag = DVR->getExpression ()->getFragmentInfo ())
1877
- VariableSlice.OffsetInBits = Frag->OffsetInBits ;
1878
- return VariableSlice;
1879
- }
1880
-
1881
- static DIExpression::FragmentInfo
1882
- getFragmentOrEntireVariable (const DbgVariableIntrinsic *DVI) {
1883
- DIExpression::FragmentInfo VariableSlice (0 , 0 );
1884
- // Get the fragment or variable size, or zero.
1885
- if (auto Sz = DVI->getFragmentSizeInBits ())
1886
- VariableSlice.SizeInBits = *Sz;
1887
- if (auto Frag = DVI->getExpression ()->getFragmentInfo ())
1888
- VariableSlice.OffsetInBits = Frag->OffsetInBits ;
1889
- return VariableSlice;
1890
- }
1867
+ // / FIXME: Remove this wrapper function and call
1868
+ // / DIExpression::calculateFragmentIntersect directly.
1891
1869
template <typename T>
1892
1870
bool calculateFragmentIntersectImpl (
1893
1871
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
1894
1872
uint64_t SliceSizeInBits, const T *AssignRecord,
1895
1873
std::optional<DIExpression::FragmentInfo> &Result) {
1896
- // There are multiple offsets at play in this function, so let's break it
1897
- // down. Starting with how variables may be stored in allocas:
1898
- //
1899
- // 1 Simplest case: variable is alloca sized and starts at offset 0.
1900
- // 2 Variable is larger than the alloca: the alloca holds just a part of it.
1901
- // 3 Variable is smaller than the alloca: the alloca may hold multiple
1902
- // variables.
1903
- //
1904
- // Imagine we have a store to the entire alloca. In case (3) the store
1905
- // affects bits outside of the bounds of each variable. In case (2), where
1906
- // the alloca holds the Xth bit to the Yth bit of a variable, the
1907
- // zero-offset store doesn't represent an assignment at offset zero to the
1908
- // variable. It is an assignment to offset X.
1909
- //
1910
- // # Example 1
1911
- // Obviously, not all stores are alloca-sized and have zero offset. Imagine
1912
- // the lower 32 bits of this store are dead and are going to be DSEd:
1913
- //
1914
- // store i64 %v, ptr %dest, !DIAssignID !1
1915
- // dbg.assign(..., !DIExpression(fragment, 128, 32), !1, %dest,
1916
- // !DIExpression(DW_OP_plus_uconst, 4))
1917
- //
1918
- // Goal: Given our dead bits at offset:0 size:32 for the store, determine the
1919
- // part of the variable, which fits in the fragment expressed by the
1920
- // dbg.assign, that has been killed, if any.
1921
- //
1922
- // calculateFragmentIntersect(..., SliceOffsetInBits=0,
1923
- // SliceSizeInBits=32, Dest=%dest, Assign=dbg.assign)
1924
- //
1925
- // Drawing the store (s) in memory followed by the shortened version ($),
1926
- // then the dbg.assign (d), with the fragment information on a separate scale
1927
- // underneath:
1928
- //
1929
- // Memory
1930
- // offset
1931
- // from
1932
- // dest 0 63
1933
- // | |
1934
- // s[######] - Original stores 64 bits to Dest.
1935
- // $----[##] - DSE says the lower 32 bits are dead, to be removed.
1936
- // d [##] - Assign's address-modifying expression adds 4 bytes to
1937
- // dest.
1938
- // Variable | |
1939
- // Fragment 128|
1940
- // Offsets 159
1941
- //
1942
- // The answer is achieved in a few steps:
1943
- // 1. Add the fragment offset to the store offset:
1944
- // SliceOffsetInBits:0 + VarFrag.OffsetInBits:128 = 128
1945
- //
1946
- // 2. Subtract the address-modifying expression offset plus difference
1947
- // between d.address and dest:
1948
- // 128 - (expression_offset:32 + (d.address - dest):0) = 96
1949
- //
1950
- // 3. That offset along with the store size (32) represents the bits of the
1951
- // variable that'd be affected by the store. Call it SliceOfVariable.
1952
- // Intersect that with Assign's fragment info:
1953
- // SliceOfVariable ∩ Assign_fragment = none
1954
- //
1955
- // In this case: none of the dead bits of the store affect Assign.
1956
- //
1957
- // # Example 2
1958
- // Similar example with the same goal. This time the upper 16 bits
1959
- // of the store are going to be DSE'd.
1960
- //
1961
- // store i64 %v, ptr %dest, !DIAssignID !1
1962
- // dbg.assign(..., !DIExpression(fragment, 128, 32), !1, %dest,
1963
- // !DIExpression(DW_OP_plus_uconst, 4))
1964
- //
1965
- // calculateFragmentIntersect(..., SliceOffsetInBits=48,
1966
- // SliceSizeInBits=16, Dest=%dest, Assign=dbg.assign)
1967
- //
1968
- // Memory
1969
- // offset
1970
- // from
1971
- // dest 0 63
1972
- // | |
1973
- // s[######] - Original stores 64 bits to Dest.
1974
- // $[####]-- - DSE says the upper 16 bits are dead, to be removed.
1975
- // d [##] - Assign's address-modifying expression adds 4 bytes to
1976
- // dest.
1977
- // Variable | |
1978
- // Fragment 128|
1979
- // Offsets 159
1980
- //
1981
- // Using the same steps in the first example:
1982
- // 1. SliceOffsetInBits:48 + VarFrag.OffsetInBits:128 = 176
1983
- // 2. 176 - (expression_offset:32 + (d.address - dest):0) = 144
1984
- // 3. SliceOfVariable offset = 144, size = 16:
1985
- // SliceOfVariable ∩ Assign_fragment = (offset: 144, size: 16)
1986
- // SliceOfVariable tells us the bits of the variable described by Assign that
1987
- // are affected by the DSE.
1874
+ // No overlap if this DbgRecord describes a killed location.
1988
1875
if (AssignRecord->isKillAddress ())
1989
1876
return false ;
1990
1877
1991
- DIExpression::FragmentInfo VarFrag =
1992
- getFragmentOrEntireVariable (AssignRecord);
1993
- if (VarFrag.SizeInBits == 0 )
1994
- return false ; // Variable size is unknown.
1995
-
1996
- // Calculate the difference between Dest and the dbg.assign address +
1997
- // address-modifying expression.
1998
- int64_t PointerOffsetInBits;
1878
+ int64_t AddrOffsetInBits;
1999
1879
{
2000
- auto DestOffsetInBytes =
2001
- AssignRecord->getAddress ()->getPointerOffsetFrom (Dest, DL);
2002
- if (!DestOffsetInBytes)
2003
- return false ; // Can't calculate difference in addresses.
2004
-
2005
- int64_t ExprOffsetInBytes;
2006
- if (!AssignRecord->getAddressExpression ()->extractIfOffset (
2007
- ExprOffsetInBytes))
1880
+ int64_t AddrOffsetInBytes;
1881
+ SmallVector<uint64_t > PostOffsetOps; // < Unused.
1882
+ // Bail if we can't find a constant offset (or none) in the expression.
1883
+ if (!AssignRecord->getAddressExpression ()->extractLeadingOffset (
1884
+ AddrOffsetInBytes, PostOffsetOps))
2008
1885
return false ;
2009
-
2010
- int64_t PointerOffsetInBytes = *DestOffsetInBytes + ExprOffsetInBytes;
2011
- PointerOffsetInBits = PointerOffsetInBytes * 8 ;
1886
+ AddrOffsetInBits = AddrOffsetInBytes * 8 ;
2012
1887
}
2013
1888
2014
- // Adjust the slice offset so that we go from describing the a slice
2015
- // of memory to a slice of the variable.
2016
- int64_t NewOffsetInBits =
2017
- SliceOffsetInBits + VarFrag.OffsetInBits - PointerOffsetInBits;
2018
- if (NewOffsetInBits < 0 )
2019
- return false ; // Fragment offsets can only be positive.
2020
- DIExpression::FragmentInfo SliceOfVariable (SliceSizeInBits, NewOffsetInBits);
2021
- // Intersect the variable slice with AssignRecord's fragment to trim it down
2022
- // to size.
2023
- DIExpression::FragmentInfo TrimmedSliceOfVariable =
2024
- DIExpression::FragmentInfo::intersect (SliceOfVariable, VarFrag);
2025
- if (TrimmedSliceOfVariable == VarFrag)
2026
- Result = std::nullopt;
2027
- else
2028
- Result = TrimmedSliceOfVariable;
2029
- return true ;
1889
+ Value *Addr = AssignRecord->getAddress ();
1890
+ // FIXME: It may not always be zero.
1891
+ int64_t BitExtractOffsetInBits = 0 ;
1892
+ DIExpression::FragmentInfo VarFrag =
1893
+ AssignRecord->getFragmentOrEntireVariable ();
1894
+
1895
+ int64_t OffsetFromLocationInBits; // < Unused.
1896
+ return DIExpression::calculateFragmentIntersect (
1897
+ DL, Dest, SliceOffsetInBits, SliceSizeInBits, Addr, AddrOffsetInBits,
1898
+ BitExtractOffsetInBits, VarFrag, Result, OffsetFromLocationInBits);
2030
1899
}
1900
+
1901
+ // / FIXME: Remove this wrapper function and call
1902
+ // / DIExpression::calculateFragmentIntersect directly.
2031
1903
bool at::calculateFragmentIntersect (
2032
1904
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
2033
1905
uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign,
2034
1906
std::optional<DIExpression::FragmentInfo> &Result) {
2035
1907
return calculateFragmentIntersectImpl (DL, Dest, SliceOffsetInBits,
2036
1908
SliceSizeInBits, DbgAssign, Result);
2037
1909
}
1910
+
1911
+ // / FIXME: Remove this wrapper function and call
1912
+ // / DIExpression::calculateFragmentIntersect directly.
2038
1913
bool at::calculateFragmentIntersect (
2039
1914
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
2040
1915
uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign,
0 commit comments