X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.h;h=424f02f7ab33e83bafbcaaf81cc8ffa897797f31;hb=22bd64173981bf1251c4b3bfc684207340534ba3;hp=946dceed66c0add37d0cadc471255626fc51ca0f;hpb=6032269837c08a94b70b0e36f8e473c293ff5fd4;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 946dceed66c..424f02f7ab3 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -15,18 +15,19 @@ #ifndef CODEGEN_DAGPATTERNS_H #define CODEGEN_DAGPATTERNS_H -#include "CodeGenTarget.h" #include "CodeGenIntrinsics.h" +#include "CodeGenTarget.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include +#include "llvm/Support/ErrorHandling.h" #include -#include #include +#include +#include namespace llvm { class Record; - struct Init; + class Init; class ListInit; class DagInit; class SDNodeInfo; @@ -104,7 +105,7 @@ namespace EEVT { /// MergeInTypeInfo - This merges in type information from the specified /// argument. If 'this' changes, it returns true. If the two types are - /// contradictory (e.g. merge f32 into i32) then this throws an exception. + /// contradictory (e.g. merge f32 into i32) then this flags an error. bool MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP); bool MergeInTypeInfo(MVT::SimpleValueType InVT, TreePattern &TP) { @@ -186,8 +187,8 @@ struct SDTypeConstraint { /// ApplyTypeConstraint - Given a node in a pattern, apply this type /// constraint to the nodes operands. This returns true if it makes a - /// change, false otherwise. If a type contradiction is found, throw an - /// exception. + /// change, false otherwise. If a type contradiction is found, an error + /// is flagged. bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo, TreePattern &TP) const; }; @@ -231,7 +232,7 @@ public: /// ApplyTypeConstraints - Given a node in a pattern, apply the type /// constraints for this node to the operands of the node. This returns /// true if it makes a change, false otherwise. If a type contradiction is - /// found, throw an exception. + /// found, an error is flagged. bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const { bool MadeChange = false; for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) @@ -239,6 +240,57 @@ public: return MadeChange; } }; + +/// TreePredicateFn - This is an abstraction that represents the predicates on +/// a PatFrag node. This is a simple one-word wrapper around a pointer to +/// provide nice accessors. +class TreePredicateFn { + /// PatFragRec - This is the TreePattern for the PatFrag that we + /// originally came from. + TreePattern *PatFragRec; +public: + /// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. + TreePredicateFn(TreePattern *N); + + + TreePattern *getOrigPatFragRecord() const { return PatFragRec; } + + /// isAlwaysTrue - Return true if this is a noop predicate. + bool isAlwaysTrue() const; + + bool isImmediatePattern() const { return !getImmCode().empty(); } + + /// getImmediatePredicateCode - Return the code that evaluates this pattern if + /// this is an immediate predicate. It is an error to call this on a + /// non-immediate pattern. + std::string getImmediatePredicateCode() const { + std::string Result = getImmCode(); + assert(!Result.empty() && "Isn't an immediate pattern!"); + return Result; + } + + + bool operator==(const TreePredicateFn &RHS) const { + return PatFragRec == RHS.PatFragRec; + } + + bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); } + + /// Return the name to use in the generated code to reference this, this is + /// "Predicate_foo" if from a pattern fragment "foo". + std::string getFnName() const; + + /// getCodeToRunOnSDNode - Return the code for the function body that + /// evaluates this predicate. The argument is expected to be in "Node", + /// not N. This handles casting and conversion to a concrete node type as + /// appropriate. + std::string getCodeToRunOnSDNode() const; + +private: + std::string getPredCode() const; + std::string getImmCode() const; +}; + /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped /// patterns), and as such should be ref counted. We currently just leak all @@ -263,7 +315,7 @@ class TreePatternNode { /// 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; + 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. @@ -323,14 +375,18 @@ public: return false; } - const std::vector &getPredicateFns() const {return PredicateFns;} + bool hasAnyPredicate() const { return !PredicateFns.empty(); } + + const std::vector &getPredicateFns() const { + return PredicateFns; + } void clearPredicateFns() { PredicateFns.clear(); } - void setPredicateFns(const std::vector &Fns) { + 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!"); + void addPredicateFn(const TreePredicateFn &Fn) { + assert(!Fn.isAlwaysTrue() && "Empty predicate string!"); if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) == PredicateFns.end()) PredicateFns.push_back(Fn); @@ -390,13 +446,12 @@ public: // Higher level manipulation routines. /// 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. + /// change, false otherwise. If a type contradiction is found, flag an error. bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters); /// UpdateNodeType - Set the node type of N to VT if VT contains - /// information. If N already contains a conflicting type, then throw an - /// exception. This returns true if any information was updated. + /// information. If N already contains a conflicting type, then flag an + /// error. This returns true if any information was updated. /// bool UpdateNodeType(unsigned ResNo, const EEVT::TypeSet &InTy, TreePattern &TP) { @@ -458,6 +513,10 @@ class TreePattern { /// isInputPattern - True if this is an input pattern, something to match. /// False if this is an output pattern, something to emit. bool isInputPattern; + + /// hasError - True if the currently processed nodes have unresolvable types + /// or other non-fatal errors + bool HasError; public: /// TreePattern constructor - Parse the specified DagInits into the @@ -509,13 +568,19 @@ public: /// InferAllTypes - Infer/propagate as many types throughout the expression /// patterns as possible. Return true if all types are inferred, false - /// otherwise. Throw an exception if a type contradiction is found. + /// otherwise. Bail out if a type contradiction is found. bool InferAllTypes(const StringMap > *NamedTypes=0); - /// error - Throw an exception, prefixing it with information about this - /// pattern. - void error(const std::string &Msg) const; + /// error - If this is the first error in the current resolution step, + /// print it and set the error flag. Otherwise, continue silently. + void error(const std::string &Msg); + bool hasError() const { + return HasError; + } + void resetError() { + HasError = false; + } void print(raw_ostream &OS) const; void dump() const; @@ -526,8 +591,8 @@ private: void ComputeNamedNodes(TreePatternNode *N); }; -/// DAGDefaultOperand - One of these is created for each PredicateOperand -/// or OptionalDefOperand that has a set ExecuteAlways / DefaultOps field. +/// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps +/// that has a set ExecuteAlways / DefaultOps field. struct DAGDefaultOperand { std::vector DefaultOps; }; @@ -546,7 +611,7 @@ public: : Pattern(TP), Results(results), Operands(operands), ImpResults(impresults), ResultPattern(0) {} - const TreePattern *getPattern() const { return Pattern; } + TreePattern *getPattern() const { return Pattern; } unsigned getNumResults() const { return Results.size(); } unsigned getNumOperands() const { return Operands.size(); } unsigned getNumImpResults() const { return ImpResults.size(); } @@ -605,23 +670,18 @@ public: unsigned getPatternComplexity(const CodeGenDAGPatterns &CGP) 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, RecordPtrCmp> SDNodeXForms; - std::map ComplexPatterns; - std::map PatternFragments; - std::map DefaultOperands; - std::map Instructions; + std::map SDNodes; + std::map, LessRecordByID> SDNodeXForms; + std::map ComplexPatterns; + std::map PatternFragments; + std::map DefaultOperands; + std::map Instructions; // Specific SDNode definitions: Record *intrinsic_void_sdnode; @@ -652,7 +712,7 @@ public: return SDNodeXForms.find(R)->second; } - typedef std::map::const_iterator + typedef std::map::const_iterator nx_iterator; nx_iterator nx_begin() const { return SDNodeXForms.begin(); } nx_iterator nx_end() const { return SDNodeXForms.end(); } @@ -668,8 +728,7 @@ public: 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(); + llvm_unreachable("Unknown intrinsic!"); } const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const { @@ -677,8 +736,7 @@ public: return Intrinsics[IID-1]; if (IID-Intrinsics.size()-1 < TgtIntrinsics.size()) return TgtIntrinsics[IID-Intrinsics.size()-1]; - assert(0 && "Bad intrinsic ID!"); - abort(); + llvm_unreachable("Bad intrinsic ID!"); } unsigned getIntrinsicID(Record *R) const { @@ -686,8 +744,7 @@ public: 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(); + llvm_unreachable("Unknown intrinsic!"); } const DAGDefaultOperand &getDefaultOperand(Record *R) const { @@ -705,7 +762,7 @@ public: return PatternFragments.find(R)->second; } - typedef std::map::const_iterator + typedef std::map::const_iterator pf_iterator; pf_iterator pf_begin() const { return PatternFragments.begin(); } pf_iterator pf_end() const { return PatternFragments.end(); } @@ -744,8 +801,9 @@ private: void ParsePatterns(); void InferInstructionFlags(); void GenerateVariants(); + void VerifyInstructionFlags(); - void AddPatternToMatch(const TreePattern *Pattern, const PatternToMatch &PTM); + void AddPatternToMatch(TreePattern *Pattern, const PatternToMatch &PTM); void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, std::map &InstInputs,