#ifndef CODEGEN_DAGPATTERNS_H
#define CODEGEN_DAGPATTERNS_H
-#include "TableGenBackend.h"
+#include <set>
+#include <algorithm>
+#include <vector>
+
#include "CodeGenTarget.h"
#include "CodeGenIntrinsics.h"
class CodeGenDAGPatterns;
class ComplexPattern;
-/// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType
-/// that we use as lattice values during type inferrence.
-namespace MVT {
+/// EMVT::DAGISelGenValueType - These are some extended forms of
+/// MVT::SimpleValueType that we use as lattice values during type inference.
+namespace EMVT {
enum DAGISelGenValueType {
isFP = MVT::LAST_VALUETYPE,
isInt,
isUnknown
};
-
+
/// isExtIntegerVT - Return true if the specified extended value type vector
/// contains isInt or an integer value type.
bool isExtIntegerInVTs(const std::vector<unsigned char> &EVTs);
bool isExtFloatingPointInVTs(const std::vector<unsigned char> &EVTs);
}
+/// Set type used to track multiply used variables in patterns
+typedef std::set<std::string> MultipleUseVarSet;
+
/// SDTypeConstraint - This is a discriminated union of constraints,
/// corresponding to the SDTypeConstraint tablegen class in Target.td.
struct SDTypeConstraint {
unsigned OperandNo; // The operand # this constraint applies to.
enum {
SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisSameAs,
- SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisIntVectorOfSameSize
+ SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisIntVectorOfSameSize,
+ SDTCisEltOfVec
} ConstraintType;
union { // The discriminated union.
struct {
- MVT::ValueType VT;
+ unsigned char VT;
} SDTCisVT_Info;
struct {
unsigned OtherOperandNum;
struct {
unsigned OtherOperandNum;
} SDTCisIntVectorOfSameSize_Info;
+ struct {
+ unsigned OtherOperandNum;
+ } SDTCisEltOfVec_Info;
} x;
/// ApplyTypeConstraint - Given a node in a pattern, apply this type
/// patterns), and as such should be ref counted. We currently just leak all
/// TreePatternNode objects!
class TreePatternNode {
- /// The inferred type for this node, or MVT::isUnknown if it hasn't
+ /// The inferred type for this node, or EMVT::isUnknown if it hasn't
/// been determined yet.
std::vector<unsigned char> Types;
///
std::string Name;
- /// PredicateFn - The predicate function to execute on this node to check
- /// for a match. If this string is empty, no predicate is involved.
- std::string PredicateFn;
+ /// PredicateFns - The predicate functions to execute on this node to check
+ /// for a match. If this list is empty, no predicate is involved.
+ std::vector<std::string> PredicateFns;
/// TransformFn - The transformation function to execute on this node before
/// it can be substituted into the resulting instruction on a pattern match.
public:
TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch)
: Types(), Operator(Op), Val(0), TransformFn(0),
- Children(Ch) { Types.push_back(MVT::isUnknown); }
+ Children(Ch) { Types.push_back(EMVT::isUnknown); }
TreePatternNode(Init *val) // leaf ctor
: Types(), Operator(0), Val(val), TransformFn(0) {
- Types.push_back(MVT::isUnknown);
+ Types.push_back(EMVT::isUnknown);
}
~TreePatternNode();
bool isLeaf() const { return Val != 0; }
bool hasTypeSet() const {
- return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR);
+ return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR) ||
+ (Types[0] == MVT::iPTRAny);
}
bool isTypeCompletelyUnknown() const {
- return Types[0] == MVT::isUnknown;
+ return Types[0] == EMVT::isUnknown;
}
bool isTypeDynamicallyResolved() const {
- return Types[0] == MVT::iPTR;
+ return (Types[0] == MVT::iPTR) || (Types[0] == MVT::iPTRAny);
}
- MVT::ValueType getTypeNum(unsigned Num) const {
+ MVT::SimpleValueType getTypeNum(unsigned Num) const {
assert(hasTypeSet() && "Doesn't have a type yet!");
assert(Types.size() > Num && "Type num out of range!");
- return (MVT::ValueType)Types[Num];
+ return (MVT::SimpleValueType)Types[Num];
}
unsigned char getExtTypeNum(unsigned Num) const {
assert(Types.size() > Num && "Extended type num out of range!");
}
const std::vector<unsigned char> &getExtTypes() const { return Types; }
void setTypes(const std::vector<unsigned char> &T) { Types = T; }
- void removeTypes() { Types = std::vector<unsigned char>(1,MVT::isUnknown); }
+ void removeTypes() { Types = std::vector<unsigned char>(1, EMVT::isUnknown); }
Init *getLeafValue() const { assert(isLeaf()); return Val; }
Record *getOperator() const { assert(!isLeaf()); return Operator; }
Children[i] = N;
}
- const std::string &getPredicateFn() const { return PredicateFn; }
- void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; }
+ const std::vector<std::string> &getPredicateFns() const { return PredicateFns; }
+ void clearPredicateFns() { PredicateFns.clear(); }
+ void setPredicateFns(const std::vector<std::string> &Fns) {
+ assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
+ PredicateFns = Fns;
+ }
+ void addPredicateFn(const std::string &Fn) {
+ assert(!Fn.empty() && "Empty predicate string!");
+ if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
+ PredicateFns.end())
+ PredicateFns.push_back(Fn);
+ }
Record *getTransformFn() const { return TransformFn; }
void setTransformFn(Record *Fn) { TransformFn = Fn; }
/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
/// CodeGenIntrinsic information for it, otherwise return a null pointer.
const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+
+ /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
+ /// marked isCommutative.
+ bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
void print(std::ostream &OS) const;
void dump() const;
/// the specified node. For this comparison, all of the state of the node
/// is considered, except for the assigned name. Nodes with differing names
/// that are otherwise identical are considered isomorphic.
- bool isIsomorphicTo(const TreePatternNode *N) const;
+ bool isIsomorphicTo(const TreePatternNode *N,
+ const MultipleUseVarSet &DepVars) const;
/// SubstituteFormalArguments - Replace the formal arguments in this tree
/// with actual values specified by ArgMap.
/// PatFrag references.
TreePatternNode *InlinePatternFragments(TreePattern &TP);
- /// ApplyTypeConstraints - Apply all of the type constraints relevent to
+ /// ApplyTypeConstraints - Apply all of the type constraints relevant to
/// this node and its children in the tree. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, throw an
/// exception.
/// canPatternMatch - If it is impossible for this pattern to match on this
/// target, fill in Reason and return false. Otherwise, return true.
- bool canPatternMatch(std::string &Reason, CodeGenDAGPatterns &CDP);
+ bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
};
TreePatternNode *getDstPattern() const { return DstPattern; }
const std::vector<Record*> &getDstRegs() const { return Dstregs; }
unsigned getAddedComplexity() const { return AddedComplexity; }
+
+ std::string getPredicateCheck() const;
};
CodeGenDAGPatterns(RecordKeeper &R);
~CodeGenDAGPatterns();
+ CodeGenTarget &getTargetInfo() { return Target; }
const CodeGenTarget &getTargetInfo() const { return Target; }
Record *getSDNodeNamed(const std::string &Name) const;
void ParseDefaultOperands();
void ParseInstructions();
void ParsePatterns();
+ void InferInstructionFlags();
void GenerateVariants();
void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,