From ec8175c1f0afe3f7758f70da240aba03a791c3a9 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 17 Aug 2017 14:51:09 -0700 Subject: [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. --- source/slang/emit.cpp | 24 ++++++++++++++++++- source/slang/ir.cpp | 38 ++++++++++++++++++++++++++++-- source/slang/ir.h | 55 ++++++++++++++++++++++++++++++++++++++++++++ source/slang/lower-to-ir.cpp | 5 ++++ 4 files changed, 119 insertions(+), 3 deletions(-) (limited to 'source') 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()) + { + 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(); + 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(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 + 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 + 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 auto irField = builder->createStructField(getSimpleType(fieldType)); builder->addInst(irStruct, irField); + builder->addHighLevelDeclDecoration(irField, fieldDecl); + context->shared->declValues.Add( DeclRef(fieldDecl, nullptr), LoweredValInfo::simple(irField)); @@ -573,6 +575,7 @@ struct DeclLoweringVisitor : DeclVisitor } } + builder->addHighLevelDeclDecoration(irStruct, decl); builder->addInst(irStruct); @@ -624,6 +627,8 @@ struct DeclLoweringVisitor : DeclVisitor lowerStmt(subContext, decl->Body); + getBuilder()->addHighLevelDeclDecoration(irFunc, decl); + getBuilder()->addInst(irFunc); return LoweredValInfo::simple(irFunc); -- cgit v1.2.3