mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Parse intrinsics correctly and perform type propagation. This doesn't currently
emit the code to select intrinsics, but that is next :) llvm-svn: 27082
This commit is contained in:
parent
1716e53341
commit
92a040dbbf
@ -691,6 +691,25 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||||||
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
|
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
|
||||||
}
|
}
|
||||||
return MadeChange;
|
return MadeChange;
|
||||||
|
} else if (getOperator()->isSubClassOf("Intrinsic")) {
|
||||||
|
const CodeGenIntrinsic &Int =
|
||||||
|
TP.getDAGISelEmitter().getIntrinsic(getOperator());
|
||||||
|
// FIXME: get type information!
|
||||||
|
bool MadeChange = false;
|
||||||
|
|
||||||
|
// Apply the result type to the node.
|
||||||
|
MadeChange = UpdateNodeType(Int.ArgVTs[0], TP);
|
||||||
|
|
||||||
|
if (getNumChildren() != Int.ArgVTs.size()-1)
|
||||||
|
TP.error("Intrinsic '" + getOperator()->getName() + " expects " +
|
||||||
|
utostr(Int.ArgVTs.size()-1) + " operands, not " +
|
||||||
|
utostr(getNumChildren()) + " operands!");
|
||||||
|
for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
|
||||||
|
MVT::ValueType OpVT = Int.ArgVTs[i+1];
|
||||||
|
MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
|
||||||
|
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
|
||||||
|
}
|
||||||
|
return MadeChange;
|
||||||
} else {
|
} else {
|
||||||
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
|
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
|
||||||
|
|
||||||
@ -723,6 +742,13 @@ bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE){
|
|||||||
if (!getChild(i)->canPatternMatch(Reason, ISE))
|
if (!getChild(i)->canPatternMatch(Reason, ISE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If this is an intrinsic, handle cases that would make it not match. For
|
||||||
|
// example, if an operand is required to be an immediate.
|
||||||
|
if (getOperator()->isSubClassOf("Intrinsic")) {
|
||||||
|
// TODO:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// If this node is a commutative operator, check that the LHS isn't an
|
// If this node is a commutative operator, check that the LHS isn't an
|
||||||
// immediate.
|
// immediate.
|
||||||
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator());
|
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator());
|
||||||
@ -811,6 +837,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
|
|||||||
if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") &&
|
if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") &&
|
||||||
!Operator->isSubClassOf("Instruction") &&
|
!Operator->isSubClassOf("Instruction") &&
|
||||||
!Operator->isSubClassOf("SDNodeXForm") &&
|
!Operator->isSubClassOf("SDNodeXForm") &&
|
||||||
|
!Operator->isSubClassOf("Intrinsic") &&
|
||||||
Operator->getName() != "set")
|
Operator->getName() != "set")
|
||||||
error("Unrecognized node '" + Operator->getName() + "'!");
|
error("Unrecognized node '" + Operator->getName() + "'!");
|
||||||
|
|
||||||
@ -1592,10 +1619,13 @@ static void GenerateVariantsOf(TreePatternNode *N,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look up interesting info about the node.
|
// Look up interesting info about the node.
|
||||||
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator());
|
const SDNodeInfo *NodeInfo = 0;
|
||||||
|
|
||||||
|
if (!N->getOperator()->isSubClassOf("Intrinsic"))
|
||||||
|
NodeInfo = &ISE.getSDNodeInfo(N->getOperator());
|
||||||
|
|
||||||
// If this node is associative, reassociate.
|
// If this node is associative, reassociate.
|
||||||
if (NodeInfo.hasProperty(SDNodeInfo::SDNPAssociative)) {
|
if (NodeInfo && NodeInfo->hasProperty(SDNodeInfo::SDNPAssociative)) {
|
||||||
// Reassociate by pulling together all of the linked operators
|
// Reassociate by pulling together all of the linked operators
|
||||||
std::vector<TreePatternNode*> MaximalChildren;
|
std::vector<TreePatternNode*> MaximalChildren;
|
||||||
GatherChildrenOfAssociativeOpcode(N, MaximalChildren);
|
GatherChildrenOfAssociativeOpcode(N, MaximalChildren);
|
||||||
@ -1656,7 +1686,7 @@ static void GenerateVariantsOf(TreePatternNode *N,
|
|||||||
CombineChildVariants(N, ChildVariants, OutVariants, ISE);
|
CombineChildVariants(N, ChildVariants, OutVariants, ISE);
|
||||||
|
|
||||||
// If this node is commutative, consider the commuted order.
|
// If this node is commutative, consider the commuted order.
|
||||||
if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) {
|
if (NodeInfo && NodeInfo->hasProperty(SDNodeInfo::SDNPCommutative)) {
|
||||||
assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
|
assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
|
||||||
// Consider the commuted order.
|
// Consider the commuted order.
|
||||||
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
|
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
|
||||||
@ -2955,6 +2985,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
for (std::map<Record*, std::vector<PatternToMatch*>,
|
for (std::map<Record*, std::vector<PatternToMatch*>,
|
||||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
||||||
|
if (PBOI->first->isSubClassOf("Intrinsic"))
|
||||||
|
continue; // Skip intrinsics here.
|
||||||
|
|
||||||
const std::string &OpName = PBOI->first->getName();
|
const std::string &OpName = PBOI->first->getName();
|
||||||
OS << "void Select_" << OpName << "(SDOperand &Result, SDOperand N) {\n";
|
OS << "void Select_" << OpName << "(SDOperand &Result, SDOperand N) {\n";
|
||||||
|
|
||||||
@ -3201,6 +3234,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
for (std::map<Record*, std::vector<PatternToMatch*>,
|
for (std::map<Record*, std::vector<PatternToMatch*>,
|
||||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
||||||
|
if (PBOI->first->isSubClassOf("Intrinsic"))
|
||||||
|
continue;
|
||||||
|
|
||||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
||||||
OS << " case " << OpcodeInfo.getEnumName() << ": "
|
OS << " case " << OpcodeInfo.getEnumName() << ": "
|
||||||
<< std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ')
|
<< std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ')
|
||||||
@ -3363,6 +3399,7 @@ void DAGISelEmitter::run(std::ostream &OS) {
|
|||||||
OS << " return ResNode;\n";
|
OS << " return ResNode;\n";
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
||||||
|
Intrinsics = LoadIntrinsics(Records);
|
||||||
ParseNodeInfo();
|
ParseNodeInfo();
|
||||||
ParseNodeTransforms(OS);
|
ParseNodeTransforms(OS);
|
||||||
ParseComplexPatterns();
|
ParseComplexPatterns();
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "TableGenBackend.h"
|
#include "TableGenBackend.h"
|
||||||
#include "CodeGenTarget.h"
|
#include "CodeGenTarget.h"
|
||||||
|
#include "CodeGenIntrinsics.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -412,6 +413,7 @@ class DAGISelEmitter : public TableGenBackend {
|
|||||||
private:
|
private:
|
||||||
RecordKeeper &Records;
|
RecordKeeper &Records;
|
||||||
CodeGenTarget Target;
|
CodeGenTarget Target;
|
||||||
|
std::vector<CodeGenIntrinsic> Intrinsics;
|
||||||
|
|
||||||
std::map<Record*, SDNodeInfo> SDNodes;
|
std::map<Record*, SDNodeInfo> SDNodes;
|
||||||
std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
|
std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
|
||||||
@ -448,6 +450,13 @@ public:
|
|||||||
return ComplexPatterns.find(R)->second;
|
return ComplexPatterns.find(R)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CodeGenIntrinsic &getIntrinsic(Record *R) const {
|
||||||
|
for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
|
||||||
|
if (Intrinsics[i].TheDef == R) return Intrinsics[i];
|
||||||
|
assert(0 && "Unknown intrinsic!");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
TreePattern *getPatternFragment(Record *R) const {
|
TreePattern *getPatternFragment(Record *R) const {
|
||||||
assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
|
assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
|
||||||
return PatternFragments.find(R)->second;
|
return PatternFragments.find(R)->second;
|
||||||
|
Loading…
Reference in New Issue
Block a user