|
| 1 | +#+title: Monthly Report for October 2022 |
| 2 | +#+author: Philip Herron and Arthur Cohen |
| 3 | +#+date: 2022-11-07 |
| 4 | + |
| 5 | +** Overview |
| 6 | + |
| 7 | +Thanks again to [[https://opensrcsec.com/][Open Source Security, inc]] and [[https://www.embecosm.com/][Embecosm]] for their ongoing support for this project. |
| 8 | + |
| 9 | +*** Milestone Progress |
| 10 | + |
| 11 | +This month saw a jump in productivity as we went back to a more regular schedule, after presenting the project's progress at several in-person conferences in September. |
| 12 | + |
| 13 | +We made great strides on multiple parts of the compiler, with Philip spending a lot of time improving our type-system and working on geting closures to work, while Arthur worked on the early name resolving of macros and on handling more intrinsics. |
| 14 | + |
| 15 | +We had also received a lot of review comments on our v2 version of the upstream patches, which consumed a lot of our time. We now have a workflow in place which should help address subsequent reviewsl We now have a workflow in place which should help address subsequent reviews. |
| 16 | +The v3 of the patches, which simply contains these fixes but no new content, has been sent. More patches will follow to update the compiler to its current state. |
| 17 | + |
| 18 | +The compilation of libcore is currently blocked by two issues: Macro importing and exporting, as well as closures. We are working hard on getting these features in the compiler as soon as possible. |
| 19 | + |
| 20 | +We are planning to spend time on these two features as well as look at the ~#[derive]~ builtin macros in order to get closer and closer to compiling ~libcore 1.49~ properly. |
| 21 | + |
| 22 | +** Completed Activities |
| 23 | + |
| 24 | +- AST: dump structs, unions and enums [[https://github.com/rust-gcc/gccrs/pull/1572][PR1572]] |
| 25 | +- Implement data prefetch intrinsics [[https://github.com/rust-gcc/gccrs/pull/1565][PR1565]] |
| 26 | +- builtins: Move implementation into source file [[https://github.com/rust-gcc/gccrs/pull/1564][PR1564]] |
| 27 | +- ast: dump assignment and if expressions [[https://github.com/rust-gcc/gccrs/pull/1563][PR1563]] |
| 28 | +- Support looking up super trait items during path resolution [[https://github.com/rust-gcc/gccrs/pull/1562][PR1562]] |
| 29 | +- Fix -Wunused using `rust-lang.cc` hack [[https://github.com/rust-gcc/gccrs/pull/1560][PR1560]] |
| 30 | +- Fix include structure [[https://github.com/rust-gcc/gccrs/pull/1559][PR1559]] |
| 31 | +- testing: try loop in const function [[https://github.com/rust-gcc/gccrs/pull/1554][PR1554]] |
| 32 | +- Dump item visibility [[https://github.com/rust-gcc/gccrs/pull/1547][PR1547]] |
| 33 | +- Reintroduce targetrustm hooks without the maze of macro definitions in target headers [[https://github.com/rust-gcc/gccrs/pull/1543][PR1543]] |
| 34 | +- ast: dump TypeAlias [[https://github.com/rust-gcc/gccrs/pull/1593][PR1593]] |
| 35 | +- AST: more dump improvements [[https://github.com/rust-gcc/gccrs/pull/1590][PR1590]] |
| 36 | +- Method resolution must support multiple candidates [[https://github.com/rust-gcc/gccrs/pull/1587][PR1587]] |
| 37 | +- Add missing lang item mappings [[https://github.com/rust-gcc/gccrs/pull/1584][PR1584]] |
| 38 | +- Support type resolution on super traits on dyn objects [[https://github.com/rust-gcc/gccrs/pull/1583][PR1583]] |
| 39 | +- Add early name resolver [[https://github.com/rust-gcc/gccrs/pull/1580][PR1580]] |
| 40 | +- fix ICE on missing closing paren [[https://github.com/rust-gcc/gccrs/pull/1574][PR1574]] |
| 41 | +- Apply #1560 master [[https://github.com/rust-gcc/gccrs/pull/1570][PR1570]] |
| 42 | +- make: Inherit CXXFLAGS, guard against non g++ compilers for warnings [[https://github.com/rust-gcc/gccrs/pull/1556][PR1556]] |
| 43 | +- Dump module items [[https://github.com/rust-gcc/gccrs/pull/1548][PR1548]] |
| 44 | +- Initial support for closures [[https://github.com/rust-gcc/gccrs/pull/1608][PR1608]] |
| 45 | +- Improve AST Fragment class [[https://github.com/rust-gcc/gccrs/pull/1607][PR1607]] |
| 46 | +- [33/37] lang-specs: Rename language spec @rs -> @rust [[https://github.com/rust-gcc/gccrs/pull/1605][PR1605]] |
| 47 | +- Add check for recursive trait cycles [[https://github.com/rust-gcc/gccrs/pull/1602][PR1602]] |
| 48 | +- [25/37] rust-privacy-reporter: Add copyright header [[https://github.com/rust-gcc/gccrs/pull/1599][PR1599]] |
| 49 | +- [10/37] rust-cfg-parser: Add copyright header [[https://github.com/rust-gcc/gccrs/pull/1598][PR1598]] |
| 50 | +- ast: Module: unloaded module and inner attributes [[https://github.com/rust-gcc/gccrs/pull/1597][PR1597]] |
| 51 | +- Add more implementations for TARGET_RUST_OS_INFO [[https://github.com/rust-gcc/gccrs/pull/1596][PR1596]] |
| 52 | +- Support outer attribute handling on trait items just like normal items [[https://github.com/rust-gcc/gccrs/pull/1595][PR1595]] |
| 53 | +- Refactor TraitResolver to not require a visitor [[https://github.com/rust-gcc/gccrs/pull/1594][PR1594]] |
| 54 | +- Dump macro declarations properly [[https://github.com/rust-gcc/gccrs/pull/1549][PR1549]] |
| 55 | +- intrinsics: Use lambdas for wrapping_<op> intrinsics [[https://github.com/rust-gcc/gccrs/pull/1621][PR1621]] |
| 56 | +- Intrinsics unchecked ops [[https://github.com/rust-gcc/gccrs/pull/1620][PR1620]] |
| 57 | +- parser: Fix ICE in closure parsing [[https://github.com/rust-gcc/gccrs/pull/1619][PR1619]] |
| 58 | +- Add missing copyright headers [[https://github.com/rust-gcc/gccrs/pull/1618][PR1618]] |
| 59 | +- Apply #1605 on master (fix lang spec) [[https://github.com/rust-gcc/gccrs/pull/1617][PR1617]] |
| 60 | +- Apply 1559 master (remove system includes) [[https://github.com/rust-gcc/gccrs/pull/1616][PR1616]] |
| 61 | +- intrinsics: Add early implementation for atomic_store_{seqcst, relaxed, release} [[https://github.com/rust-gcc/gccrs/pull/1615][PR1615]] |
| 62 | +- intrinsics: Add rust_sorry wrapper for unimplemented intrinsics [[https://github.com/rust-gcc/gccrs/pull/1614][PR1614]] |
| 63 | +- builtins: Rename all bang macro handlers [[https://github.com/rust-gcc/gccrs/pull/1613][PR1613]] |
| 64 | +- Apply #1556 on master [[https://github.com/rust-gcc/gccrs/pull/1585][PR1585]] |
| 65 | + |
| 66 | +*** Contributors this month |
| 67 | + |
| 68 | +- [[https://github.com/ibuclaw][Iain Buclaw]] |
| 69 | +- [[https://github.com/dafaust][David Faust]] |
| 70 | +- [[https://github.com/abbasfaisal][Faisal Abas]] |
| 71 | +- [[https://github.com/dkm][Marc Poulhiès]] |
| 72 | +- [[https://github.com/jdupak][Jakub Dupak]] |
| 73 | + |
| 74 | +*** Overall Task Status |
| 75 | + |
| 76 | +| Category | Last Month | This Month | Delta | |
| 77 | +|-------------+------------+------------+-------| |
| 78 | +| TODO | 168 | 180 | +12 | |
| 79 | +| In Progress | 28 | 31 | +3 | |
| 80 | +| Completed | 466 | 482 | +16 | |
| 81 | + |
| 82 | +*** Test Case |
| 83 | + |
| 84 | +| TestCases | Last Month | This Month | Delta | |
| 85 | +|-----------+------------+------------+-------| |
| 86 | +| Passing | 6794 | 6948 | +154 | |
| 87 | +| Failed | - | - | - | |
| 88 | +| XFAIL | 52 | 52 | - | |
| 89 | +| XPASS | - | - | - | |
| 90 | + |
| 91 | +*** Bugs |
| 92 | + |
| 93 | +| Category | Last Month | This Month | Delta | |
| 94 | +|-------------+------------+------------+-------| |
| 95 | +| TODO | 51 | 56 | +5 | |
| 96 | +| In Progress | 14 | 16 | +2 | |
| 97 | +| Completed | 210 | 214 | +4 | |
| 98 | + |
| 99 | +*** Milestones Progress |
| 100 | + |
| 101 | +We have added milestones to better reflect the GCC merging cycle. More milestones will be put together as more themes of work are discovered along the year. We have closed out the ~Const Generics~ milestone, as it is in a sufficiently complete state for ~libcore-1.49~ compilation. Nonetheless, some const generics features are missing, and have been added to a separate ~Const Generics 2~ project. |
| 102 | + |
| 103 | +Note that the intrinsics milestone percentage on github is not representative: It shows a 66% completion rate, but does not take into account the tracking issues with dozens of unresolved items. |
| 104 | +Thus the percentage is computed using the sum of issues and tracked items done divided by the sums of issues and tracked items overall. |
| 105 | + |
| 106 | +| Milestone | Last Week | This Week | Delta | Start Date | Completion Date | Target | |
| 107 | +|-----------------------------------+-----------+-----------+-------+----------------+-----------------+---------------| |
| 108 | +| Data Structures 1 - Core | 100% | 100% | - | 30th Nov 2020 | 27th Jan 2021 | 29th Jan 2021 | |
| 109 | +| Control Flow 1 - Core | 100% | 100% | - | 28th Jan 2021 | 10th Feb 2021 | 26th Feb 2021 | |
| 110 | +| Data Structures 2 - Generics | 100% | 100% | - | 11th Feb 2021 | 14th May 2021 | 28th May 2021 | |
| 111 | +| Data Structures 3 - Traits | 100% | 100% | - | 20th May 2021 | 17th Sept 2021 | 27th Aug 2021 | |
| 112 | +| Control Flow 2 - Pattern Matching | 100% | 100% | - | 20th Sept 2021 | 9th Dec 2021 | 29th Nov 2021 | |
| 113 | +| Macros and cfg expansion | 100% | 100% | - | 1st Dec 2021 | 31st Mar 2022 | 28th Mar 2022 | |
| 114 | +| Imports and Visibility | 100% | 100% | - | 29th Mar 2022 | 13th Jul 2022 | 27th May 2022 | |
| 115 | +| Const Generics | 76% | 100% | +24% | 30th May 2022 | 10th Oct 2022 | 17th Oct 2022 | |
| 116 | +| Intrinsics and builtins | 15% | 18% | +3% | 6th Sept 2022 | - | 14th Nov 2022 | |
| 117 | +| Initial upstream patches | 0% | 83% | +83% | 10th Oct 2022 | - | 13th Nov 2022 | |
| 118 | +| Final set of upstream patches | 0% | 6% | +6% | 16th Nov 2022 | - | 30th Apr 2023 | |
| 119 | +| Borrow checking | 0% | 0% | - | TBD | - | TBD | |
| 120 | +| Const Generics 2 | 0% | 0% | - | TBD | - | TBD | |
| 121 | + |
| 122 | + |
| 123 | +*** Risks |
| 124 | + |
| 125 | +| Risk | Impact (1-3) | Likelihood (0-10) | Risk (I * L) | Mitigation | |
| 126 | +|--------------------------------+--------------+-------------------+--------------+------------------------------------------------| |
| 127 | +| Missing GCC 13 upstream window | 2 | 3 | 6 | Merge in GCC 14 and be proactive about reviews | |
| 128 | + |
| 129 | +*** Testing project |
| 130 | + |
| 131 | +| Testsuite | Compiler | Last month | This month | Success delta | |
| 132 | +|-------------------------------+---------------------+------------+------------+---------------| |
| 133 | +| rustc testsuite | gccrs -fsyntax-only | 82.1% | 82.2% | +0.1% | |
| 134 | +| gccrs testsuite | rustc stable | 64.5% | 64.2% | -0.1% | |
| 135 | +| rustc testsuite passing tests | gccrs | 12.6% | 12.3% | -0.3% | |
| 136 | +| rustc testsuite (no_std) | gccrs | 28.0% | 27.6% | -0.4% | |
| 137 | +| rustc testsuite (no_core) | gccrs | 83.3% | 33.3% | -50.0% | |
| 138 | +| blake3 | gccrs | 25.0% | 25.5% | - | |
| 139 | +| libcore | gccrs | 0% | 0% | - | |
| 140 | + |
| 141 | +** Planned Activities |
| 142 | + |
| 143 | +- Finish closure support |
| 144 | +- Finish builtin macro name resolution support |
| 145 | +- Implement remaining intrinsics |
| 146 | +- Finish patch upstreaming |
| 147 | + |
| 148 | +** Detailed changelog |
| 149 | + |
| 150 | +*** Macro expansion and name resolution |
| 151 | + |
| 152 | +If you are not familiar with the concept of name resolution, I would recommend starting by reading parts of the macro expansion and name resolution chapters of the Rust compiler development guide: |
| 153 | + |
| 154 | +1. [[https://rustc-dev-guide.rust-lang.org/name-resolution.html][Name Resolution]] |
| 155 | +2. [[https://rustc-dev-guide.rust-lang.org/macro-expansion.html#name-resolution][Macro Name Resolution]] |
| 156 | + |
| 157 | +Macros needing to be name resolved is one of the reasons why name resolution happens at the AST level: Because macros expand to new fragments of AST, and need to be expanded before further compiler passes, we need to be able to refer a macro invocation to its definition. |
| 158 | + |
| 159 | +This includes resolving "simple" examples such as the following: |
| 160 | + |
| 161 | +#+BEGIN_SRC rust |
| 162 | +macro_rules! a { () => () }; |
| 163 | + |
| 164 | +a!(); |
| 165 | + |
| 166 | +macro_rules! a { (now_with_more_tokens) => () }; |
| 167 | + |
| 168 | +a!(now_with_more_tokens); |
| 169 | +#+END_SRC |
| 170 | + |
| 171 | +or more complex ones involving imports: |
| 172 | + |
| 173 | +#+BEGIN_SRC rust |
| 174 | +use lazy_static::lazy_static as the_famous_lazy_macro; |
| 175 | + |
| 176 | +the_famous_lazy_macro! { |
| 177 | + static ref A: i32 = 15; |
| 178 | +} |
| 179 | +#+END_SRC |
| 180 | + |
| 181 | +However, it does not make sense to perform a "full" name resolution at this point: macro expansion will generate new tokens, which could then benefit from a later resolution. Furthermore, the macro lexical scope is quite simple compared to the type scope of name scope and has slightly different rules. |
| 182 | +This explains why name resolution is "split in two" in ~rustc~: One part takes care of resolving macro invocations and imports, and the other takes care of resolving types, variables, function calls... |
| 183 | + |
| 184 | +From this point onward, we will refer to the ~Early Name Resolution~ as the pass responsible for resolving imports and macro invocations, and to ~Name Resolution~ as the later pass. |
| 185 | + |
| 186 | +Up until the month of October, our macro expander performed macro name resolution whenever a macro invocation required expansion. This worked fine in practice, even for complex cases, but made it difficult to expand with proper name resolution rules or imports. |
| 187 | +Adding functionality such as ~#[macro_export]~ and ~#[macro_import]~ on top of it would prove to be too difficult, so we chose to split up the name resolution pass away from the expansion pass. |
| 188 | + |
| 189 | +**** A new expansion system |
| 190 | + |
| 191 | +To take care of macro and import name resolution, we have implemented a new ~EarlyNameResolver~ visitor which takes care of tying a macro invocation to its rules definition. The previous system worked recursively and expanded as many macros as it could in one place, but it was difficult to integrate the ~EarlyNameResolver~ within that system, which was starting to be hard to maintain and very complex. |
| 192 | + |
| 193 | +We have thus switched over to a fixed-point algorithm for resolving and expanding macros: we run the early name resolver, run the macro expander, check if anything has changed, and do it again. |
| 194 | + |
| 195 | +Let's look at an example of how the two systems differ, given this piece of code, and assuming that all these macro invocations expand to their input. |
| 196 | + |
| 197 | +#+BEGIN_SRC rust |
| 198 | +fn main() { |
| 199 | + foo!(bar!(baz!(let v = 15))); |
| 200 | + |
| 201 | + a!(b!(a_fn_call())); |
| 202 | +} |
| 203 | +#+END_SRC |
| 204 | + |
| 205 | +1. Previous system |
| 206 | + |
| 207 | +#+BEGIN_SRC rust |
| 208 | +fn main() { |
| 209 | + // recursively expand this invocation for as long as possible |
| 210 | + foo!(bar!(baz!(let v = 15))); |
| 211 | + |
| 212 | + a!(b!(a_fn_call())); |
| 213 | +} |
| 214 | + |
| 215 | +// into... |
| 216 | + |
| 217 | +fn main() { |
| 218 | + bar!(baz!(let v = 15)); |
| 219 | + |
| 220 | + a!(b!(a_fn_call())); |
| 221 | +} |
| 222 | + |
| 223 | +// into... |
| 224 | + |
| 225 | +fn main() { |
| 226 | + baz!(let v = 15); |
| 227 | + |
| 228 | + a!(b!(a_fn_call())); |
| 229 | +} |
| 230 | + |
| 231 | +// into... |
| 232 | + |
| 233 | +fn main() { |
| 234 | + let v = 15; |
| 235 | + |
| 236 | + a!(b!(a_fn_call())); |
| 237 | +} |
| 238 | + |
| 239 | +// into... |
| 240 | + |
| 241 | +fn main() { |
| 242 | + let v = 15; |
| 243 | + |
| 244 | + // now this invocation |
| 245 | + a!(b!(a_fn_call())); |
| 246 | +} |
| 247 | + |
| 248 | +// into... |
| 249 | + |
| 250 | +fn main() { |
| 251 | + let v = 15; |
| 252 | + |
| 253 | + b!(a_fn_call()); |
| 254 | +} |
| 255 | + |
| 256 | +// into... |
| 257 | + |
| 258 | + |
| 259 | +fn main() { |
| 260 | + let v = 15; |
| 261 | + |
| 262 | + a_fn_call(); |
| 263 | +} |
| 264 | + |
| 265 | +// done! |
| 266 | +#+END_SRC |
| 267 | + |
| 268 | +2. Fixed-point fashion |
| 269 | + |
| 270 | +#+BEGIN_SRC rust |
| 271 | +fn main() { |
| 272 | + // expand each invocation *once* as we go through the crate |
| 273 | + |
| 274 | + foo!(bar!(baz!(let v = 15))); |
| 275 | + |
| 276 | + a!(b!(a_fn_call())); |
| 277 | +} |
| 278 | + |
| 279 | +// into... |
| 280 | + |
| 281 | +fn main() { |
| 282 | + bar!(baz!(let v = 15)); |
| 283 | + |
| 284 | + b!(a_fn_call()); |
| 285 | +} |
| 286 | + |
| 287 | +// into... |
| 288 | + |
| 289 | +fn main() { |
| 290 | + baz!(let v = 15); |
| 291 | + |
| 292 | + a_fn_call(); |
| 293 | +} |
| 294 | + |
| 295 | +// into... |
| 296 | + |
| 297 | +fn main() { |
| 298 | + let v = 15; |
| 299 | + |
| 300 | + a_fn_call(); |
| 301 | +} |
| 302 | + |
| 303 | +// done! |
| 304 | +#+END_SRC |
| 305 | + |
| 306 | +The code responsible for performing this dance looks a bit like the following. |
| 307 | + |
| 308 | +#+BEGIN_SRC c++ |
| 309 | +auto enr = EarlyNameResolver(); |
| 310 | +auto expander = MacroExpander(); |
| 311 | + |
| 312 | +do { |
| 313 | + enr.go(crate); |
| 314 | + expander.go(crate); |
| 315 | +} while (expander.has_changed() && !recursion_limit_reached()); |
| 316 | +#+END_SRC |
| 317 | + |
| 318 | +It's a really simple and robust system, which helps clean up the code a lot. |
| 319 | + |
| 320 | +**** The problem |
| 321 | + |
| 322 | +Sadly, this system is not without flaw. As you may know, not all Rust macros can be expanded lazily! |
| 323 | + |
| 324 | +#+BEGIN_SRC rust |
| 325 | +macro_rules! gives_literal { () => ("literal!") } |
| 326 | + |
| 327 | +macro_rules! fake_concat { |
| 328 | + ($a:literal, $b:literal) => { concat!($a, $b); } |
| 329 | +} |
| 330 | + |
| 331 | +fn main() { |
| 332 | + let a = concat!("a ", gives_literal!()); // builtin macro, this is fine |
| 333 | + let b = fake_concat!("a ", gives_literal!()); // error! |
| 334 | +} |
| 335 | +#+END_SRC |
| 336 | + |
| 337 | +...and this is the one remaining feature that the fixed-point system has to be able to deal with before we integrate it into the compiler, hopefully soon! |
| 338 | + |
| 339 | +*** Mapping intrinsics to GCC builtins |
| 340 | + |
| 341 | +~gccrs~ differs between two kinds of intrinsics: |
| 342 | + |
| 343 | +1. Those who map directly to GCC builtins, such as ~sqrtf32~ which can be replaced with a call to ~__builtin_sqrtf~ |
| 344 | +2. Those who require the creation of a function block and which might take generic arguments |
| 345 | + |
| 346 | +A nice and short example is the handling of the ~copy_nonoverlapping~ intrinsic, whose declaration is as follows: |
| 347 | + |
| 348 | +#+BEGIN_SRC rust |
| 349 | +pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); |
| 350 | +#+END_SRC |
| 351 | + |
| 352 | +[[https://doc.rust-lang.org/core/intrinsics/fn.copy_nonoverlapping.html][The documentation for that intrinsic]] informs us that it is equivalent to a ~memcpy~ in C, with the argument order swapped. Furthermore, the ~count~ parameter refers to the number of values to copy, not the amount of bytes. We can thus make use of GCC's ~__builtin_memcpy~ to create the following function block: |
| 353 | + |
| 354 | +#+BEGIN_SRC rust |
| 355 | +pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) { |
| 356 | + __builtin_memcpy(dst, src, count * size_of::<T>()); |
| 357 | +} |
| 358 | +#+END_SRC |
| 359 | + |
| 360 | +We do similar things for a lot of Rust intrinsics and have recently encountered some fun limitations. |
| 361 | + |
| 362 | +**** data prefetch intrinsics |
| 363 | + |
| 364 | +Two data prefetch intrinsics exist in Rust, ~core::intrinsics::prefetch_read_data~ and ~core::intrinsics::prefetch_write_data~. These functions are generic over a type parameter ~T~, and take as argument a pointer to that type ~T~. An extra argument is the ~locality~, which refers to a value between 0 and 3 indicating how local the data should be kept cache-wise. |
| 365 | + |
| 366 | +This maps quite nicely to GCC's ~__builtin_prefetch~, whose "declaration" would look like the following: |
| 367 | + |
| 368 | +#+BEGIN_SRC c |
| 369 | +void __builtin_prefetch(const void *addr, int rw, int locality); |
| 370 | +#+END_SRC |
| 371 | + |
| 372 | +The function blocks seem quite easy to create: |
| 373 | + |
| 374 | +#+BEGIN_SRC rust |
| 375 | +pub fn prefetch_read_data<T>(data: *const T, locality: i32) { |
| 376 | + __builtin_prefetch(data, 0 /* read */, locality); |
| 377 | +} |
| 378 | + |
| 379 | +pub fn prefetch_write_data<T>(data: *const T, locality: i32) { |
| 380 | + __builtin_prefetch(data, 1 /* write */, locality); |
| 381 | +} |
| 382 | +#+END_SRC |
| 383 | + |
| 384 | +but an error arises when trying to compile them. For its locality argument, ~__builtin_prefetch~ expects a compile time constant, which it cannot reliably get from the function's argument. This causes a verification pass in our gimplification (a lowering pass in GCC's middle-end) to throw an error and fail the compilation. |
| 385 | + |
| 386 | +Interestingly, a similar limitation is present with ~rustc~ and ~LLVM~, [[https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=8012b1bf794c73b4038f62d4922179aa][but will appear further down the compilation pipeline]]. |
| 387 | + |
| 388 | +This is no-doubt due to our lack of proper constant folding: GCC is able to tell that a call to ~prefetch_read_data(addr, 3)~ is valid and contains a compile-time constant, but we simply do not yet give it the possiblity. Thanks to this year GSOC's student [[https://github.com/abbasfaisal][Faisal Abbas]], we should be able to hook into that constant evaluator and try to extract a constant value if possible. |
| 389 | + |
| 390 | +If intrinsics piqued your interest, feel free to come on our Zulip channel and discuss the work left to be done. There are plenty to implement and we'd love the extra help! |
0 commit comments