Andrew Trick
2013-Apr-30 02:21 UTC
[LLVMdev] Instruction Scheduling - migration from v3.1 to v3.2
On Apr 26, 2013, at 3:53 AM, Martin J. O'Riordan <Martin.ORiordan at movidius.com> wrote:> I am migrating the llvm/clang derived compiler for our processor from the > v3.1 to v3.2 codebase. This has mostly gone well except that instruction > latency scheduling is no longer happening. > > The people who implemented this previously sub-classed 'ScheduleDAGInstrs' > and implemented the virtual methods 'computeLatency' and > 'computeOperandLatency'. However, these methods have been removed from > 'ScheduleDAG' and 'ScheduleDAGInstrs' so are no longer invoked on our > implementation. Instead, the correct approach seems to implement a > sub-class of 'TargetSchedModel'. > > When I had a look at how other targets dealt with this transition I found > that none of them had implemented the latency scheduler the way we had, so I > couldn't just mimic a strategy used by other targets moving from v3.1 to > v3.2. Unfortunately the people who implemented the existing solution are no > longer with the organization so I am trying to determine how to fix this > without their experience. > > Is there any preferred or recommended approach for rewriting our existing > implementation to fit the 'TargetSchedModel' mechanism?Hi Martin, Yes, TargetSchedModel is the machine-instr scheduler's interface to the machine model. It is not extensible. Instead, it checks the current subtarget configuration, and either directly queries latency tables, or calls hooks. Three possible configurations are: (1) No per-opcode tables In this case, only one helper is used: unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel *SchedModel, const MachineInstr *DefMI) const; This is currently non-virtual because it is designed to directly query the fields in the SchedMachineModel tablegen class using another hook to select high latency ops: virtual bool isHighLatencyDef(int opc) const; Instructions that are not high latency default to one cycle. Example: def GenericModel : SchedMachineModel { let LoadLatency = 4; let HighLatency = 10; } If it really helps, you could redeclare defaultDefLatency as a virtual hook and override it. (2) The "old" style of pipeline itineraries. This is closest to the old behavior. If an itinerary is defined, you get to override two hooks: virtual int TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, unsigned UseIdx) const; virtual unsigned TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr *MI, unsigned *PredCost = 0) const; Example: def CortexA8Model : SchedMachineModel { ... let Itineraries = CortexA8Itineraries; } If you don't actually have any itineraries defined in you target's Schedule.td files, you need to define some dummy itinerary with at least one entry. Something like this may work (I haven't tried it). def IIC_Default : InstrItinClass; def MyItineraries : ProcessorItineraries<[ InstrItinData<IIC_Default, [], []> ]>; 3) The new style of machine model. Here, you don't use any hooks above the machine model. Instead you define all possible instruction latencies and resources in your .td. For a particular opcode, the model allows selecting the set of resources based on hooks. But all the resources are defined in one place. -Andy -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130429/b15c5779/attachment.html>
Martin J. O'Riordan
2013-Apr-30 09:42 UTC
[LLVMdev] Instruction Scheduling - migration from v3.1 to v3.2
Thanks Andrew, that information is a great help. I think I will rewrite our old mechanism to use the method you describe, as we do not currently have a Schedule.td implementation. MartinO From: Andrew Trick [mailto:atrick at apple.com] Sent: 30 April 2013 03:21 To: Martin.ORiordan at movidius.com Cc: llvmdev at cs.uiuc.edu; Dev Subject: Re: [LLVMdev] Instruction Scheduling - migration from v3.1 to v3.2 On Apr 26, 2013, at 3:53 AM, Martin J. O'Riordan <Martin.ORiordan at movidius.com> wrote: I am migrating the llvm/clang derived compiler for our processor from the v3.1 to v3.2 codebase. This has mostly gone well except that instruction latency scheduling is no longer happening. The people who implemented this previously sub-classed 'ScheduleDAGInstrs' and implemented the virtual methods 'computeLatency' and 'computeOperandLatency'. However, these methods have been removed from 'ScheduleDAG' and 'ScheduleDAGInstrs' so are no longer invoked on our implementation. Instead, the correct approach seems to implement a sub-class of 'TargetSchedModel'. When I had a look at how other targets dealt with this transition I found that none of them had implemented the latency scheduler the way we had, so I couldn't just mimic a strategy used by other targets moving from v3.1 to v3.2. Unfortunately the people who implemented the existing solution are no longer with the organization so I am trying to determine how to fix this without their experience. Is there any preferred or recommended approach for rewriting our existing implementation to fit the 'TargetSchedModel' mechanism? Hi Martin, Yes, TargetSchedModel is the machine-instr scheduler's interface to the machine model. It is not extensible. Instead, it checks the current subtarget configuration, and either directly queries latency tables, or calls hooks. Three possible configurations are: (1) No per-opcode tables In this case, only one helper is used: unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel *SchedModel, const MachineInstr *DefMI) const; This is currently non-virtual because it is designed to directly query the fields in the SchedMachineModel tablegen class using another hook to select high latency ops: virtual bool isHighLatencyDef(int opc) const; Instructions that are not high latency default to one cycle. Example: def GenericModel : SchedMachineModel { let LoadLatency = 4; let HighLatency = 10; } If it really helps, you could redeclare defaultDefLatency as a virtual hook and override it. (2) The "old" style of pipeline itineraries. This is closest to the old behavior. If an itinerary is defined, you get to override two hooks: virtual int TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, unsigned UseIdx) const; virtual unsigned TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr *MI, unsigned *PredCost = 0) const; Example: def CortexA8Model : SchedMachineModel { ... let Itineraries = CortexA8Itineraries; } If you don't actually have any itineraries defined in you target's Schedule.td files, you need to define some dummy itinerary with at least one entry. Something like this may work (I haven't tried it). def IIC_Default : InstrItinClass; def MyItineraries : ProcessorItineraries<[ InstrItinData<IIC_Default, [], []> ]>; 3) The new style of machine model. Here, you don't use any hooks above the machine model. Instead you define all possible instruction latencies and resources in your .td. For a particular opcode, the model allows selecting the set of resources based on hooks. But all the resources are defined in one place. -Andy -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130430/3204202f/attachment.html>