public void AcceptStore(StoreStatement stmt) { if (stmt.Container.Type.CILType.IsValueType || stmt.Container.Type.HasIntrinsicTypeOverride) { CreateLabelForNextInstruction(stmt); if (stmt.Label != null) { _closeBBOnNextInstr = true; } int rslot = stmt.Value.Accept(this); _litMode = ELiteralAcceptMode.Write; var lit = stmt.Container; lit.Accept(this); _litMode = ELiteralAcceptMode.Read; } else { // FIXME: Otherwise ignore it because sometimes, some bogus statements // like tmp := this occur. } }
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; } }