diff options
author | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2015-02-25 09:46:31 +0000 |
---|---|---|
committer | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2015-02-25 09:46:31 +0000 |
commit | 56eadcf5ce7bb1cc5d3a4d25f40d73c882ef9087 (patch) | |
tree | 7a286df920ed74eab31897c4d5dc3d3303a955c9 /llvm/utils | |
parent | 3eff5f46d7821f2fa8529c93155f70f717cb71ee (diff) | |
download | bcm5719-llvm-56eadcf5ce7bb1cc5d3a4d25f40d73c882ef9087.tar.gz bcm5719-llvm-56eadcf5ce7bb1cc5d3a4d25f40d73c882ef9087.zip |
AVX-512: Gather and Scatter patterns
Gather and scatter instructions additionally write to one of the source operands - mask register.
In this case Gather has 2 destination values - the loaded value and the mask.
Till now we did not support code gen pattern for gather - the instruction was generated from
intrinsic only and machine node was hardcoded.
When we introduce the masked_gather node, we need to select instruction automatically,
in the standard way.
I added a flag "hasTwoExplicitDefs" that allows to handle 2 destination operands.
(Some code in the X86InstrFragmentsSIMD.td is commented out, just to split one big
patch in many small patches)
llvm-svn: 230471
Diffstat (limited to 'llvm/utils')
-rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 20 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenInstruction.cpp | 1 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenInstruction.h | 1 |
3 files changed, 17 insertions, 5 deletions
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 20bf29eb859..4e3e588fbad 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1113,6 +1113,8 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { // FIXME: Should allow access to all the results here. unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0; + if (InstInfo.hasTwoExplicitDefs) + ++NumDefsToAdd; // Add on one implicit def if it has a resolvable type. if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other) @@ -1609,11 +1611,20 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { assert(getNumTypes() == 0 && "Set doesn't produce a value"); assert(getNumChildren() >= 2 && "Missing RHS of a set?"); unsigned NC = getNumChildren(); + unsigned NumOfSrcs = NC-1; + // destination TreePatternNode *SetVal = getChild(NC-1); bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters); - for (unsigned i = 0; i < NC-1; ++i) { + // second explicit destination + if (TP.getRecord()->getValueAsBit("hasTwoExplicitDefs")) { + TreePatternNode *Set2Val = getChild(NC-2); + MadeChange = Set2Val->ApplyTypeConstraints(TP, NotRegisters); + NumOfSrcs --; + } + + for (unsigned i = 0; i < NumOfSrcs; ++i) { TreePatternNode *Child = getChild(i); MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); @@ -2856,7 +2867,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( // Check that all of the results occur first in the list. std::vector<Record*> Results; - TreePatternNode *Res0Node = nullptr; + SmallVector<TreePatternNode *, 2> ResNode; for (unsigned i = 0; i != NumResults; ++i) { if (i == CGI.Operands.size()) I->error("'" + InstResults.begin()->first + @@ -2868,8 +2879,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( if (!RNode) I->error("Operand $" + OpName + " does not exist in operand list!"); - if (i == 0) - Res0Node = RNode; + ResNode.push_back(RNode); Record *R = cast<DefInit>(RNode->getLeafValue())->getDef(); if (!R) I->error("Operand $" + OpName + " should be a set destination: all " @@ -2946,7 +2956,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( GetNumNodeResults(I->getRecord(), *this)); // Copy fully inferred output node type to instruction result pattern. for (unsigned i = 0; i != NumResults; ++i) - ResultPattern->setType(i, Res0Node->getExtType(i)); + ResultPattern->setType(i, ResNode[i]->getExtType(0)); // Create and insert the instruction. // FIXME: InstImpResults should not be part of DAGInstruction. diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp index 10602964e48..b1e43183634 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -320,6 +320,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) isRegSequence = R->getValueAsBit("isRegSequence"); isExtractSubreg = R->getValueAsBit("isExtractSubreg"); isInsertSubreg = R->getValueAsBit("isInsertSubreg"); + hasTwoExplicitDefs = R->getValueAsBit("hasTwoExplicitDefs"); bool Unset; mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset); diff --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h index bdbe546ec97..82b23f465f3 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.h +++ b/llvm/utils/TableGen/CodeGenInstruction.h @@ -255,6 +255,7 @@ namespace llvm { bool isRegSequence : 1; bool isExtractSubreg : 1; bool isInsertSubreg : 1; + bool hasTwoExplicitDefs : 1; std::string DeprecatedReason; bool HasComplexDeprecationPredicate; |