<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Nikita Popov wrote a great block post last week: “<a href="https://www.npopov.com/2021/06/02/Design-issues-in-LLVM-IR.html" class="">Design issues in LLVM IR</a>” that I just found.  It is well framed and nicely written, it seems like a good idea to discuss this on llvm-dev.  :-)<div class=""><br class=""></div><div class="">Here are my 2c for what it is worth:<div class=""><br class=""></div><div class="">a) I completely agree we should continue to invest in fixing the core of LLVM.  There are long standing issues that we should fix, and not doing so slows things down, leads to worse quality of results, etc.</div></div><div class=""><br class=""></div><div class="">b) I completely agree with his framing on canonicalization and its value.  I think that LLVM has historically taken this a bit too far (e.g. loop transformations, the old IndVar/LSR dichotomy among others) but many of those have already been walked back.</div><div class=""><br class=""></div><div class="">c) I completely agree we need to continue to march towards opaque pointers, I’m a fan of this work.</div><div class=""><br class=""></div><div class="">d) I’m less enthused about eliminating type based GEP.  The post is right that indexing computations are expensive, but that is largely due to the algorithms used, not the IR structure.  If this was the thing to fix, then we should fix other aspects of the design.  The thing that I’m particularly concerned about is array indexes: I think we need to preserve the ability to do simple dependence analysis and other array subscript indexing analyses in the middle end.  I think the sweet spot is to drop types from pointers, but keep them on GEPs.  Alternatively, finish the typeless pointer migration and then evaluate what to do with GEPs only when that completes.</div><div class=""><br class=""></div><div class="">e) Constant Expressions are a disaster.  In addition to the problem identified, there are also many annoying cases to deal with, eg. When constexprs exist in phi nodes, trapping constexprs, etc.  In my opinion, the fix is to eliminate them entirely, in a few steps:</div><div class=""><br class=""></div><div class="">    1) Introduce a new “RelocatableConstant” object which is *not* a mirror of all the IR operations in LLVM, but is instead designed to be used in global variables and allows the standard “globalpointer+offset” pattern that object files support, and we should add a new MachoRelocatableConstant class to represent the “(gv1-gv2+offset)” relocations macho supports.  The presence of this would make codegen and frontends easier to write, and get rid of all the fiddly pattern matching stuff.  I think we need to talk about whether “offset” is a byte offset, or whether it is a series of (constant integer) field indexes in a GEP like operation.  I would argue for the later to make inter procedural optimizations easier to write, but it is debatable.</div><div class=""><br class=""></div><div class="">    2) Move the general constant folding API off of ConstantExpr to somewhere else, it never should have been there for reasons pointed out in the blog.</div><div class=""><br class=""></div><div class="">    3) Eliminate ConstExpr: after #1, we don’t need a mirror of the LLVM IR in constant nodes.  Constant folding should be a failable operation and would return the primitive nodes like ConstantInt.  The asmparser / byte code parser could auto upgrade general unfolded constexprs to instructions when in a function and to [Macho]RelocatableConstant</div><div class=""><br class=""></div><div class="">In any case, I’d love to see progress on any of these.  I’d personally love to see the typeless pointers land because we’re in an unfortunate in-between state, and we should close off partial transitions.</div><div class=""><br class=""></div><div class="">-Chris</div></body></html>