Пример #1
0
    public override Variable VisitVariable(Variable node)
    {
      string domainName = FindDomainName(node);
      if (domainName != null)
      {
        varToDomainName[node] = domainName;
        LinearKind kind = FindLinearKind(node);
        if (kind != LinearKind.LINEAR)
        {
          if (node is GlobalVariable || node is LocalVariable || (node is Formal formal && !formal.InComing))
          {
            Error(node, "Variable must be declared linear (as opposed to linear_in or linear_out)");
          }
        }
      }

      return base.VisitVariable(node);
    }
Пример #2
0
 public LinearQualifier(string domainName, LinearKind kind)
 {
     this.domainName = domainName;
     this.kind = kind;
 }
Пример #3
0
    private HashSet<Variable> PropagateAvailableLinearVarsAcrossBlock(Block b)
    {
      HashSet<Variable> start = new HashSet<Variable>(availableLinearVars[b]);
      foreach (Cmd cmd in b.Cmds)
      {
        if (cmd is AssignCmd assignCmd)
        {
          for (int i = 0; i < assignCmd.Lhss.Count; i++)
          {
            if (FindDomainName(assignCmd.Lhss[i].DeepAssignedVariable) == null) continue;
            IdentifierExpr ie = assignCmd.Rhss[i] as IdentifierExpr;
            if (!start.Contains(ie.Decl))
            {
              Error(ie, "unavailable source for a linear read");
            }
            else
            {
              start.Remove(ie.Decl);
            }
          }

          foreach (AssignLhs assignLhs in assignCmd.Lhss)
          {
            if (FindDomainName(assignLhs.DeepAssignedVariable) == null) continue;
            start.Add(assignLhs.DeepAssignedVariable);
          }
        }
        else if (cmd is CallCmd callCmd)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
          {
            Error(cmd, $"Global variable {g.Name} must be available at a call");
          }

          for (int i = 0; i < callCmd.Proc.InParams.Count; i++)
          {
            Variable param = callCmd.Proc.InParams[i];
            if (FindDomainName(param) == null) continue;
            IdentifierExpr ie = callCmd.Ins[i] as IdentifierExpr;
            LinearKind paramKind = FindLinearKind(param);
            if (start.Contains(ie.Decl))
            {
              if (callCmd.IsAsync || paramKind == LinearKind.LINEAR_IN)
              {
                start.Remove(ie.Decl);
              }
            }
            else
            {
              if (paramKind == LinearKind.LINEAR_OUT)
              {
                start.Add(ie.Decl);
              }
              else
              {
                Error(ie, "unavailable source for a linear read");
              }
            }
          }

          AddAvailableVars(callCmd, start);
          availableLinearVars[callCmd] = new HashSet<Variable>(start);
        }
        else if (cmd is ParCallCmd parCallCmd)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
          {
            Error(cmd, $"Global variable {g.Name} must be available at a call");
          }

          foreach (CallCmd parCallCallCmd in parCallCmd.CallCmds)
          {
            for (int i = 0; i < parCallCallCmd.Proc.InParams.Count; i++)
            {
              Variable param = parCallCallCmd.Proc.InParams[i];
              if (FindDomainName(param) == null) continue;
              IdentifierExpr ie = parCallCallCmd.Ins[i] as IdentifierExpr;
              LinearKind paramKind = FindLinearKind(param);
              if (start.Contains(ie.Decl))
              {
                if (paramKind == LinearKind.LINEAR_IN)
                {
                  start.Remove(ie.Decl);
                }
              }
              else
              {
                if (paramKind == LinearKind.LINEAR_OUT)
                {
                  start.Add(ie.Decl);
                }
                else
                {
                  Error(ie, "unavailable source for a linear read");
                }
              }
            }
          }

          AddAvailableVars(parCallCmd, start);
          availableLinearVars[parCallCmd] = new HashSet<Variable>(start);
        }
        else if (cmd is HavocCmd havocCmd)
        {
          foreach (IdentifierExpr ie in havocCmd.Vars)
          {
            if (FindDomainName(ie.Decl) == null) continue;
            start.Remove(ie.Decl);
          }
        }
        else if (cmd is YieldCmd)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
          {
            Error(cmd, $"Global variable {g.Name} must be available at a yield");
          }

          availableLinearVars[cmd] = new HashSet<Variable>(start);
        }
      }

      return start;
    }
Пример #4
0
 public LinearQualifier(string domainName, LinearKind kind)
 {
   this.domainName = domainName;
   this.kind = kind;
 }