예제 #1
0
		List<String>& PipelineSymbol::GetWorldTopologyOrder()
		{
			if (WorldTopologyOrder.Count() != 0)
				return WorldTopologyOrder;
			List<String> rs;
			HashSet<String> rsSet;
			bool changed = true;
			while (changed)
			{
				changed = false;
				for (auto & w : WorldDependency)
				{
					if (!rsSet.Contains(w.Key))
					{
						bool canAdd = true;
						for (auto & dw : w.Value)
							if (!rsSet.Contains(dw))
							{
								canAdd = false;
								break;
							}
						if (canAdd)
						{
							rsSet.Add(w.Key);
							rs.Add(w.Key);
							changed = true;
						}
					}
				}
			}
			WorldTopologyOrder = _Move(rs);
			return WorldTopologyOrder;
		}
예제 #2
0
int32_t CountDistinct(MEM_POOL_PTR mem_pool, struct low_data_struct *cur_value,
		struct low_data_struct* new_value) {

	if (cur_value == NULL || new_value == NULL) {
		return -1;
	}

	if (cur_value->data == NULL) {
		cur_value->type = HI_TYPE_SET;
		cur_value->len = 0;
		Equals * equals =
				new (mem_pool_malloc(mem_pool, sizeof(LDEquals))) LDEquals();
		HashCoding* hash =
				new (mem_pool_malloc(mem_pool, sizeof(LDHash))) LDHash();
		cur_value->data =
				new (mem_pool_malloc(mem_pool, sizeof(HashSet))) HashSet(equals,
						hash, mem_pool);
	}

	HashSet* set = (HashSet*) cur_value->data;
	if (set->Contains(new_value)) {
		return MILE_RETURN_SUCCESS;
	} else if (new_value->type != HI_TYPE_NULL) {
		struct low_data_struct* ld = (struct low_data_struct*) mem_pool_malloc(
				mem_pool, sizeof(struct low_data_struct));
		memset(ld, 0, sizeof(struct low_data_struct));
		copy_low_data_struct(mem_pool, ld, new_value);
		set->Add(ld);
		cur_value->len++;
	}

	return MILE_RETURN_SUCCESS;
}
예제 #3
0
	List<ShaderLibFile> CompileShaderSource(Spire::Compiler::CompileResult & compileResult,
		const CoreLib::String & src, Spire::Compiler::CompileOptions & options)
	{
		Spire::Compiler::NamingCounter = 0;
		RefPtr<ShaderCompiler> compiler = CreateShaderCompiler();
		List<CompileUnit> units;
		HashSet<String> processedUnits;
		List<String> unitsToInclude;
		unitsToInclude.Add(L"");
		processedUnits.Add(L"");
		auto predefUnit = compiler->Parse(compileResult, LibIncludeString, L"stdlib");
		for (int i = 0; i < unitsToInclude.Count(); i++)
		{
			auto inputFileName = unitsToInclude[i];
			try
			{
				String source = src;
				if (i > 0)
					source = File::ReadAllText(inputFileName);
				auto unit = compiler->Parse(compileResult, source, Path::GetFileName(inputFileName));
				units.Add(unit);
				if (unit.SyntaxNode)
				{
					for (auto inc : unit.SyntaxNode->Usings)
					{
						String includeFile = Path::Combine(Path::GetDirectoryName(inputFileName), inc.Content);
						if (processedUnits.Add(includeFile))
						{
							unitsToInclude.Add(includeFile);
						}
					}
				}
			}
			catch (IOException)
			{
				compileResult.GetErrorWriter()->Error(1, L"cannot open file '" + Path::GetFileName(inputFileName) + L"'.", CodePosition(0, 0, L""));
			}
		}
		units.Add(predefUnit);
		return CompileUnits(compileResult, compiler.Ptr(), units, options);
	}
