summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-08-15 20:55:21 -0700
committerGitHub <noreply@github.com>2023-08-15 20:55:21 -0700
commitc16f711d83df90f6826a65d61fc56cdbb932c92c (patch)
tree3680ff05b91aa4521fd5c5e9caa9de171cbac558 /source
parent0c366bc0a4332ee14d08f2555396a18cb64229fa (diff)
SPIRV: debug source and debug line. (#3109)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-c-like.cpp5
-rw-r--r--source/slang/slang-emit-spirv-ops-debug-info-ext.h28
-rw-r--r--source/slang/slang-emit-spirv.cpp171
-rw-r--r--source/slang/slang-ir-inst-defs.h4
-rw-r--r--source/slang/slang-ir-insts.h21
-rw-r--r--source/slang/slang-ir.cpp17
-rw-r--r--source/slang/slang-lower-to-ir.cpp58
-rw-r--r--source/slang/slang.cpp3
8 files changed, 268 insertions, 39 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 337860771..e1f631283 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -2507,7 +2507,6 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
}
-
default:
diagnoseUnhandledInst(inst);
break;
@@ -2557,6 +2556,10 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
m_writer->emit(";\n");
break;
+ case kIROp_DebugSource:
+ case kIROp_DebugLine:
+ break;
+
// Insts that needs to be emitted as code blocks.
case kIROp_CudaKernelLaunch:
emitInstStmtImpl(inst);
diff --git a/source/slang/slang-emit-spirv-ops-debug-info-ext.h b/source/slang/slang-emit-spirv-ops-debug-info-ext.h
new file mode 100644
index 000000000..d1ca9665a
--- /dev/null
+++ b/source/slang/slang-emit-spirv-ops-debug-info-ext.h
@@ -0,0 +1,28 @@
+#ifdef SLANG_IN_SPIRV_EMIT_CONTEXT
+
+// https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Shader.DebugInfo.100.asciidoc#DebugCompilationUnit
+template<typename T>
+SpvInst* emitOpDebugCompilationUnit(SpvInstParent* parent, IRInst* inst, const T& idResultType, SpvInst* set, SpvInst* version, SpvInst* dwarfVersion, SpvInst* source, SpvInst* language)
+{
+ static_assert(isSingular<T>);
+ return emitInst(parent, inst, SpvOpExtInst, idResultType, kResultID, set, SpvWord(1), version, dwarfVersion, source, language);
+}
+
+// https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Shader.DebugInfo.100.asciidoc#DebugSource
+template<typename T>
+SpvInst* emitOpDebugSource(SpvInstParent* parent, IRInst* inst, const T& idResultType, SpvInst* set, IRInst* file, IRInst* text)
+{
+ static_assert(isSingular<T>);
+ return emitInst(parent, inst, SpvOpExtInst, idResultType, kResultID, set, SpvWord(35), file, text);
+}
+
+// https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Shader.DebugInfo.100.asciidoc#DebugLine
+template<typename T>
+SpvInst* emitOpDebugLine(SpvInstParent* parent, IRInst* inst, const T& idResultType, SpvInst* set, IRInst* source, IRInst* lineStart, IRInst* lineEnd, IRInst* colStart, IRInst* colEnd)
+{
+ static_assert(isSingular<T>);
+ return emitInst(parent, inst, SpvOpExtInst, idResultType, kResultID, set, SpvWord(103), source, lineStart, lineEnd, colStart, colEnd);
+}
+
+
+#endif // SLANG_IN_SPIRV_EMIT_CONTEXT
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index d93a50756..a3051fadb 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -291,6 +291,41 @@ struct SpvLiteralBits
{
static SpvLiteralBits from32(uint32_t value) { return SpvLiteralBits{{value}}; }
static SpvLiteralBits from64(uint64_t value) { return SpvLiteralBits{{SpvWord(value), SpvWord(value >> 32)}}; }
+ static SpvLiteralBits fromUnownedStringSlice(UnownedStringSlice text)
+ {
+ SpvLiteralBits result;
+
+ // [Section 2.2.1 : Instructions]
+ //
+ // > Literal String: A nul-terminated stream of characters consuming
+ // > an integral number of words. The character set is Unicode in the
+ // > UTF-8 encoding scheme. The UTF-8 octets (8-bit bytes) are packed
+ // > four per word, following the little-endian convention (i.e., the
+ // > first octet is in the lowest-order 8 bits of the word).
+ // > The final word contains the string’s nul-termination character (0), and
+ // > all contents past the end of the string in the final word are padded with 0.
+
+ // First work out the amount of words we'll need
+ const Index textCount = text.getLength();
+ // Calculate the minimum amount of bytes needed - which needs to include terminating 0
+ const Index minByteCount = textCount + 1;
+ // Calculate the amount of words including padding if necessary
+ const Index wordCount = (minByteCount + 3) >> 2;
+
+ // Make space on the operand stack, keeping the free space start in operandStartIndex
+ result.value.setCount(wordCount);
+
+ // Set dst to the start of the operand memory
+ char* dst = (char*)(result.value.getBuffer());
+
+ // Copy the text
+ memcpy(dst, text.begin(), textCount);
+
+ // Set terminating 0, and remaining buffer 0s
+ memset(dst + textCount, 0, wordCount * sizeof(SpvWord) - textCount);
+
+ return result;
+ }
List<SpvWord> value; // Words, stored low words to high (TODO, SmallArray or something here)
};
@@ -482,6 +517,9 @@ struct SPIRVEmitContext
// `IRInst` may not have been emitted.
Dictionary<IRInst*, SpvWord> m_mapIRInstToSpvID;
+ // Map a Slang IR instruction to the corresponding SPIR-V debug instruction.
+ Dictionary<IRInst*, SpvInst*> m_mapIRInstToSpvDebugInst;
+
/// Register that `irInst` maps to `spvInst`
void registerInst(IRInst* irInst, SpvInst* spvInst)
{
@@ -498,6 +536,23 @@ struct SPIRVEmitContext
}
}
+ /// Register that `irInst` has debug info represented by `spvDebugInst`.
+ void registerDebugInst(IRInst* irInst, SpvInst* spvDebugInst)
+ {
+ m_mapIRInstToSpvDebugInst.add(irInst, spvDebugInst);
+ }
+
+ SpvInst* findDebugScope(IRInst* inst)
+ {
+ for (auto parent = inst; parent; parent = parent->getParent())
+ {
+ SpvInst* spvInst = nullptr;
+ if (m_mapIRInstToSpvDebugInst.tryGetValue(parent, spvInst))
+ return spvInst;
+ }
+ return nullptr;
+ }
+
/// Get or reserve a SpvID for an IR value.
SpvWord getIRInstSpvID(IRInst* inst)
{
@@ -728,36 +783,7 @@ struct SPIRVEmitContext
// Assert that `text` doesn't contain any embedded nul bytes, since they
// could lead to invalid encoded results.
SLANG_ASSERT(text.indexOf(0) < 0);
-
- // [Section 2.2.1 : Instructions]
- //
- // > Literal String: A nul-terminated stream of characters consuming
- // > an integral number of words. The character set is Unicode in the
- // > UTF-8 encoding scheme. The UTF-8 octets (8-bit bytes) are packed
- // > four per word, following the little-endian convention (i.e., the
- // > first octet is in the lowest-order 8 bits of the word).
- // > The final word contains the string’s nul-termination character (0), and
- // > all contents past the end of the string in the final word are padded with 0.
-
- // First work out the amount of words we'll need
- const Index textCount = text.getLength();
- // Calculate the minimum amount of bytes needed - which needs to include terminating 0
- const Index minByteCount = textCount + 1;
- // Calculate the amount of words including padding if necessary
- const Index wordCount = (minByteCount + 3) >> 2;
-
- // Make space on the operand stack, keeping the free space start in operandStartIndex
- const Index operandStartIndex = m_operandStack.getCount();
- m_operandStack.setCount(operandStartIndex + wordCount);
-
- // Set dst to the start of the operand memory
- char* dst = (char*)(m_operandStack.getBuffer() + operandStartIndex);
-
- // Copy the text
- memcpy(dst, text.begin(), textCount);
-
- // Set terminating 0, and remaining buffer 0s
- memset(dst + textCount, 0, wordCount * sizeof(SpvWord) - textCount);
+ emitOperand(SpvLiteralBits::fromUnownedStringSlice(text));
}
// Sometimes we will want to pass down an argument that
@@ -1014,6 +1040,7 @@ struct SPIRVEmitContext
# define SLANG_IN_SPIRV_EMIT_CONTEXT
# include "slang-emit-spirv-ops.h"
+ #include "slang-emit-spirv-ops-debug-info-ext.h"
# undef SLANG_IN_SPIRV_EMIT_CONTEXT
/// The SPIRV OpExtInstImport inst that represents the GLSL450
@@ -1031,6 +1058,21 @@ struct SPIRVEmitContext
return m_glsl450ExtInst;
}
+ /// The SPIRV OpExtInstImport inst that represents the NonSemantic debug info
+ /// extended instruction set.
+ SpvInst* m_NonSemanticDebugInfoExtInst = nullptr;
+
+ SpvInst* getNonSemanticDebugInfoExtInst()
+ {
+ if (m_NonSemanticDebugInfoExtInst)
+ return m_NonSemanticDebugInfoExtInst;
+ m_NonSemanticDebugInfoExtInst = emitOpExtInstImport(
+ getSection(SpvLogicalSectionID::ExtIntInstImports),
+ nullptr,
+ UnownedStringSlice("NonSemantic.Shader.DebugInfo.100"));
+ return m_NonSemanticDebugInfoExtInst;
+ }
+
// Now that we've gotten the core infrastructure out of the way,
// let's start looking at emitting some instructions that make
// up a SPIR-V module.
@@ -1152,7 +1194,6 @@ struct SPIRVEmitContext
const FloatInfo i = getFloatingTypeInfo(as<IRType>(inst));
return emitOpTypeFloat(inst, SpvLiteralInteger::from32(int32_t(i.width)));
}
-
case kIROp_PtrType:
case kIROp_RefType:
case kIROp_OutType:
@@ -1342,6 +1383,7 @@ struct SPIRVEmitContext
case kIROp_BoolLit:
case kIROp_IntLit:
case kIROp_FloatLit:
+ case kIROp_StringLit:
return emitLit(inst);
case kIROp_GlobalParam:
@@ -1359,6 +1401,36 @@ struct SPIRVEmitContext
dumpIRToString(g);
SLANG_UNEXPECTED(e.getBuffer());
}
+
+ case kIROp_DebugSource:
+ {
+ ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_non_semantic_info"));
+ auto debugSource = as<IRDebugSource>(inst);
+ auto result = emitOpDebugSource(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ inst,
+ inst->getFullType(),
+ getNonSemanticDebugInfoExtInst(),
+ debugSource->getFileName(),
+ debugSource->getSource());
+ auto moduleInst = inst->getModule()->getModuleInst();
+ if (!m_mapIRInstToSpvDebugInst.containsKey(moduleInst))
+ {
+ IRBuilder builder(inst);
+ builder.setInsertBefore(inst);
+ auto translationUnit = emitOpDebugCompilationUnit(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ moduleInst,
+ inst->getFullType(),
+ getNonSemanticDebugInfoExtInst(),
+ emitIntConstant(100, builder.getUIntType()), // ExtDebugInfo version.
+ emitIntConstant(5, builder.getUIntType()), // DWARF version.
+ result,
+ emitIntConstant(6, builder.getUIntType())); // Language, use HLSL's ID for now.
+ registerDebugInst(moduleInst, translationUnit);
+ }
+ return result;
+ }
default:
{
String e = "Unhandled global inst in spirv-emit:\n"
@@ -1909,6 +1981,9 @@ struct SPIRVEmitContext
}
case kIROp_MakeArray:
return emitConstruct(parent, inst);
+
+ case kIROp_DebugLine:
+ return emitDebugLine(parent, as<IRDebugLine>(inst));
}
}
@@ -1944,6 +2019,11 @@ struct SPIRVEmitContext
);
}
}
+ case kIROp_StringLit:
+ {
+ auto value = as<IRStringLit>(inst)->getStringSlice();
+ return emitInst(getSection(SpvLogicalSectionID::DebugStringsAndSource), inst, SpvOpString, kResultID, SpvLiteralBits::fromUnownedStringSlice(value));
+ }
default:
return nullptr;
}
@@ -2085,6 +2165,17 @@ struct SPIRVEmitContext
name,
params
);
+
+ // Stage specific execution mode declarations.
+ switch (entryPointDecor->getProfile().getStage())
+ {
+ case Stage::Fragment:
+ //OpExecutionMode %main OriginUpperLeft
+ emitInst(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, SpvOpExecutionMode, dstID, SpvExecutionModeOriginUpperLeft);
+ break;
+ default:
+ break;
+ }
}
break;
@@ -3138,6 +3229,19 @@ struct SPIRVEmitContext
SLANG_UNREACHABLE("Arithmetic op with 0 or more than 2 operands");
}
+ SpvInst* emitDebugLine(SpvInstParent* parent, IRDebugLine* debugLine)
+ {
+ auto scope = findDebugScope(debugLine);
+ if (!scope)
+ return nullptr;
+ return emitOpDebugLine(parent, debugLine, debugLine->getFullType(), getNonSemanticDebugInfoExtInst(),
+ debugLine->getSource(),
+ debugLine->getLineStart(),
+ debugLine->getLineEnd(),
+ debugLine->getColStart(),
+ debugLine->getColEnd());
+ }
+
OrderedHashSet<SpvCapability> m_capabilities;
void requireSPIRVCapability(SpvCapability capability)
@@ -3212,6 +3316,11 @@ SlangResult emitSPIRVFromIR(
#endif
context.emitFrontMatter();
+ for (auto inst : irModule->getGlobalInsts())
+ {
+ if (as<IRDebugSource>(inst))
+ context.ensureInst(inst);
+ }
for (auto irEntryPoint : irEntryPoints)
{
context.ensureInst(irEntryPoint);
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 623fca32f..3007351d2 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -1041,6 +1041,10 @@ INST(ExistentialTypeSpecializationDictionary, ExistentialTypeSpecializationDicti
/* Differentiable Type Dictionary */
INST(DifferentiableTypeDictionaryItem, DifferentiableTypeDictionaryItem, 0, 0)
+/* DebugInfo */
+INST(DebugSource, DebugSource, 2, HOISTABLE)
+INST(DebugLine, DebugLine, 5, 0)
+
#undef PARENT
#undef USE_OTHER
#undef INST_RANGE
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 4af21c50a..3503ece79 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -2855,6 +2855,24 @@ struct IRCastFloatToInt : IRInst
IR_LEAF_ISA(CastFloatToInt)
};
+struct IRDebugSource : IRInst
+{
+ IR_LEAF_ISA(DebugSource)
+ IRInst* getFileName() { return getOperand(0); }
+ IRInst* getSource() { return getOperand(1); }
+};
+
+struct IRDebugLine : IRInst
+{
+ IR_LEAF_ISA(DebugLine)
+ IRInst* getSource() { return getOperand(0); }
+ IRInst* getLineStart() { return getOperand(1); }
+ IRInst* getLineEnd() { return getOperand(2); }
+ IRInst* getColStart() { return getOperand(3); }
+ IRInst* getColEnd() { return getOperand(4); }
+};
+
+
struct IRBuilderSourceLocRAII;
struct IRBuilder
@@ -3184,6 +3202,9 @@ public:
return getAttributedType(baseType, attributes.getCount(), attributes.getBuffer());
}
+ IRInst* emitDebugSource(UnownedStringSlice fileName, UnownedStringSlice source);
+ IRInst* emitDebugLine(IRInst* source, IRIntegerValue lineStart, IRIntegerValue lineEnd, IRIntegerValue colStart, IRIntegerValue colEnd);
+
/// Emit an LiveRangeStart instruction indicating the referenced item is live following this instruction
IRLiveRangeStart* emitLiveRangeStart(IRInst* referenced);
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 131c8d407..421c60d1d 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -3123,6 +3123,23 @@ namespace Slang
{
return emitIntrinsicInst((IRType*)type, kIROp_OutImplicitCast, 1, &value);
}
+ IRInst* IRBuilder::emitDebugSource(UnownedStringSlice fileName, UnownedStringSlice source)
+ {
+ IRInst* args[] = { getStringValue(fileName), getStringValue(source) };
+ return emitIntrinsicInst(getVoidType(), kIROp_DebugSource, 2, args);
+ }
+ IRInst* IRBuilder::emitDebugLine(IRInst* source, IRIntegerValue lineStart, IRIntegerValue lineEnd, IRIntegerValue colStart, IRIntegerValue colEnd)
+ {
+ IRInst* args[] =
+ {
+ source,
+ getIntValue(getIntType(), lineStart),
+ getIntValue(getIntType(), lineEnd),
+ getIntValue(getIntType(), colStart),
+ getIntValue(getIntType(), colEnd)
+ };
+ return emitIntrinsicInst(getVoidType(), kIROp_DebugLine, 5, args);
+ }
IRLiveRangeStart* IRBuilder::emitLiveRangeStart(IRInst* referenced)
{
// This instruction doesn't produce any result,
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index f89f92711..74ece5bc9 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -494,6 +494,8 @@ struct SharedIRGenContext
Dictionary<Stmt*, IRBlock*> breakLabels;
Dictionary<Stmt*, IRBlock*> continueLabels;
+ Dictionary<SourceFile*, IRInst*> mapSourceFileToDebugSourceInst;
+
void setGlobalValue(Decl* decl, LoweredValInfo value)
{
globalEnv.mapDeclToValue[decl] = value;
@@ -503,17 +505,20 @@ struct SharedIRGenContext
Session* session,
DiagnosticSink* sink,
bool obfuscateCode,
- ModuleDecl* mainModuleDecl = nullptr)
+ ModuleDecl* mainModuleDecl,
+ Linkage* linkage)
: m_session(session)
, m_sink(sink)
, m_obfuscateCode(obfuscateCode)
, m_mainModuleDecl(mainModuleDecl)
+ , m_linkage(linkage)
{}
Session* m_session = nullptr;
DiagnosticSink* m_sink = nullptr;
bool m_obfuscateCode = false;
ModuleDecl* m_mainModuleDecl = nullptr;
+ Linkage* m_linkage = nullptr;
// List of all string literals used in user code, regardless
// of how they were used (i.e., whether or not they were hashed).
@@ -556,6 +561,8 @@ struct IRGenContext
// The IR witness value to use for `ThisType`
IRInst* thisTypeWitness = nullptr;
+ bool includeDebugInfo = false;
+
explicit IRGenContext(SharedIRGenContext* inShared, ASTBuilder* inAstBuilder)
: shared(inShared)
, astBuilder(inAstBuilder)
@@ -588,6 +595,11 @@ struct IRGenContext
return shared->m_mainModuleDecl;
}
+ Linkage* getLinkage()
+ {
+ return shared->m_linkage;
+ }
+
LoweredValInfo* findLoweredDecl(Decl* decl)
{
IRGenEnv* envToFindIn = env;
@@ -5712,6 +5724,24 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
}
};
+void maybeEmitDebugLine(IRGenContext* context, Stmt* stmt)
+{
+ if (!context->includeDebugInfo)
+ return;
+ if (as<EmptyStmt>(stmt))
+ return;
+ auto sourceView = context->getLinkage()->getSourceManager()->findSourceView(stmt->loc);
+ if (!sourceView)
+ return;
+ auto source = sourceView->getSourceFile();
+ IRInst* debugSourceInst = nullptr;
+ if (context->shared->mapSourceFileToDebugSourceInst.tryGetValue(source, debugSourceInst))
+ {
+ auto humaneLoc = context->getLinkage()->getSourceManager()->getHumaneLoc(stmt->loc, SourceLocType::Emit);
+ context->irBuilder->emitDebugLine(debugSourceInst, humaneLoc.line, humaneLoc.line, humaneLoc.column, humaneLoc.column + 1);
+ }
+}
+
void lowerStmt(
IRGenContext* context,
Stmt* stmt)
@@ -5723,6 +5753,7 @@ void lowerStmt(
try
{
+ maybeEmitDebugLine(context, stmt);
visitor.dispatch(stmt);
}
// Don't emit any context message for an explicit `AbortCompilationException`
@@ -9542,7 +9573,8 @@ RefPtr<IRModule> generateIRForTranslationUnit(
session,
translationUnit->compileRequest->getSink(),
translationUnit->compileRequest->getLinkage()->m_obfuscateCode,
- translationUnit->getModuleDecl());
+ translationUnit->getModuleDecl(),
+ translationUnit->compileRequest->getLinkage());
SharedIRGenContext* sharedContext = &sharedContextStorage;
IRGenContext contextStorage(sharedContext, astBuilder);
@@ -9554,10 +9586,22 @@ RefPtr<IRModule> generateIRForTranslationUnit(
IRBuilder* builder = &builderStorage;
context->irBuilder = builder;
+ context->includeDebugInfo = compileRequest->getLinkage()->debugInfoLevel != DebugInfoLevel::None;
// We need to emit IR for all public/exported symbols
// in the translation unit.
//
+ // If debug info is enabled, we emit the DebugSource insts for each source file into IR.
+ if (context->includeDebugInfo)
+ {
+ builder->setInsertInto(module->getModuleInst());
+ for (auto source : translationUnit->getSourceFiles())
+ {
+ auto debugSource = builder->emitDebugSource(source->getPathInfo().getMostUniqueIdentity().getUnownedSlice(), source->getContent());
+ context->shared->mapSourceFileToDebugSourceInst.add(source, debugSource);
+ }
+ }
+
// For now, we will assume that *all* global-scope declarations
// represent public/exported symbols.
@@ -9781,7 +9825,9 @@ struct SpecializedComponentTypeIRGenContext : ComponentTypeVisitor
SharedIRGenContext sharedContextStorage(
session,
sink,
- linkage->m_obfuscateCode
+ linkage->m_obfuscateCode,
+ nullptr,
+ linkage
);
SharedIRGenContext* sharedContext = &sharedContextStorage;
@@ -9918,7 +9964,7 @@ struct TypeConformanceIRGenContext
linkage = typeConformance->getLinkage();
session = linkage->getSessionImpl();
- SharedIRGenContext sharedContextStorage(session, sink, linkage->m_obfuscateCode);
+ SharedIRGenContext sharedContextStorage(session, sink, linkage->m_obfuscateCode, nullptr, linkage);
SharedIRGenContext* sharedContext = &sharedContextStorage;
IRGenContext contextStorage(sharedContext, linkage->getASTBuilder());
@@ -10268,7 +10314,9 @@ RefPtr<IRModule> TargetProgram::createIRModuleForLayout(DiagnosticSink* sink)
SharedIRGenContext sharedContextStorage(
session,
sink,
- linkage->m_obfuscateCode);
+ linkage->m_obfuscateCode,
+ nullptr,
+ linkage);
auto sharedContext = &sharedContextStorage;
ASTBuilder* astBuilder = linkage->getASTBuilder();
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 71c705246..da818984b 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -170,6 +170,7 @@ void Session::init()
// Built in linkage uses the built in builder
m_builtinLinkage = new Linkage(this, builtinAstBuilder, nullptr);
+ m_builtinLinkage->debugInfoLevel = DebugInfoLevel::None;
// Because the `Session` retains the builtin `Linkage`,
// we need to make sure that the parent pointer inside
@@ -2425,8 +2426,6 @@ void FrontEndCompileRequest::generateIR()
// * it can generate diagnostics
/// Generate IR for translation unit.
- /// TODO(JS): Use the linkage ASTBuilder, because it seems possible that cross module constructs are possible in
- /// ir lowering.
RefPtr<IRModule> irModule(generateIRForTranslationUnit(getLinkage()->getASTBuilder(), translationUnit));
if (verifyDebugSerialization)