aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp174
1 files changed, 82 insertions, 92 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 34f8a34e7a..3df6f74b21 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2367,36 +2367,25 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
class InstAnalyzer {
const CodeGenDAGPatterns &CDP;
- bool &mayStore;
- bool &mayLoad;
- bool &IsBitcast;
- bool &HasSideEffects;
- bool &IsVariadic;
public:
- InstAnalyzer(const CodeGenDAGPatterns &cdp,
- bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv)
- : CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc),
- HasSideEffects(hse), IsVariadic(isv) {
- }
-
- /// Analyze - Analyze the specified instruction, returning true if the
- /// instruction had a pattern.
- bool Analyze(Record *InstRecord) {
- const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
- if (Pattern == 0) {
- HasSideEffects = 1;
- return false; // No pattern.
- }
+ bool hasSideEffects;
+ bool mayStore;
+ bool mayLoad;
+ bool isBitcast;
+ bool isVariadic;
- // FIXME: Assume only the first tree is the pattern. The others are clobber
- // nodes.
- AnalyzeNode(Pattern->getTree(0));
- return true;
+ InstAnalyzer(const CodeGenDAGPatterns &cdp)
+ : CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false),
+ isBitcast(false), isVariadic(false) {}
+
+ void Analyze(const TreePattern *Pat) {
+ // Assume only the first tree is the pattern. The others are clobber nodes.
+ AnalyzeNode(Pat->getTree(0));
}
private:
bool IsNodeBitcast(const TreePatternNode *N) const {
- if (HasSideEffects || mayLoad || mayStore || IsVariadic)
+ if (hasSideEffects || mayLoad || mayStore || isVariadic)
return false;
if (N->getNumChildren() != 2)
@@ -2427,7 +2416,7 @@ private:
const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
if (CP.hasProperty(SDNPMayStore)) mayStore = true;
if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
- if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+ if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true;
}
}
return;
@@ -2439,7 +2428,7 @@ private:
// Ignore set nodes, which are not SDNodes.
if (N->getOperator()->getName() == "set") {
- IsBitcast = IsNodeBitcast(N);
+ isBitcast = IsNodeBitcast(N);
return;
}
@@ -2449,8 +2438,8 @@ private:
// Notice properties of the node.
if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
- if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
- if (OpInfo.hasProperty(SDNPVariadic)) IsVariadic = true;
+ if (OpInfo.hasProperty(SDNPSideEffect)) hasSideEffects = true;
+ if (OpInfo.hasProperty(SDNPVariadic)) isVariadic = true;
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
// If this is an intrinsic, analyze it.
@@ -2462,62 +2451,27 @@ private:
if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
// WriteMem intrinsics can have other strange effects.
- HasSideEffects = true;
+ hasSideEffects = true;
}
}
};
-static void InferFromPattern(const CodeGenInstruction &Inst,
- bool &MayStore, bool &MayLoad,
- bool &IsBitcast,
- bool &HasSideEffects, bool &IsVariadic,
- const CodeGenDAGPatterns &CDP) {
- MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false;
-
- bool HadPattern =
- InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic)
- .Analyze(Inst.TheDef);
-
- // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
- if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
- // If we decided that this is a store from the pattern, then the .td file
- // entry is redundant.
- if (MayStore)
- PrintWarning(Inst.TheDef->getLoc(),
- "mayStore flag explicitly set on "
- "instruction, but flag already inferred from pattern.");
- MayStore = true;
- }
-
- if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it.
- // If we decided that this is a load from the pattern, then the .td file
- // entry is redundant.
- if (MayLoad)
- PrintWarning(Inst.TheDef->getLoc(),
- "mayLoad flag explicitly set on "
- "instruction, but flag already inferred from pattern.");
- MayLoad = true;
- }
+static void InferFromPattern(CodeGenInstruction &InstInfo,
+ const InstAnalyzer &PatInfo,
+ Record *PatDef) {
+ // Remember where InstInfo got its flags.
+ if (InstInfo.hasUndefFlags())
+ InstInfo.InferredFrom = PatDef;
- if (Inst.neverHasSideEffects) {
- if (HadPattern)
- PrintWarning(Inst.TheDef->getLoc(),
- "neverHasSideEffects flag explicitly set on "
- "instruction, but flag already inferred from pattern.");
- HasSideEffects = false;
- }
+ // Transfer inferred flags.
+ InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
+ InstInfo.mayStore |= PatInfo.mayStore;
+ InstInfo.mayLoad |= PatInfo.mayLoad;
- if (Inst.hasSideEffects) {
- if (HasSideEffects)
- PrintWarning(Inst.TheDef->getLoc(),
- "hasSideEffects flag explicitly set on "
- "instruction, but flag already inferred from pattern.");
- HasSideEffects = true;
- }
-
- if (Inst.Operands.isVariadic)
- IsVariadic = true; // Can warn if we want.
+ // These flags are silently added without any verification.
+ InstInfo.isBitcast |= PatInfo.isBitcast;
+ InstInfo.Operands.isVariadic |= PatInfo.isVariadic;
}
/// hasNullFragReference - Return true if the DAG has any reference to the
@@ -2852,24 +2806,60 @@ void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern,
void CodeGenDAGPatterns::InferInstructionFlags() {
const std::vector<const CodeGenInstruction*> &Instructions =
Target.getInstructionsByEnumValue();
+
+ // First try to infer flags from the primary instruction pattern, if any.
+ SmallVector<CodeGenInstruction*, 8> Revisit;
for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
CodeGenInstruction &InstInfo =
const_cast<CodeGenInstruction &>(*Instructions[i]);
- // Determine properties of the instruction from its pattern.
- bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic;
- InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast,
- HasSideEffects, IsVariadic, *this);
- InstInfo.mayStore = MayStore;
- InstInfo.mayLoad = MayLoad;
- InstInfo.isBitcast = IsBitcast;
- InstInfo.hasSideEffects = HasSideEffects;
- InstInfo.Operands.isVariadic = IsVariadic;
-
- // Sanity checks.
- if (InstInfo.isReMaterializable && InstInfo.hasSideEffects)
- throw TGError(InstInfo.TheDef->getLoc(), "The instruction " +
- InstInfo.TheDef->getName() +
- " is rematerializable AND has unmodeled side effects?");
+
+ // 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);
+ InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
+ }
+
+ // 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");
}
}