Page MenuHomePhabricator

TableGen: Add support of Intrinsics with multiple returns
Needs ReviewPublic

Authored by wenbos on Apr 20 2017, 2:29 AM.

Details

Reviewers
ab
stoklund
bogner
Summary

This patch deals with intrinsics with multiple outputs, for example load instrinsic with address updated. 
 
DAG selection for Instrinsics could be done either through source code or tablegen. Handling all intrinsics in source code would introduce a huge chunk of repetitive code if we have a large number of intrinsic that return multiple values (see NVPTX as an example).  While intrinsic class in tablegen supports multiple outputs, tablegen only supports Intrinsics with zero or one output on TreePattern. This appears to be a simple bug in tablegen that is fixed by this patch.

Intrinsics is defined as:

def int_xxx_load_addr_updated: Intrinsic<[llvm_i32_ty, llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty], []>;

Instruction will be defined as:

def L32_X: Inst<(outs reg:$d1, reg:$d2), (ins reg:$s1, reg:$s2), "ld32_x $d1, $d2, $s2", [(set i32:$d1, i32:$d2, (int_xxx_load_addr_updated i32:$s1, i32:$s2))]>;

Diff Detail

Repository
rL LLVM

Event Timeline

wenbos created this revision.Apr 20 2017, 2:29 AM
wenbos retitled this revision from Add support of Intrinsics with multiple returns to TableGen to TableGen: Add support of Intrinsics with multiple returns.Apr 20 2017, 6:01 PM
wenbos edited the summary of this revision. (Show Details)
wenbos added reviewers: MatzeB, stoklund.
wenbos added a subscriber: llvm-commits.
MatzeB resigned from this revision.Apr 21 2017, 10:04 AM
MatzeB edited reviewers, added: bogner, ab; removed: MatzeB.

Unfortunately I am not a good reviewer for the DAGPattern part of TableGen. Adding some people who may know about SelectionDAG.

chenwj added a subscriber: chenwj.Apr 28 2017, 5:43 AM
chenwj added a comment.EditedApr 28 2017, 6:21 AM

@wenbos Could you explain why moving GetNumNodeResults up ahead solves the problem? I see one problem is Operator will be changed if it's SubClassOf("Intrinsic"), that might make GetNumNodeResults return the wrong result. I don't know if your patch is the right fix, although it works.

This comment was removed by wenbos.

@wenbos Could you explain why moving GetNumNodeResults up ahead solves the problem? I see one problem is Operator will be changed if it's SubClassOf("Intrinsic"), that might make GetNumNodeResults return the wrong result. I don't know if your patch is the right fix, although it works.

@chenwj Here is source code of how intrinsics SDNode for tablegen are defined. Intrinsics are hard-coded to have zero or one output. Check def for SDTypeProfile.
In TargetSelectionDAG.td:

// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
// these internally.  Don't reference these directly.
def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
                            SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
                            [SDNPHasChain]>;
def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
                               SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
                               [SDNPHasChain]>;
def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
                                SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;