public static bool IsBinOp(this IThreeAddressCode t) { switch (t.Operation) { case Operation.NoOperation: case Operation.Assign: case Operation.Goto: case Operation.CondGoto: case Operation.Print: case Operation.Println: return(false); case Operation.Plus: case Operation.Minus: case Operation.Mult: case Operation.Div: case Operation.Less: case Operation.LessOrEquals: case Operation.Great: case Operation.GreatOrEquals: case Operation.And: case Operation.Or: case Operation.NotEqual: case Operation.Equals: case Operation.Phi: return(true); default: throw new ArgumentOutOfRangeException(); } }
public static LabelValue GotoDest(this IThreeAddressCode t) { if (!t.IsGoto()) { throw new Exception("Calling GotoDest on non-goto operator!"); } return(t.Destination as LabelValue); }
public bool InsertAfter(IThreeAddressCode after, IThreeAddressCode newElem) { var node = _elems.Find(after); if (node == null) { return(false); } _elems.AddAfter(node, newElem); return(true); }
public static IdentificatorValue AsDefinition(this IThreeAddressCode t) { if (t.IsBinOp() || t.Operation == Operation.Assign) { var res = t.Destination as IdentificatorValue; if (res == null) { throw new Exception("Asserion error"); } return(res); } return(null); }
public static Func <int, int, int> ExecBinOp(this IThreeAddressCode t) { var ops = new Dictionary <Operation, Func <int, int, int> > { [Operation.Minus] = (x, y) => x - y, [Operation.Mult] = (x, y) => x * y, [Operation.Div] = (x, y) => x / y, [Operation.Plus] = (x, y) => x + y, [Operation.Less] = (x, y) => Convert.ToInt32(x < y), [Operation.LessOrEquals] = (x, y) => Convert.ToInt32(x <= y), [Operation.Great] = (x, y) => Convert.ToInt32(x > y), [Operation.GreatOrEquals] = (x, y) => Convert.ToInt32(x >= y), [Operation.And] = (x, y) => x == 0 ? 0 : y, [Operation.Or] = (x, y) => x == 0 ? y : x, [Operation.NotEqual] = (x, y) => Convert.ToInt32(x != y), [Operation.Equals] = (x, y) => Convert.ToInt32(x == y), }; return(ops[t.Operation]); }
// композиция передаточных функций // f1 и f2 определены в терминах входного отображения m public SymbolicMap Composition(IThreeAddressCode s, SymbolicMap f1, SymbolicMap f2) { VariableValue newVal = new VariableValue(); SymbolicMap res = f2; var key = s.Destination as IdentificatorValue; if (/*TransferFunc(s, f2)*/ f2.variableTable[key].type == VariableValueType.NAA) // if f2(m)(v) = NAA { newVal.type = VariableValueType.NAA; res.variableTable[key] = newVal; } else if (/*TransferFunc(s, f2)*/ f2.variableTable[key].type == VariableValueType.AFFINE) // if f2(m)(v) = AFFINE { if (/*TransferFunc(s, f1)*/ f1.variableTable[key].type == VariableValueType.NAA) // if f1(m)(v) == NAA { newVal.type = VariableValueType.NAA; res.variableTable[key] = newVal; } else { // подставляем f1(m)(v) вместо m(v) в f2 var affunc = /*TransferFunc(s, f2)*/ f2.variableTable[key].value; var appliedf1 = TransferFunc(s, f1); newVal.type = VariableValueType.AFFINE; newVal.value.constants = affunc.constants; newVal.value.variables = appliedf1.variableTable[key].value.variables; res.variableTable[key] = newVal; } } else { newVal.type = VariableValueType.UNDEF; res.variableTable[key] = newVal; } return(res); }
// передаточная функция инструкции public SymbolicMap TransferFunc(IThreeAddressCode s, SymbolicMap m) { VariableValue newVal = new VariableValue(); //compute affine expression even if instruction is NAA newVal.value = ComputeAffineExpr(s, m);//to keep track of variables var key = s.Destination as IdentificatorValue; if (IsAffineExpressible(s)) { newVal.type = VariableValueType.AFFINE; } else { newVal.type = VariableValueType.NAA; } m.variableTable[key] = newVal; return(m); }
// Передаточная функция для распространения констант private VariableValue CalculateTransmitionFunc(IThreeAddressCode line, VariableConstantMap currentTable) { VariableValue newValue = new VariableValue(); // если присваиваем константу if (line.LeftOperand is NumericValue) { newValue.type = VariableValueType.CONSTANT; newValue.value = (line.LeftOperand as NumericValue).Value; } // присваиваем переменную else { // если в таблице нет такой переменной, говорим что она NAC if (!currentTable.variableTable.ContainsKey(line.LeftOperand as IdentificatorValue)) { newValue.type = VariableValueType.NAC; return(newValue); } //если переменная уже есть в таблице, то говорим что она константа и присваиваем значение VariableValue x = currentTable.variableTable[line.LeftOperand as IdentificatorValue]; if (x.type.Equals(VariableValueType.CONSTANT)) { newValue.type = VariableValueType.CONSTANT; newValue.value = x.value; } //если NAC то оставляем else if (x.type.Equals(VariableValueType.NAC)) { newValue.type = VariableValueType.NAC; } //если UNDEF то оставляем else { newValue.type = VariableValueType.UNDEF; } } if (line.RightOperand == null || newValue.type == VariableValueType.NAC) { return(newValue); } //если правая часть - константа, вычисляем ее if (line.RightOperand is NumericValue) { newValue.value = CalculateConstant(line.Operation, newValue.value, (line.RightOperand as NumericValue).Value); return(newValue); } // если в таблице нет такой переменной правой части, говорим что она NAC if (!currentTable.variableTable.ContainsKey(line.RightOperand as IdentificatorValue)) { newValue.type = VariableValueType.NAC; return(newValue); } VariableValue y = currentTable.variableTable[line.RightOperand as IdentificatorValue]; //если переменная уже есть в таблице, то говорим что она константа и присваиваем значение if (y.type.Equals(VariableValueType.CONSTANT)) { newValue.value = CalculateConstant(line.Operation, newValue.value, y.value); return(newValue); } if (y.type.Equals(VariableValueType.NAC)) { newValue.type = VariableValueType.NAC; } else { newValue.type = VariableValueType.UNDEF; } return(newValue); }
public static bool isExpression(this IThreeAddressCode t) { return(t.Operation != Operation.CondGoto && t.Operation != Operation.Goto && t.Operation != Operation.NoOperation); }
public static bool IsPhiFunction(IThreeAddressCode line) { return(line.Operation == Operation.Phi); }
static bool IsDefinition(IThreeAddressCode t) { return(t.AsDefinition() != null); }
public static bool IsGoto(this IThreeAddressCode t) { return(t.Operation == Operation.CondGoto || t.Operation == Operation.Goto); }
public void Add(IThreeAddressCode elem) { _currentBlock.Append(elem); }
public bool Remove(IThreeAddressCode elem) { return(_elems.Remove(elem)); }
public void AppendFirst(IThreeAddressCode newElem) { _elems.AddFirst(newElem); }
public static bool IsPhiAssignment(IThreeAddressCode line) { return(IsPhiIdentificator(line.LeftOperand as IdentificatorValue) && line.Operation == Operation.Assign); }
private AffineExpr ComputeAffineExpr(IThreeAddressCode s, SymbolicMap m) { AffineExpr res = new AffineExpr(); res.constants = new List <int>(); res.variables = new List <IdentificatorValue>(); if (s.LeftOperand is NumericValue) { res.constants.Add((s.LeftOperand as NumericValue).Value); } else { res.variables.Add(s.LeftOperand as IdentificatorValue); if (IsAffineExpressible(s)) { if (m.variableTable.ContainsKey(s.LeftOperand as IdentificatorValue)) { if (m.variableTable[s.LeftOperand as IdentificatorValue].value.constants != null) { if ((s.LeftOperand as IdentificatorValue).ToString()[0] == '$') { foreach (var v in m.variableTable[s.LeftOperand as IdentificatorValue].value.constants) { res.constants.Add(v); } } } } } } if (s.RightOperand != null) { if (s.RightOperand is NumericValue) { res.constants.Add((s.RightOperand as NumericValue).Value); } else { res.variables.Add(s.RightOperand as IdentificatorValue); if (IsAffineExpressible(s)) { if (m.variableTable.ContainsKey(s.RightOperand as IdentificatorValue)) { if (m.variableTable[s.RightOperand as IdentificatorValue].value.constants != null) { if ((s.RightOperand as IdentificatorValue).ToString()[0] == '$') { foreach (var v in m.variableTable[s.RightOperand as IdentificatorValue].value.constants) { res.constants.Add(v); } } } } } } } return(res); }
private Boolean IsAffineExpressible(IThreeAddressCode s) { return(s.Operation == Operation.Plus || s.Operation == Operation.Minus); }
// степень передаточной функции public SymbolicMap SelfComposition(IThreeAddressCode line, SymbolicMap f1) { return(Composition(line, f1, f1)); }