Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call ctor function for static globals in patch constant function. #3122

Merged
merged 2 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion tools/clang/lib/CodeGen/CGHLSLMS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3333,8 +3333,32 @@ void CGMSHLSLRuntime::FinishCodeGen() {
bool bIsLib = HLM.GetShaderModel()->IsLib();
if (!bIsLib) {
// need this for "llvm.global_dtors"?
if (HLM.GetShaderModel()->IsHS()) {
if (Function *patchConstantFn = HLM.GetPatchConstantFunction()) {
// static globals are independent for entry function and patch constant function.
// Update static global in entry function will not affect value in patch constant function.
// So just call ctors for patch constant function too.
ProcessCtorFunctions(
M, "llvm.global_ctors",
patchConstantFn->getEntryBlock().getFirstInsertionPt(), false);
IRBuilder<> B(patchConstantFn->getEntryBlock().getFirstInsertionPt());
// For static globals which has const initialize value, copy it at
// beginning of patch constant function to avoid use value updated by
// entry function.
for (GlobalVariable &GV : M.globals()) {
if (GV.isConstant())
continue;
if (!GV.hasInitializer())
continue;
if (GV.getName() == "llvm.global_ctors")
continue;
Value *V = GV.getInitializer();
B.CreateStore(V, &GV);
}
}
}
ProcessCtorFunctions(M, "llvm.global_ctors",
Entry.Func->getEntryBlock().getFirstInsertionPt());
Entry.Func->getEntryBlock().getFirstInsertionPt(), true);
}

UpdateLinkage(HLM, CGM, m_ExportMap, entryFunctionMap,
Expand Down
6 changes: 4 additions & 2 deletions tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2190,7 +2190,7 @@ bool BuildImmInit(Function *Ctor) {
namespace CGHLSLMSHelper {

void ProcessCtorFunctions(llvm::Module &M, StringRef globalName,
Instruction *InsertPt) {
Instruction *InsertPt, bool bRemoveGlobal) {
// add global call to entry func
GlobalVariable *GV = M.getGlobalVariable(globalName);
if (!GV)
Expand Down Expand Up @@ -2228,7 +2228,9 @@ void ProcessCtorFunctions(llvm::Module &M, StringRef globalName,
}
}
// remove the GV
GV->eraseFromParent();
if (bRemoveGlobal) {
GV->eraseFromParent();
}
}

void FinishCBuffer(
Expand Down
2 changes: 1 addition & 1 deletion tools/clang/lib/CodeGen/CGHLSLMSHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void FinishCBuffer(
&AnnotationMap);

void ProcessCtorFunctions(llvm::Module &M, llvm::StringRef globalName,
llvm::Instruction *InsertPt);
llvm::Instruction *InsertPt, bool bRemoveGlobal);

void TranslateRayQueryConstructor(hlsl::HLModule &HLM);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RUN: %dxc -E main -T hs_6_0 %s 2>&1 | FileCheck %s

// Make sure generated buffer load for static buffer used in patch constant function.
// CHECK:call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68,

struct HSPerPatchData
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};

Buffer<float> buf;

const static Buffer<float> static_buf = buf;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also have a test where the static global is modified in the hull shader function and verify that it is not modified in the patch constant function.


HSPerPatchData HSPerPatchFunc()
{
HSPerPatchData d;

d.edges[0] = -5;
d.edges[1] = -6;
d.edges[2] = -7;
d.inside = static_buf[0];

return d;
}



// hull per-control point shader
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[patchconstantfunc("HSPerPatchFunc")]
[outputcontrolpoints(3)]
void main( const uint id : SV_OutputControlPointID )
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: %dxc -E main -T hs_6_0 %s 2>&1 | FileCheck %s

// Make sure @sf is restored to original value in patch constant function.
// CHECK:define void @"\01?HSPerPatchFunc@@YA?AUHSPerPatchData@@XZ"() {
// CHECK:store float 3.000000e+00, float* @sf, align 4
// CHECK-NEXT:call void @dx.op.storePatchConstant.f32
// CHECK-NEXT:call void @dx.op.storePatchConstant.f32
// CHECK-NEXT:call void @dx.op.storePatchConstant.f32
// CHECK-NEXT:load float, float* @sf, align 4
// CHECK-NEXT:call void @dx.op.storePatchConstant.f32
struct HSPerPatchData
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};

static float sf = 3;

HSPerPatchData HSPerPatchFunc()
{
HSPerPatchData d;

d.edges[0] = -5;
d.edges[1] = -6;
d.edges[2] = -7;
d.inside = sf;

return d;
}



// hull per-control point shader
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[patchconstantfunc("HSPerPatchFunc")]
[outputcontrolpoints(3)]
void main( const uint id : SV_OutputControlPointID )
{
sf = 0;
}