This is an archive of the discontinued LLVM Phabricator instance.

[HLSL] Call global constructors inside entry
ClosedPublic

Authored by beanz on Aug 30 2022, 2:44 PM.

Details

Summary

HLSL doesn't have a runtime loader model that supports global
construction by a loader or runtime initializer. To allow us to leverage
global constructors with minimal code generation impact we put calls to
the global constructors inside the generated entry function.

Diff Detail

Event Timeline

beanz created this revision.Aug 30 2022, 2:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 30 2022, 2:44 PM
Herald added a subscriber: Anastasia. · View Herald Transcript
beanz requested review of this revision.Aug 30 2022, 2:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 30 2022, 2:44 PM
python3kgae added inline comments.Aug 30 2022, 2:48 PM
clang/lib/CodeGen/CGHLSLRuntime.cpp
151

Don't need to generate CtorCalls for lib profile in clang codeGen.
Have to do this when linking anyway.

beanz added inline comments.Aug 30 2022, 2:58 PM
clang/lib/CodeGen/CGHLSLRuntime.cpp
151

Are you sure? The global constructors contain the createHandle calls for resources, and DXC does currently generate those inside shader entries for lib shaders.

I'm sure we're not generating those _correctly_ with this change, but I think we still need the constructor calls inside any function annotated with the [shader(...)] attribute.

python3kgae added inline comments.Aug 30 2022, 3:21 PM
clang/lib/CodeGen/CGHLSLRuntime.cpp
151

I saw dxc did call ctor for all entries. Maybe to match the behavior, we need to do the same thing.
But I don't understand why we must do that except to match what dxc does.
Maybe we can also have a test for lib profile to make understanding things easier?

beanz added inline comments.Sep 6 2022, 8:57 AM
clang/lib/CodeGen/CGHLSLRuntime.cpp
151

I can (and should) add a library shader test too.

In addition to the cases where DXC generates global constructors, we need them in clang in more cases, because I'm using global constructors to reduce the scope of changes HLSL needs in CodeGen.

In the case of global resource variables (as shown in the test in this PR), DXC generates the handle creation calls with a bunch of custom code in clang CodeGen, and inserts that code into the entry functions.

To avoid needing special code for handle creation in Clang, I've put handle creation calls inside the constructors for the resource object. For global definitions, the constructors then get called by the global initialization function automatically, which we can inline into the entry.

aaron.ballman added inline comments.Sep 6 2022, 12:29 PM
clang/test/CodeGenHLSL/GlobalConstructors.hlsl
4

Can you also add a test using __attribute__((constructor))? And probably one using __attribute__((destructor)) at some point as well?

https://godbolt.org/z/jqedf1qGa

I see the docs said that global destructors are not supported, which is fine, but then what's the behavior when a user tries one anyway? (I would expect we'd get reasonable errors about it not being supported). Feel free to handle the dtor bits in a follow-up though.

beanz updated this revision to Diff 458542.Sep 7 2022, 1:00 PM

Adding test coverage for __attribute__((constructor))

beanz added inline comments.Sep 7 2022, 1:46 PM
clang/test/CodeGenHLSL/GlobalConstructors.hlsl
4

I need to play with this. We don't currently support global destructors, but I think we're going to in Clang.

I'll try to get a second patch up today or tomorrow to add global destructors.

aaron.ballman added inline comments.Sep 8 2022, 10:32 AM
clang/lib/CodeGen/CGHLSLRuntime.cpp
167–170

Do we have sema checks for this so users get decent diagnostics instead of a crash (or miscompile)?

beanz added inline comments.Sep 8 2022, 11:02 AM
clang/lib/CodeGen/CGHLSLRuntime.cpp
167–170

It looks like COMDats are only attached if object format supports them (and DXContainer isn't properly handled there). I don't think there is any sema-level validation because the COMDat just binds to the global value address. I'll get a patch up to llvm::Triple to mark DXContainer as not supporting COMDat.

aaron.ballman added inline comments.Sep 8 2022, 11:03 AM
clang/lib/CodeGen/CGHLSLRuntime.cpp
167–170

Thanks! Also be sure to add some logic to SemaDeclAttr.cpp to diagnose specifying a priority.

beanz updated this revision to Diff 458867.Sep 8 2022, 2:19 PM

Adding Sema errors for specifying initializer priority, and a test case for library shaders.

This revision is now accepted and ready to land.Sep 9 2022, 5:08 AM
This revision was landed with ongoing or failed builds.Sep 9 2022, 7:01 AM
This revision was automatically updated to reflect the committed changes.