From 3e3e2473bf85365593629bd1f6f070d11f0b8ab2 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 13 Oct 2017 22:39:15 -0700 Subject: Get rid of the `-slang-ir-asm` target (#212) * Get rid of the `-slang-ir-asm` target This is really only useful for debugging, so I've replaced the functionality with a `-dump-ir` command line option (which dump's the IR for an entry point before doing codegen). * fixup: use HLSL target, not DXBC, so test can run on Linux --- source/slang/compiler.cpp | 8 ++++++ source/slang/compiler.h | 6 ++++- source/slang/emit.cpp | 14 ++++++++++- source/slang/ir-insts.h | 36 --------------------------- source/slang/ir.cpp | 15 +++++------ source/slang/lower-to-ir.cpp | 59 +++++++++++++++++++------------------------- source/slang/lower.cpp | 6 +++++ source/slang/options.cpp | 10 ++++++-- source/slang/slang.cpp | 5 ++++ source/slang/syntax.cpp | 39 +++++++++++++++++++++++++++++ source/slang/type-defs.h | 22 ++++++++++++++++- source/slang/type-layout.cpp | 1 - 12 files changed, 137 insertions(+), 84 deletions(-) (limited to 'source') diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index d57c9b6cf..10755370a 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -559,6 +559,7 @@ namespace Slang } break; +#if 0 case CodeGenTarget::SlangIRAssembly: { String code = emitSlangIRAssemblyForEntryPoint(entryPoint); @@ -566,6 +567,7 @@ namespace Slang result = CompileResult(code); } break; +#endif case CodeGenTarget::None: // The user requested no output @@ -818,6 +820,10 @@ namespace Slang // If we are in command-line mode, we might be expected to actually // write output to one or more files here. + // But don't write any output if we were told to skip it. + if (compileRequest->shouldSkipCodegen) + return; + if (compileRequest->isCommandLineCompile) { for( auto entryPoint : compileRequest->entryPoints ) @@ -910,9 +916,11 @@ namespace Slang dumpIntermediateText(compileRequest, data, size, ".spv.asm"); break; +#if 0 case CodeGenTarget::SlangIRAssembly: dumpIntermediateText(compileRequest, data, size, ".slang-ir.asm"); break; +#endif case CodeGenTarget::SPIRV: dumpIntermediateBinary(compileRequest, data, size, ".spv"); diff --git a/source/slang/compiler.h b/source/slang/compiler.h index ca06e3a65..9de74e2cd 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -48,7 +48,6 @@ namespace Slang DXBytecode = SLANG_DXBC, DXBytecodeAssembly = SLANG_DXBC_ASM, SlangIR = SLANG_IR, - SlangIRAssembly = SLANG_IR_ASM, }; enum class LineDirectiveMode : SlangLineDirectiveMode @@ -211,6 +210,9 @@ namespace Slang // Should we dump intermediate results along the way, for debugging? bool shouldDumpIntermediates = false; + bool shouldDumpIR = false; + bool shouldSkipCodegen = false; + // How should `#line` directives be emitted (if at all)? LineDirectiveMode lineDirectiveMode = LineDirectiveMode::Default; @@ -391,6 +393,8 @@ namespace Slang // Construct pointer types on-demand RefPtr getPtrType(RefPtr valueType); + RefPtr getGroupSharedType(RefPtr valueType); + SyntaxClass findSyntaxClass(Name* name); Dictionary > mapNameToSyntaxClass; diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 7d7553bc5..8dcbcdbf4 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1224,6 +1224,12 @@ struct EmitVisitor emitTypeImpl(arrayType->baseType, &arrayDeclarator); } + void visitGroupSharedType(GroupSharedType* type, TypeEmitArg const& arg) + { + Emit("groupshared "); + emitTypeImpl(type->valueType, arg.declarator); + } + void EmitType( RefPtr type, SourceLoc const& typeLoc, @@ -4492,6 +4498,9 @@ emitDeclImpl(decl, nullptr); if(!type) return; + if (type->Equals(getSession()->getVoidType())) + return; + emitIRType(context, type, getIRName(inst)); emit(" = "); } @@ -6266,7 +6275,10 @@ String emitEntryPoint( auto lowered = lowerEntryPointToIR(entryPoint, programLayout, target); // debugging: -// dumpIR(lowered); + if (translationUnit->compileRequest->shouldDumpIR) + { + dumpIR(lowered); + } // TODO: depending on the target we are trying to generate code for, // we may need to apply certain transformations, and we may also diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h index 6f6af13cb..64c200b12 100644 --- a/source/slang/ir-insts.h +++ b/source/slang/ir-insts.h @@ -76,38 +76,6 @@ struct IRDeclRef : IRValue // -// TODO(tfoley): the IR-level representation of -// pointers had an "address space" field that the -// current AST level lacks. This capability was -// used to represent `groupshared` allocation, -// so we probably need to find an alternative. - -// Address spaces for IR pointers -enum IRAddressSpace : UInt -{ - // A default address space for things like local variables - kIRAddressSpace_Default, - - // Address space for HLSL `groupshared` allocations - kIRAddressSpace_GroupShared, -}; - -#if 0 -struct IRPtrType : IRType -{ - IRUse valueType; - IRUse addressSpace; - - IRType* getValueType() { return (IRType*) valueType.usedValue; } - - IRAddressSpace getAddressSpace() - { - return IRAddressSpace( - ((IRConstant*)addressSpace.usedValue)->u.intVal); - } -}; -#endif - struct IRCall : IRInst { IRUse func; @@ -383,10 +351,6 @@ struct IRBuilder IRParam* emitParam( IRType* type); - IRVar* emitVar( - IRType* type, - IRAddressSpace addressSpace); - IRVar* emitVar( IRType* type); diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index a79dc3992..79d9883ea 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -805,8 +805,7 @@ namespace Slang } IRVar* IRBuilder::emitVar( - IRType* type, - IRAddressSpace addressSpace) + IRType* type) { auto allocatedType = getSession()->getPtrType(type); auto inst = createInst( @@ -817,13 +816,6 @@ namespace Slang return inst; } - - IRVar* IRBuilder::emitVar( - IRType* type) - { - return emitVar(type, kIRAddressSpace_Default); - } - IRInst* IRBuilder::emitLoad( IRValue* ptr) { @@ -1451,6 +1443,11 @@ namespace Slang { dumpDeclRef(context, declRefType->declRef); } + else if(auto groupSharedType = type->As()) + { + dump(context, "@ThreadGroup "); + dumpType(context, groupSharedType->valueType); + } else { // Need a default case here diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index e0dbd5dae..29a1fec2f 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -906,38 +906,24 @@ struct LoweringVisitor LoweredValInfo createVar( IRGenContext* context, - LoweredTypeInfo type, + RefPtr type, Decl* decl = nullptr, - Layout* layout = nullptr, - IRAddressSpace addressSpace = kIRAddressSpace_Default) + Layout* layout = nullptr) { auto builder = context->irBuilder; - switch( type.flavor ) - { - case LoweredTypeInfo::Flavor::Simple: - { - auto irAlloc = builder->emitVar(getSimpleType(type), addressSpace); - - if (decl) - { - builder->addHighLevelDeclDecoration(irAlloc, decl); - } - - if (layout) - { - builder->addLayoutDecoration(irAlloc, layout); - } + auto irAlloc = builder->emitVar(type); + if (decl) + { + builder->addHighLevelDeclDecoration(irAlloc, decl); + } - return LoweredValInfo::ptr(irAlloc); - } - break; - - default: - SLANG_UNIMPLEMENTED_X("var type"); - return LoweredValInfo(); + if (layout) + { + builder->addLayoutDecoration(irAlloc, layout); } + return LoweredValInfo::ptr(irAlloc); } void addArgs( @@ -1140,7 +1126,7 @@ struct ExprLoweringVisitorBase : ExprVisitor } auto paramDecl = paramDeclRef.getDecl(); - auto paramType = lowerType(context, GetType(paramDeclRef)); + RefPtr paramType = lowerSimpleType(context, GetType(paramDeclRef)); auto argExpr = expr->Arguments[argIndex++]; if (paramDecl->HasModifier() @@ -2084,13 +2070,19 @@ struct DeclLoweringVisitor : DeclVisitor LoweredValInfo lowerGlobalVarDecl(VarDeclBase* decl) { - auto varType = lowerSimpleType(context, decl->getType()); + RefPtr varType = lowerSimpleType(context, decl->getType()); - IRAddressSpace addressSpace = kIRAddressSpace_Default; if (decl->HasModifier()) { - addressSpace = kIRAddressSpace_GroupShared; + varType = context->getSession()->getGroupSharedType(varType); } + // TODO: There might be other cases of storage qualifiers + // that should translate into "rate-qualified" types + // for the variable's storage. + // + // TODO: Also worth asking whether we should have semantic + // checking be responsible for applying qualifiers applied + // to a variable over to its type, when it makes sense. auto builder = getBuilder(); auto irGlobal = builder->createGlobalVar(varType); @@ -2140,7 +2132,7 @@ struct DeclLoweringVisitor : DeclVisitor // emit an SSA value in this common case. // - auto varType = lowerType(context, decl->getType()); + RefPtr varType = lowerSimpleType(context, decl->getType()); // TODO: If the variable is marked `static` then we need to // deal with it specially: we should move its allocation out @@ -2169,13 +2161,14 @@ struct DeclLoweringVisitor : DeclVisitor // For now we might do the expedient thing and handle this // via a notion of an "address space." - IRAddressSpace addressSpace = kIRAddressSpace_Default; if (decl->HasModifier()) { - addressSpace = kIRAddressSpace_GroupShared; + // TODO: This logic is duplicated with the global-variable + // case. We should seek to share it. + varType = context->getSession()->getGroupSharedType(varType); } - LoweredValInfo varVal = createVar(context, varType, decl, getLayout(), addressSpace); + LoweredValInfo varVal = createVar(context, varType, decl, getLayout()); if( auto initExpr = decl->initExpr ) { diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index b620a7837..1387abc23 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -785,6 +785,12 @@ struct LoweringVisitor return loweredType; } + RefPtr visitGroupSharedType(GroupSharedType* type) + { + return getSession()->getGroupSharedType( + lowerType(type->valueType)); + } + RefPtr transformSyntaxField(Type* type) { return lowerType(type); diff --git a/source/slang/options.cpp b/source/slang/options.cpp index 693081f2a..79832a9c3 100644 --- a/source/slang/options.cpp +++ b/source/slang/options.cpp @@ -266,6 +266,14 @@ struct OptionsParser { flags |= SLANG_COMPILE_FLAG_NO_MANGLING; } + else if(argStr == "-dump-ir" ) + { + requestImpl->shouldDumpIR = true; + } + else if(argStr == "-skip-codegen" ) + { + requestImpl->shouldSkipCodegen = true; + } else if (argStr == "-backend" || argStr == "-target") { String name = tryReadCommandLineArgument(arg, &argCursor, argEnd); @@ -304,8 +312,6 @@ struct OptionsParser CASE(spirv, SPIRV); CASE(spirv-assembly, SPIRV_ASM); - CASE(slang-ir, IR); - CASE(slang-ir-assembly, IR_ASM); CASE(none, TARGET_NONE); #undef CASE diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 66ff9e429..6e57c104c 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -301,6 +301,11 @@ int CompileRequest::executeActionsInner() if (mSink.GetErrorCount() != 0) return 1; } + + // If command line specifies to skip codegen, we exit here. + // Note: this is a debugging option. +// if (shouldSkipCodegen) +// return 0; // Generate output code, in whatever format was requested generateOutput(this); diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 4dbb6c05b..b863cb707 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -294,6 +294,15 @@ void Type::accept(IValVisitor* visitor, void* extra) declRef)->As(); } + RefPtr Session::getGroupSharedType(RefPtr valueType) + { + RefPtr groupSharedType = new GroupSharedType(); + groupSharedType->setSession(this); + groupSharedType->valueType = valueType; + return groupSharedType; + } + + SyntaxClass Session::findSyntaxClass(Name* name) { SyntaxClass syntaxClass; @@ -337,6 +346,36 @@ void Type::accept(IValVisitor* visitor, void* extra) return baseType->ToString() + "[]"; } + // GroupSharedType + + Slang::String GroupSharedType::ToString() + { + return "@ThreadGroup " + valueType->ToString(); + } + + bool GroupSharedType::EqualsImpl(Type * type) + { + auto t = type->As(); + if (!t) + return false; + return valueType->Equals(t->valueType); + } + + Type* GroupSharedType::CreateCanonicalType() + { + auto canonicalValueType = valueType->GetCanonicalType(); + auto canonicalGroupSharedType = getSession()->getGroupSharedType(canonicalValueType); + session->canonicalTypes.Add(canonicalGroupSharedType); + return canonicalGroupSharedType; + } + + int GroupSharedType::GetHashCode() + { + return combineHash( + valueType->GetHashCode(), + (int)(typeid(this).hash_code())); + } + // DeclRefType String DeclRefType::ToString() diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index 7fbefc368..fc3b651b4 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -308,7 +308,27 @@ protected: virtual bool EqualsImpl(Type * type) override; virtual Type* CreateCanonicalType() override; virtual int GetHashCode() override; -) + ) +END_SYNTAX_CLASS() + +// The effective type of a variable declared with `groupshared` storage qualifier. +SYNTAX_CLASS(GroupSharedType, Type) + SYNTAX_FIELD(RefPtr, valueType); + +RAW( + virtual ~GroupSharedType() + { + int f = 0; + } + + virtual Slang::String ToString() override; + +protected: + virtual bool EqualsImpl(Type * type) override; + virtual Type* CreateCanonicalType() override; + virtual int GetHashCode() override; + ) + END_SYNTAX_CLASS() // The "type" of an expression that resolves to a type. diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp index 27bcbd174..034982ae4 100644 --- a/source/slang/type-layout.cpp +++ b/source/slang/type-layout.cpp @@ -622,7 +622,6 @@ LayoutRulesFamilyImpl* GetLayoutRulesFamilyImpl(CodeGenTarget target) case CodeGenTarget::DXBytecode: case CodeGenTarget::DXBytecodeAssembly: case CodeGenTarget::SlangIR: - case CodeGenTarget::SlangIRAssembly: return &kHLSLLayoutRulesFamilyImpl; case CodeGenTarget::GLSL: -- cgit v1.2.3