Skip to content

Commit 1a0a7f6

Browse files
author
Tim Foley
authored
Various IR fixes for Falcor (shader-slang#280)
- Change function mangling so we use `p<parameterCount>p` instead of just `p<parameterCount>` to avoid the parameter count running into digits at the start of a mangled type name and tripping up the un-mangling logic. - We really need to step back at some point and define our mangling scheme a bit more carefully, especially if we are going to keep going down this road where un-mangling things is important for generating HLSL output. - Also allow the unmangling logic to unmangle a few more cases of generic parameters, so that it can skip over them to get to the parameter count of the underlying function. - Add a notion of an `unreachable` instruction to the IR, and emit it as the terminator (if needed) at the end of the last block for a function with a non-void return type. - This does *not* implement any logic to emit a diagnostic if the `unreachable` turns out to be potentially reachable - Fix a bug in IR specialization of generics where we can't create two different specializations of the same function, because both get registered in the same hash map With all these fixes, testing in Falcor modified to use the full Slang compiler and IR for all HLSL/Slang: - The UI and text rendering shaders yield HLSL that compiles without error; no idea if they actually *work* - The ModelViewer shaders yield HLSL, but there are some issues (looks like type legalization isn't applying to stuff inside constant buffers)
1 parent 59a4c0c commit 1a0a7f6

File tree

7 files changed

+58
-10
lines changed

7 files changed

+58
-10
lines changed

source/slang/emit.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -4743,9 +4743,15 @@ emitDeclImpl(decl, nullptr);
47434743
switch(peek())
47444744
{
47454745
case 'T':
4746+
case 'C':
47464747
get();
47474748
break;
47484749

4750+
case 'v':
4751+
get();
4752+
readType();
4753+
break;
4754+
47494755
default:
47504756
SLANG_UNEXPECTED("bad name mangling");
47514757
break;
@@ -4862,7 +4868,9 @@ emitDeclImpl(decl, nullptr);
48624868
UInt readParamCount()
48634869
{
48644870
expect("p");
4865-
return readCount();
4871+
UInt count = readCount();
4872+
expect("p");
4873+
return count;
48664874
}
48674875
};
48684876

@@ -5438,6 +5446,9 @@ emitDeclImpl(decl, nullptr);
54385446
SLANG_UNEXPECTED("terminator inst");
54395447
return;
54405448

5449+
case kIROp_unreachable:
5450+
return;
5451+
54415452
case kIROp_ReturnVal:
54425453
case kIROp_ReturnVoid:
54435454
case kIROp_discard:

source/slang/ir-inst-defs.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ INST(loopTest, loopTest, 3, 0)
184184
INST(switch, switch, 3, 0)
185185

186186
INST(discard, discard, 0, 0)
187+
INST(unreachable, unreachable, 0, 0)
187188

188189
INST(Add, add, 2, 0)
189190
INST(Sub, sub, 2, 0)

source/slang/ir-insts.h

+9
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ struct IRReturnVoid : IRReturn
138138
struct IRDiscard : IRTerminatorInst
139139
{};
140140

141+
// Signals that this point in the code should be unreachable.
142+
// We can/should emit a dataflow error if we can ever determine
143+
// that a block ending in one of these can actually be
144+
// executed.
145+
struct IRUnreachable : IRTerminatorInst
146+
{};
147+
141148
struct IRBlock;
142149

143150
struct IRUnconditionalBranch : IRTerminatorInst
@@ -487,6 +494,8 @@ struct IRBuilder
487494

488495
IRInst* emitDiscard();
489496

497+
IRInst* emitUnreachable();
498+
490499
IRInst* emitBranch(
491500
IRBlock* block);
492501

source/slang/ir.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ namespace Slang
168168
case kIROp_loopTest:
169169
case kIROp_discard:
170170
case kIROp_switch:
171+
case kIROp_unreachable:
171172
return true;
172173
}
173174
}
@@ -1152,6 +1153,16 @@ namespace Slang
11521153
return inst;
11531154
}
11541155

