From 54f016e7ef36b7505bf47d188cf4b7e1fdc443a4 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 4 Oct 2017 13:54:25 -0700 Subject: 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 --- source/slang/syntax.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 123 insertions(+), 9 deletions(-) (limited to 'source/slang/syntax.cpp') 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 Session::getPtrType( + RefPtr valueType) + { + auto genericDecl = findMagicDecl( + this, "PtrType").As(); + auto typeDecl = genericDecl->inner; + + auto substitutions = new Substitutions(); + substitutions->genericDecl = genericDecl.Ptr(); + substitutions->args.Add(valueType); + + auto declRef = DeclRef(typeDecl.Ptr(), substitutions); + + return DeclRefType::Create( + this, + declRef)->As(); + } + SyntaxClass Session::findSyntaxClass(Name* name) { SyntaxClass 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(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()) { - 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().Ptr(); } + // PtrTypeBase + + Type* PtrTypeBase::getValueType() + { + return this->declRef.substitutions->args[0].As().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; } -- cgit v1.2.3