public void MergeOrigins (UsageVector o_vectors) { Report.Debug (1, " MERGING BREAK ORIGINS", this); if (o_vectors == null) return; if (IsUnreachable && locals != null) locals.SetAll (true); for (UsageVector vector = o_vectors; vector != null; vector = vector.Next) { Report.Debug (1, " MERGING BREAK ORIGIN", vector); if (vector.IsUnreachable) continue; locals &= vector.locals; is_unreachable &= vector.is_unreachable; } Report.Debug (1, " MERGING BREAK ORIGINS DONE", this); }
public static UsageVector MergeSiblings (UsageVector sibling_list, Location loc) { if (sibling_list.Next == null) return sibling_list; MyBitVector locals = null; bool is_unreachable = sibling_list.is_unreachable; if (!sibling_list.IsUnreachable) locals &= sibling_list.locals; for (UsageVector child = sibling_list.Next; child != null; child = child.Next) { is_unreachable &= child.is_unreachable; if (!child.IsUnreachable) locals &= child.locals; } return new UsageVector (locals, is_unreachable, null, loc); }
// <summary> // Merges a child branching. // </summary> public UsageVector MergeChild (UsageVector child, bool overwrite) { Report.Debug (2, " MERGING CHILD EFFECTS", this, child, Type); bool new_isunr = child.is_unreachable; // // We've now either reached the point after the branching or we will // never get there since we always return or always throw an exception. // // If we can reach the point after the branching, mark all locals and // parameters as initialized which have been initialized in all branches // we need to look at (see above). // if ((Type == SiblingType.SwitchSection) && !new_isunr) { Report.Error (163, Location, "Control cannot fall through from one " + "case label to another"); return child; } locals |= child.locals; // throw away un-necessary information about variables in child blocks if (locals.Count != CountLocals) locals = new MyBitVector (locals, CountLocals); if (overwrite) is_unreachable = new_isunr; else is_unreachable |= new_isunr; return child; }
// // Normally, you should not use any of these constructors. // public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc, int num_locals) { this.Type = type; this.Block = block; this.Location = loc; this.InheritsFrom = parent; this.CountLocals = num_locals; locals = num_locals == 0 ? MyBitVector.Empty : new MyBitVector (parent == null ? MyBitVector.Empty : parent.locals, num_locals); if (parent != null) is_unreachable = parent.is_unreachable; id = ++next_id; }
private UsageVector (MyBitVector locals, bool is_unreachable, Block block, Location loc) { this.Type = SiblingType.Block; this.Location = loc; this.Block = block; this.is_unreachable = is_unreachable; this.locals = locals; id = ++next_id; }
// <summary> // Performs an `or' operation on the bit vector. The `new_vector' may have a // different size than the current one. // </summary> private MyBitVector Or (MyBitVector new_vector) { if (Count == 0 || new_vector.Count == 0) return this; var o = new_vector.vector != null ? new_vector.vector : new_vector.shared; if (o == null) { int n = new_vector.Count; if (n < Count) { for (int i = 0; i < n; ++i) this [i] = true; } else { SetAll (true); } return this; } if (Count == o.Count) { if (vector == null) { if (shared == null) return this; initialize_vector (); } vector.Or (o); return this; } int min = o.Count; if (Count < min) min = Count; for (int i = 0; i < min; i++) { if (o [i]) this [i] = true; } return this; }
// <summary> // Performs an `and' operation on the bit vector. The `new_vector' may have // a different size than the current one. // </summary> private MyBitVector And (MyBitVector new_vector) { if (Count == 0) return this; var o = new_vector.vector != null ? new_vector.vector : new_vector.shared; if (o == null) { for (int i = new_vector.Count; i < Count; ++i) this [i] = false; return this; } if (o.Count == 0) { SetAll (false); return this; } if (Count == o.Count) { if (vector == null) { if (shared == null) { shared = new_vector.MakeShared (Count); return this; } initialize_vector (); } vector.And (o); return this; } int min = o.Count; if (Count < min) min = Count; for (int i = 0; i < min; i++) { if (! o [i]) this [i] = false; } for (int i = min; i < Count; i++) this [i] = false; return this; }
public void SetStructFieldAssigned (MyBitVector vector, string field_name) { int field_idx = TypeInfo.GetFieldIndex (field_name); if (field_idx == 0) return; vector [Offset + field_idx] = true; is_ever_assigned = true; }
public MyBitVector (MyBitVector InheritsFrom, int Count) { if (InheritsFrom != null) shared = InheritsFrom.MakeShared (Count); this.Count = Count; }
public bool IsStructFieldAssigned (MyBitVector vector, string field_name) { int field_idx = TypeInfo.GetFieldIndex (field_name); if (field_idx == 0) return true; return vector [Offset + field_idx]; }
public void SetAssigned (MyBitVector vector) { if (Length == 1) vector [Offset] = true; else vector.SetRange (Offset, Length); is_ever_assigned = true; }
public bool IsAssigned (MyBitVector vector) { if (vector == null) return true; if (vector [Offset]) return true; // FIXME: Fix SetFieldAssigned to set the whole range like SetAssigned below. Then, get rid of this stanza for (VariableInfo parent = Parent; parent != null; parent = parent.Parent) { if (vector [parent.Offset]) { // 'parent' is assigned, but someone forgot to note that all its components are assigned too parent.SetAssigned (vector); return true; } } // Return unless this is a struct. if (!TypeInfo.IsStruct) return false; // Ok, so each field must be assigned. for (int i = 0; i < TypeInfo.Length; i++) { if (!vector [Offset + i + 1]) return false; } // Ok, now check all fields which are structs. for (int i = 0; i < sub_info.Length; i++) { VariableInfo sinfo = sub_info [i]; if (sinfo == null) continue; if (!sinfo.IsAssigned (vector)) return false; } vector [Offset] = true; is_ever_assigned = true; return true; }
public void SetStructFieldAssigned (MyBitVector vector, string field_name) { if (vector[Offset]) return; int field_idx = TypeInfo.GetFieldIndex (field_name); if (field_idx == 0) return; var complex_field = TypeInfo.GetStructField (field_name); if (complex_field != null) { vector.SetRange (Offset + complex_field.Offset, complex_field.TotalLength); } else { vector[Offset + field_idx] = true; } IsEverAssigned = true; // // Each field must be assigned // for (int i = Offset + 1; i < TypeInfo.TotalLength + Offset; i++) { if (!vector[i]) return; } // // Set master struct flag to assigned when all tested struct // fields have been assigned // vector[Offset] = true; }
public bool IsAssigned (MyBitVector vector) { if (vector == null) return true; if (vector [Offset]) return true; // Unless this is a struct if (!TypeInfo.IsStruct) return false; // // Following case cannot be handled fully by SetStructFieldAssigned // because we may encounter following case // // struct A { B b } // struct B { int value; } // // setting a.b.value is propagated only to B's vector and not upwards to possible parents // // // Each field must be assigned // for (int i = Offset + 1; i <= TypeInfo.Length + Offset; i++) { if (!vector[i]) return false; } // Ok, now check all fields which are structs. for (int i = 0; i < sub_info.Length; i++) { VariableInfo sinfo = sub_info[i]; if (sinfo == null) continue; if (!sinfo.IsAssigned (vector)) return false; } vector [Offset] = true; return true; }