diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-04 13:54:25 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-04 13:54:25 -0700 |
| commit | 54f016e7ef36b7505bf47d188cf4b7e1fdc443a4 (patch) | |
| tree | f8a385c8a3bbac807c2c0d08a9b1e4cd208db95c /source/slang/syntax.cpp | |
| parent | 8a0ebb9fa25fd44def17b03b3f8aa1a33ad77940 (diff) | |
IR: overhaul IR design/implementation (#195)
* IR: overhaul IR design/implementation
Closes #192
Closes #188
This is a major overhaul of how the IR is implemented, with the primary goal of just using the AST-level type representation as the IR's type representation, rather than inventing an entire shadow set of types (as captured in issue #192).
One consequence of this choice is that types in the IR are no longer explicit "instructions" and are not represented as ordinary operands (so a bunch of `+ 1` cases end up going away when enumerating ordinary operands).
Along the way I also got rid of the embedded IDs in the IR (issue #188) because this wasn't too hard to deal with at the same time.
Another related change was to split the `IRValue` and `IRInst` cases, so that there are values that are not also instructions. Non-instruction values are now used to represent literals, references to declarations, and would eventually be used for an `undef` value if we need one. IR functions, global variables, and basic blocks are all values (because they can appear as operands), but not instructions.
The main benefit of this approach is that the top-level structure of a bytecode (BC) module is much simpler to understand and walk, and BC-level types are represented much more directly (such that we could conceivably use them for reflection soon).
* fixup: 64-bit build fix
* fixup: try to silence clang's pedantic dependent-type errors
* fixup: bug in VM loading of constants
Diffstat (limited to 'source/slang/syntax.cpp')
| -rw-r--r-- | source/slang/syntax.cpp | 132 |
1 files changed, 123 insertions, 9 deletions
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 475802cb1..4dbb6c05b 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -216,6 +216,9 @@ void Type::accept(IValVisitor* visitor, void* extra) overloadedType = new OverloadGroupType(); overloadedType->setSession(this); + + irBasicBlockType = new IRBasicBlockType(); + irBasicBlockType->setSession(this); } Type* Session::getBoolType() @@ -268,6 +271,29 @@ void Type::accept(IValVisitor* visitor, void* extra) return errorType; } + Type* Session::getIRBasicBlockType() + { + return irBasicBlockType; + } + + RefPtr<PtrType> Session::getPtrType( + RefPtr<Type> valueType) + { + auto genericDecl = findMagicDecl( + this, "PtrType").As<GenericDecl>(); + auto typeDecl = genericDecl->inner; + + auto substitutions = new Substitutions(); + substitutions->genericDecl = genericDecl.Ptr(); + substitutions->args.Add(valueType); + + auto declRef = DeclRef<Decl>(typeDecl.Ptr(), substitutions); + + return DeclRefType::Create( + this, + declRef)->As<PtrType>(); + } + SyntaxClass<RefObject> Session::findSyntaxClass(Name* name) { SyntaxClass<RefObject> syntaxClass; @@ -545,7 +571,26 @@ void Type::accept(IValVisitor* visitor, void* extra) else { - SLANG_UNEXPECTED("unhandled type"); + auto classInfo = session->findSyntaxClass( + session->getNamePool()->getName(magicMod->name)); + if (!classInfo.classInfo) + { + SLANG_UNEXPECTED("unhandled type"); + } + + auto type = classInfo.createInstance(); + if (!type) + { + SLANG_UNEXPECTED("constructor failure"); + } + + auto declRefType = dynamic_cast<DeclRefType*>(type); + if (!declRefType) + { + SLANG_UNEXPECTED("expected a declaration reference type"); + } + declRefType->declRef = declRef; + return declRefType; } } else @@ -578,6 +623,28 @@ void Type::accept(IValVisitor* visitor, void* extra) return (int)(int64_t)(void*)this; } + // IRBasicBlockType + + String IRBasicBlockType::ToString() + { + return "Block"; + } + + bool IRBasicBlockType::EqualsImpl(Type * /*type*/) + { + return false; + } + + Type* IRBasicBlockType::CreateCanonicalType() + { + return this; + } + + int IRBasicBlockType::GetHashCode() + { + return (int)(int64_t)(void*)this; + } + // InitializerListType String InitializerListType::ToString() @@ -653,18 +720,43 @@ void Type::accept(IValVisitor* visitor, void* extra) String FuncType::ToString() { - // TODO: a better approach than this - if (declRef) - return getText(declRef.GetName()); - else - return "/* unknown FuncType */"; + StringBuilder sb; + sb << "("; + UInt paramCount = getParamCount(); + for (UInt pp = 0; pp < paramCount; ++pp) + { + if (pp != 0) sb << ", "; + sb << getParamType(pp)->ToString(); + } + sb << ") -> "; + sb << getResultType()->ToString(); + return sb.ProduceString(); } bool FuncType::EqualsImpl(Type * type) { if (auto funcType = type->As<FuncType>()) { - return declRef == funcType->declRef; + auto paramCount = getParamCount(); + auto otherParamCount = funcType->getParamCount(); + if (paramCount != otherParamCount) + return false; + + for (UInt pp = 0; pp < paramCount; ++pp) + { + auto paramType = getParamType(pp); + auto otherParamType = funcType->getParamType(pp); + if (!paramType->Equals(otherParamType)) + return false; + } + + if(!resultType->Equals(funcType->resultType)) + return false; + + // TODO: if we ever introduce other kinds + // of qualification on function types, we'd + // want to consider it here. + return true; } return false; } @@ -676,7 +768,16 @@ void Type::accept(IValVisitor* visitor, void* extra) int FuncType::GetHashCode() { - return declRef.GetHashCode(); + int hashCode = getResultType()->GetHashCode(); + UInt paramCount = getParamCount(); + hashCode = combineHash(hashCode, Slang::GetHashCode(paramCount)); + for (UInt pp = 0; pp < paramCount; ++pp) + { + hashCode = combineHash( + hashCode, + getParamType(pp)->GetHashCode()); + } + return hashCode; } // TypeType @@ -782,6 +883,13 @@ void Type::accept(IValVisitor* visitor, void* extra) return this->declRef.substitutions->args[2].As<IntVal>().Ptr(); } + // PtrTypeBase + + Type* PtrTypeBase::getValueType() + { + return this->declRef.substitutions->args[0].As<Type>().Ptr(); + } + // GenericParamIntVal bool GenericParamIntVal::EqualsVal(Val* val) @@ -1161,7 +1269,13 @@ void Type::accept(IValVisitor* visitor, void* extra) { auto funcType = new FuncType(); funcType->setSession(session); - funcType->declRef = declRef; + + funcType->resultType = GetResultType(declRef); + for (auto pp : GetParameters(declRef)) + { + funcType->paramTypes.Add(GetType(pp)); + } + return funcType; } |
