This is an archive of the discontinued LLVM Phabricator instance.

[HLSL] Added HLSL this as a reference
ClosedPublic

Authored by gracejennings on Oct 11 2022, 3:29 PM.

Details

Summary

This change makes this a reference instead of a pointer in
HLSL. HLSL does not have the -> operator, and accesses through this
are with the . syntax.

Tests were added and altered to make sure
the AST accurately reflects the types.

Diff Detail

Event Timeline

gracejennings created this revision.Oct 11 2022, 3:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 11 2022, 3:29 PM
Herald added a subscriber: Anastasia. · View Herald Transcript
gracejennings requested review of this revision.Oct 11 2022, 3:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 11 2022, 3:29 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
gracejennings edited the summary of this revision. (Show Details)Oct 11 2022, 3:30 PM
bob80905 added inline comments.Oct 11 2022, 3:44 PM
clang/test/AST/HLSL/this-reference.hlsl
63

One small nitpick I've received in some of my revisions is that the llvm repo doesn't want files ending without a new line.
I'm surprised clang-format doesn't catch this.

beanz added a subscriber: aaron.ballman.

Looping in @aaron.ballman here too because this is a bit of a fun one... I know Aaron loves when we show him the best of HLSL 😄

python3kgae added inline comments.Oct 11 2022, 3:58 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Should this be a reference type?

267

Same here, a reference type?

clang/lib/Sema/SemaExprMember.cpp
1906

Is it possible that ThisTy is not a pointer type?

clang/test/AST/HLSL/RWBuffer-AST.hlsl
50

reference type?

Formatting

Added new line file ending

Includng formatting update

gracejennings marked an inline comment as done.Oct 11 2022, 4:18 PM
gracejennings added inline comments.
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Could you expand on the question? I'm not sure I understand what you're asking. The two changes in this file were made to update the previous RWBuffer implementation

python3kgae added inline comments.Oct 11 2022, 4:35 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

The current code will create CXXThisExpr with the pointeeType.
I thought it should be a reference type of the pointeeType.

Like in the test,
CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type> *' implicit this

The type is RWBuffer<element_type> * before,
I expected this patch will change it to
RWBuffer<element_type> &.

gracejennings added inline comments.Oct 14 2022, 12:31 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

The change that makes it more reference like than c++ from:

-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:17> 'int' lvalue ->First 0x{{[0-9A-Fa-f]+}}
-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:11> 'Pair *' this

to hlsl with this change

-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> 'int' lvalue .First 0x{{[0-9A-Fa-f]+}}
-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:11> 'Pair' lvalue this

python3kgae added inline comments.Oct 14 2022, 2:31 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

I guess we have to change clang codeGen for this anyway.

Not sure which has less impact for codeGen side, lvalue like what is in the current patch or make it a lvalue reference? My feeling is lvalue reference might be eaiser.

Did you test what needs to change for clang codeGen on top of the current patch?

gracejennings marked 5 inline comments as done.Oct 19 2022, 11:03 AM
gracejennings added inline comments.
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

With just the lvalue change in the current patch there should be no additional changes needed in clang CodeGen on top of the current patch

python3kgae added inline comments.Oct 19 2022, 2:39 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Since we already get the codeGen working with this patch,
it would be nice to have a codeGen test.

Thank you for your patience while I sat and thought about this for a while. I'm not against the idea, but I've definitely got some design concerns with it which I've pointed out in the review. I think this also needs considerably more testing of the codegen and semantic behaviors around improper use of this. It's also worth investigating what else needs modifications to support this properly -- I would imagine the static analyzer cares about CXXThisExpr semantics, and I'm betting thread safety analysis does as well. If you haven't already, you should search for uses of CXXThisExpr in the code base to spot other areas that need test coverage to prove they still work properly in HLSL.

