/// <summary> /// Upate use information and l-values table from the given command information /// </summary> /// <param name="commandInfo"></param> private void UpdateChains_CommandInfo(HlCommandInfo commandInfo) { //Get all l-values in RHS expression of statement var rhsLvaluesList = _valueAccessProcessor.GetLValues(commandInfo.AssociatedCommand.RhsExpression); //Set dependency information (definition information) for all RHS l-values foreach (var rhsLvalue in rhsLvaluesList) { //Get the last definition command for this RHS l-value from the l-values table var rhsLastLvalueDefInfo = _lValuesTable.GetLastDefinitionInfo(rhsLvalue); var rhsLastCommandInfo = rhsLastLvalueDefInfo.DefiningCommand; //Add use information in the last definition command of this RHS l-value if (!ReferenceEquals(rhsLastCommandInfo, null)) { rhsLastCommandInfo.LhslValueUses.Add(commandInfo); } //Set dependency information (definition information) for this RHS l-value commandInfo.RhsVariablesInfo.Add(rhsLastLvalueDefInfo); } //Never add a definition for a macro output parameter because it will never be used in any RHS expression if (commandInfo.LhslValueIsOutputParameter == false) { //Update dependency information (definition information) of LHS l-value in the l-values table _lValuesTable.AddDefinition(commandInfo); } }
/// <summary> /// Mark a command information entry (and its LHS local variable if present) for removal /// </summary> /// <param name="commandInfo"></param> private void MarkCommandInfoForRemoval(HlCommandInfo commandInfo) { _updateChainFlag = true; _markedCommandsList.Add(commandInfo.AssociatedCommand); if (commandInfo.LhslValueIsLocalVariable) { _markedLocalVariablesList.Add((SymbolLocalVariable)commandInfo.LhslValue); } }
/// <summary> /// Add definition for an l-value /// </summary> /// <param name="defSt"></param> /// <returns></returns> public HlLValueDefinitionInfo AddDefinition(HlCommandInfo defSt) { var lvalue = defSt.LhslValue; List <HlLValueDefinitionInfo> lvalueDefList; if (_lValuesDictionary.TryGetValue(lvalue.ObjectName, out lvalueDefList) == false) { lvalueDefList = new List <HlLValueDefinitionInfo>(); _lValuesDictionary.Add(lvalue.ObjectName, lvalueDefList); } var defInfo = new HlLValueDefinitionInfo(lvalueDefList.Count, lvalue, defSt); lvalueDefList.Add(defInfo); return(defInfo); }
/// <summary> /// Remove the given command after propagating its RHS expression to any other command using its LHS /// </summary> /// <param name="commandInfo"></param> private void PropagateCommand(HlCommandInfo commandInfo) { MarkCommandInfoForRemoval(commandInfo); foreach (var useCommandInfo in commandInfo.LhslValueUses) { var oldExpr = useCommandInfo.AssociatedCommand.RhsExpression; var oldLvalue = commandInfo.LhslValue; var newExpr = (ILanguageExpressionAtomic)commandInfo.AssociatedCommand.RhsExpression; var newRhsExpr = _valueAccessProcessor.ReplaceLValueByExpression(oldExpr, oldLvalue, newExpr); useCommandInfo.AssociatedCommand.SetRhsExpression(newRhsExpr); //CheckIntegrity(); } }
public HlLValueDefinitionInfo(int defIndex, SymbolLValue lvalue, HlCommandInfo commandInfo) { //Output macro parameters are not accepted here var parameter = lvalue as SymbolProcedureParameter; if (parameter != null && parameter.DirectionOut) { throw new InvalidOperationException("Cannot generate definition for macro output parameter"); } //A local variable l-value must have a defining assignment command if (lvalue is SymbolLocalVariable && ReferenceEquals(commandInfo, null)) { throw new InvalidOperationException("A local variable must have a defining assignment command"); } DefinitionIndex = defIndex; LValue = lvalue; DefiningCommand = commandInfo; switch (DefinitionIndex) { case 0: //This is the first use of this l-value as the LHS of an assignment command CurrentSsaFormName = LValue.ObjectName; PreviousSsaFormName = ""; break; case 1: //This is the second use of this l-value as the LHS of an assignment command CurrentSsaFormName = LValue.ObjectName + "SSA" + DefinitionIndex; PreviousSsaFormName = LValue.ObjectName; break; default: CurrentSsaFormName = LValue.ObjectName + "SSA" + DefinitionIndex; PreviousSsaFormName = LValue.ObjectName + "SSA" + (DefinitionIndex - 1); break; } }
/// <summary> /// Add the definition commands for the RHS l-values of the given command to the list of active commands /// and add the given command itself to the list if indicated by the given flag /// </summary> /// <param name="activeCommandsList">The list of active commands</param> /// <param name="commandInfo">The command information object</param> /// <param name="addCommandToList">If true, add the command information object to the list</param> private static void UpdateActiveCommandList(List <HlCommandInfo> activeCommandsList, HlCommandInfo commandInfo, bool addCommandToList) { if (addCommandToList) { activeCommandsList.Add(commandInfo); } var commandsInfoList = commandInfo .RhsVariablesInfo .Select(rhsLvalueInfo => rhsLvalueInfo.DefiningCommand) .Where( rhsLvalueDefCommandInfo => !ReferenceEquals(rhsLvalueDefCommandInfo, null) && !rhsLvalueDefCommandInfo.IsActive(activeCommandsList) ); activeCommandsList.AddRange(commandsInfoList); }
/// <summary> /// Create a composite type initialized constructor RHS expression based on the given command with /// partial LHS value access and a new temporary local variable as explained in Optimize_ReplaceAllLHSPartialAccess /// </summary> /// <param name="commandInfo"></param> /// <param name="newLvalue"></param> /// <returns></returns> private BasicPolyadic CreateConstructorExpression(HlCommandInfo commandInfo, SymbolLValue newLvalue) { var oldValueAccess = commandInfo.AssociatedCommand.LhsValueAccess; var oldLvalue = oldValueAccess.RootSymbolAsLValue; var firstDefStId = _lValuesTable.GetFirstDefiningCommandInfo(oldLvalue).CommandInfoId; var useDefaultSource = firstDefStId < 0 || firstDefStId != commandInfo.CommandInfoId; var typeStructure = oldValueAccess.RootSymbolAsLValue.SymbolType as GMacStructure; if (typeStructure != null) { var structure = typeStructure; var operands = OperandsByValueAccess.Create(); var dataMemberName = ((ValueAccessStepByKey <string>)oldValueAccess.LastAccessStep).AccessKey; var dataMember = structure.GetDataMember(dataMemberName); var operandLhsValueAccess = LanguageValueAccess.Create(dataMember); var operandRhsExpr = LanguageValueAccess.Create(newLvalue); operandLhsValueAccess.Append(oldValueAccess.AccessSteps.Skip(2)); operands.AddOperand(operandLhsValueAccess, operandRhsExpr); if (useDefaultSource) { return(structure.CreateConstructorExpression( LanguageValueAccess.Create(oldLvalue), operands )); } return(structure.CreateConstructorExpression(operands)); } if (!(oldValueAccess.RootSymbolAsLValue.SymbolType is GMacFrameMultivector)) { throw new InvalidOperationException("Unknown composite type to be constructed"); } var mvType = (GMacFrameMultivector)oldValueAccess.RootSymbolAsLValue.SymbolType; var operandsByIndex = OperandsByIndex.Create(); var stepByKey = oldValueAccess.LastAccessStep as ValueAccessStepByKey <int>; if (stepByKey != null) { var id = stepByKey.AccessKey; operandsByIndex.AddOperand(id, LanguageValueAccess.Create(newLvalue)); } else { var stepByKeyList = oldValueAccess.LastAccessStep as ValueAccessStepByKeyList <int>; if (stepByKeyList == null) { throw new InvalidOperationException("Invalid access step for a multivector"); } var idsList = stepByKeyList.AccessKeyList; foreach (var id in idsList) { operandsByIndex.AddOperand(id, LanguageValueAccess.Create(newLvalue).Append(id, ((GMacAst)BaseMacro.RootAst).ScalarType)); } } if (useDefaultSource) { return(mvType.CreateConstructorExpression( LanguageValueAccess.Create(oldLvalue), operandsByIndex )); } return(mvType.CreateConstructorExpression(operandsByIndex)); }