Verify explicit instruction properties when they can be inferred.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 24 Aug 2012 17:08:41 +0000 (17:08 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 24 Aug 2012 17:08:41 +0000 (17:08 +0000)
It is now allowed to explicitly set hasSideEffects, mayStore, and
mayLoad on instructions with patterns.

Verify that the patterns are consistent with the explicit flags.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162569 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenDAGPatterns.cpp

index 3df6f74b21428a70a7735800b152175218230653..2e4ec67d545abc5093f5cb3662c187f2509e0245 100644 (file)
@@ -2457,13 +2457,44 @@ private:
 
 };
 
-static void InferFromPattern(CodeGenInstruction &InstInfo,
+static bool InferFromPattern(CodeGenInstruction &InstInfo,
                              const InstAnalyzer &PatInfo,
                              Record *PatDef) {
+  bool Error = false;
+
   // Remember where InstInfo got its flags.
   if (InstInfo.hasUndefFlags())
       InstInfo.InferredFrom = PatDef;
 
+  // Check explicitly set flags for consistency.
+  if (InstInfo.hasSideEffects != PatInfo.hasSideEffects &&
+      !InstInfo.hasSideEffects_Unset) {
+    // Allow explicitly setting hasSideEffects = 1 on instructions, even when
+    // the pattern has no side effects. That could be useful for div/rem
+    // instructions that may trap.
+    if (!InstInfo.hasSideEffects) {
+      Error = true;
+      PrintError(PatDef->getLoc(), "Pattern doesn't match hasSideEffects = " +
+                 Twine(InstInfo.hasSideEffects));
+    }
+  }
+
+  if (InstInfo.mayStore != PatInfo.mayStore && !InstInfo.mayStore_Unset) {
+    Error = true;
+    PrintError(PatDef->getLoc(), "Pattern doesn't match mayStore = " +
+               Twine(InstInfo.mayStore));
+  }
+
+  if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) {
+    // Allow explicitly setting mayLoad = 1, even when the pattern has no loads.
+    // Some targets translate imediates to loads.
+    if (!InstInfo.mayLoad) {
+      Error = true;
+      PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " +
+                 Twine(InstInfo.mayLoad));
+    }
+  }
+
   // Transfer inferred flags.
   InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
   InstInfo.mayStore |= PatInfo.mayStore;
@@ -2472,6 +2503,8 @@ static void InferFromPattern(CodeGenInstruction &InstInfo,
   // These flags are silently added without any verification.
   InstInfo.isBitcast |= PatInfo.isBitcast;
   InstInfo.Operands.isVariadic |= PatInfo.isVariadic;
+
+  return Error;
 }
 
 /// hasNullFragReference - Return true if the DAG has any reference to the
@@ -2809,6 +2842,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
 
   // First try to infer flags from the primary instruction pattern, if any.
   SmallVector<CodeGenInstruction*, 8> Revisit;
+  unsigned Errors = 0;
   for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
     CodeGenInstruction &InstInfo =
       const_cast<CodeGenInstruction &>(*Instructions[i]);
@@ -2829,9 +2863,12 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
     }
     InstAnalyzer PatInfo(*this);
     PatInfo.Analyze(Pattern);
-    InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
+    Errors += InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
   }
 
+  if (Errors)
+    throw "pattern conflicts";
+
   // Revisit instructions with undefined flags and no pattern.
   if (Target.guessInstructionProperties()) {
     for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {