MCPcopy Create free account
hub / github.com/carbonengine/trinity / DetectUnusedArguments

Function DetectUnusedArguments

shadercompiler/EffectCompilerMetal.cpp:4270–4344  ·  view source on GitHub ↗

Implements a disgusting method of funding which shader parameters turn out to be unused by the shader and emits warnings for them. Uses metal-objdump to disassemble the shader binary, finds a shader definition and looks through parameters. Parameters having "readnone" token are unused. Or so I think...

Source from the content-addressed store, hash-verified

4268// Uses metal-objdump to disassemble the shader binary, finds a shader definition and looks through parameters.
4269// Parameters having "readnone" token are unused. Or so I think...
4270void DetectUnusedArguments( const char* libPath, ParserState& state, ASTNode* callNode )
4271{
4272 ZoneScoped;
4273
4274 std::string entryName = ToString( callNode->GetChild( 1 )->GetSymbol()->name );
4275 auto functionHeader = callNode->GetChild( 1 )->GetSymbol()->definition->GetChild( 0 );
4276
4277 for( auto child : functionHeader->GetChildren() )
4278 {
4279 if( child && child->GetSymbol() )
4280 {
4281 child->GetSymbol()->used = true;
4282 }
4283 }
4284
4285 std::ostringstream cmd;
4286 cmd << MetalTool( "metal-objdump" ) << " -disassemble " << libPath;
4287 auto objdump = RunProcess( cmd.str().c_str() );
4288 if( objdump.first != 0 )
4289 {
4290 state.ShowMessage( callNode->GetLocation(), EC_CUSTOM_WARNING, "failed to run objdump, unused parameter information is unavailable" );
4291 }
4292
4293 size_t argumentIndex = 0;
4294 size_t stageInIndex = 0;
4295
4296 std::regex shader( "define.*@" + entryName + "(.*)" );
4297 std::smatch match;
4298 if( std::regex_search( objdump.second, match, shader ) )
4299 {
4300 auto args = match[1].str();
4301 SplitString( args, ',', [&]( auto arg ) {
4302 std::string argName = arg;
4303 Symbol* argumentSymbol = nullptr;
4304
4305 if( argumentIndex < functionHeader->GetChildrenCount() )
4306 {
4307 argumentSymbol = functionHeader->GetChild( argumentIndex )->GetSymbol();
4308
4309 bool isStageIn = false;
4310 for( auto reg : argumentSymbol->registerSpecifier )
4311 {
4312 if( reg.second.registerType == MetalRegister::StageIn )
4313 {
4314 isStageIn = true;
4315 break;
4316 }
4317 }
4318
4319 argName = ToString( argumentSymbol->name );
4320 if( isStageIn )
4321 {
4322 argName += "." + ToString( functionHeader->GetChild( argumentIndex )->GetType().symbol->definition->GetChild( stageInIndex )->GetChild( 0 )->GetSymbol()->name );
4323 if( ++stageInIndex >= functionHeader->GetChild( argumentIndex )->GetType().symbol->definition->GetChildrenCount() )
4324 {
4325 ++argumentIndex;
4326 }
4327 }

Callers

nothing calls this directly

Calls 9

RunProcessFunction · 0.85
SplitStringFunction · 0.85
GetSymbolMethod · 0.80
ShowMessageMethod · 0.80
GetChildrenCountMethod · 0.80
ToStringFunction · 0.70
MetalToolFunction · 0.70
GetChildMethod · 0.45
GetTypeMethod · 0.45

Tested by

no test coverage detected