| Age | Commit message (Collapse) | Author |
|
This gets us far enough that we can convert a single test case to use the IR, under the new `-use-ir` flag.
Getting this merged into mainline will at least ensure that we keep the IR path working in a minimal fashion, even when we have to add functionality the existing AST-based path
There is definitely some clutter here from keeping both IR-based and AST-based translation around, but I don't want to have a long-lived branch for the IR that gets further and further away from the `master` branch that is actually getting used and tested.
Summary of changes:
- Add pointer types and basic `load` operation to be able to handle variable declarations
- Add basic `call` instruction type
- Add simple address math for field reference in l-value
- Always add IR for referenced decls to global scope
- Add notion of "intrinsic" type modifier, which maps a type declaration directly to an IR opcode (plus optional literal operands to handle things like texture/sampler flavor)
- Improve printing of IR instructions, types, operands
- Add constant-buffer type to IR
- Allow any instruction to be detected as "should be folded into use sites" and use this to tag things of constant-buffer type
- Also add logic for implicit base on member expressions, to handle references to `cbuffer` members
- Add connection back to original decl to IR variables (including global shader parameters...)
- Use reflection name instead of true name when emitting HLSL from IR (so that we can match HLSL output)
- Make IR include decorations for type layout
- Re-use existing emit logic for HLSL semantics to output `register` semantics for IR-based code
- Make IR-based codegen be an option we can enable from the command line
- It still isn't on by default (it can barely manage a trivial shader), but it seems better to enable it always instead of putting it under an `#ifdef`
- Fix up how we check for intrinsic operations suring AST-based cross compilation so that adding new intrinsic ops for the IR won't break codegen.
|
|
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.
|
|
Previously, a `StructType` was an ordinary instruction that took a variable number of types are operands, representing the types of fields.
This ends up being inconvenient for a few reasons:
- To add decorations to the fields, you'd end up having to decorate the struct type instead (SPIR-V has this problem)
- You need to compute field indices during lowering, when you might prefer to defer that until later
- The get/set field operations now need an index, which needs to be an explicit operand, which means a magic numeric literal floating around to represent the index
The new approach fixes for the first two of these, and at least makes the last one a bit nicer.
A `StructDecl` is now a parent instruction, and its sub-instructions represent the fields of the type - each field is an explicit instruction of type `StructField`.
The operation to extract a field takes a direct reference the struct field, so everything is quite explicit.
|
|
- Change IR instructions to just hold an integer opcode instead of a pointer to the "info" structure
- Externalize definition of IR instructions to a header file, and use the "X macro" approach to allow generating different definitions
- Add notion of function types to the IR, so that we can easily query the result type of a function
- Add some convenience accesors to allow walking the IR in a strongly-typed manner (e.g., iterate over the parameters of a function)
- TODO: these should really be changed to assert the type of things, as least in debug builds
- Add very basic logic to `emit.cpp` so that it can walk the generated IR and start printing it back as HLSL
- This isn't meant to be usable as-is, but it is a step toward where we need to go
|
|
- Make all instructions store their argument count for now, so we can iterate over them easily.
- Longer term we might try to optimize for space because the common case is that the operand count is known, but keeping it simpler seems better for now
- Split apart the creation of an instruction from adding it to a parent
- Use the above capability to make sure that we add a function to its parent *after* all the parameter/result type emission has occured.
- Perform simple value numbering for types during IR creation
- This logic also tries to pick a good parent for any type instructions, so that types don't get created local to a function unless they really need to
- Create all constants at global scope, and re-use when values are identical
|
|
With this change, basic generation of IR works for a trivial shader, and there is some basic support for dumping the generated IR in an assembly-like format.
As with the other IR change, the use of the IR is statically disabled for now, so that existing users won't be affected.
|
|
Right now none of this is hooked up, but I want to get things checked in incrementally rather than have along long-lived branches.
- Added placeholder declarations for IR representation of instructions, basic blocks, etc.
- Start adding a `lower-to-ir` pass to translate from AST representation to IR
Again: none of this is functional, so it shouldn't mess with existing users of the compiler.
|