PATCH: R600/SI: Do abs/neg folding with ComplexPatterns
Tom Stellard
tom at stellard.net
Tue Jul 29 20:40:22 PDT 2014
Hi Matt,
Here are some updated patches. I've responded to two of you comments below.
-Tom
On Thu, Jul 24, 2014 at 11:20:10AM -0700, Matt Arsenault wrote:
> On 07/24/2014 10:47 AM, Tom Stellard wrote:
> >+multiclass VOP3b_2_m <bits<9> op, dag outs, dag ins, string asm,
> >+ list<dag> pattern, string opName, string revOp,
> >+ bit HasMods = 1, bit UseFullOp = 0> {
> >+ def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
> >+ VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
> >+
> >+ // The VOP2 variant puts the carry out into VCC, the VOP3 variant
> >+ // can write it into any SGPR. We currently don't use the carry out,
> >+ // so for now hardcode it to VCC as well.
> Is this something that should be reversed and handled by the
> instruction shrinking pass now?
>
This is an optimization we could do in the future. For now, it is
easier to have both the VOP2 and VOP3 variants writing carry-out to
VCC.
> >+ let sdst = SIOperand.VCC in {
> >+ def _si : VOP3b <
> >+ !if(UseFullOp, op,
> >+ {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}),
> >+ outs, ins, asm, pattern>,
> >+ VOP3DisableFields<1, 0, HasMods>,
> >+ SIMCInstr<opName, SISubtarget.SI>,
> >+ VOP2_REV<revOp#"_e64_si", !eq(revOp, opName)>;
> >+ } // End sdst = SIOperand.VCC
> > }
> >-multiclass VOP3_2_m <bits<6> op, dag outs, dag ins, string asm,
> >- list<dag> pattern, string opName, string revOp> {
> >+multiclass VOP3_C_m <bits<8> op, dag outs, dag ins, string asm,
> >+ list<dag> pattern, string opName,
> >+ bit HasMods, bit defExec> {
> > def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
> >- let src2 = 0, src2_modifiers = 0 in {
> >+// let Defs = !if(defExec, [EXEC], []) in {
> Potentially confusing commented out code
>
> > def _si : VOP3_Real_si <
> >- {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
> >- outs, ins, asm, opName>,
> >- VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
> >-
> >- } // src2 = 0, src2_modifiers = 0
> >-}
> >+ {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
> >+ outs, ins, asm, opName>,
> >+ VOP3DisableFields<1, 0, HasMods> {
> >+ let Defs = !if(defExec, [EXEC], []);
> >+ }
> >-// This must always be right before the operand being input modified.
> >-def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
> >- let PrintMethod = "printOperandAndMods";
> >+// } // End Defs = !if(defExec, [EXEC], [])
> > }
> > multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
> >- string opName, list<dag> pattern> {
> >+ string opName, list<dag> pattern64, bit HasMods = 1,
> >+ list<dag> pattern32 = []> {
> > def _e32 : VOP1 <
> > op, (outs drc:$dst), (ins src:$src0),
> >- opName#"_e32 $dst, $src0", pattern
> >+ opName#"_e32 $dst, $src0", pattern32
> > >, VOP <opName>;
> > defm _e64 : VOP3_1_m <
> > op,
> > (outs drc:$dst),
> >- (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
> >- opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", [], opName>;
> >+ !if(HasMods, (ins InputModsNoDefault:$src0_modifiers, src:$src0,
> >+ i32imm:$clamp, i32imm:$omod),
> >+ (ins src:$src0)),
> >+ opName#"_e64 $dst, "#!if(HasMods, "$src0_modifiers $clamp, $omod", "$src0"),
> >+ pattern64, opName,
> >+ HasMods
> >+ >;
> > }
> >+multiclass VOP1InstModHelper <bits<8> op, RegisterClass drc, RegisterClass src,
> >+ ValueType dstVT, ValueType srcVT, string opName,
> >+ SDPatternOperator node,
> >+ bit HasMods> : VOP1_Helper <
> >+ op, drc, src, opName,
> >+ !if(HasMods, [(set dstVT:$dst,
> >+ (node (srcVT (VOP3Mods0 srcVT:$src0, i32:$src0_modifiers,
> >+ i32:$clamp, i32:$omod))))],
> >+ [(set dstVT:$dst, (node srcVT:$src0))]),
> >+ HasMods
> >+>;
> >+
> >+multiclass VOP1Inst <bits<8> op, string opName, ValueType dstVT,
> >+ ValueType srcVT = dstVT,
> >+ SDPatternOperator node = null_frag> : VOP1InstModHelper <
> I think passing in the entire instruction pattern, rather than the
> srcVT, dstVT, and the pattern operator is much easier to follow.
> This becomes more unmanageable when there are more operands with
> different types
>
In my updated patch I've removed a few layers of inheritance. The VOP*Inst
classes still exist, but if you need to make define a custom instruction, you
can use the VOP*_Helper classes which let you specify the ins, outs, asm,
and patterns directly.
I've also added a VOPProfile class that can be used for specifying the
operands for an instruction.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-R600-SI-Fix-incorrect-commute-operation-in-shrink-in.patch
Type: text/x-diff
Size: 4773 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/4cf16db9/attachment.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-R600-SI-Fold-immediates-when-shrinking-instructions.patch
Type: text/x-diff
Size: 7392 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/4cf16db9/attachment-0001.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-R600-SI-Simplify-and-fix-handling-of-VOP2-in-SIInstr.patch
Type: text/x-diff
Size: 5748 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/4cf16db9/attachment-0002.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-TableGen-Allow-AddedComplexity-values-to-be-negative.patch
Type: text/x-diff
Size: 4121 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/4cf16db9/attachment-0003.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-R600-SI-Do-abs-neg-folding-with-ComplexPatterns.patch
Type: text/x-diff
Size: 104720 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/4cf16db9/attachment-0004.patch>
More information about the llvm-commits
mailing list