X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.h;h=398764b30a0973281e93f45d8dd3f0f4a17cb28f;hb=2214dc07649d36e47d11914e1ffc7c56eb40ad73;hp=6000e551ec7c288e1482d0d587d5050701e4b416;hpb=327d0651f8c3b1480d8fc1f4d96e07a1452eaa8c;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 6000e551ec7..398764b30a0 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -16,8 +16,9 @@ #define CODEGEN_DAGPATTERNS_H #include +#include +#include -#include "TableGenBackend.h" #include "CodeGenTarget.h" #include "CodeGenIntrinsics.h" @@ -32,22 +33,27 @@ namespace llvm { 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 { +/// EEVT::DAGISelGenValueType - These are some extended forms of +/// MVT::SimpleValueType that we use as lattice values during type inference. +/// The existing MVT iAny, fAny and vAny types suffice to represent +/// arbitrary integer, floating-point, and vector types, so only an unknown +/// value is needed. +namespace EEVT { enum DAGISelGenValueType { - isFP = MVT::LAST_VALUETYPE, - isInt, - isUnknown + isUnknown = MVT::LAST_VALUETYPE }; - - /// isExtIntegerVT - Return true if the specified extended value type vector - /// contains isInt or an integer value type. + + /// isExtIntegerInVTs - Return true if the specified extended value type + /// vector contains iAny or an integer value type. bool isExtIntegerInVTs(const std::vector &EVTs); - /// isExtFloatingPointVT - Return true if the specified extended value type - /// vector contains isFP or a FP value type. + /// isExtFloatingPointInVTs - Return true if the specified extended value + /// type vector contains fAny or a FP value type. bool isExtFloatingPointInVTs(const std::vector &EVTs); + + /// isExtVectorinVTs - Return true if the specified extended value type + /// vector contains vAny or a vector value type. + bool isExtVectorInVTs(const std::vector &EVTs); } /// Set type used to track multiply used variables in patterns @@ -60,14 +66,13 @@ struct SDTypeConstraint { unsigned OperandNo; // The operand # this constraint applies to. enum { - SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisSameAs, - SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisIntVectorOfSameSize, - SDTCisEltOfVec + SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, + SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec } ConstraintType; union { // The discriminated union. struct { - MVT::ValueType VT; + unsigned char VT; } SDTCisVT_Info; struct { unsigned OtherOperandNum; @@ -78,9 +83,6 @@ struct SDTypeConstraint { struct { unsigned BigOperandNum; } SDTCisOpSmallerThanOp_Info; - struct { - unsigned OtherOperandNum; - } SDTCisIntVectorOfSameSize_Info; struct { unsigned OtherOperandNum; } SDTCisEltOfVec_Info; @@ -143,8 +145,9 @@ public: /// 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 - /// been determined yet. + /// The inferred type for this node, or EEVT::isUnknown if it hasn't + /// been determined yet. This is a std::vector because during inference + /// there may be multiple possible types. std::vector Types; /// Operator - The Record for the operator if this is an interior node (not @@ -159,9 +162,9 @@ class TreePatternNode { /// 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 PredicateFns; /// TransformFn - The transformation function to execute on this node before /// it can be substituted into the resulting instruction on a pattern match. @@ -171,10 +174,10 @@ class TreePatternNode { public: TreePatternNode(Record *Op, const std::vector &Ch) : Types(), Operator(Op), Val(0), TransformFn(0), - Children(Ch) { Types.push_back(MVT::isUnknown); } + Children(Ch) { Types.push_back(EEVT::isUnknown); } TreePatternNode(Init *val) // leaf ctor : Types(), Operator(0), Val(val), TransformFn(0) { - Types.push_back(MVT::isUnknown); + Types.push_back(EEVT::isUnknown); } ~TreePatternNode(); @@ -183,18 +186,19 @@ public: 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] == EEVT::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!"); @@ -202,7 +206,7 @@ public: } const std::vector &getExtTypes() const { return Types; } void setTypes(const std::vector &T) { Types = T; } - void removeTypes() { Types = std::vector(1,MVT::isUnknown); } + void removeTypes() { Types = std::vector(1, EEVT::isUnknown); } Init *getLeafValue() const { assert(isLeaf()); return Val; } Record *getOperator() const { assert(!isLeaf()); return Operator; } @@ -213,8 +217,18 @@ public: Children[i] = N; } - const std::string &getPredicateFn() const { return PredicateFn; } - void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; } + const std::vector &getPredicateFns() const { return PredicateFns; } + void clearPredicateFns() { PredicateFns.clear(); } + void setPredicateFns(const std::vector &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; } @@ -222,8 +236,12 @@ public: /// 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 print(raw_ostream &OS) const; void dump() const; public: // Higher level manipulation routines. @@ -249,7 +267,7 @@ public: // Higher level manipulation routines. /// 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. @@ -277,7 +295,7 @@ public: // Higher level manipulation routines. /// 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); }; @@ -349,7 +367,7 @@ public: } /// InferAllTypes - Infer/propagate as many types throughout the expression - /// patterns as possible. Return true if all types are infered, false + /// patterns as possible. Return true if all types are inferred, false /// otherwise. Throw an exception if a type contradiction is found. bool InferAllTypes(); @@ -357,7 +375,7 @@ public: /// pattern. void error(const std::string &Msg) const; - void print(std::ostream &OS) const; + void print(raw_ostream &OS) const; void dump() const; private: @@ -440,20 +458,27 @@ struct PatternToMatch { TreePatternNode *getDstPattern() const { return DstPattern; } const std::vector &getDstRegs() const { return Dstregs; } unsigned getAddedComplexity() const { return AddedComplexity; } + + std::string getPredicateCheck() const; }; +// Deterministic comparison of Record*. +struct RecordPtrCmp { + bool operator()(const Record *LHS, const Record *RHS) const; +}; class CodeGenDAGPatterns { RecordKeeper &Records; CodeGenTarget Target; std::vector Intrinsics; + std::vector TgtIntrinsics; - std::map SDNodes; - std::map > SDNodeXForms; - std::map ComplexPatterns; - std::map PatternFragments; - std::map DefaultOperands; - std::map Instructions; + std::map SDNodes; + std::map, RecordPtrCmp> SDNodeXForms; + std::map ComplexPatterns; + std::map PatternFragments; + std::map DefaultOperands; + std::map Instructions; // Specific SDNode definitions: Record *intrinsic_void_sdnode; @@ -467,6 +492,7 @@ public: CodeGenDAGPatterns(RecordKeeper &R); ~CodeGenDAGPatterns(); + CodeGenTarget &getTargetInfo() { return Target; } const CodeGenTarget &getTargetInfo() const { return Target; } Record *getSDNodeNamed(const std::string &Name) const; @@ -483,7 +509,8 @@ public: return SDNodeXForms.find(R)->second; } - typedef std::map::const_iterator nx_iterator; + typedef std::map::const_iterator + nx_iterator; nx_iterator nx_begin() const { return SDNodeXForms.begin(); } nx_iterator nx_end() const { return SDNodeXForms.end(); } @@ -496,18 +523,26 @@ public: const CodeGenIntrinsic &getIntrinsic(Record *R) const { for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i) if (Intrinsics[i].TheDef == R) return Intrinsics[i]; + for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i) + if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i]; assert(0 && "Unknown intrinsic!"); abort(); } const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const { - assert(IID-1 < Intrinsics.size() && "Bad intrinsic ID!"); - return Intrinsics[IID-1]; + if (IID-1 < Intrinsics.size()) + return Intrinsics[IID-1]; + if (IID-Intrinsics.size()-1 < TgtIntrinsics.size()) + return TgtIntrinsics[IID-Intrinsics.size()-1]; + assert(0 && "Bad intrinsic ID!"); + abort(); } unsigned getIntrinsicID(Record *R) const { for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i) if (Intrinsics[i].TheDef == R) return i; + for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i) + if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size(); assert(0 && "Unknown intrinsic!"); abort(); } @@ -522,7 +557,8 @@ public: assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); return PatternFragments.find(R)->second; } - typedef std::map::const_iterator pf_iterator; + typedef std::map::const_iterator + pf_iterator; pf_iterator pf_begin() const { return PatternFragments.begin(); } pf_iterator pf_end() const { return PatternFragments.end(); } @@ -548,6 +584,8 @@ public: return intrinsic_wo_chain_sdnode; } + bool hasTargetIntrinsics() { return !TgtIntrinsics.empty(); } + private: void ParseNodeInfo(); void ParseNodeTransforms(); @@ -556,6 +594,7 @@ private: void ParseDefaultOperands(); void ParseInstructions(); void ParsePatterns(); + void InferInstructionFlags(); void GenerateVariants(); void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,