This is an archive of the discontinued LLVM Phabricator instance.

[ARM][SchedModels] Convert IsPredicatedPred to MCSchedPredicate
AbandonedPublic

Authored by evgeny777 on Oct 15 2020, 5:21 AM.

Details

Summary

Patch allows llvm-mca to correcty detect latencies of conditional ops.

Diff Detail

Event Timeline

evgeny777 created this revision.Oct 15 2020, 5:21 AM
evgeny777 requested review of this revision.Oct 15 2020, 5:21 AM
evgeny777 updated this revision to Diff 298357.Oct 15 2020, 5:49 AM

Removed wrongly added file from diff

andreadb added inline comments.Oct 15 2020, 3:23 PM
llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
183–186

It is unfortunate that the MCSchedPredicate framework is not expressive enough to let users define predicates on MCInstrDesc.

Your idea of adding an extra field (a MCInstrDesc pointer) to MCInst does solve the issue.
To be honest, at the moment I don't think that there are other ways to fix this issue. The only alternative is to expand/improve the MCSchedPredicate framework. However, it is not a simple task, and it would requires modifications to the SubtargetEmitter, the InstructionInfoEmitter and the PredicateExpander.

evgeny777 added inline comments.Oct 16 2020, 12:11 AM
llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
183–186

The only alternative is to expand/improve the MCSchedPredicate framework. However, it is not a simple task, and it would requires modifications to the SubtargetEmitter, the InstructionInfoEmitter and the PredicateExpander.

I tried adding extra parameter (MCInstrInfo) to resolveVariantSchedClass and resolveVariantSchedClassImpl, updating SubtargetEmitter and all callers (llvm-mca, llvm-exegesis, etc) respectively. However I didn't like the result much due to

  • lots of code modification
  • all MC predicates will have two parameters, which codegen predicates have only one, so PredicateExpander should be modified (like you said)
  • most of MC predicates likely won't need MCInstrDesc.

Looking at MachineInstr I found getDesc/setDesc and decided to use similar approach for MCInst.

evgeny777 updated this revision to Diff 298562.Oct 16 2020, 1:08 AM

Removed commented line of code

andreadb added inline comments.Oct 16 2020, 1:46 AM
llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
183–186

Yeah.

I agree with you that having a pointer to the instruction descriptor is quite convenient. It simplifies some interactions and avoids that we always keep around a reference to the MCInstrInfo. So, if other people are happy with it, then I am OK too.

Yesterday I was trying to prototype something to workaround that issue, and I think I ended up doing exactly the same modifications (i.e. adding an extra MCInstrInfo* operand to resolveVariantSchedClass).
However I think (although I didn't test it yet) that you can probably implement something simpler by introducing only a new predicate, and not having to touch existing predicates.

The main problem in your case was that CheckFunctionPredicate is not very good because it assumes a single operand in input to the function (i.e. a MachineInstr/MCInst operand).

We could introduce a CheckFunctionPredicateWithMCII<string MCInstFn, string MachineInstrFn>

which is similar in principle to CheckFunctionPredicate, but it assumes that the MachineInstrFn is a method of TII, and MCInstrFn is just a normal function that also takes a pointer to MCII in input. So, something that expands to either of:

  • TII->MachineInstrFn(MI);
  • MCInstFn(MI, MCII).

Basically, same idea, but extra MCII operand.
That would obviously require that MCII is accessible somehow (hence the need of that change to the signature of resolveVariantSchedClass - so that MCII is always available).

If that works, then your new function would be become like this:

bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo* MCII) {
  const MCInstrDesc& Desc = MCII->get(MI.getOpcode());
  int PredOpIdx = Desc.findFirstPredOperandIdx();
  return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
}

In conclusion:
I am not against the idea of adding an extra field to MCInst since it may be useful in general (maybe not just for mca).
It definitely simplifies writing portable predicates that can be used by mca. It is a pragmatic approach after all, and - as you wrote - we already do something similar in MachineInstr.

An alternative approach, would require a change to the resolveVariant signature, and the introduction of a new predicate. As you wrote , the downside is that it introduces code modifications in a few places (at least in the SubtargetEmitter, MCSchedule.h (functionalities that need to resolve scheduling classes to compute latency/throughput), and llvm-mca/exegesis (since those obviously need to resolve latency/throughput). That being said, those are mostly mechanical changes (I personally don't think it is a problem to change those tools).

The main problem in your case was that CheckFunctionPredicate is not very good because it assumes a single operand in input to the function (i.e. a MachineInstr/MCInst operand).

Exactly :). When I realized that new CheckFunction-like predicate should be introduced to cope with changed function signature I switch to getDesc/setDesc approach. Ok, let's wait for others.

For the record, this is how your patch would look like if you decided to add a new predicate.


I am just trying to be helpful by showing how the alternative approach would look like (in case, if people decide that it is not a good idea to add an extra field to MCInst).

P.s.: I still think that your approach is simpler.

ARM changes look good to me.

This adds an extra pointer into MCInst? So something like changing an instruction from 32byte + 16bytes per operand to 40bytes + 16bytes per operand. I'm not sure how much a change like that would matter, but if we have the other patch and we don't know of any other uses for Desc, perhaps that is the more conservative route. I don't have a very strong opinions either way though.

I have been thinking a bit more about this patch.
D89553 is surprisingly less complicated than I have originally thought it was. It definitely touches more files. However the majority of the changes are very mechanical (mostly boilerplate required for the new MCSchedPredicate to work). It is also a non-controversial change, since it doesn't modify the layout of MCInst.
Bonus point: by changing the signature of resolveVariantSchedClass() we potentially enable future developments in the area of MCSchedPredicate (and mca). Basically that change would make it possible for users to declare new predicates on MCinstrDesc (which is definitely not a bad thing!).

The more I look at D89553, the more I feel confident that it may be the right way to go. So, if you and @dmgreen are also happy with D89553, then please consider committing that patch instead of this one.

Thanks!

evgeny777 abandoned this revision.Oct 19 2020, 2:00 AM

D89553 was pushed instead