Hi Andrew,
We are currently using a custom model where scheduling information is attached to each MCInstrDesc through tablegen, and we're trying to move to one of LLVM's models.
To expand on what JinGu mentioned, our target has explicit ports that are used to read and write values from and to the register file. The read port is usually accessed on cycle 0 while the write port is accessed when the result is written back to the destination register. Let's assume ADD has a latency of 1, MUL has a latency of 2 and both use port P0 to write back their result. The two instructions below would conflict on P0:
MUL r3, r4, r5
ADD r0, r1, r2
NOP ; Both r0 and r4 are written back using P0 - conflict.
On our target there is no interlock which means any conflict results in the wrong value being written back to one of the register. That's why we want to model these ports as resources in the new model. That's also why we map these port resources to each operand as each operand accesses a different port.
After reading your replies, we have realized that the scheduler does not need to know which operand corresponds to each port. It simply needs to know the set of ports used by each instruction and after how many cycles these ports are used/reserved to avoid any conflict. That's why I believe the new process resource model closely fits what we need, except for the per-resource delay you mentioned.
This is how our model currently looks like:
def :ItinRW<[1_LATENCY_WITH_P0, 0_LATENCY_WITH_P1, 0_LATENCY_WITH_P2], [II_ADD]>;
def :ItinRW<[2_LATENCY_WITH_P0, 0_LATENCY_WITH_P1, 0_LATENCY_WITH_P2], [II_MUL]>;
where n_LATENCY_WITH_p is defined roughly as:
class n_LATENCY_WITH_p<int latency, ProcResourceKind port> : SchedWriteRes<[PR_Pp]> {
let Latency = latency;
let ResourceDelays = [latency];
}
class PR_Pp<int portIdx> : ProcResource<1>;
The latency for register write-back/port access is static and without interlock, which I think means the port resources should have 'Buffered = 0' in the definition. Is that correct?
I have attached a patch that adds the 'ResourceDelays' field in tablegen. Could you have a look at it? A couple possible issues are:
- 'Delay' is signed, since 'Cycles' in MCWriteLatencyEntry is also signed.
- When an instruction accesses the same resource multiple times, the uses are aggregated in SubtargetEmitter::GenSchedClassTables. I'm not sure how that would work if we add a 'Delay' field to MCWriteProcResEntry.
Thanks,
Pierre
add_resource_delays.patch (4.93 KB)