+
+ // Treat neverHasSideEffects = 1 as the equivalent of hasSideEffects = 0.
+ // This flag is obsolete and will be removed.
+ if (InstInfo.neverHasSideEffects) {
+ assert(!InstInfo.hasSideEffects);
+ InstInfo.hasSideEffects_Unset = false;
+ }
+
+ // Get the primary instruction pattern.
+ const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern();
+ if (!Pattern) {
+ if (InstInfo.hasUndefFlags())
+ Revisit.push_back(&InstInfo);
+ continue;
+ }
+ InstAnalyzer PatInfo(*this);
+ PatInfo.Analyze(Pattern);
+ Errors += InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
+ }
+
+ // Second, look for single-instruction patterns defined outside the
+ // instruction.
+ for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) {
+ const PatternToMatch &PTM = *I;
+
+ // We can only infer from single-instruction patterns, otherwise we won't
+ // know which instruction should get the flags.
+ SmallVector<Record*, 8> PatInstrs;
+ getInstructionsInTree(PTM.getDstPattern(), PatInstrs);
+ if (PatInstrs.size() != 1)
+ continue;
+
+ // Get the single instruction.
+ CodeGenInstruction &InstInfo = Target.getInstruction(PatInstrs.front());
+
+ // Only infer properties from the first pattern. We'll verify the others.
+ if (InstInfo.InferredFrom)
+ continue;
+
+ InstAnalyzer PatInfo(*this);
+ PatInfo.Analyze(&PTM);
+ Errors += InferFromPattern(InstInfo, PatInfo, PTM.getSrcRecord());
+ }
+
+ if (Errors)
+ PrintFatalError("pattern conflicts");
+
+ // Revisit instructions with undefined flags and no pattern.
+ if (Target.guessInstructionProperties()) {
+ for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
+ CodeGenInstruction &InstInfo = *Revisit[i];
+ if (InstInfo.InferredFrom)
+ continue;
+ // The mayLoad and mayStore flags default to false.
+ // Conservatively assume hasSideEffects if it wasn't explicit.
+ if (InstInfo.hasSideEffects_Unset)
+ InstInfo.hasSideEffects = true;
+ }
+ return;
+ }
+
+ // Complain about any flags that are still undefined.
+ for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
+ CodeGenInstruction &InstInfo = *Revisit[i];
+ if (InstInfo.InferredFrom)
+ continue;
+ if (InstInfo.hasSideEffects_Unset)
+ PrintError(InstInfo.TheDef->getLoc(),
+ "Can't infer hasSideEffects from patterns");
+ if (InstInfo.mayStore_Unset)
+ PrintError(InstInfo.TheDef->getLoc(),
+ "Can't infer mayStore from patterns");
+ if (InstInfo.mayLoad_Unset)
+ PrintError(InstInfo.TheDef->getLoc(),
+ "Can't infer mayLoad from patterns");
+ }
+}
+
+
+/// 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");
+ }