summaryrefslogtreecommitdiff
path: root/source/slang/ir.h
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2017-10-06 14:31:42 -0700
committerGitHub <noreply@github.com>2017-10-06 14:31:42 -0700
commitfaf26afdcfd343c79517f56f215bf8dcd5e0b992 (patch)
tree070bbc0acb2ed5c9a5e522ea522fbcfdc77af78c /source/slang/ir.h
parent3693bff4a2b822a2b29ac563d464d1012a3a3eda (diff)
Perform some transformations on IR to legalize for GLSL (#200)
When outputting GLSL from a Slang or HLSL entry point, we need to translate any parameters or results of an entry-point function into global declarations of `in` or `out` parameters, as needed by GLSL. This change adds these transformations at the IR level, so that they don't need to complicate the emit logic. More detailed changes: - Make `render0` test use IR. It passes out of the box. - Fix test runner to not always dump diffs on failures I accidentally initialized an option to `true` instead of `false` when working on debugging the Travis CI failures. - Special-case output for component-wise multiplication to handle GLSL `matrixCompMul()` - Handle GLSL vs. HLSL output for calls to `mul()` - Output proper `layout(std140)` on GLSL constant buffer declarations - Require appropriate GLSL extension when emitting explicit `layout(offset = ...)` on constant buffer members - TODO: Need to avoid requiring this extension in cases where the offsets are what would be computed anyway. Realistically, should probably be emitting code with explicit padding, etc. to guarantee layouts. - Add an IR-based pass to translate entry point functions by eliminating their input/output parameters and replacing them with global variables. - Demangle names when calling target intrinsics The lowering to the IR will turn a call like `sin(foo)` into a call to a function declaration with a mangled name like `_S3sin...`. This works fine when the user is calling their own functions, since the name mangling will apply to both the definition and use sites, but for builtin functions it obviously isn't what we want. This change makes it so that we demangle the name of an instrinsic function just enough so that we can extract the original simple name, and make a call using that. These changes do nor provide 100% of what we need when translating to GLSL, so the `cross-compile-entry-point` test *still* hasn't been flipped over to use the IR (even though that is the test case I've been using to develop these changes).
Diffstat (limited to 'source/slang/ir.h')
-rw-r--r--source/slang/ir.h63
1 files changed, 56 insertions, 7 deletions
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 82684ae17..4fd165c33 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -15,6 +15,7 @@ class Decl;
class FuncType;
class Layout;
class Type;
+class Session;
struct IRFunc;
struct IRInst;
@@ -133,7 +134,7 @@ struct IRValue
Type* getType() { return type; }
// The linked list of decorations attached to this value
- IRDecoration* firstDecoration;
+ IRDecoration* firstDecoration = nullptr;
// Look up a decoration in the list of decorations
IRDecoration* findDecorationImpl(IRDecorationOp op);
@@ -144,9 +145,16 @@ struct IRValue
}
// The first use of this value (start of a linked list)
- IRUse* firstUse;
+ IRUse* firstUse = nullptr;
+ // Replace all uses of this value with `other`, so
+ // that this value will now have no uses.
+ void replaceUsesWith(IRValue* other);
+
+ // Free a value (which needs to have been removed
+ // from its parent, had its uses eliminated, etc.)
+ void deallocate();
};
// Instructions are values that can be executed,
@@ -180,6 +188,18 @@ struct IRInst : IRValue
{
return getArgs()[index].usedValue;
}
+
+ // Insert this instruction into the same basic block
+ // as `other`, right before it.
+ void insertBefore(IRInst* other);
+
+ // Remove this instruction from its parent block,
+ // but don't delete it, or replace uses.
+ void removeFromParent();
+
+ // Remove this instruction from its parent block,
+ // and then destroy it (it had better have no uses!)
+ void removeAndDeallocate();
};
typedef int64_t IRIntegerValue;
@@ -268,7 +288,27 @@ struct IRBlock : IRValue
typedef FuncType IRFuncType;
struct IRGlobalValue : IRValue
-{};
+{
+ IRModule* parentModule;
+
+ IRGlobalValue* nextGlobalValue;
+ IRGlobalValue* prevGlobalValue;
+
+ IRGlobalValue* getNextValue() { return nextGlobalValue; }
+ IRGlobalValue* getPrevValue() { return prevGlobalValue; }
+
+ void insertBefore(IRGlobalValue* other);
+ void insertBefore(IRGlobalValue* other, IRModule* module);
+ void insertAtStart(IRModule* module);
+
+ void insertAfter(IRGlobalValue* other);
+ void insertAfter(IRGlobalValue* other, IRModule* module);
+ void insertAtEnd(IRModule* module);
+
+ void removeFromParent();
+
+ void moveToEnd();
+};
// A function is a parent to zero or more blocks of instructions.
//
@@ -311,14 +351,16 @@ struct IRFunc : IRGlobalValue
// A module is a parent to functions, global variables, types, etc.
struct IRModule : RefObject
{
- // The designated entry-point function, if any
- IRFunc* entryPoint;
+ // The compilation session in use.
+ Session* session;
// A list of all the functions and other
// global values declared in this module.
- List<IRGlobalValue*> globalValues;
+ IRGlobalValue* firstGlobalValue = nullptr;
+ IRGlobalValue* lastGlobalValue = nullptr;
- // TODO: need a symbol of all the global variables too
+ IRGlobalValue* getFirstGlobalValue() { return firstGlobalValue; }
+ IRGlobalValue* getlastGlobalValue() { return lastGlobalValue; }
};
void printSlangIRAssembly(StringBuilder& builder, IRModule* module);
@@ -326,6 +368,13 @@ String getSlangIRAssembly(IRModule* module);
void dumpIR(IRModule* module);
+// IR transformations
+
+// Transform shader entry points so that they conform to GLSL rules.
+void legalizeEntryPointsForGLSL(
+ Session* session,
+ IRModule* module);
+
}