예제 #4
0
		bool SymbolTable::SortShaders()
		{
			HashSet<ShaderSymbol*> shaderSet;
			ShaderDependenceOrder.Clear();
			List<ShaderSymbol *> nextShaders, currentShaders;
			// sort shaders in dependency order
			for (auto & shader : Shaders)
			{
				if (shader.Value->DependentShaders.Count() == 0)
				{
					ShaderDependenceOrder.Add(shader.Value.Ptr());
					shaderSet.Add(shader.Value.Ptr());
				}
				else
					currentShaders.Add(shader.Value.Ptr());
			}
			while (currentShaders.Count())
			{
				nextShaders.Clear();
				for (auto & shader : currentShaders)
				{
					bool pass = true;
					for (auto & dshader : shader->DependentShaders)
						if (!shaderSet.Contains(dshader))
						{
							pass = false;
							break;
						}
					if (pass)
					{
						ShaderDependenceOrder.Add(shader);
						shaderSet.Add(shader);
					}
					else
						nextShaders.Add(shader);
				}
				currentShaders.SwapWith(nextShaders);
			}
			return (ShaderDependenceOrder.Count() == Shaders.Count());
		}
예제 #5
0
		List<ShaderComponentSymbol*> ShaderIR::GetComponentDependencyOrder()
		{
			List<ShaderComponentSymbol*> result, workList;
			HashSet<String> set;
			for (auto & comp : DefinitionsByComponent)
			{
				bool emptyDependency = true;
				for (auto & def : comp.Value)
					if (def.Value->Dependency.Count())
					{
						emptyDependency = false;
						break;
					}
				if (emptyDependency)
				{
					workList.Add(Shader->AllComponents[comp.Key]());
				}
			}
			for (int i = 0; i < workList.Count(); i++)
			{
				auto comp = workList[i];
				if (!set.Contains(comp->UniqueName))
				{
					bool insertable = true;
					for (auto & def : DefinitionsByComponent[comp->UniqueName]())
					{
						for (auto & dep : def.Value->Dependency)
							if (!set.Contains(dep->Component->UniqueName))
							{
								insertable = false;
								goto breakLoc;
							}
					}
				breakLoc:;
					if (insertable)
					{
						if (set.Add(comp->UniqueName))
						{
							result.Add(comp);
							for (auto & def : DefinitionsByComponent[comp->UniqueName]())
								for (auto & user : def.Value->Users)
									workList.Add(user->Component);
						}
					}
				}
			}
			return result;
		}
예제 #6
0
	void ChoiceForm::Autotune(float timeBudget)
	{
		bool countOnly = false;
		ResetButton_Clicked(nullptr);
		referenceFrame = ReadFrameData(choiceControl->RenderFrame());
		EnumerableDictionary<String, Spire::Compiler::ShaderChoiceValue> currentChoices;
		currentBestValue = 1e30f;
		currentBestChoices = currentChoices;
		HashSet<String> selectedChoices;
		for (auto & chk : choiceCheckBoxes)
			if (chk.Value->Checked)
				selectedChoices.Add(chk.Key);
		autotuningLog.Clear();
		auto startTimePoint = PerformanceCounter::Start();
		int count = AutotuneHelper(selectedChoices, currentChoices, timeBudget, countOnly);
		float time = PerformanceCounter::EndSeconds(startTimePoint);
		autotuningLog << L"time: " << time << EndLine;
		printf("variant count: %d\ntime: %f\n", count, time);
		File::WriteAllText(L"autotuneLog.txt", autotuningLog.ToString());
		if (!countOnly)
		{
			existingChoices = currentBestChoices;
			disableChoiceChangeCapture = true;
			for (auto & choice : existingChoices)
			{
				auto cmb = choiceComboBoxes[choice.Key].GetValue();
				int idxToSelect = 0;
				for (int i = 0; i < cmb->Items.Count(); i++)
					if (cmb->GetTextItem(i)->GetText() == choice.Value.ToString())
					{
						idxToSelect = i;
						break;
					}
				cmb->SetSelectedIndex(idxToSelect);
			}
			disableChoiceChangeCapture = false;
			Recompile();
			ShaderChanged(currentShaderName);
		}
			
	}
예제 #7
0
 void addThread(Thread *pthread)
 {
     Mutex::Locker lock(&ThreadMutex);
     ThreadSet.Add(pthread);
 }
