summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-17 14:51:09 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-17 14:51:09 -0700
commitec8175c1f0afe3f7758f70da240aba03a791c3a9 (patch)
tree53a6a509f3bba87d964ba3a5007b538db1d83a4e /source
parent95348fdb623509eb22c04d4c7c19af8228c5a533 (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.cpp24
-rw-r--r--source/slang/ir.cpp38
-rw-r--r--source/slang/ir.h55
-rw-r--r--source/slang/lower-to-ir.cpp5
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);