From e618abd6e0c1a38092dc90b139154a7e884bbaad 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. llvm-svn: 177428 --- llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp') diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 00907067180..2c3161bc82a 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1654,8 +1654,42 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { TreePatternNode *Child = getChild(ChildNo++); unsigned ChildResNo = 0; // Instructions always use res #0 of their op. + + // If the operand has sub-operands, they may be provided by distinct + // child patterns, so attempt to match each sub-operand separately. + if (OperandNode->isSubClassOf("Operand")) { + DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo"); + if (unsigned NumArgs = MIOpInfo->getNumArgs()) { + // But don't do that if the whole operand is being provided by + // a single ComplexPattern. + const ComplexPattern *AM = Child->getComplexPatternInfo(CDP); + if (!AM || AM->getNumOperands() < NumArgs) { + // Match first sub-operand against the child we already have. + Record *SubRec = cast(MIOpInfo->getArg(0))->getDef(); + MadeChange |= + Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); + + // And the remaining sub-operands against subsequent children. + for (unsigned Arg = 1; Arg < NumArgs; ++Arg) { + if (ChildNo >= getNumChildren()) { + TP.error("Instruction '" + getOperator()->getName() + + "' expects more operands than were provided."); + return false; + } + Child = getChild(ChildNo++); + + SubRec = cast(MIOpInfo->getArg(Arg))->getDef(); + MadeChange |= + Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); + } + continue; + } + } + } + + // If we didn't match by pieces above, attempt to match the whole + // operand now. MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP); - MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); } if (ChildNo != getNumChildren()) { @@ -1664,6 +1698,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { return false; } + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); return MadeChange; } -- cgit v1.2.3