Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
Show First 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | private: | ||||
// Result Code Generation. | // Result Code Generation. | ||||
unsigned getNamedArgumentSlot(StringRef Name) { | unsigned getNamedArgumentSlot(StringRef Name) { | ||||
unsigned VarMapEntry = VariableMap[Name]; | unsigned VarMapEntry = VariableMap[Name]; | ||||
assert(VarMapEntry != 0 && | assert(VarMapEntry != 0 && | ||||
"Variable referenced but not defined and not caught earlier!"); | "Variable referenced but not defined and not caught earlier!"); | ||||
return VarMapEntry-1; | return VarMapEntry-1; | ||||
} | } | ||||
/// GetInstPatternNode - Get the pattern for an instruction. | |||||
const TreePatternNode *GetInstPatternNode(const DAGInstruction &Ins, | |||||
const TreePatternNode *N); | |||||
void EmitResultOperand(const TreePatternNode *N, | void EmitResultOperand(const TreePatternNode *N, | ||||
SmallVectorImpl<unsigned> &ResultOps); | SmallVectorImpl<unsigned> &ResultOps); | ||||
void EmitResultOfNamedOperand(const TreePatternNode *N, | void EmitResultOfNamedOperand(const TreePatternNode *N, | ||||
SmallVectorImpl<unsigned> &ResultOps); | SmallVectorImpl<unsigned> &ResultOps); | ||||
void EmitResultLeafAsOperand(const TreePatternNode *N, | void EmitResultLeafAsOperand(const TreePatternNode *N, | ||||
SmallVectorImpl<unsigned> &ResultOps); | SmallVectorImpl<unsigned> &ResultOps); | ||||
void EmitResultInstructionAsOperand(const TreePatternNode *N, | void EmitResultInstructionAsOperand(const TreePatternNode *N, | ||||
SmallVectorImpl<unsigned> &ResultOps); | SmallVectorImpl<unsigned> &ResultOps); | ||||
▲ Show 20 Lines • Show All 511 Lines • ▼ Show 20 Lines | if (Def->isSubClassOf("SubRegIndex")) { | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
errs() << "unhandled leaf node: \n"; | errs() << "unhandled leaf node: \n"; | ||||
N->dump(); | N->dump(); | ||||
} | } | ||||
/// GetInstPatternNode - Get the pattern for an instruction. | |||||
/// | |||||
const TreePatternNode *MatcherGen:: | |||||
GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) { | |||||
const TreePattern *InstPat = Inst.getPattern(); | |||||
// FIXME2?: Assume actual pattern comes before "implicit". | |||||
TreePatternNode *InstPatNode; | |||||
if (InstPat) | |||||
InstPatNode = InstPat->getTree(0).get(); | |||||
else if (/*isRoot*/ N == Pattern.getDstPattern()) | |||||
InstPatNode = Pattern.getSrcPattern(); | |||||
else | |||||
return nullptr; | |||||
if (InstPatNode && !InstPatNode->isLeaf() && | |||||
InstPatNode->getOperator()->getName() == "set") | |||||
InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1); | |||||
return InstPatNode; | |||||
} | |||||
static bool | static bool | ||||
mayInstNodeLoadOrStore(const TreePatternNode *N, | mayInstNodeLoadOrStore(const TreePatternNode *N, | ||||
const CodeGenDAGPatterns &CGP) { | const CodeGenDAGPatterns &CGP) { | ||||
Record *Op = N->getOperator(); | Record *Op = N->getOperator(); | ||||
const CodeGenTarget &CGT = CGP.getTargetInfo(); | const CodeGenTarget &CGT = CGP.getTargetInfo(); | ||||
CodeGenInstruction &II = CGT.getInstruction(Op); | CodeGenInstruction &II = CGT.getInstruction(Op); | ||||
return II.mayLoad || II.mayStore; | return II.mayLoad || II.mayStore; | ||||
} | } | ||||
Show All 21 Lines | |||||
void MatcherGen:: | void MatcherGen:: | ||||
EmitResultInstructionAsOperand(const TreePatternNode *N, | EmitResultInstructionAsOperand(const TreePatternNode *N, | ||||
SmallVectorImpl<unsigned> &OutputOps) { | SmallVectorImpl<unsigned> &OutputOps) { | ||||
Record *Op = N->getOperator(); | Record *Op = N->getOperator(); | ||||
const CodeGenTarget &CGT = CGP.getTargetInfo(); | const CodeGenTarget &CGT = CGP.getTargetInfo(); | ||||
CodeGenInstruction &II = CGT.getInstruction(Op); | CodeGenInstruction &II = CGT.getInstruction(Op); | ||||
const DAGInstruction &Inst = CGP.getInstruction(Op); | const DAGInstruction &Inst = CGP.getInstruction(Op); | ||||
// If we can, get the pattern for the instruction we're generating. We derive | |||||
// a variety of information from this pattern, such as whether it has a chain. | |||||
// | |||||
// FIXME2: This is extremely dubious for several reasons, not the least of | |||||
// which it gives special status to instructions with patterns that Pat<> | |||||
// nodes can't duplicate. | |||||
const TreePatternNode *InstPatNode = GetInstPatternNode(Inst, N); | |||||
// NodeHasChain - Whether the instruction node we're creating takes chains. | |||||
bool NodeHasChain = InstPatNode && | |||||
InstPatNode->TreeHasProperty(SDNPHasChain, CGP); | |||||
// Instructions which load and store from memory should have a chain, | |||||
// regardless of whether they happen to have an internal pattern saying so. | |||||
if (Pattern.getSrcPattern()->TreeHasProperty(SDNPHasChain, CGP) && | |||||
(II.hasCtrlDep || II.mayLoad || II.mayStore || II.canFoldAsLoad || | |||||
II.hasSideEffects)) | |||||
NodeHasChain = true; | |||||
bool isRoot = N == Pattern.getDstPattern(); | bool isRoot = N == Pattern.getDstPattern(); | ||||
// TreeHasOutGlue - True if this tree has glue. | // TreeHasOutGlue - True if this tree has glue. | ||||
bool TreeHasInGlue = false, TreeHasOutGlue = false; | bool TreeHasInGlue = false, TreeHasOutGlue = false; | ||||
if (isRoot) { | if (isRoot) { | ||||
const TreePatternNode *SrcPat = Pattern.getSrcPattern(); | const TreePatternNode *SrcPat = Pattern.getSrcPattern(); | ||||
TreeHasInGlue = SrcPat->TreeHasProperty(SDNPOptInGlue, CGP) || | TreeHasInGlue = SrcPat->TreeHasProperty(SDNPOptInGlue, CGP) || | ||||
SrcPat->TreeHasProperty(SDNPInGlue, CGP); | SrcPat->TreeHasProperty(SDNPInGlue, CGP); | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | unsigned NumNodesThatLoadOrStore = | ||||
numNodesThatMayLoadOrStore(Pattern.getDstPattern(), CGP); | numNodesThatMayLoadOrStore(Pattern.getDstPattern(), CGP); | ||||
bool NodeIsUniqueLoadOrStore = mayInstNodeLoadOrStore(N, CGP) && | bool NodeIsUniqueLoadOrStore = mayInstNodeLoadOrStore(N, CGP) && | ||||
NumNodesThatLoadOrStore == 1; | NumNodesThatLoadOrStore == 1; | ||||
NodeHasMemRefs = | NodeHasMemRefs = | ||||
NodeIsUniqueLoadOrStore || (isRoot && (mayInstNodeLoadOrStore(N, CGP) || | NodeIsUniqueLoadOrStore || (isRoot && (mayInstNodeLoadOrStore(N, CGP) || | ||||
NumNodesThatLoadOrStore != 1)); | NumNodesThatLoadOrStore != 1)); | ||||
} | } | ||||
// Determine whether we need to attach a chain to this node. | |||||
bool NodeHasChain = false; | |||||
if (Pattern.getSrcPattern()->TreeHasProperty(SDNPHasChain, CGP)) { | |||||
// For some instructions, we were able to infer from the pattern whether | |||||
// they should have a chain. Otherwise, attach the chain to the root. | |||||
// | |||||
// FIXME2: This is extremely dubious for several reasons, not the least of | |||||
// which it gives special status to instructions with patterns that Pat<> | |||||
// nodes can't duplicate. | |||||
if (II.hasChain_Inferred) | |||||
NodeHasChain = II.hasChain; | |||||
else | |||||
NodeHasChain = isRoot; | |||||
// Instructions which load and store from memory should have a chain, | |||||
// regardless of whether they happen to have a pattern saying so. | |||||
if (II.hasCtrlDep || II.mayLoad || II.mayStore || II.canFoldAsLoad || | |||||
II.hasSideEffects) | |||||
NodeHasChain = true; | |||||
} | |||||
assert((!ResultVTs.empty() || TreeHasOutGlue || NodeHasChain) && | assert((!ResultVTs.empty() || TreeHasOutGlue || NodeHasChain) && | ||||
"Node has no result"); | "Node has no result"); | ||||
AddMatcher(new EmitNodeMatcher(II.Namespace.str()+"::"+II.TheDef->getName().str(), | AddMatcher(new EmitNodeMatcher(II.Namespace.str()+"::"+II.TheDef->getName().str(), | ||||
ResultVTs, InstOps, | ResultVTs, InstOps, | ||||
NodeHasChain, TreeHasInGlue, TreeHasOutGlue, | NodeHasChain, TreeHasInGlue, TreeHasOutGlue, | ||||
NodeHasMemRefs, NumFixedArityOperands, | NodeHasMemRefs, NumFixedArityOperands, | ||||
NextRecordedOperandNo)); | NextRecordedOperandNo)); | ||||
▲ Show 20 Lines • Show All 115 Lines • Show Last 20 Lines |