clang/include/clang/AST/ExprCXX.h
1158–1161 ↗(On Diff #466964)

I don't think we need to add the Create() method -- but if there's a reason you really want to add it, I think we should protect the constructor so it's clear which interface callers should use. I think that sort of change is logically orthogonal to the rest of the patch and would be better as a separate (NFC) change.

clang/lib/Sema/HLSLExternalSemaSource.cpp
180

I think it's an interesting question to consider, but I have some concerns. Consider code like this:

struct S {
  int Val = 0;
  void foo() {
    Val = 10;
    S Another;
    this = Another; // If this is a non-const reference, we can assign into it...
    print(); // ... so do we print 0 or 10?
    // When this function ends, is `this` destroyed because `Another` goes out of scope?
  }
  void print() {
    std::cout << Val;
  }
};

I think we need to prevent code like that from working. But it's not just direct assignments that are a concern. Consider:

struct S;

void func(S &Out, S &In) {
  Out = In;
}

struct S {
  int Val = 0;
  void foo() {
    Val = 10;
    S Another;
    func(this, Another); // Same problem here!
    print();
  }
  void print() {
    std::cout << Val;
  }
};

Another situation that I'm not certain of is whether HLSL supports tail-allocation where the code is doing something like this + 1 to get to the start of the trailing objects.

gracejennings marked an inline comment as done.
  • Add codegen test and fix member implicit this
gracejennings marked an inline comment as done.Nov 2 2022, 3:48 PM
gracejennings added inline comments.
clang/include/clang/AST/ExprCXX.h
1158–1161 ↗(On Diff #466964)

Ok that makes a lot of sense. I'll go ahead and move it out of this change.

1158–1161 ↗(On Diff #466964)

Ok that makes sense, there was no compelling reason, so I'll go ahead and move it out of this change.

clang/lib/Sema/HLSLExternalSemaSource.cpp
180

For the first example we would expect this to work for HLSL because this is reference like (with modifications to make it supported by HLSL). We would expect Val to be 0, printing 0, and Another to be destroyed, but not this. I went ahead and added similar CodeGen test coverage.

For the second example, there is not reference support in HLSL. Changing to a similar example with copy-in and copy-out to make it HLSL supported would take care of that case, but copy-in/out is not supported upstream yet.

aaron.ballman added inline comments.Nov 3 2022, 11:04 AM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

For the first example we would expect this to work for HLSL because this is reference like (with modifications to make it supported by HLSL). We would expect Val to be 0, printing 0, and Another to be destroyed, but not this. I went ahead and added similar CodeGen test coverage.

I was surprised about the dangers of that design, so I spoke with @beanz over IRC about it and he was saying that the goal for HLSL was for that code to call the copy assignment operator and not do a reference replacement, so it'd behave more like *this in C++, as in: https://godbolt.org/z/qrEav6sjq. That design makes a lot more sense to me, but I'm also not at all an expert on HLSL, so I'll defer to whatever you and @beanz think the behavior should be here.

beanz added inline comments.Nov 3 2022, 12:58 PM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Yea. The syntax looks a little funky coming from C++ where this is a pointer, but with this being a reference and following C++ rules that references can't be re-assigned you end up with something more like https://godbolt.org/z/555vrK6q3.

This change does seem to capture the copy behavior with Another being copied into this.Addr, so I think this has the HLSL feature correct.

aaron.ballman added inline comments.Nov 4 2022, 7:21 AM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Is there a way we can make the codegen test more obvious by adding a copy assignment operator that gets called (so there's something more clear in the IR that this isn't reference re-binding)? Does HLSL have this notion or because there are no references there's no copy/move operations?

gracejennings added inline comments.Nov 4 2022, 10:27 AM
clang/lib/Sema/HLSLExternalSemaSource.cpp
180

We don't have copy assignment support in that way for HLSL here yet

Generally looking good to me aside from a test change that I don't quite understand yet.

clang/lib/Sema/HLSLExternalSemaSource.cpp
180

Okie dokie, thank you for the explanations and discussion on this while I learned about HLSL. :-)

clang/test/AST/HLSL/RWBuffer-AST.hlsl
49–51

// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}

I'm confused by this -- it says the type of the expression is element_type * but that it uses . as an operator instead of ->. One of these seems like it is wrong, but perhaps I'm missing something.

59–60

Similar confusion here.

clang/test/AST/HLSL/this-reference-template.hlsl
36

Phab may have made this suggestion hard to understand. I added a space between // and CHECK and removed one of the whitespaces used for alignment.)

beanz added inline comments.Nov 4 2022, 11:52 AM
clang/test/AST/HLSL/RWBuffer-AST.hlsl
49–51

Isn't that the type of the member not the type of the this? This example seems to result in a pointer MemberExpr with a . access: https://godbolt.org/z/j9f5nP4s6

This is a little awkward because we have a pointer member inside this struct even though pointers are illegal in HLSL source :(

  • Add assignment overload codegen test
gracejennings marked 4 inline comments as done.Nov 4 2022, 12:02 PM
aaron.ballman accepted this revision.Nov 7 2022, 6:43 AM

LGTM, thank you!

clang/test/AST/HLSL/RWBuffer-AST.hlsl
49–51

Isn't that the type of the member not the type of the this? This example seems to result in a pointer MemberExpr with a . access: https://godbolt.org/z/j9f5nP4s6

Oh yeah, that is correct, it's the member type not the base object type. I was reading the AST dumping code incorrectly when I peeked at it, this is fine (for the moment; it'd be good to fix the illegal pointer bits but that's orthogonal).

This revision is now accepted and ready to land.Nov 7 2022, 6:43 AM
This revision was automatically updated to reflect the committed changes.