summaryrefslogtreecommitdiffstats
path: root/llvm/utils
diff options
context:
space:
mode:
authorElena Demikhovsky <elena.demikhovsky@intel.com>2015-02-25 09:46:31 +0000
committerElena Demikhovsky <elena.demikhovsky@intel.com>2015-02-25 09:46:31 +0000
commit56eadcf5ce7bb1cc5d3a4d25f40d73c882ef9087 (patch)
tree7a286df920ed74eab31897c4d5dc3d3303a955c9 /llvm/utils
parent3eff5f46d7821f2fa8529c93155f70f717cb71ee (diff)
downloadbcm5719-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.cpp20
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.cpp1
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.h1
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;
OpenPOWER on IntegriCloud