1156+
IRInst* IRBuilder::emitUnreachable()
1157+
{
1158+
auto inst = createInst<IRUnreachable>(
1159+
this,
1160+
kIROp_unreachable,
1161+
nullptr);
1162+
addInst(inst);
1163+
return inst;
1164+
}
1165+
11551166
IRInst* IRBuilder::emitDiscard()
11561167
{
11571168
auto inst = createInst<IRDiscard>(
@@ -3457,6 +3468,14 @@ namespace Slang
34573468
return clonedFunc;
34583469
}
34593470

3471+
IRFunc* cloneSimpleFuncWithoutRegistering(IRSpecContextBase* context, IRFunc* originalFunc)
3472+
{
3473+
auto clonedFunc = context->builder->createFunc();
3474+
cloneFunctionCommon(context, clonedFunc, originalFunc);
3475+
return clonedFunc;
3476+
}
3477+
3478+
34603479
IRFunc* cloneSimpleFunc(IRSpecContextBase* context, IRFunc* originalFunc)
34613480
{
34623481
auto clonedFunc = context->builder->createFunc();
@@ -4017,7 +4036,7 @@ namespace Slang
40174036

40184037
// TODO: other initialization is needed here...
40194038

4020-
auto specFunc = cloneSimpleFunc(&context, genericFunc);
4039+
auto specFunc = cloneSimpleFuncWithoutRegistering(&context, genericFunc);
40214040

40224041
// Set up the clone to recognize that it is no longer generic
40234042
specFunc->mangledName = specMangledName;

source/slang/lower-to-ir.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -3242,8 +3242,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
32423242
// this by putting an `unreachable` terminator here,
32433243
// and then emit a dataflow error if this block
32443244
// can't be eliminated.
3245-
SLANG_UNEXPECTED("Needed a return here");
3246-
UNREACHABLE(subContext->irBuilder->emitReturn());
3245+
subContext->irBuilder->emitUnreachable();
32473246
}
32483247
}
32493248
}

source/slang/mangle.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ namespace Slang
164164
// parameter are they at the specified depth).
165165
emitName(context, genericParamIntVal->declRef.GetName());
166166
}
167+
else if( auto constantIntVal = dynamic_cast<ConstantIntVal*>(val) )
168+
{
169+
// TODO: need to figure out what prefix/suffix is needed
170+
// to allow demangling later.
171+
emitRaw(context, "k");
172+
emit(context, (UInt) constantIntVal->value);
173+
}
167174
else
168175
{
169176
SLANG_UNEXPECTED("unimplemented case in mangling");
@@ -277,11 +284,13 @@ namespace Slang
277284
//
278285
if( auto callableDeclRef = declRef.As<CallableDecl>())
279286
{
280-
emitRaw(context, "p");
281-
282287
auto parameters = GetParameters(callableDeclRef);
283288
UInt parameterCount = parameters.Count();
289+
290+
emitRaw(context, "p");
284291
emit(context, parameterCount);
292+
emitRaw(context, "p");
293+
285294
for(auto paramDeclRef : parameters)
286295
{
287296
emitType(context, GetType(paramDeclRef));

tests/ir/loop.slang.expected

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ ir_global_var @_SV01s : Ptr<@ThreadGroup vector<float,4>[64]>;
55

66
ir_global_var @_SV05input : Ptr<StructuredBuffer<vector<float,4>>>;
77

8-
ir_func @_S031GroupMemoryBarrierWithGroupSyncp0V : () -> void;
8+
ir_func @_S031GroupMemoryBarrierWithGroupSyncp0pV : () -> void;
99

1010
ir_global_var @_SV06output : Ptr<RWStructuredBuffer<vector<float,4>>>;
1111

12-
ir_func @_S04mainp3uuuV : (uint, uint, uint) -> void
12+
ir_func @_S04mainp3puuuV : (uint, uint, uint) -> void
1313
{
1414
block %1(
1515
param %2 : uint,
@@ -39,7 +39,7 @@ block %15:
3939
loopTest(%20, %21, %16)
4040

4141
block %21:
42-
call(@_S031GroupMemoryBarrierWithGroupSyncp0V)
42+
call(@_S031GroupMemoryBarrierWithGroupSyncp0pV)
4343
let %22 : uint = load(%6)
4444
let %23 : Ptr<vector<float,4>> = getElementPtr(@_SV01s, %22)
4545
let %24 : Ptr<vector<float,4>> = var()
@@ -70,7 +70,7 @@ block %17:
7070
unconditionalBranch(%15)
7171

7272
block %16:
73-
call(@_S031GroupMemoryBarrierWithGroupSyncp0V)
73+
call(@_S031GroupMemoryBarrierWithGroupSyncp0pV)
7474
let %40 : RWStructuredBuffer<vector<float,4>> = load(@_SV06output)
7575
let %41 : uint = load(%5)
7676
let %42 : Ptr<vector<float,4>> = getElementPtr(@_SV01s, 0)

0 commit comments

Comments
 (0)