diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-08-17 14:51:09 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-08-17 14:51:09 -0700 |
| commit | ec8175c1f0afe3f7758f70da240aba03a791c3a9 (patch) | |
| tree | 53a6a509f3bba87d964ba3a5007b538db1d83a4e /source | |
| parent | 95348fdb623509eb22c04d4c7c19af8228c5a533 (diff) | |
[ir] Add support for "decorations" on instructions
The terminology here is similar to SPIR-V. For right now the only decoration exposed is a fairly brute-force one that just points back to a high-level declaration so that we can look up info on it that might affect how we print output.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 24 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 38 | ||||
| -rw-r--r-- | source/slang/ir.h | 55 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 5 |
4 files changed, 119 insertions, 3 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 1f0436d8a..6440c63a3 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3827,6 +3827,11 @@ emitDeclImpl(decl, nullptr); String getName(IRInst* inst) { + if(auto decoration = inst->findDecoration<IRHighLevelDeclDecoration>()) + { + return getText(decoration->decl->getName()); + } + StringBuilder sb; sb << "_S"; sb << inst->id; @@ -4038,6 +4043,17 @@ emitDeclImpl(decl, nullptr); } } + void emitIRSemantics( + EmitContext* context, + IRInst* inst) + { + auto decoration = inst->findDecoration<IRHighLevelDeclDecoration>(); + if( decoration ) + { + EmitSemantics(decoration->decl); + } + } + void emitIRFunc( EmitContext* context, IRFunc* func) @@ -4061,6 +4077,9 @@ emitDeclImpl(decl, nullptr); } emit(")"); + + emitIRSemantics(context, func); + // TODO: encode declaration vs. definition bool isDefinition = true; if(isDefinition) @@ -4097,6 +4116,9 @@ emitDeclImpl(decl, nullptr); { auto fieldType = ff->getFieldType(); emitIRType(context, fieldType, getName(ff)); + + emitIRSemantics(context, ff); + emit(";\n"); } emit("};\n"); @@ -4250,7 +4272,7 @@ String emitEntryPoint( // // We'll try to detect the cases here: // -#if 1 +#if 0 if(!(translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )) { // This seems to be case (3), because the user is asking for full diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index b6af6aabb..8e4f789ef 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -46,6 +46,16 @@ namespace Slang return &type; } + IRDecoration* IRInst::findDecorationImpl(IRDecorationOp decorationOp) + { + for( auto dd = firstDecoration; dd; dd = dd->next ) + { + if(dd->op == decorationOp) + return dd; + } + return nullptr; + } + // IRParam* IRFunc::getFirstParam() @@ -129,8 +139,6 @@ namespace Slang IRValue* inst = (IRInst*) malloc(size); memset(inst, 0, size); - IRUse* instArgs = inst->getArgs(); - auto module = builder->getModule(); if (!module || (type && type->op == kIROp_VoidType)) { @@ -793,6 +801,32 @@ namespace Slang return inst; } + IRDecoration* IRBuilder::addDecorationImpl( + IRInst* inst, + UInt decorationSize, + IRDecorationOp op) + { + auto decoration = (IRDecoration*) malloc(decorationSize); + memset(decoration, 0, decorationSize); + + decoration->op = op; + + decoration->next = inst->firstDecoration; + inst->firstDecoration = decoration; + + return decoration; + } + + IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl) + { + auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl); + decoration->decl = decl; + return decoration; + } + + // + + struct IRDumpContext { FILE* file; diff --git a/source/slang/ir.h b/source/slang/ir.h index 319340024..fcebf5d15 100644 --- a/source/slang/ir.h +++ b/source/slang/ir.h @@ -69,6 +69,22 @@ struct IRUse void init(IRInst* user, IRInst* usedValue); }; +enum IRDecorationOp : uint16_t +{ + kIRDecorationOp_HighLevelDecl, +}; + +// A "decoration" that gets applied to an instruction. +// These usually don't affect semantics, but are useful +// for preserving high-level source information. +struct IRDecoration +{ + // Next decoration attached to the same instruction + IRDecoration* next; + + IRDecorationOp op; +}; + typedef uint32_t IRInstID; // In the IR, almost *everything* is an instruction, @@ -99,6 +115,18 @@ struct IRInst // The first use of this value (start of a linked list) IRUse* firstUse; + // The linked list of decorations attached to this instruction + IRDecoration* firstDecoration; + + IRDecoration* findDecorationImpl(IRDecorationOp op); + + template<typename T> + T* findDecoration() + { + return (T*) findDecorationImpl(IRDecorationOp(T::kDecorationOp)); + } + + // The type of this value IRUse type; @@ -117,8 +145,22 @@ struct IRInst } }; +// This type alias exists because I waffled on the name for a bit. +// All existing uses of `IRValue` should move to `IRInst` typedef IRInst IRValue; +class Decl; + +// Associates an IR-level decoration with a source declaration +// in the high-level AST, that can be used to extract +// additional information that informs code emission. +struct IRHighLevelDeclDecoration : IRDecoration +{ + enum { kDecorationOp = kIRDecorationOp_HighLevelDecl }; + + Decl* decl; +}; + typedef long long IRIntegerValue; typedef double IRFloatingPointValue; @@ -360,6 +402,19 @@ struct IRBuilder IRValue* val); IRInst* emitReturn(); + + IRDecoration* addDecorationImpl( + IRInst* inst, + UInt decorationSize, + IRDecorationOp op); + + template<typename T> + T* addDecoration(IRInst* inst, IRDecorationOp op) + { + return (T*) addDecorationImpl(inst, sizeof(T), op); + } + + IRHighLevelDeclDecoration* addHighLevelDeclDecoration(IRInst* inst, Decl* decl); }; void dumpIR(IRModule* module); diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index 5d0a40072..781209dce 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -562,6 +562,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> auto irField = builder->createStructField(getSimpleType(fieldType)); builder->addInst(irStruct, irField); + builder->addHighLevelDeclDecoration(irField, fieldDecl); + context->shared->declValues.Add( DeclRef<StructField>(fieldDecl, nullptr), LoweredValInfo::simple(irField)); @@ -573,6 +575,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> } } + builder->addHighLevelDeclDecoration(irStruct, decl); builder->addInst(irStruct); @@ -624,6 +627,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> lowerStmt(subContext, decl->Body); + getBuilder()->addHighLevelDeclDecoration(irFunc, decl); + getBuilder()->addInst(irFunc); return LoweredValInfo::simple(irFunc); |
