Skip to content

Commit

Permalink
Merge pull request #167 from tfoleyNV/ir
Browse files Browse the repository at this point in the history
More work on IR
  • Loading branch information
tangent-vector authored Aug 16, 2017
2 parents 74e04b8 + e30ba2f commit 3dd88c2
Show file tree
Hide file tree
Showing 7 changed files with 1,382 additions and 198 deletions.
2 changes: 2 additions & 0 deletions slang.h
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ namespace slang
#include "source/core/text-io.cpp"
#include "source/slang/diagnostics.cpp"
#include "source/slang/emit.cpp"
#include "source/slang/ir.cpp"
#include "source/slang/lexer.cpp"
#include "source/slang/name.cpp"
#include "source/slang/options.cpp"
Expand All @@ -982,6 +983,7 @@ namespace slang
#include "source/slang/profile.cpp"
#include "source/slang/lookup.cpp"
#include "source/slang/lower.cpp"
#include "source/slang/lower-to-ir.cpp"
#include "source/slang/check.cpp"
#include "source/slang/compiler.cpp"
#include "source/slang/slang-stdlib.cpp"
Expand Down
183 changes: 160 additions & 23 deletions source/slang/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -47,6 +48,9 @@ struct SharedEmitContext
// The entry point we are being asked to compile
EntryPointRequest* entryPoint;

// The layout for the entry point
EntryPointLayout* entryPointLayout;

// The target language we want to generate code for
CodeGenTarget target;

Expand Down Expand Up @@ -519,7 +523,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(" ");
Expand Down Expand Up @@ -679,7 +683,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(" ");
Expand Down Expand Up @@ -2282,8 +2286,32 @@ struct EmitVisitor
emitName(expr->lookupResult2.getName());
}

void setSampleRateFlag()
{
context->shared->entryPointLayout->flags |= EntryPointLayout::Flag::usesAnySampleRateInput;
}

void doSampleRateInputCheck(VarDeclBase* decl)
{
if (decl->HasModifier<HLSLSampleModifier>())
{
setSampleRateFlag();
}
}

void doSampleRateInputCheck(Name* name)
{
auto text = getText(name);
if (text == "gl_SampleID")
{
setSampleRateFlag();
}
}

void visitVarExpr(VarExpr* varExpr, ExprEmitArg const& arg)
{
doSampleRateInputCheck(varExpr->name);

auto prec = kEOp_Atomic;
auto outerPrec = arg.outerPrec;
bool needClose = MaybeEmitParens(outerPrec, kEOp_Atomic);
Expand Down Expand Up @@ -2484,6 +2512,11 @@ struct EmitVisitor
Emit("{\n");
for( auto& token : stmt->tokens )
{
if (token.type == TokenType::Identifier)
{
doSampleRateInputCheck(token.getName());
}

emitTokenWithLocation(token);
}
Emit("}\n");
Expand Down Expand Up @@ -3559,6 +3592,15 @@ struct EmitVisitor

void visitVarDeclBase(RefPtr<VarDeclBase> decl, DeclEmitArg const& arg)
{
// Global variable? Check if it is a sample-rate input.
if (dynamic_cast<ModuleDecl*>(decl->ParentDecl))
{
if (decl->HasModifier<InModifier>())
{
doSampleRateInputCheck(decl);
}
}

// Skip fields that have been tuple-ified and don't contribute
// any fields of "ordinary" type.
if (auto tupleFieldMod = decl->FindModifier<TupleFieldModifier>())
Expand Down Expand Up @@ -3756,7 +3798,7 @@ struct EmitVisitor

void EmitDecl(RefPtr<Decl> decl)
{
emitDeclImpl(decl, nullptr);
emitDeclImpl(decl, nullptr);
}

void EmitDeclUsingLayout(RefPtr<Decl> decl, RefPtr<VarLayout> layout)
Expand All @@ -3770,9 +3812,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
Expand All @@ -3782,6 +3824,29 @@ struct EmitVisitor
}
};


EntryPointLayout* findEntryPointLayout(
ProgramLayout* programLayout,
EntryPointRequest* entryPointRequest)
{
for( auto entryPointLayout : programLayout->entryPoints )
{
if(entryPointLayout->entryPoint->getName() != entryPointRequest->name)
continue;

if(entryPointLayout->profile != entryPointRequest->profile)
continue;

// TODO: can't easily filter on translation unit here...
// Ideally the `EntryPointRequest` should get filled in with a pointer
// the specific function declaration that represents the entry point.

return entryPointLayout.Ptr();
}

return nullptr;
}

String emitEntryPoint(
EntryPointRequest* entryPoint,
ProgramLayout* programLayout,
Expand All @@ -3794,6 +3859,13 @@ String emitEntryPoint(
sharedContext.finalTarget = entryPoint->compileRequest->Target;
sharedContext.entryPoint = entryPoint;

if (entryPoint)
{
sharedContext.entryPointLayout = findEntryPointLayout(
programLayout,
entryPoint);
}

sharedContext.programLayout = programLayout;

// Layout information for the global scope is either an ordinary
Expand All @@ -3805,7 +3877,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
Expand Down Expand Up @@ -3837,32 +3909,97 @@ 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`.
//
// 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());
// 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).
//
// 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.EmitDeclsInContainerUsingLayout(
translationUnitSyntax,
globalStructLayout);
}

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();
Expand Down
Loading

0 comments on commit 3dd88c2

Please sign in to comment.