예제 #8
0
	void DFA_Graph::Generate(NFA_Graph * nfa)
	{
		table = new RegexCharTable();
		List<RegexCharSet * > charSets;
		for (int i=0; i<nfa->translations.Count(); i++)
		{
			if (nfa->translations[i]->CharSet && nfa->translations[i]->CharSet->Ranges.Count())
				charSets.Add(nfa->translations[i]->CharSet.operator->());
		}
		CharTableGenerator gen(table.operator ->());
		int elements = gen.Generate(charSets);
		CharElements = gen.elements;
		List<DFA_Node *> L,D;
		startNode = new DFA_Node(elements);
		startNode->ID = 0;
		startNode->Nodes.Add(nfa->start);
		L.Add(startNode);
		nodes.Add(startNode);
		List<Word> charElem;
		do
		{
			DFA_Node * node = L.Last();
			L.RemoveAt(L.Count()-1);
			charElem.Clear();
			node->IsFinal = false;
			for (int i=0; i<node->Nodes.Count(); i++)
			{
				CombineCharElements(node->Nodes[i], charElem);
				if (node->Nodes[i]->IsFinal)
					node->IsFinal = true;
			}
			for (int i=0; i<charElem.Count(); i++)
			{
				DFA_Node * n = new DFA_Node(0);
				for (int j=0; j<node->Nodes.Count(); j++)
				{
					for (int k=0; k<node->Nodes[j]->Translations.Count(); k++)
					{
						NFA_Translation * trans = node->Nodes[j]->Translations[k];
						if (trans->CharSet->Elements.Contains(charElem[i]))
						{
							if (!n->Nodes.Contains(node->Nodes[j]->Translations[k]->NodeDest))
								n->Nodes.Add(node->Nodes[j]->Translations[k]->NodeDest);
						}
					}
				}
				int fid = -1;
				for (int j=0; j<nodes.Count(); j++)
				{
					if ((*nodes[j]) == *n)
					{
						fid = j;
						break;
					}
				}
				if (fid == -1)
				{
					n->Translations.SetSize(elements);
					for (int m=0; m<elements; m++)
						n->Translations[m] = 0;
					n->ID = nodes.Count();
					L.Add(n);
					nodes.Add(n);
					fid = nodes.Count()-1;
				}
				else
					delete n;
				n = nodes[fid].operator ->();
				node->Translations[charElem[i]] = n;
			}
		}
		while (L.Count());

		// Set Terminal Identifiers
		HashSet<int> terminalIdentifiers;
		for (int i=0; i<nodes.Count(); i++)
		{
			terminalIdentifiers.Clear();
			for (int j=0; j<nodes[i]->Nodes.Count(); j++)
			{
				if (nodes[i]->Nodes[j]->IsFinal && 
					!terminalIdentifiers.Contains(nodes[i]->Nodes[j]->TerminalIdentifier))
				{
					nodes[i]->IsFinal = true;
					terminalIdentifiers.Add(nodes[i]->Nodes[j]->TerminalIdentifier);
					nodes[i]->TerminalIdentifiers.Add(nodes[i]->Nodes[j]->TerminalIdentifier);
				}
			}
			nodes[i]->TerminalIdentifiers.Sort();
		}
	}
