6
6
#include " slang-ir-call-graph.h"
7
7
#include " slang-ir-insts.h"
8
8
#include " slang-ir-layout.h"
9
+ #include " slang-ir-redundancy-removal.h"
9
10
#include " slang-ir-spirv-legalize.h"
10
11
#include " slang-ir-spirv-snippet.h"
11
12
#include " slang-ir-util.h"
@@ -2628,14 +2629,75 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
2628
2629
// / Emit a declaration for the given `irFunc`
2629
2630
SpvInst* emitFuncDeclaration (IRFunc* irFunc)
2630
2631
{
2631
- if (irFunc->findDecorationImpl (kIROp_SPIRVOpDecoration ))
2632
- return nullptr ;
2633
- // For now we aren't handling function declarations;
2634
- // we expect to deal only with fully linked modules.
2632
+ // [2.4: Logical Layout of a Module]
2633
+ //
2634
+ // > All function declarations("declarations" are functions without a
2635
+ // body; there is no forward declaration to a function with a body).
2636
+ //
2637
+ auto section = getSection (SpvLogicalSectionID::FunctionDeclarations);
2638
+
2639
+ // > A function declaration is as follows.
2640
+ // > * Function declaration, using OpFunction.
2641
+ // > * Function parameter declarations, using OpFunctionParameter.
2642
+ // > * Function end, using OpFunctionEnd.
2643
+ //
2644
+
2645
+ // [3.24. Function Control]
2646
+ //
2647
+ // TODO: We should eventually support emitting the "function control"
2648
+ // mask to include inline and other hint bits based on decorations
2649
+ // set on `irFunc`.
2650
+ //
2651
+ SpvFunctionControlMask spvFunctionControl = SpvFunctionControlMaskNone;
2652
+
2653
+ // [3.32.9. Function Instructions]
2654
+ //
2655
+ // > OpFunction
2656
+ //
2657
+ // Note that the type <id> of a SPIR-V function uses the
2658
+ // *result* type of the function, while the actual function
2659
+ // type is given as a later operand. Slan IR instead uses
2660
+ // the type of a function instruction store, you know, its *type*.
2661
+ //
2662
+ SpvInst* spvFunc = emitOpFunction (
2663
+ section,
2664
+ irFunc,
2665
+ irFunc->getDataType ()->getResultType (),
2666
+ spvFunctionControl,
2667
+ irFunc->getDataType ());
2668
+
2669
+ // > OpFunctionParameter
2670
+ //
2671
+ // Though parameters always belong to blocks in Slang, there are no
2672
+ // blocks in a function declaration, so we will emit the parameters
2673
+ // as derived from the function's type.
2674
+ //
2675
+ auto funcType = irFunc->getDataType ();
2676
+ auto paramCount = funcType->getParamCount ();
2677
+ for (UInt pp = 0 ; pp < paramCount; ++pp)
2678
+ {
2679
+ auto paramType = funcType->getParamType (pp);
2680
+ SpvInst* spvParam = emitOpFunctionParameter (spvFunc, nullptr , paramType);
2681
+ maybeEmitPointerDecoration (spvParam, paramType, false , kIROp_Param );
2682
+ }
2683
+
2684
+ // [3.32.9. Function Instructions]
2685
+ //
2686
+ // > OpFunctionEnd
2687
+ //
2688
+ // In the SPIR-V encoding a function is logically the parent of any
2689
+ // instructions up to a matching `OpFunctionEnd`. In our intermediate
2690
+ // structure we will make the `OpFunctionEnd` be the last child of
2691
+ // the `OpFunction`.
2635
2692
//
2636
- m_sink->diagnose (irFunc, Diagnostics::internalCompilerError);
2637
- SLANG_UNEXPECTED (" function declaration in SPIR-V emit" );
2638
- UNREACHABLE_RETURN (nullptr );
2693
+ emitOpFunctionEnd (spvFunc, nullptr );
2694
+
2695
+ // We will emit any decorations pertinent to the function to the
2696
+ // appropriate section of the module.
2697
+ //
2698
+ emitDecorations (irFunc, getID (spvFunc));
2699
+
2700
+ return spvFunc;
2639
2701
}
2640
2702
2641
2703
// / Emit a SPIR-V function definition for the Slang IR function `irFunc`.
@@ -4358,6 +4420,21 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
4358
4420
SpvLinkageTypeExport);
4359
4421
break ;
4360
4422
}
4423
+ case kIROp_DownstreamModuleImportDecoration :
4424
+ {
4425
+ requireSPIRVCapability (SpvCapabilityLinkage);
4426
+ auto name =
4427
+ decoration->getParent ()->findDecoration <IRExportDecoration>()->getMangledName ();
4428
+ emitInst (
4429
+ getSection (SpvLogicalSectionID::Annotations),
4430
+ decoration,
4431
+ SpvOpDecorate,
4432
+ dstID,
4433
+ SpvDecorationLinkageAttributes,
4434
+ name,
4435
+ SpvLinkageTypeImport);
4436
+ break ;
4437
+ }
4361
4438
// ...
4362
4439
}
4363
4440
@@ -5019,9 +5096,9 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
5019
5096
return nullptr ;
5020
5097
}
5021
5098
5022
- void maybeEmitPointerDecoration (SpvInst* varInst, IRInst* inst )
5099
+ void maybeEmitPointerDecoration (SpvInst* varInst, IRType* type, bool isVar, IROp op )
5023
5100
{
5024
- auto ptrType = as<IRPtrType>(unwrapArray (inst-> getDataType () ));
5101
+ auto ptrType = as<IRPtrType>(unwrapArray (type ));
5025
5102
if (!ptrType)
5026
5103
return ;
5027
5104
if (addressSpaceToStorageClass (ptrType->getAddressSpace ()) ==
@@ -5033,7 +5110,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
5033
5110
getSection (SpvLogicalSectionID::Annotations),
5034
5111
nullptr ,
5035
5112
varInst,
5036
- (as<IRVar>(inst) ? SpvDecorationAliasedPointer : SpvDecorationAliased));
5113
+ (isVar ? SpvDecorationAliasedPointer : SpvDecorationAliased));
5037
5114
}
5038
5115
else
5039
5116
{
@@ -5049,14 +5126,18 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
5049
5126
getSection (SpvLogicalSectionID::Annotations),
5050
5127
nullptr ,
5051
5128
varInst,
5052
- (inst->getOp () == kIROp_GlobalVar || inst->getOp () == kIROp_Var ||
5053
- inst->getOp () == kIROp_DebugVar
5129
+ (op == kIROp_GlobalVar || op == kIROp_Var || op == kIROp_DebugVar
5054
5130
? SpvDecorationAliasedPointer
5055
5131
: SpvDecorationAliased));
5056
5132
}
5057
5133
}
5058
5134
}
5059
5135
5136
+ void maybeEmitPointerDecoration (SpvInst* varInst, IRInst* inst)
5137
+ {
5138
+ maybeEmitPointerDecoration (varInst, inst->getDataType (), as<IRVar>(inst), inst->getOp ());
5139
+ }
5140
+
5060
5141
SpvInst* emitParam (SpvInstParent* parent, IRInst* inst)
5061
5142
{
5062
5143
auto paramSpvInst = emitOpFunctionParameter (parent, inst, inst->getFullType ());
@@ -7534,6 +7615,8 @@ SlangResult emitSPIRVFromIR(
7534
7615
}
7535
7616
#endif
7536
7617
7618
+ removeAvailableInDownstreamModuleDecorations (CodeGenTarget::SPIRV, irModule);
7619
+
7537
7620
auto shouldPreserveParams = codeGenContext->getTargetProgram ()->getOptionSet ().getBoolOption (
7538
7621
CompilerOptionName::PreserveParameters);
7539
7622
auto generateWholeProgram = codeGenContext->getTargetProgram ()->getOptionSet ().getBoolOption (
0 commit comments