Hi Andy and all, I have a question about per-operand machine model. I am finding some relations between 'MCWriteLatencyEntry' and 'MCWriteProcResEntry'. For example, class InstTEST<..., InstrItinClass itin> : Instruction { let Itinerary = Itin; } // I assume this MI writes 2 registers. def TESTINST : InstTEST<..., II_TEST> // schedule info II_TEST: InstrItinClass; def ALU1: ProcResource<1>; def ALU2: ProcResource<1>; def WriteALU1: SchedWriteRes<[ALU1]> { let Latency = 1; } def WriteALU2: SchedWriteRes<[ALU2]> { let Latency = 2; } def : ItinRW<[WriteALU1, WriteALU2], [II_TEST]> From this example, we can access the latency information of MI with 'getWriteLatencyEntry()' and the resource information of MI with 'getWriteProcResBegin()'. At this point, I would like to find the related resource information with each latency information. But TableGen generates the 'WriteResourceID' of 'MCWriteLatencyEntry' when the 'Write' is referenced by a 'ReadAdvance'. And the order of each information, which are resource and latency, is not same. Could you let me know whether it is possible to find the related resource information with each latency information or not? Thanks, JinGu Kang
On Feb 18, 2014, at 9:56 AM, JinGu Kang <jingu at codeplay.com> wrote:> Hi Andy and all, > > I have a question about per-operand machine model. I am finding some relations between 'MCWriteLatencyEntry' and 'MCWriteProcResEntry'. > > For example, > > class InstTEST<..., InstrItinClass itin> : Instruction { > let Itinerary = Itin; > } > // I assume this MI writes 2 registers. > def TESTINST : InstTEST<..., II_TEST> > > // schedule info > II_TEST: InstrItinClass; > > def ALU1: ProcResource<1>; > def ALU2: ProcResource<1>; > > def WriteALU1: SchedWriteRes<[ALU1]> { let Latency = 1; } > def WriteALU2: SchedWriteRes<[ALU2]> { let Latency = 2; } > > def : ItinRW<[WriteALU1, WriteALU2], [II_TEST]> > > From this example, we can access the latency information of MI with 'getWriteLatencyEntry()' and the resource information of MI with 'getWriteProcResBegin()'. At this point, I would like to find the related resource information with each latency information. But TableGen generates the 'WriteResourceID' of 'MCWriteLatencyEntry' when the 'Write' is referenced by a 'ReadAdvance'. And the order of each information, which are resource and latency, is not same. Could you let me know whether it is possible to find the related resource information with each latency information or not? > > Thanks, > JinGu KangResources and latency are not tied. An instruction is mapped to a scheduling class. A scheduling class is mapped to a set of resources and a per-operand list of latencies. For resources that are not fully pipelined, you indicate the number of cycles during which the resource is used: This uses two ALUs in the same cycle: def WriteALU2: SchedWriteRes<[ALU, ALU]> {} This uses an ALU for two cycles: def WriteALUReplay: SchedWriteRes<[ALU]> { let ResourceCycles = [2]; } This uses a MUL for 4 cycles and an ALU for two cycles: def WriteMULALU: SchedWriteRes<[MUL, ALU]> { let ResourceCycles = [4, 2]; } The weakness of the per-operand model (as opposed to the per-pipeline-stage itinerary) is that we cannot indicate, for example, that the ALU resources are used after the MUL resources. We could extend the model fairly easily to accomodate that. -Andy
>Resources and latency are not tied. An instruction is mapped to a scheduling class. A scheduling class is mapped to a set of resources and a per-operand list of latencies.Thanks for your kind explanation. Our heuristic algorithm have needed the latency and the resource per operand to check resource conflicts per cycle. In order to support this with LLVM, I expected a per-operand list of resources like latencies with a scheduling class. Can I ask you something to modify on tablegen? I think that the 'WriteResourceID' field of 'MCWriteLatencyEntry' is for identifying the WriteResources of each defintion as commented on code. As you know, tablegen sets the 'WriteResourceID' field of 'MCWriteLatencyEntry' with 'WriteID' when the 'Write' of defition is referenced by a 'ReadAdvance'. If we always set this field with 'WriteID', it causes problem? I can see that 'ReadAdvance' only uses the 'WriteResourceID' field of 'MCWriteLatencyEntry' in 'computeOperandLatency' function. I think the pair of latency and write resource for defintion will be useful to check conflicts of resources. As reference, I have attached simple patch. Thanks, JinGu Kang -------------- next part -------------- Index: utils/TableGen/SubtargetEmitter.cpp ==================================================================--- utils/TableGen/SubtargetEmitter.cpp (revision 201607) +++ utils/TableGen/SubtargetEmitter.cpp (working copy) @@ -932,12 +932,7 @@ WLEntry.Cycles = 0; unsigned WriteID = WriteSeq.back(); WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name); - // If this Write is not referenced by a ReadAdvance, don't distinguish it - // from other WriteLatency entries. - if (!SchedModels.hasReadOfWrite( - SchedModels.getSchedWrite(WriteID).TheDef)) { - WriteID = 0; - } + WLEntry.WriteResourceID = WriteID;