예제 #9
0
		void ShaderIR::ResolveComponentReference()
		{
			// build bidirectional dependency map of component definitions
			for (auto & comp : Definitions)
			{
				comp->Dependency.Clear();
				comp->Users.Clear();
			}
			for (auto & comp : Definitions)
			{
				List<ShaderComponentSymbol *> workList;
				for (auto & dep : comp->Implementation->DependentComponents)
					workList.Add(dep);
				HashSet<ShaderComponentSymbol*> proceseedDefCompss;
				for (int i = 0; i < workList.Count(); i++)
				{
					auto dep = workList[i];
					if (!proceseedDefCompss.Add(dep))
						continue;
					auto & depDefs = DefinitionsByComponent[dep->UniqueName]();
					// select the best overload according to import operator ordering,
					// prefer user-pinned definitions (as provided in the choice file)
					List<String> depWorlds;
					depWorlds.Add(comp->World);
					for (auto & w : Shader->Pipeline->WorldDependency[comp->World]())
						depWorlds.Add(w);
					for (int pass = 0; pass < 2; pass++)
					{
						// in the first pass, examine the pinned definitions only
						// in the second pass, examine all the rest definitions
						for (auto & depWorld : depWorlds)
						{
							bool isPinned = false;
							for (auto existingDef : dep->Type->PinnedWorlds)
								if (existingDef.StartsWith(depWorld))
								{
									isPinned = true;
									break;
								}
							if (pass == 0 && !isPinned || pass == 1 && isPinned) continue;
							ComponentDefinitionIR * depDef;
							if (depDefs.TryGetValue(depWorld, depDef))
							{
								comp->Dependency.Add(depDef);
								depDef->Users.Add(comp.Ptr());
								// add additional dependencies due to import operators
								if (depWorld != comp->World)
								{
									auto importPath = Shader->Pipeline->FindImportOperatorChain(depWorld, comp->World);
									if (importPath.Count() == 0)
										throw InvalidProgramException(L"no import path found.");
									auto & usings = importPath.First().Nodes.Last().ImportOperator->Usings;
									for (auto & importUsing : usings)
									{
										ShaderComponentSymbol* refComp;
										if (!Shader->AllComponents.TryGetValue(importUsing.Content, refComp))
											throw InvalidProgramException(L"import operator dependency not exists.");
										workList.Add(refComp);
									}
								}
								goto selectionEnd; // first preferred overload is found, terminate searching
							}
						}
					}
					selectionEnd:;
				}
			}
		}
예제 #10
0
		void ShaderIR::EliminateDeadCode()
		{
			// mark entry points
			auto MarkUsing = [&](String compName, String userWorld)
			{
				if (auto defs = DefinitionsByComponent.TryGetValue(compName))
				{
					if (auto def = defs->TryGetValue(userWorld))
						(*def)->IsEntryPoint = true;
					else
					{
						for (auto & world : Shader->Pipeline->WorldDependency[userWorld]())
						{
							if (auto def2 = defs->TryGetValue(world))
							{
								(*def2)->IsEntryPoint = true;
								break;
							}
						}
					}
				}
			};
			for (auto & impOp : Shader->Pipeline->SyntaxNode->ImportOperators)
				for (auto & ref : impOp->Usings)
					MarkUsing(ref.Content, impOp->DestWorld.Content);
			for (auto & w : Shader->Pipeline->SyntaxNode->Worlds)
				for (auto & ref : w->Usings)
					MarkUsing(ref.Content, w->Name.Content);
			for (auto & comp : Definitions)
				if (comp->Implementation->ExportWorlds.Contains(comp->World) ||
					Shader->Pipeline->IsAbstractWorld(comp->World) &&
					(comp->Implementation->SyntaxNode->LayoutAttributes.ContainsKey(L"Pinned") || Shader->Pipeline->Worlds[comp->World]().SyntaxNode->LayoutAttributes.ContainsKey(L"Pinned")))
				{
					comp->IsEntryPoint = true;
				}

			List<ComponentDefinitionIR*> workList;
			HashSet<ComponentDefinitionIR*> referencedDefs;
			for (auto & def : Definitions)
			{
				if (def->IsEntryPoint)
				{
					if (referencedDefs.Add(def.Ptr()))
						workList.Add(def.Ptr());
				}
			}
			for (int i = 0; i < workList.Count(); i++)
			{
				auto def = workList[i];
				for (auto & dep : def->Dependency)
				{
					if (referencedDefs.Add(dep))
						workList.Add(dep);
				}
			}
			List<RefPtr<ComponentDefinitionIR>> newDefinitions;
			for (auto & def : Definitions)
			{
				if (referencedDefs.Contains(def.Ptr()))
				{
					newDefinitions.Add(def);
					EnumerableHashSet<ComponentDefinitionIR*> newSet;
					for (auto & comp : def->Users)
						if (referencedDefs.Contains(comp))
						{
							newSet.Add(comp);
						}
					def->Users = newSet;
					newSet.Clear();
					for (auto & comp : def->Dependency)
						if (referencedDefs.Contains(comp))
						{
							newSet.Add(comp);
						}
					def->Dependency = newSet;
				}
			}
			Definitions = _Move(newDefinitions);
			for (auto & kv : DefinitionsByComponent)
			{
				for (auto & def : kv.Value)
					if (!referencedDefs.Contains(def.Value))
						kv.Value.Remove(def.Key);
			}
		}
