This is an archive of the discontinued LLVM Phabricator instance.

[TableGen] Add bang-operators !getop and !setop.
ClosedPublic

Authored by simon_tatham on Dec 9 2019, 3:12 AM.

Details

Summary

These allow you to get and set the operator of a dag node, without
affecting its list of arguments.

!getop is slightly fiddly because in many contexts you need its
return value to have a static type more specific than 'any record'. It
works to say !cast<BaseClass>(!getop(...)), but it's cumbersome, so
I made !getop take an optional type suffix itself, so that can be
written as the shorter !getop<BaseClass>(...).

Diff Detail

Event Timeline

simon_tatham created this revision.Dec 9 2019, 3:12 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 9 2019, 3:12 AM

Suddenly realised that it wasn't as hard as I thought to make
!getop(...) usable as the operator of a new dag literal expression.

This looks fine, but have you thought through !setop discarding the name on the operand? The only use of this feature seems to be naming DAG pattern nodes, a feature that seems to have been around forever but I haven't seen used in the code I've touched...

I'm sorry, I'm not sure I understand that question.

!setop affects the operator of a dag value, not the operands. The :$name suffix can only be applied to an operand. So !setop leaves all the operand names completely alone, since the part of the dag value it's replacing is nothing to do with them.

(Perhaps !setop is a bad name, for that reason, since it could very easily mean either 'operator' or 'operand'...)

The name suffix _can_ be applied to the operator:

def op;
def Foo {
  dag x = (op:$blah 1:$foo, 2, 3);
}
// produces:
------------- Defs -----------------
def Foo {
  dag x = (op:blah 1:$foo, 2, 3);
}
def op {
}

Though the inconsistent output and undocumented nature of it suggests that this feature is hardly ever used...

nhaehnle accepted this revision.Dec 11 2019, 3:57 AM

Okay, digging in further, the feature is actually used quite a bit in pattern definitions like:

def : GCNPat <
  (VGPRImm<(i32 imm)>:$imm),
  (V_MOV_B32_e32 imm:$imm)
>;

or

def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>;

The first really ought to be expressible by placing the $imm inside the inner DAG expression, but for some reason the TableGen backend doesn't allow that. I don't know about the second... maybe if it was wrapped as (i32 s32_0ImmPred:$s16)? Fundamentally, the feature seems to be used as a hacky workaround for the fact that SelectionDAG patterns don't have an "outer" DAG, and having a naked expression like s32_0ImmPred:$s16 is not possible.

So here we are. I think your change is okay as-is though. It strips such names, but this naming feature seems kind of awkward to me anyway, and its use should probably be discouraged.

This revision is now accepted and ready to land.Dec 11 2019, 3:57 AM

OK, I'll commit it as is. Thanks!

I must admit that I hadn't known about that feature of dags at all, and I probably should have found out about it, because I did see that nullptr argument when I copied the form of an existing call to DagInit::get, but I lazily didn't dig down to find out what it was for. Ahem.

This revision was automatically updated to reflect the committed changes.