This is an archive of the discontinued LLVM Phabricator instance.

[TII] add new target hook isAdd
ClosedPublic

Authored by SjoerdMeijer on Aug 17 2016, 1:41 AM.

Details

Summary

This adds a new target hook isAdd to TargetInstrInfo. This is refactored from the Hexagon backend and is more groundwork to find induction variables and calculate loop counts on MachineLoops.

Diff Detail

Repository
rL LLVM

Event Timeline

SjoerdMeijer retitled this revision from to [TII] add new target hook isAdd.
SjoerdMeijer updated this object.
SjoerdMeijer added reviewers: bcahoon, kparzysz, jmolloy.
SjoerdMeijer added a subscriber: llvm-commits.
kparzysz added inline comments.Aug 17 2016, 1:10 PM
include/llvm/Target/TargetInstrInfo.h
1086 ↗(On Diff #68320)

There should be some description about what is expected from an instruction for which this function returns "true". Something like: one output operand (0), two input operands (1 and 2), either input can be an immediate/register/global symbol/etc. Should the instruction be free from any side-effects (such as setting some flags), or it does not matter? And so on.

Hi,

If we start adding more semantic of the instructions to TargetInstrInfo, I think we need to think more broadly on how to do that. Otherwise, I am afraid the API will not be consistent on the long run. E.g., why would we have isAdd and not isSub?
To be fair, the API is probably already broken, but there is not bad time to start fixing the problems :).

I am supportive of the idea of adding semantic, I am not convince a bunch of target hooks is necessarily the best approach or at least, having to populate those target hooks by hand.
At the very least, we should be able to annotate the instruction with isAdd in the td file and generate the hook in tablegen.

Cheers,
-Quentin

Hi,

If we start adding more semantic of the instructions to TargetInstrInfo, I think we need to think more broadly on how to do that. Otherwise, I am afraid the API will not be consistent on the long run. E.g., why would we have isAdd and not isSub?
To be fair, the API is probably already broken, but there is not bad time to start fixing the problems :).

I am supportive of the idea of adding semantic, I am not convince a bunch of target hooks is necessarily the best approach or at least, having to populate those target hooks by hand.
At the very least, we should be able to annotate the instruction with isAdd in the td file and generate the hook in tablegen.

Cheers,
-Quentin

I'd really like an interface that allows converting from an MI entity to something with known semantics; I think that, with the new generic opcodes being introduced for GlobalISel, we have a good opportunity here. How about the following interface (modulo bikeshedding)?

MachineOperand *Op0, *Op1, *Op2;
if (TII->convertToGenericOp(MI, Op0, Op1, Op2) == G_ADD) {
  // This MI is equivalent to Op0 = G_ADD Op1, Op2
}
kparzysz edited edge metadata.Aug 18 2016, 6:09 AM

I'd really like an interface that allows converting from an MI entity to something with known semantics; I think that, with the new generic opcodes being introduced for GlobalISel, we have a good opportunity here. How about the following interface (modulo bikeshedding)?

MachineOperand *Op0, *Op1, *Op2;
if (TII->convertToGenericOp(MI, Op0, Op1, Op2) == G_ADD) {
  // This MI is equivalent to Op0 = G_ADD Op1, Op2
}

I've been planning to implement something along the lines of the m_xxx pattern matching for MachineInstr. There would be some set of predefined generic operations, such as add, mul, shift, etc. but an object that can match an "add" operation could also be annotated with flags indicating that the "add" should be saturating, for example. In the absence of such annotations, the matched object would acquire such annotations from the instruction that it matched.

Hi,
Thanks a lot for the feedback!
I agree that adding it to TargetInstrInfo is a bit of a hack; adding isAdd in the td file and generate the hook in tablegen makes sense and also doable.
I will follow that approach and continue with that here.
Cheers,
Sjoerd.

SjoerdMeijer edited edge metadata.

This is a rewrite of the previous patch. Rather than adding a new isAdd target hook to TII, isAdd is now a field in MCInstrDesc that can be queried.

ping ;-)