예제 #11
0
 protected: HashSetTest() {
   set_.Add("1");
   set_.Add("2");
   set_.Add("3");
 }
예제 #12
0
			/* Generate a shader variant by applying mechanic choice rules and the choice file.
			   The choice file provides "preferred" definitions, as represented in ShaderComponentSymbol::Type::PinnedWorlds
		       The process resolves the component references by picking a pinned definition if one is available, or a definition
			   with the preferred import path as defined by import operator ordering.
			   After all references are resolved, all unreferenced definitions (dead code) are eliminated, 
			   resulting a shader variant ready for code generation.
			*/
			RefPtr<ShaderIR> GenerateShaderVariantIR(CompileResult & cresult, ShaderClosure * shader, Schedule & schedule, SymbolTable * symbolTable)
			{
				RefPtr<ShaderIR> result = new ShaderIR();
				result->Shader = shader;
				result->SymbolTable = symbolTable;
				// mark pinned worlds
				for (auto & comp : shader->Components)
				{
					for (auto & impl : comp.Value->Implementations)
					{
						for (auto & w : impl->Worlds)
						{
							if (impl->SrcPinnedWorlds.Contains(w) || impl->SyntaxNode->IsInline() || impl->ExportWorlds.Contains(w) || impl->SyntaxNode->IsInput())
							{
								comp.Value->Type->PinnedWorlds.Add(w);
							}
						}
					}
				}
				// apply choices
				Dictionary<String, ShaderComponentSymbol*> choiceComps;
				for (auto & comp : shader->AllComponents)
				{
					for (auto & choiceName : comp.Value.Symbol->ChoiceNames)
						choiceComps[choiceName] = comp.Value.Symbol;
				}
				HashSet<ShaderComponentImplSymbol*> pinnedImpl;
				for (auto & choice : schedule.Choices)
				{
					ShaderComponentSymbol * comp = nullptr;
					if (choiceComps.TryGetValue(choice.Key, comp))
					{
						comp->Type->PinnedWorlds.Clear();
						for (auto & selectedDef : choice.Value)
						{
							if (comp->Type->ConstrainedWorlds.Contains(selectedDef->WorldName))
							{
								comp->Type->PinnedWorlds.Add(selectedDef->WorldName);
								// find specified impl
								for (auto & impl : comp->Implementations)
								{
									if (impl->Worlds.Contains(selectedDef->WorldName))
										pinnedImpl.Add(impl.Ptr());
								}
							}
							else
							{
                                cresult.GetErrorWriter()->diagnose(selectedDef.Ptr()->Position, Diagnostics::worldIsNotAValidChoiceForKey, selectedDef->WorldName, choice.Key);
							}
						}
					}
				}
				for (auto & attribs : schedule.AddtionalAttributes)
				{
					ShaderComponentSymbol * comp = nullptr;
					if (choiceComps.TryGetValue(attribs.Key, comp))
					{
						// apply attributes
						for (auto & impl : comp->Implementations)
						{
                            for (auto & attrib : attribs.Value)
                            {
                                auto modifier = new SimpleAttribute();
                                modifier->Key = attrib.Key;
                                modifier->Value.Content = attrib.Value;

                                modifier->next = impl->SyntaxNode->modifiers.first;
                                impl->SyntaxNode->modifiers.first = modifier;
                            }
						}
					}
				}
				// generate definitions
				Dictionary<ShaderClosure*, ModuleInstanceIR*> moduleInstanceMap;
				auto createModuleInstance = [&](ShaderClosure * closure)
				{
					ModuleInstanceIR * inst;
					if (moduleInstanceMap.TryGetValue(closure, inst))
						return inst;
					List<String> namePath;
					
					auto parent = closure;
					while (parent)
					{
						if (parent->Name.Length())
							namePath.Add(parent->Name);
						else
							namePath.Add(parent->ModuleSyntaxNode->Name.Content);
						parent = parent->Parent;
					}
					StringBuilder sbBindingName;
					for (int i = namePath.Count() - 2; i >= 0; i--)
					{
						sbBindingName << namePath[i];
						if (i > 0)
							sbBindingName << ".";
					}
					// if this is the root module, its binding name is module name.
					if (namePath.Count() == 1)
						sbBindingName << namePath[0];
					inst = new ModuleInstanceIR();
					inst->SyntaxNode = closure->ModuleSyntaxNode;
					inst->BindingIndex = closure->BindingIndex;
					inst->UsingPosition = closure->UsingPosition;
					result->ModuleInstances.Add(inst);
					inst->BindingName = sbBindingName.ProduceString();
					moduleInstanceMap[closure] = inst;
					return inst;
				};
				for (auto & comp : shader->AllComponents)
				{
					EnumerableDictionary<String, ComponentDefinitionIR*> defs;
					Dictionary<String, ShaderComponentImplSymbol*> impls;
					for (auto & impl : comp.Value.Symbol->Implementations)
					{
						auto createComponentDef = [&](const String & w)
						{
							RefPtr<ComponentDefinitionIR> def = new ComponentDefinitionIR();
							def->OriginalName = comp.Value.Symbol->Name;
							def->UniqueKey = comp.Value.Symbol->UniqueKey;
							def->UniqueName = comp.Value.Symbol->UniqueName;
							def->Type = comp.Value.Symbol->Type->DataType;
							def->IsEntryPoint = (impl->ExportWorlds.Contains(w) || impl->SyntaxNode->IsParam() ||
								(shader->Pipeline->IsAbstractWorld(w) &&
								(impl->SyntaxNode->HasSimpleAttribute("Pinned") || shader->Pipeline->Worlds[w]()->HasSimpleAttribute("Pinned"))));
							CloneContext cloneCtx;
							def->SyntaxNode = impl->SyntaxNode->Clone(cloneCtx);
							def->World = w;
							def->ModuleInstance = createModuleInstance(comp.Value.Closure);
							return def;
						};
						// parameter component will only have one defintion that is shared by all worlds
						if (impl->SyntaxNode->IsParam())
						{
							auto def = createComponentDef("<uniform>");
							result->Definitions.Add(def);
							defs["<uniform>"] = def.Ptr();
						}
						else
						{
							for (auto & w : impl->Worlds)
							{
								auto def = createComponentDef(w);
								result->Definitions.Add(def);
								bool existingDefIsPinned = false;
								if (defs.ContainsKey(w))
									existingDefIsPinned = pinnedImpl.Contains(impls[w]());
								if (!existingDefIsPinned)
								{
									defs[w] = def.Ptr();
									impls[w] = impl.Ptr();
								}
							}
						}
					}
					result->DefinitionsByComponent[comp.Key] = defs;
				}
				bool changed = true;
				while (changed)
				{
					changed = false;
					result->ResolveComponentReference();
					result->EliminateDeadCode();
					// check circular references
					for (auto & def : result->Definitions)
					{
						if (def->Dependency.Contains(def.Ptr()))
						{
                            cresult.GetErrorWriter()->diagnose(def->SyntaxNode->Position, Diagnostics::componentDefinitionCircularity, def->OriginalName);
							return nullptr;
						}
					}
					/*
					// eliminate redundant (downstream) definitions, one at a time
					auto comps = result->GetComponentDependencyOrder();
					for (int i = comps.Count() - 1; i >= 0; i--)
					{
						auto comp = comps[i];
						auto & defs = result->DefinitionsByComponent[comp->UniqueName]();
						EnumerableHashSet<ComponentDefinitionIR*> removedDefs;
						for (auto & def : defs)
							if (!def.Value->IsEntryPoint && !comp->Type->PinnedWorlds.Contains(def.Value->World))
							{
								for (auto & otherDef : defs)
								{
									if (otherDef.Value != def.Value && !removedDefs.Contains(otherDef.Value)
										&& shader->Pipeline->IsWorldReachable(otherDef.Value->World, def.Value->World))
									{
										removedDefs.Add(def.Value);
										break;
									}
								}
							}
						if (removedDefs.Count())
						{
							result->RemoveDefinitions([&](ComponentDefinitionIR* def) {return removedDefs.Contains(def); });
							changed = true;
						}
					}
					*/
				}
				return result;
			}