summaryrefslogtreecommitdiff
path: root/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-24 17:08:41 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-24 17:08:41 +0000
commit91f8dc9baeb35d5812a797d733e689120e041fef (patch)
treef9d3ffbb8d9cf7e2e0d8547a774800bfcb90fe18 /utils/TableGen/CodeGenDAGPatterns.cpp
parentb5b86d263a651566cb25c0f406f75ceffb771029 (diff)
downloadllvm-91f8dc9baeb35d5812a797d733e689120e041fef.tar.gz
llvm-91f8dc9baeb35d5812a797d733e689120e041fef.tar.bz2
llvm-91f8dc9baeb35d5812a797d733e689120e041fef.tar.xz
Verify explicit instruction properties when they can be inferred.
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
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp41
1 files changed, 39 insertions, 2 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 3df6f74b21..2e4ec67d54 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -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) {