[PATCH] D63371: Rewrite ConstStructBuilder with a mechanism that can cope with splitting and updating constants.
John McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 17 13:35:42 PDT 2019
rjmccall added a comment.
Minor requests, then LGTM.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:73
+/// Incremental builder for an llvm::Constant* holding a structure constant.
+class ConstantBuilder : private ConstantBuilderUtils {
+ llvm::SmallVector<llvm::Constant*, 32> Elems;
----------------
rsmith wrote:
> rjmccall wrote:
> > This seems like a very generic name for this type.
> It is intended to be a very generic type. (I was trying to arrange it so that it could possibly be moved to LLVM eventually. I heard that globalopt would benefit from being able to do this kind of constant splitting / reforming.) Is `ConstantAggregateBuilder` sufficiently more precise?
Yeah, that makes sense, since it aligns with the LLVM type name. I guess the big blocker there is the lack of a `CharUnits` equivalent in LLVM.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:190
+bool ConstantBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
+ bool AllowOverwrite) {
+ const ASTContext &Context = CGM.getContext();
----------------
rsmith wrote:
> rjmccall wrote:
> > `AllowOversized` (which you used in the interface) seems like a better name.
> `AllowOversized` is used to mean "the size of the constant may be larger than the size of the type", and is a parameter to `build` / `buildFrom`.
> `AllowOverwrite` is used to mean "adding this constant may overwrite something you've already been given", and is a parameter to `add` / `addBits`.
>
> I can make these names more different from each other if that would help?
Oh, oops. No, sorry, no need to do anything here.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:258
+ return false;
+ assert(CI->getBitWidth() == CharWidth && "splitAt failed");
+ assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
----------------
rsmith wrote:
> rjmccall wrote:
> > Oh, because we're splitting before and after a single-`CharUnits` range? That seems worthy of a somewhat clearer explanation in the code.
> >
> > I guess we could have a non-`ConstantInt` single-byte value. Unlikely but not impossible. :)
> Yes. It's not too hard to craft a testcase where we'd get an explicit `undef` here; added handling for that and for all-zeroes constants, which are both correctly handled by overwriting the whole byte.
Ah, yeah, good catch; I was thinking it was okay to be suboptimal if we saw a `<1 x i8>` or a 1-byte pointer or whatever, but undef and zero are definitely worth covering here.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:375
+
+ // FIXME: We could theoretically split a ConstantInt if the need ever arose.
+
----------------
rsmith wrote:
> rjmccall wrote:
> > Does this not come up all the time with bit-fields? I guess we emit them in single-`char` chunks, so it wouldn't. Probably worth a comment.
> Done.
>
> We could hit this case for cases such as:
>
> ```
> union U { int a; int b : 3; };
> struct S { U u; };
> S s = {(union U){1234}, .u.b = 5};
> ```
>
> (which `CodeGen` currently rejects with "cannot compile this static initializer yet" in C), and splitting the `ConstantInt` would allow us to emit that initializer as a constant, but I'm not sure it's worthwhile unless it lets us simplify or improve bitfield emission in general. (The above isn't a case that C requires us to treat as a constant initializer, so rejecting it is not a conformance issue.)
>
> Maybe instead of splitting bitfields into 1-byte chunks like we currently do, we should try to combine them into a single `iN`, like `CGRecordLayoutBuilder` does. But splitting to `i8` maintains the status quo, which is what I was aiming for in this patch.
I'm fine with single-byte emission for constant bit-fields; ugliness here shouldn't really have significant consequences. The comment is good enough.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:162
+ return replace(V, BeginOff, EndOff, Vals.begin(), Vals.end());
+}
+
----------------
Can these go to STLExtras or somewhere similar?
================
Comment at: lib/CodeGen/CGExprConstant.cpp:221
+ // bits have unspecified values.
+ llvm::APInt BitsThisByte = Bits;
+ if (BitsThisByte.getBitWidth() < CharWidth)
----------------
Should this be `BitsThisChar` for consistency?
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63371/new/
https://reviews.llvm.org/D63371
More information about the cfe-commits
mailing list