diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-28 03:26:49 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-28 03:26:49 +0000 |
commit | 325907d0860f8316edcc3bb00bf7b8b04497c177 (patch) | |
tree | 420a23a3b0f1f3f05e476984ac916ebce649b08d /utils/TableGen/CodeGenDAGPatterns.cpp | |
parent | 36d29bc72345d882623b001c2692b9246a19688a (diff) |
Check all patterns for missing instruction flags.
Both single-instruction and multi-instruction patterns can be checked
for missing mayLoad / mayStore, and hasSideEffects flags.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 0842c0016d..49db093f6e 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2027,6 +2027,9 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : // stores, and side effects in many cases by examining an // instruction's pattern. InferInstructionFlags(); + + // Verify that instruction flags match the patterns. + VerifyInstructionFlags(); } CodeGenDAGPatterns::~CodeGenDAGPatterns() { @@ -2405,6 +2408,7 @@ private: return OpInfo.getEnumName() == "ISD::BITCAST"; } +public: void AnalyzeNode(const TreePatternNode *N) { if (N->isLeaf()) { if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) { @@ -2937,6 +2941,73 @@ void CodeGenDAGPatterns::InferInstructionFlags() { } } + +/// Verify instruction flags against pattern node properties. +void CodeGenDAGPatterns::VerifyInstructionFlags() { + unsigned Errors = 0; + for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { + const PatternToMatch &PTM = *I; + SmallVector<Record*, 8> Instrs; + getInstructionsInTree(PTM.getDstPattern(), Instrs); + if (Instrs.empty()) + continue; + + // Count the number of instructions with each flag set. + unsigned NumSideEffects = 0; + unsigned NumStores = 0; + unsigned NumLoads = 0; + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + NumSideEffects += InstInfo.hasSideEffects; + NumStores += InstInfo.mayStore; + NumLoads += InstInfo.mayLoad; + } + + // Analyze the source pattern. + InstAnalyzer PatInfo(*this); + PatInfo.Analyze(&PTM); + + // Collect error messages. + SmallVector<std::string, 4> Msgs; + + // Check for missing flags in the output. + // Permit extra flags for now at least. + if (PatInfo.hasSideEffects && !NumSideEffects) + Msgs.push_back("pattern has side effects, but hasSideEffects isn't set"); + + // Don't verify store flags on instructions with side effects. At least for + // intrinsics, side effects implies mayStore. + if (!PatInfo.hasSideEffects && PatInfo.mayStore && !NumStores) + Msgs.push_back("pattern may store, but mayStore isn't set"); + + // Similarly, mayStore implies mayLoad on intrinsics. + if (!PatInfo.mayStore && PatInfo.mayLoad && !NumLoads) + Msgs.push_back("pattern may load, but mayLoad isn't set"); + + // Print error messages. + if (Msgs.empty()) + continue; + ++Errors; + + for (unsigned i = 0, e = Msgs.size(); i != e; ++i) + PrintError(PTM.getSrcRecord()->getLoc(), Twine(Msgs[i]) + " on the " + + (Instrs.size() == 1 ? + "instruction" : "output instructions")); + // Provide the location of the relevant instruction definitions. + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + if (Instrs[i] != PTM.getSrcRecord()) + PrintError(Instrs[i]->getLoc(), "defined here"); + const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + if (InstInfo.InferredFrom && + InstInfo.InferredFrom != InstInfo.TheDef && + InstInfo.InferredFrom != PTM.getSrcRecord()) + PrintError(InstInfo.InferredFrom->getLoc(), "inferred from patttern"); + } + } + if (Errors) + throw "Errors in DAG patterns"; +} + /// Given a pattern result with an unresolved type, see if we can find one /// instruction with an unresolved result type. Force this result type to an /// arbitrary element if it's possible types to converge results. |