add support for referencing registers and immediates,

building the tree to represent them but not emitting 
table entries for them yet.

llvm-svn: 96617
This commit is contained in:
Chris Lattner 2010-02-18 22:03:03 +00:00
parent cd8428c41f
commit 4cfdecc52b
5 changed files with 132 additions and 36 deletions

View File

@ -203,7 +203,7 @@ GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
enum BuiltinOpcodes {
OPC_Emit,
OPC_Push,
OPC_Record,
OPC_RecordNode,
OPC_MoveChild,
OPC_MoveParent,
OPC_CheckSame,
@ -294,7 +294,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
MatchScopes.push_back(NewEntry);
continue;
}
case OPC_Record:
case OPC_RecordNode:
// Remember this node, it may end up being an operand in the pattern.
RecordedNodes.push_back(N);
continue;

View File

@ -10,6 +10,7 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@ -117,3 +118,19 @@ void CheckChainCompatibleMatcherNode::print(raw_ostream &OS,
OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n";
printNext(OS, indent);
}
void EmitIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "EmitIntegerMatcherNode " << Val << " VT=" << VT << '\n';
printNext(OS, indent);
}
void EmitRegisterMatcherNode::print(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "EmitRegisterMatcherNode ";
if (Reg)
OS << Reg->getName();
else
OS << "zero_reg";
OS << " VT=" << VT << '\n';
printNext(OS, indent);
}

View File

