lower: Share constant slice data insertion
a7f15291cc1c15c8080affa5754f38030aa7aca0b1007046bdd5735ba45544ab
Use one data insertion path for constant slices and carry the data builder's zero-initialization result into it. This avoids duplicate construction and another scan of mutable constant values. Keep immutable data reuse and distinct storage for mutable literals. Assisted-by: Codex:gpt-6-astra
1 parent
625eabb9
lib/std/lang/lower.rad
+11 -17
| 1860 | 1860 | ||
| 1861 | 1861 | /// Lower constant data to a slice value. |
|
| 1862 | 1862 | /// Creates or reuses a data section entry, then builds a slice header on the stack. |
|
| 1863 | 1863 | fn lowerConstDataAsSlice( |
|
| 1864 | 1864 | self: *mut FnLowerer, |
|
| 1865 | - | values: *[il::DataValue], |
|
| 1865 | + | result: *ConstDataResult, |
|
| 1866 | 1866 | alignment: u32, |
|
| 1867 | 1867 | readOnly: bool, |
|
| 1868 | 1868 | elemTy: *resolver::Type, |
|
| 1869 | 1869 | mutable: bool, |
|
| 1870 | 1870 | length: u32 |
|
| 1871 | 1871 | ) -> il::Val throws (LowerError) { |
|
| 1872 | + | let values = result.values; |
|
| 1872 | 1873 | let elemLayout = resolver::getTypeLayout(*elemTy); |
|
| 1873 | 1874 | let size = elemLayout.size * length; |
|
| 1874 | 1875 | let mut dataName: *[u8] = undefined; |
|
| 1876 | + | let mut found: ?*[u8] = nil; |
|
| 1875 | 1877 | if readOnly { |
|
| 1876 | - | if let found = findConstData(self.low, values, alignment) { |
|
| 1877 | - | set dataName = found; |
|
| 1878 | - | } else { |
|
| 1879 | - | set dataName = try nextDataName(self); |
|
| 1880 | - | self.low.data.append(il::Data { |
|
| 1881 | - | name: dataName, |
|
| 1882 | - | size, |
|
| 1883 | - | alignment, |
|
| 1884 | - | readOnly, |
|
| 1885 | - | isZeroInit: false, |
|
| 1886 | - | values, |
|
| 1887 | - | }, self.low.allocator); |
|
| 1888 | - | } |
|
| 1878 | + | set found = findConstData(self.low, values, alignment); |
|
| 1879 | + | } |
|
| 1880 | + | if let name = found { |
|
| 1881 | + | set dataName = name; |
|
| 1889 | 1882 | } else { |
|
| 1890 | 1883 | set dataName = try nextDataName(self); |
|
| 1891 | 1884 | self.low.data.append(il::Data { |
|
| 1892 | 1885 | name: dataName, |
|
| 1893 | 1886 | size, |
|
| 1894 | 1887 | alignment, |
|
| 1895 | 1888 | readOnly, |
|
| 1896 | - | isZeroInit: dataValuesAreZeroInit(values), |
|
| 1889 | + | isZeroInit: not readOnly and result.zeroInit, |
|
| 1897 | 1890 | values, |
|
| 1898 | 1891 | }, self.low.allocator); |
|
| 1899 | 1892 | } |
|
| 1900 | 1893 | ||
| 1901 | 1894 | // Get data address. |
| 5107 | 5100 | else => throw LowerError::UnexpectedNodeValue(arrayNode), |
|
| 5108 | 5101 | } |
|
| 5109 | 5102 | let result = dataBuilderFinish(&b); |
|
| 5110 | 5103 | let alignment = resolver::getTypeLayout(*item).alignment; |
|
| 5111 | 5104 | return try lowerConstDataAsSlice( |
|
| 5112 | - | self, result.values, alignment, not mutable, |
|
| 5105 | + | self, &result, alignment, not mutable, |
|
| 5113 | 5106 | item, mutable, length |
|
| 5114 | 5107 | ); |
|
| 5115 | 5108 | } |
|
| 5116 | 5109 | let data = try lowerExpr(self, arrayNode); |
|
| 5117 | 5110 | let count = il::Val::Imm(length as i64); |
| 6173 | 6166 | let ptr = try! alloc::alloc( |
|
| 6174 | 6167 | self.low.arena, @sizeOf(il::DataValue), @alignOf(il::DataValue) |
|
| 6175 | 6168 | ) as *mut il::DataValue; |
|
| 6176 | 6169 | ||
| 6177 | 6170 | set *ptr = il::DataValue { item: il::DataItem::Str(s), count: 1 }; |
|
| 6171 | + | let result = ConstDataResult { values: @sliceOf(ptr, 1), zeroInit: false }; |
|
| 6178 | 6172 | ||
| 6179 | 6173 | return try lowerConstDataAsSlice( |
|
| 6180 | - | self, @sliceOf(ptr, 1), 1, true, item, mutable, s.len |
|
| 6174 | + | self, &result, 1, true, item, mutable, s.len |
|
| 6181 | 6175 | ); |
|
| 6182 | 6176 | } |
|
| 6183 | 6177 | ||
| 6184 | 6178 | /// Lower a builtin call expression. |
|
| 6185 | 6179 | fn lowerBuiltinCall(self: *mut FnLowerer, node: *ast::Node, kind: ast::Builtin, args: *mut [*ast::Node]) -> il::Val throws (LowerError) { |