@qcolombet is this more like what you had in mind?

qcolombet accepted this revision.Sep 8 2016, 4:36 PM
qcolombet added a reviewer: qcolombet.

Hi Sjoerd,

Yes, that was what I had in mind.
For some reasons though, the reply I made to Hal's proposal didn't make it to phabricator so I guess you missed it. Basically, I was saying that Hal's proposal was a good way to move.

That being said, I don't what to hold on that patch, I guess we could move towards the more generic approach in a follow up patch or when we want to add more semantic.

Just one thing, please do the replacement of 1<< by 1ULL<< in a different patch that you would apply first.

Cheers,
-Quentin

This revision is now accepted and ready to land.Sep 8 2016, 4:36 PM

Thanks for reviewing!

The 1ULL << fix has been separately committed as revision 281149.

I noticed that I missed a failing regression test: CodeGen/Hexagon/addh-sext-trunc.ll due to a change in codegen. Interestingly, it is different because now a hwloop is created.


Before:

.LBB0_1: // %for.inc.preheader
{

			r3:2 = combine(##262144, #0)

}
.p2align 4
.LBB0_2: // %for.inc

// =>This Inner Loop Header: Depth=1

{

			r2 = add(r2.l, r3.h)
			if (cmp.gt(r1, r2.new)) jump:t .LBB0_2

}


After:

LBB0_1: // %for.inc.preheader
{

			r1 = add(r1, ##262143)

}
{

			r1 = lsr(r1, #18)

}
{

			loop0(.LBB0_2, r1)

}
.p2align 4
.Ltmp0: Block address taken
.LBB0_2:
%for.inc

// =>This Inner Loop Header: Depth=1

{

			nop
			nop

} :endloop0

At a first glance, this looks correct to me. But hexagon code is completely new to me, so I don't think I can make chances here and am hoping someone can confirm this is ok.

SjoerdMeijer edited edge metadata.

Just to be sure, I have uploaded a modified patch set that fixes failing regression test "test/CodeGen/Hexagon/addh-sext-trunc.ll". This was not a minimal test as all it is testing, as the name suggests, is an add and sign extension, but the function had loops and lots more. Please shout if there are objections, otherwise I will be committing it soon'ish.

bcahoon edited edge metadata.Sep 12 2016, 1:43 PM

The change to the Hexagon test looks good to me. As you mention correctly, the intent is to check that the compiler generates one of special add variants on Hexagon, so the reduced test case is a good change.

Thanks for reviewing!

This revision was automatically updated to reflect the committed changes.
MatzeB added a subscriber: MatzeB.Sep 21 2017, 1:57 PM

It would be great if someone could add more comments of what isAdd entails. All documentation in the current llvm code is a variation of Is this instruction an add instruction?/\brief Return true if the instruction is an add instruction.. Are there any requirements on which operands of the instruction are actually added together or hold the result? Can they be immediates and register operands, load from memory?

This flag seems to only be used on 2 hexagon instructions and it makes me wonder if it shouldn't rather have been a member function in HexagonInstrInfo.

The context of this work was to recognise loop induction statements in Machine Instructions/Loops and to allow calculation of loop iteration counts. And isAdd provides more semantic information about a MI and helps recognising induction variables. Thus, this was the ground work for D27193, which was the next step to recognise loop induction. This patch was abandoned because the Quentin's comment was that the analysis was too ad-hoc and missing some formalism. The reason this is used only in the Hexagon backend, is because I refactored it and took it from the Hexagon backend. The Hexagon backend has a lot of MachineLoop/MI analysis and other goodness (sw pipeliner) that is mostly target independent and could be made available, but a few target specific hooks are required to do this.
Now, I really would like to pick up this work again because I still think it will be valuable, but need to rethink strategy after abandoning D27193. Probably that will be a some SVEC-like approach, but hopefully that can be a light-weight implementation to recognise simple loops (which is what we're doing anyway). This will probably be quite some work, so in the mean time, I really don't mind removing or moving isAdd back to the Hexagon backend. I could also dig up the exact requirements and document that if it's okay to keep it.