summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-15 15:12:29 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-16 12:44:50 -0700
commit87c50675941a3ac853a79f50ec0ce3465631fa8f (patch)
tree0fe0f40745e61ef11c987ca5bbf754366422568f /source/slang/emit.cpp
parent74e04b8746f7254d5e95520ff31fb09d4bc327b1 (diff)
More work on IR
With this change, basic generation of IR works for a trivial shader, and there is some basic support for dumping the generated IR in an assembly-like format. As with the other IR change, the use of the IR is statically disabled for now, so that existing users won't be affected.
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp110
1 files changed, 87 insertions, 23 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 71ee31e5e..3bec17456 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2,6 +2,7 @@
#include "emit.h"
#include "lower.h"
+#include "lower-to-ir.h"
#include "name.h"
#include "syntax.h"
#include "type-layout.h"
@@ -519,7 +520,7 @@ struct EmitVisitor
emitRawText("\n#line ");
char buffer[16];
- sprintf(buffer, "%d", sourceLocation.line);
+ sprintf(buffer, "%llu", (unsigned long long)sourceLocation.line);
emitRawText(buffer);
emitRawText(" ");
@@ -679,7 +680,7 @@ struct EmitVisitor
// and how we do.
if(sourceLocation.column > context->shared->loc.column)
{
- int delta = sourceLocation.column - context->shared->loc.column;
+ Slang::Int delta = sourceLocation.column - context->shared->loc.column;
for( int ii = 0; ii < delta; ++ii )
{
emitRawText(" ");
@@ -3756,7 +3757,7 @@ struct EmitVisitor
void EmitDecl(RefPtr<Decl> decl)
{
- emitDeclImpl(decl, nullptr);
+emitDeclImpl(decl, nullptr);
}
void EmitDeclUsingLayout(RefPtr<Decl> decl, RefPtr<VarLayout> layout)
@@ -3770,9 +3771,9 @@ struct EmitVisitor
{
EmitDecl(decl);
}
- else if(auto declGroup = declBase.As<DeclGroup>())
+ else if( auto declGroup = declBase.As<DeclGroup>() )
{
- for(auto d : declGroup->decls)
+ for( auto d : declGroup->decls )
EmitDecl(d);
}
else
@@ -3805,7 +3806,7 @@ String emitEntryPoint(
{
globalStructLayout = gs.Ptr();
}
- else if(auto globalConstantBufferLayout = globalScopeLayout.As<ParameterBlockTypeLayout>())
+ else if( auto globalConstantBufferLayout = globalScopeLayout.As<ParameterBlockTypeLayout>() )
{
// TODO: the `cbuffer` case really needs to be emitted very
// carefully, but that is beyond the scope of what a simple rewriter
@@ -3837,32 +3838,95 @@ String emitEntryPoint(
}
sharedContext.globalStructLayout = globalStructLayout;
+ auto translationUnitSyntax = translationUnit->SyntaxNode.Ptr();
+
EmitContext context;
context.shared = &sharedContext;
EmitVisitor visitor(&context);
- auto translationUnitSyntax = translationUnit->SyntaxNode.Ptr();
-
- // We perform lowering of the program before emitting *anything*,
- // because the lowering process might change how we emit some
- // boilerplate at the start of the ouput for GLSL (e.g., what
- // version we require).
- auto lowered = lowerEntryPoint(entryPoint, programLayout, target, &sharedContext.extensionUsageTracker);
- sharedContext.program = lowered.program;
-
- // Note that we emit the main body code of the program *before*
- // we emit any leading preprocessor directives for GLSL.
- // This is to give the emit logic a change to make last-minute
- // adjustments like changing the required GLSL version.
+ // Depending on how the compiler was invoked, we may need to perform
+ // some amount of preocessing on the code before we can emit it.
+ //
+ // For our purposes, there are basically three different "modes" we
+ // care about:
+ //
+ // 1. "Full rewriter" mode, where the user provides HLSL/GLSL, and
+ // doesn't make use of any Slang code via `import`.
+ //
+ // 2. "Partial rewriter" mode, where the user starts with HLSL/GLSL,
+ // but also imports some Slang code, and may need us to rewrite
+ // their HLSL/GLSL function bodies to make things work.
+ //
+ // 3. "Full" mode, where all of the input code is in Slang (and/or
+ // the subset of HLSL we can fully type-check).
//
- // TODO: All such adjustments would be better handled during
- // lowering, but that requires having a semantic rather than
- // textual format for the HLSL->GLSL mapping.
- visitor.EmitDeclsInContainer(lowered.program.Ptr());
+ // We'll try to detect the cases here:
+ //
+#if 0
+ if(!(translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING ))
+ {
+ // This seems to be case (3), because the user is asking for full
+ // checking, and so we can assume we understand the code fully.
+ //
+ // In this case we want to translate to our intermediate representation
+ // and do optimizations/transformations there before we emit final code.
+ //
+
+ auto lowered = lowerEntryPointToIR(entryPoint, programLayout, target);
+
+ dumpIR(lowered);
+
+ throw 99;
+
+ }
+ else if(translationUnit->compileRequest->loadedModulesList.Count() != 0)
+#else
+ if(!(translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
+ || translationUnit->compileRequest->loadedModulesList.Count() != 0)
+#endif
+ {
+ // The user has `import`ed some Slang modules, and so we are in case (2)
+ //
+ // We need to apply a "rewriting" pass to the code the user wrote,
+ // and then emit the result.
+
+ // We perform lowering of the program before emitting *anything*,
+ // because the lowering process might change how we emit some
+ // boilerplate at the start of the ouput for GLSL (e.g., what
+ // version we require).
+ auto lowered = lowerEntryPoint(entryPoint, programLayout, target, &sharedContext.extensionUsageTracker);
+ sharedContext.program = lowered.program;
+
+ // Note that we emit the main body code of the program *before*
+ // we emit any leading preprocessor directives for GLSL.
+ // This is to give the emit logic a change to make last-minute
+ // adjustments like changing the required GLSL version.
+ //
+ // TODO: All such adjustments would be better handled during
+ // lowering, but that requires having a semantic rather than
+ // textual format for the HLSL->GLSL mapping.
+ visitor.EmitDeclsInContainer(lowered.program.Ptr());
+ }
+ else
+ {
+ // We are in case (1).
+ //
+ // We should be able to just emit the AST we parsed right back out,
+ // along with whatever annotations we added along the way.
+
+ sharedContext.program = translationUnitSyntax;
+ visitor.EmitDeclsInContainer(translationUnitSyntax);
+ }
+
String code = sharedContext.sb.ProduceString();
sharedContext.sb.Clear();
+ // Now that we've emitted the code for all the declaratiosn in the file,
+ // it is time to stich together the final output.
+
+
+
// There may be global-scope modifiers that we should emit now
visitor.emitGLSLPreprocessorDirectives(translationUnitSyntax);
String prefix = sharedContext.sb.ProduceString();