From ec8d1a5b72b1cb2d230ba52b25a017231393b182 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 19 Mar 2013 19:51:09 +0000 Subject: Extend TableGen instruction selection matcher to improve handling of complex instruction operands (e.g. address modes). Currently, if a Pat pattern creates an instruction that has a complex operand (i.e. one that consists of multiple sub-operands at the MI level), this operand must match a ComplexPattern DAG pattern with the correct number of output operands. This commit extends TableGen to alternatively allow match a complex operands against multiple separate operands at the DAG level. This allows using Pat patterns to match pre-increment nodes like pre_store (which must have separate operands at the DAG level) onto an instruction pattern that uses a multi-operand memory operand, like the following example on PowerPC (will be committed as a follow-on patch): def STWU : DForm_1<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, memri:$dst), "stwu $rS, $dst", LdStStoreUpd, []>, RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; def : Pat<(pre_store GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff), (STWU GPRC:$rS, iaddroff:$ptroff, ptr_rc:$ptrreg)>; Here, the pair of "ptroff" and "ptrreg" operands is matched onto the complex operand "dst" of class "memri" in the "STWU" instruction. Approved by Jakob Stoklund Olesen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177428 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/DAGISelMatcherGen.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'utils/TableGen/DAGISelMatcherGen.cpp') diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 38ffa30ec8..8541390b41 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -734,20 +734,33 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, continue; } - const TreePatternNode *Child = N->getChild(ChildNo); - // Otherwise this is a normal operand or a predicate operand without // 'execute always'; emit it. - unsigned BeforeAddingNumOps = InstOps.size(); - EmitResultOperand(Child, InstOps); - assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands"); - // If the operand is an instruction and it produced multiple results, just - // take the first one. - if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction")) - InstOps.resize(BeforeAddingNumOps+1); + // For operands with multiple sub-operands we may need to emit + // multiple child patterns to cover them all. However, ComplexPattern + // children may themselves emit multiple MI operands. + unsigned NumSubOps = 1; + if (OperandNode->isSubClassOf("Operand")) { + DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo"); + if (unsigned NumArgs = MIOpInfo->getNumArgs()) + NumSubOps = NumArgs; + } + + unsigned FinalNumOps = InstOps.size() + NumSubOps; + while (InstOps.size() < FinalNumOps) { + const TreePatternNode *Child = N->getChild(ChildNo); + unsigned BeforeAddingNumOps = InstOps.size(); + EmitResultOperand(Child, InstOps); + assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands"); - ++ChildNo; + // If the operand is an instruction and it produced multiple results, just + // take the first one. + if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction")) + InstOps.resize(BeforeAddingNumOps+1); + + ++ChildNo; + } } // If this node has input glue or explicitly specified input physregs, we -- cgit v1.2.3-18-g5258