/// <summary> /// Segments the instruction sequence into basic blocks and returns their boundaries. /// </summary> /// <returns>Instruction indices of basic block boundaries</returns> public int[] GetBasicBlockBoundaries() { HashSet <int> bbs = new HashSet <int>(); bbs.Add(0); for (int i = 0; i < Instructions.Length; i++) { XIL3Instr xil3i = Instructions[i]; switch (xil3i.Name) { case InstructionCodes.BranchIfFalse: case InstructionCodes.BranchIfTrue: case InstructionCodes.Goto: { BranchLabel target = (BranchLabel)xil3i.StaticOperand; bbs.Add(target.InstructionIndex); bbs.Add(i + 1); } break; default: break; } } return(bbs.OrderBy(i => i).ToArray()); }
public void Bind(XIL3Instr xil3i, int cstep, IXILMapping mapping) { _csteps[xil3i.Index] = cstep; _ii[xil3i.Index] = mapping.InitiationInterval; _lat[xil3i.Index] = mapping.Latency; int lat = Math.Max(1, mapping.Latency); _maxCStep = Math.Max(cstep + lat - 1, _maxCStep); }
/// <summary> /// Creates a control-flow graph from a given XIL-3 instruction list /// </summary> /// <param name="ilist">XIL-3 instruction list</param> /// <returns>XIL-3 control-flow graph</returns> public static ControlFlowGraph <XIL3Instr> CreateCFG(IList <XIL3Instr> ilist) { XIL3Instr marshal = DefaultInstructionSet .Instance .ExitMarshal() .Create3AC( DefaultInstructionSet.Empty, new int[0], new int[0]); marshal.Index = ilist.Count; XIL3InstructionInfo iinfo = new XIL3InstructionInfo(); return(new ControlFlowGraph <XIL3Instr>(ilist, marshal, iinfo)); }
private void Process(XIL3Instr xil3i) { var preds = xil3i.Preds.Select(p => p.Remap(_slotRemap[p.PredIndex])).ToArray(); _instRemap.Add(_outInstrs.Count); foreach (int oslot in xil3i.OperandSlots) { Emit(DefaultInstructionSet.Instance .LoadVar(_interLocals[oslot]).CreateStk(preds, 0, _interLocals[oslot].Type)); } _slotRemap.Add(_outInstrs.Count); var cmd = xil3i.Command; if (cmd.Name == InstructionCodes.BranchIfFalse || cmd.Name == InstructionCodes.BranchIfTrue || cmd.Name == InstructionCodes.Goto) { var target = (BranchLabel)cmd.Operand; var newTarget = new BranchLabel() { InstructionIndex = target.InstructionIndex }; cmd = new XILInstr(cmd.Name, newTarget) { BackRef = cmd.BackRef }; _labels.Add(newTarget); } Emit(cmd.CreateStk(preds, xil3i.OperandSlots.Length, xil3i.OperandSlots.Select(os => _interLocals[os].Type) .Concat(xil3i.ResultSlots.Select(rs => _interLocals[rs].Type)) .ToArray())); foreach (int rslot in xil3i.ResultSlots.Reverse()) { Emit(DefaultInstructionSet.Instance .StoreVar(_interLocals[rslot]).CreateStk(1, _interLocals[rslot].Type)); } }
/// <summary> /// Tries to map and bind a given XIL-3 instruction to hardware /// </summary> /// <param name="instr">XIL-3 instruction to be mapped and bound</param> /// <param name="cstep">c-step at which instruction is scheduled</param> /// <param name="operandTypes">operand types of instruction</param> /// <param name="resultTypes">result types of instruction</param> /// <returns>a hardware mapping for the supplied instruction or null if no such exists</returns> public IXILMapping TryBind(XIL3Instr instr, long cstep, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { ReservationTable rtbl; var mappers = _xmm.LookupMappers(instr.Command); var viableMappings = new List <IXILMapping>(); foreach (IXILMapper mapper in mappers) { var tas = _taBindLookup.Get(mapper); foreach (var ta in tas) { var mappings = mapper.TryMap(ta, instr.Command, operandTypes, resultTypes); rtbl = _resTables[ta]; foreach (var mapping in mappings) { if (mapping.InitiationInterval > 0) { if (!rtbl.IsReserved(cstep, cstep + mapping.InitiationInterval - 1)) { viableMappings.Add(mapping); } else if (mapping.ResourceKind == EMappingKind.ExclusiveResource) { return(null); } } else { viableMappings.Add(mapping); } } } } bool allocateNew = true; IXILMapping bestMapping = null; int lat = 0; if (viableMappings.Count > 0) { lat = viableMappings.First().Latency; if (!viableMappings.All(m => m.Latency == lat)) { throw new XILSchedulingFailedException("Mappings with different latencies exist for " + instr); } if (viableMappings.All(m => m.ResourceKind == EMappingKind.ExclusiveResource)) { allocateNew = false; bestMapping = viableMappings.First(); } else if (viableMappings.All(m => m.ResourceKind == EMappingKind.LightweightResource)) { allocateNew = true; } else { allocateNew = Policy.SelectBestMapping(instr, cstep, viableMappings, out bestMapping) == EAllocationDecision.AllocateNew; } } if (allocateNew) { foreach (IXILMapper mapper in mappers) { bestMapping = mapper.TryAllocate(_host, instr.Command, operandTypes, resultTypes, _targetProject); if (bestMapping != null) { if (viableMappings.Count > 0 && bestMapping.Latency != lat) { throw new XILSchedulingFailedException("Newly allocated mapping for " + instr + " has different latency."); } if (_onAllocation != null) { _onAllocation(bestMapping); } _taBindLookup.Add(mapper, bestMapping.TASite); //bestMapping.TASite.Establish(binder); break; } } } if (bestMapping == null) { return(null); } rtbl = _resTables[bestMapping.TASite]; bool ok = rtbl.TryReserve(cstep, cstep + bestMapping.InitiationInterval - 1, instr); Debug.Assert(ok); return(bestMapping); }
public void TellMapping(XIL3Instr instr, long cstep, IXILMapping mapping) { }
public EAllocationDecision SelectBestMapping(XIL3Instr instr, long cstep, IEnumerable <IXILMapping> mappings, out IXILMapping bestMapping) { bestMapping = mappings.First(); return(EAllocationDecision.UseExisting); }