protected override void ProcessDefault(XIL3Instr i) { if (_bbBoundaries.Contains(i.Index)) { _map.Clear(); } var preds = RemapPreds(i.Preds); int[] operands = RemapOperandSlots(i.OperandSlots); var ir = i.Command.Create3AC(preds, operands, i.ResultSlots); XIL3Instr eqv; if (_map.TryGetValue(ir, out eqv)) { for (int j = 0; j < i.ResultSlots.Length; j++) { RemapSlot(i.ResultSlots[j], eqv.ResultSlots[j]); } } else { int[] results = RemapResultSlots(i.ResultSlots); var ir2 = i.Command.Create3AC(preds, operands, results); Emit(ir2); _map[ir] = ir2; } }
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> /// The default handler is applied to any non-branching instruction when there is no more specific handler registered. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessDefault(XIL3Instr i) { int[] rslots = RemapResultSlots(i.ResultSlots); int[] oslots = RemapOperandSlots(i.OperandSlots); var preds = RemapPreds(i.Preds); Emit(i.Command.Create3AC(preds, oslots, rslots)); }
/// <summary> /// Tries to add a reservation for the specified time interval. If there is an existing reservation for that interval, /// the state of this object will not be changed. /// </summary> /// <param name="startTime">reservation start time</param> /// <param name="endTime">reservation end time</param> /// <param name="instr">associated instruction</param> /// <returns>true if reservation was successful, i.e. no colliding reservation</returns> public bool TryReserve(long startTime, long endTime, XIL3Instr instr) { if (IsReserved(startTime, endTime)) { return(false); } _rset.Add((int)startTime, (int)endTime); _resList.Add(new Reservation(startTime, endTime, instr)); return(true); }
/// <summary> /// This method implements the complete transformation. /// </summary> protected virtual void Rewrite() { _remap[-1] = -1; foreach (XIL3Instr i in InInstructions) { CurInstr = i; ProcessInstruction(i); _remap[i.Index] = LastOutputInstructionIndex; } PostProcess(); CheckSanityOfResult(); }
/// <summary> /// The default branch handler is applied to any branching instruction when there is no more specific handler registered. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessBranch(XIL3Instr i) { BranchLabel label = (BranchLabel)i.StaticOperand; BranchLabel newLabel = Retarget(label); XILInstr xi = new XILInstr(i.Name, newLabel); int[] rslots = RemapResultSlots(i.ResultSlots); int[] oslots = RemapOperandSlots(i.OperandSlots); var preds = RemapPreds(i.Preds); Emit(xi.Create3AC(preds, oslots, rslots)); }
private static void ComputeCStepsForBranchTargets(XILSchedulingAdapter xsa) { var cfg = xsa.CFG; for (int i = 0; i < cfg.Instructions.Count; i++) { XIL3Instr xil3i = cfg.Instructions[i]; switch (xil3i.Name) { case InstructionCodes.BranchIfFalse: case InstructionCodes.BranchIfTrue: case InstructionCodes.Goto: { var target = (BranchLabel)xil3i.StaticOperand; var bb = cfg.GetBasicBlockContaining(target.InstructionIndex); target.CStep = (int)bb.Range.Select(xi => xsa.CStep[xi]).Min(); } break; default: break; } } }
public EAllocationDecision SelectBestMapping(XIL3Instr instr, long cstep, IEnumerable <IXILMapping> mappings, out IXILMapping bestMapping) { foreach (int rslot in instr.ResultSlots) { _interlinks[rslot] = new Interlink(rslot); } bestMapping = null; double bestCost = double.MaxValue; foreach (var mapping in mappings) { var sources = instr.OperandSlots.Select(os => _interlinks[os]).ToArray(); var sinks = instr.ResultSlots.Select(rs => _interlinks[rs]).ToArray(); var verbs = mapping.Realize(sources, sinks); long curStep = cstep; double cost = 0.0; foreach (var verb in verbs) { var pflow = verb.ToCombFlow(); foreach (var flow in pflow.Flows) { var sflow = flow as SignalFlow; if (sflow == null) { continue; } if (sflow.Source.Desc.HasAttribute <int>() && !sflow.Target.Desc.HasAttribute <int>()) { int index = sflow.Source.Desc.QueryAttribute <int>(); var driver = _interlinks[index].Driver; if (driver == null) { continue; } var fanIn = _fanIn[sflow.Target.Desc]; foreach (int v in fanIn.Values) { cost += Math.Pow(2.0, -v); } int prevSlack; if (fanIn.TryGetValue(driver, out prevSlack)) { cost -= Math.Pow(2.0, -prevSlack); } int slack = (int)(curStep - _interlinks[index].DriveTime); cost += Math.Pow(2.0, -slack); } } curStep++; } cost /= instr.OperandSlots.Length; if (cost < bestCost) { bestCost = cost; bestMapping = mapping; } } object iclass = mappings.First().TASite.Host.GetType(); var fuSet = _fuCount[iclass]; int curCount = fuSet.Count; int limit; if (!FULimits.TryGetValue(iclass, out limit)) { limit = int.MaxValue; } if (curCount < limit && bestCost > MaxCost) { return(EAllocationDecision.AllocateNew); } else { return(EAllocationDecision.UseExisting); } }
public void TellMapping(XIL3Instr instr, long cstep, IXILMapping mapping) { foreach (int rslot in instr.ResultSlots) { if (!_interlinks.ContainsKey(rslot)) { _interlinks[rslot] = new Interlink(rslot); } } var sources = instr.OperandSlots.Select(os => _interlinks[os]).ToArray(); var sinks = instr.ResultSlots.Select(rs => _interlinks[rs]).ToArray(); var verbs = mapping.Realize(sources, sinks); long curStep = cstep; foreach (var verb in verbs) { var pflow = verb.ToCombFlow(); foreach (var flow in pflow.Flows) { var sflow = flow as SignalFlow; if (sflow == null) { continue; } if (sflow.Target.Desc.HasAttribute <int>()) { int index = sflow.Target.Desc.QueryAttribute <int>(); _interlinks[index].Driver = sflow.Source.Desc; _interlinks[index].DriveTime = curStep; } else if (sflow.Source.Desc.HasAttribute <int>()) { Dictionary <ISignalOrPortDescriptor, int> fanIn; if (!_fanIn.TryGetValue(sflow.Target.Desc, out fanIn)) { fanIn = new Dictionary <ISignalOrPortDescriptor, int>(); _fanIn[sflow.Target.Desc] = fanIn; } int index = sflow.Source.Desc.QueryAttribute <int>(); var driver = _interlinks[index].Driver; if (driver == null) { continue; } int slack = (int)(curStep - _interlinks[index].DriveTime); int prevSlack; if (!fanIn.TryGetValue(driver, out prevSlack) || prevSlack > slack) { fanIn[driver] = slack; } } } } object iclass = mapping.TASite.Host.GetType(); HashSet <object> fuSet; if (!_fuCount.TryGetValue(iclass, out fuSet)) { fuSet = new HashSet <object>(); _fuCount[iclass] = fuSet; } fuSet.Add(mapping.TASite); }
/// <summary> /// This method is called for any instruction. Its default behavior is to lookup handler inside the handler dictionary /// and redirect the processing to that handler. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessInstruction(XIL3Instr i) { Action<XIL3Instr> handler = _handlers[i.Name]; handler(i); }
/// <summary> /// Constructs a new instance /// </summary> /// <param name="startTime">start time of reservation</param> /// <param name="endTime">end time of reservation</param> /// <param name="instr">associated instruction</param> public Reservation(long startTime, long endTime, XIL3Instr instr) { StartTime = startTime; EndTime = endTime; Instr = instr; }
/// <summary> /// Emits an instruction and assigns an index to it /// </summary> /// <param name="i">instruction to emit</param> protected void Emit(XIL3Instr i) { i.Index = NextOutputInstructionIndex; i.CILRef = CurInstr.CILRef; OutInstructions.Add(i); }
/// <summary> /// This method is called for any instruction. Its default behavior is to lookup handler inside the handler dictionary /// and redirect the processing to that handler. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessInstruction(XIL3Instr i) { Action <XIL3Instr> handler = _handlers[i.Name]; handler(i); }
/// <summary> /// Tries to add a reservation for the specified time interval. If there is an existing reservation for that interval, /// the state of this object will not be changed. /// </summary> /// <param name="startTime">reservation start time</param> /// <param name="endTime">reservation end time</param> /// <param name="instr">associated instruction</param> /// <returns>true if reservation was successful, i.e. no colliding reservation</returns> public bool TryReserve(long startTime, long endTime, XIL3Instr instr) { if (IsReserved(startTime, endTime)) return false; _rset.Add((int)startTime, (int)endTime); _resList.Add(new Reservation(startTime, endTime, instr)); return true; }
public EAllocationDecision SelectBestMapping(XIL3Instr instr, long cstep, IEnumerable<IXILMapping> mappings, out IXILMapping bestMapping) { bestMapping = mappings.First(); return EAllocationDecision.UseExisting; }
public void TellMapping(XIL3Instr instr, long cstep, IXILMapping mapping) { }
/// <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; }