@ -21,6 +21,7 @@ namespace llvm {
class PatternToMatch;
class raw_ostream;
class ComplexPattern;
class Record;
MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
const CodeGenDAGPatterns &CGP);
@ -36,25 +37,31 @@ class MatcherNode {
OwningPtr<MatcherNode> Next;
public:
enum KindTy {
EmitNode,
Push, // [Push, Dest0, Dest1, Dest2, Dest3]
Record, // [Record]
MoveChild, // [MoveChild, Child#]
MoveParent, // [MoveParent]
// Stack manipulation.
Push, // Push a checking scope.
RecordNode, // Record the current node.
MoveChild, // Move current node to specified child.
MoveParent, // Move current node to parent.
CheckSame, // [CheckSame, N] Fail if not same as prev match.
// Predicate checking.
CheckSame, // Fail if not same as prev match.
CheckPatternPredicate,
CheckPredicate, // [CheckPredicate, P] Fail if predicate fails.
CheckOpcode, // [CheckOpcode, Opcode] Fail if not opcode.
CheckType, // [CheckType, MVT] Fail if not correct type.
CheckInteger, // [CheckInteger, int0,int1,int2,...int7] Fail if wrong val.
CheckCondCode, // [CheckCondCode, CondCode] Fail if not condcode.
CheckPredicate, // Fail if node predicate fails.
CheckOpcode, // Fail if not opcode.
CheckType, // Fail if not correct type.
CheckInteger, // Fail if wrong val.
CheckCondCode, // Fail if not condcode.
CheckValueType,
CheckComplexPat,
CheckAndImm,
CheckOrImm,
CheckFoldableChainNode,
CheckChainCompatible
CheckChainCompatible,
// Node creation/emisssion.
EmitInteger, // Create a TargetConstant
EmitRegister, // Create a register.
EmitNode
};
const KindTy Kind;
@ -77,23 +84,6 @@ protected:
void printNext(raw_ostream &OS, unsigned indent) const;
};
/// EmitNodeMatcherNode - This signals a successful match and generates a node.
class EmitNodeMatcherNode : public MatcherNode {
const PatternToMatch &Pattern;
public:
EmitNodeMatcherNode(const PatternToMatch &pattern)
: MatcherNode(EmitNode), Pattern(pattern) {}
const PatternToMatch &getPattern() const { return Pattern; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == EmitNode;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
/// PushMatcherNode - This pushes a failure scope on the stack and evaluates
/// 'Next'. If 'Next' fails to match, it pops its scope and attempts to
/// match 'Failure'.
@ -123,12 +113,12 @@ class RecordMatcherNode : public MatcherNode {
std::string WhatFor;
public:
RecordMatcherNode(const std::string &whatfor)
: MatcherNode(Record), WhatFor(whatfor) {}
: MatcherNode(RecordNode), WhatFor(whatfor) {}
const std::string &getWhatFor() const { return WhatFor; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == Record;
return N->getKind() == RecordNode;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
@ -388,8 +378,60 @@ public:
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
/// EmitIntegerMatcherNode - This creates a new TargetConstant.
class EmitIntegerMatcherNode : public MatcherNode {
int64_t Val;
MVT::SimpleValueType VT;
public:
EmitIntegerMatcherNode(int64_t val, MVT::SimpleValueType vt)
: MatcherNode(EmitInteger), Val(val), VT(vt) {}
int64_t getVal() const { return Val; }
MVT::SimpleValueType getVT() const { return VT; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == EmitInteger;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
/// EmitRegisterMatcherNode - This creates a new TargetConstant.
class EmitRegisterMatcherNode : public MatcherNode {
/// Reg - The def for the register that we're emitting. If this is null, then
/// this is a reference to zero_reg.
Record *Reg;
MVT::SimpleValueType VT;
public:
EmitRegisterMatcherNode(Record *reg, MVT::SimpleValueType vt)
: MatcherNode(EmitRegister), Reg(reg), VT(vt) {}
Record *getReg() const { return Reg; }
MVT::SimpleValueType getVT() const { return VT; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == EmitRegister;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
/// EmitNodeMatcherNode - This signals a successful match and generates a node.
class EmitNodeMatcherNode : public MatcherNode {
const PatternToMatch &Pattern;
public:
EmitNodeMatcherNode(const PatternToMatch &pattern)
: MatcherNode(EmitNode), Pattern(pattern) {}
const PatternToMatch &getPattern() const { return Pattern; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == EmitNode;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
} // end namespace llvm
#endif

View File

@ -125,8 +125,8 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
<< *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << "\n";
OS.PadToColumn(Indent*2) << "OPC_Emit, /*XXX*/\n\n";
return 1;
case MatcherNode::Record:
OS << "OPC_Record,";
case MatcherNode::RecordNode:
OS << "OPC_RecordNode,";
OS.PadToColumn(CommentIndent) << "// "
<< cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
return 1;
@ -212,6 +212,11 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
OS << "OPC_CheckChainCompatible, "
<< cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
return 2;
case MatcherNode::EmitInteger:
case MatcherNode::EmitRegister:
// FIXME: Implement.
return 0;
}
assert(0 && "Unreachable");
return 0;

View File

@ -397,6 +397,38 @@ void MatcherGen::EmitMatcherCode() {
void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps) {
assert(N->isLeaf() && "Must be a leaf");
if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
AddMatcherNode(new EmitIntegerMatcherNode(II->getValue(),N->getTypeNum(0)));
//ResultOps.push_back(TmpNode(TmpNo++));
return;
}
// If this is an explicit register reference, handle it.
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
if (DI->getDef()->isSubClassOf("Register")) {
AddMatcherNode(new EmitRegisterMatcherNode(DI->getDef(),
N->getTypeNum(0)));
//ResultOps.push_back(TmpNode(TmpNo++));
return;
}
if (DI->getDef()->getName() == "zero_reg") {
AddMatcherNode(new EmitRegisterMatcherNode(0, N->getTypeNum(0)));
//ResultOps.push_back(TmpNode(TmpNo++));
return;
}
#if 0
if (DI->getDef()->isSubClassOf("RegisterClass")) {
// Handle a reference to a register class. This is used
// in COPY_TO_SUBREG instructions.
// FIXME: Implement.
}
#endif
}
errs() << "unhandled leaf node: \n";
N->dump();
}