private void HandleStoreVar(XILSInstr i) { int readPoint; Variable local = i.StaticOperand as Variable; if (DflowAnalyzer.IsReadAfterWrite(i.Index, out readPoint)) { var preds = RemapPreds(i.Preds); // keep expression on the stack, but bury it at the very bottom. for (int j = 1; j < _resultStack.Count; j++) { var resultTypes = TypeStack.Reverse().Skip(1).Concat(TypeStack.Skip(_resultStack.Count - 1)).ToArray(); Emit(DefaultInstructionSet.Instance.Dig(_resultStack.Count - 1).CreateStk( preds, TypeStack.Reverse().ToArray(), resultTypes)); preds = new InstructionDependency[0]; } _read2write[readPoint] = _resultStack[0]; } else if (local == null) { ProcessDefault(i); } else if (DflowAnalyzer.EliminableLocals.Contains(local.LocalIndex)) { Emit(DefaultInstructionSet.Instance.Pop().CreateStk(1, local.Type)); } else { ProcessDefault(i); } }
private void EmitIndexComputation(Array array) { MemoryMappedStorage mms = GetDataLayout(array); ArrayMemoryLayout layout = mms.Layout as ArrayMemoryLayout; if (layout.ElementsPerWord > 1) { throw new NotImplementedException("Multiple elements per word not yet implemented"); } MemoryRegion region = mms.Region; IMarshalInfo minfo = region.MarshalInfo; int shiftWidth = MathExt.CeilLog2(mms.Region.AddressWidth); TypeDescriptor indexType = TypeDescriptor.GetTypeOf(mms.BaseAddress); for (int i = 0; i < layout.Strides.Length; i++) { TypeDescriptor orgIndexType; if (i > 0) { orgIndexType = TypeStack.Skip(1).First(); Emit(_iset.Swap().CreateStk(2, orgIndexType, indexType, indexType, orgIndexType)); } else { orgIndexType = TypeStack.Peek(); } ulong stride = layout.Strides[layout.Strides.Length - i - 1]; if (MathExt.IsPow2(stride)) { Emit(_iset.Convert().CreateStk(1, orgIndexType, indexType)); int ishift = MathExt.CeilLog2(stride); if (ishift > 0) { Unsigned shift = Unsigned.FromULong((ulong)ishift, shiftWidth); TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift); Emit(_iset.LdConst(shift).CreateStk(0, shiftType)); Emit(_iset.LShift().CreateStk(2, indexType, shiftType, indexType)); } } else { throw new NotImplementedException("Stride ain't a power of 2"); } if (i > 0) { Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); } } if (mms.BaseAddress.ULongValue != 0) { Emit(_iset.LdConst(mms.BaseAddress).CreateStk(0, indexType)); if (minfo.UseStrongPow2Alignment) { Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); } else { Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType)); } } }