public override bool Equals(object obj) { ArrayMod other = obj as ArrayMod; if (other == null) { return(false); } if (other.TheArray != TheArray) { return(false); } switch (Mode) { case EMode.AnyIndex: return(other.Mode == EMode.AnyIndex); case EMode.HaveIndices: return(other.Mode == EMode.HaveIndices && Indices.SequenceEqual(other.Indices)); case EMode.UnknownIndex: return(other.Mode == EMode.UnknownIndex); default: throw new NotImplementedException(); } }
public void VisitArrayRef(ArrayRef arrayRef) { LiteralReference lr = arrayRef.ArrayExpr as LiteralReference; object arrayObj; if (lr == null || !lr.ReferencedObject.IsConst(out arrayObj)) { throw new NotSupportedException("Array references must be fixed (referenced array must be known in advance)!"); } Array array = arrayObj as Array; if (array == null) { throw new InvalidOperationException("Not an array"); } ELiteralAcceptMode saveMode = _litMode; _litMode = ELiteralAcceptMode.Read; FixedArrayRef far = arrayRef.AsFixed(); if (!far.IndicesConst) { foreach (Expression index in arrayRef.Indices) { index.Accept(this); } } _litMode = saveMode; int[] preds; switch (_litMode) { case ELiteralAcceptMode.Read: if (far.IndicesConst) { ArrayMod amod1 = new ArrayMod(array, far.Indices); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod3 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_storesInCurBB.Get(amod3)) .Union(_readsInCurBB.Get(amod3)) .Distinct() .ToArray(); _readsInCurBB.Add(amod1, NextInstructionIndex); _readsInCurBB.Add(amod3, NextInstructionIndex); Emit(ISet.LdelemFixAFixI(far), preds, 0, arrayRef.Type); } else { ArrayMod amod1 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod2)) .Distinct() .ToArray(); _readsInCurBB.Add(amod1, NextInstructionIndex); Emit(ISet.LdelemFixA(far), preds, arrayRef.Indices.Length, arrayRef.Type); } break; case ELiteralAcceptMode.Write: if (far.IndicesConst) { ArrayMod amod1 = new ArrayMod(array, far.Indices); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod3 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod3)) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod1)) .Union(_readsInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod3)) .Distinct() .ToArray(); _storesInCurBB.Add(amod1, NextInstructionIndex); _storesInCurBB.Add(amod3, NextInstructionIndex); Emit(ISet.StelemFixAFixI(far), preds, 1); } else { ArrayMod amod1 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod1)) .Union(_readsInCurBB.Get(amod2)) .Distinct() .ToArray(); _storesInCurBB.Add(amod1, NextInstructionIndex); Emit(ISet.StelemFixA(far), preds, 1 + arrayRef.Indices.Length); } break; } }