aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp6
-rw-r--r--utils/TableGen/CodeGenInstruction.h3
-rw-r--r--utils/TableGen/CodeGenTarget.cpp6
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp55
4 files changed, 43 insertions, 27 deletions
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 9778db3..0ee6b41 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -97,14 +97,14 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+ hasSideEffects = R->getValueAsBit("hasSideEffects");
mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
hasOptionalDef = false;
isVariadic = false;
- if (mayHaveSideEffects && neverHasSideEffects)
- throw R->getName() +
- ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!";
+ if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1)
+ throw R->getName() + ": multiple conflicting side-effect flags set!";
DagInit *DI;
try {
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index f3cdbfe..ad076a2 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -103,8 +103,7 @@ namespace llvm {
bool hasCtrlDep;
bool isNotDuplicable;
bool hasOptionalDef;
- bool mayHaveSideEffects;
- bool neverHasSideEffects;
+ bool hasSideEffects, mayHaveSideEffects, neverHasSideEffects;
/// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
/// where $foo is a whole operand and $foo.bar refers to a suboperand.
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 53dbbf8..cf33fe6 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -340,6 +340,12 @@ ComplexPattern::ComplexPattern(Record *R) {
Properties |= 1 << SDNPHasChain;
} else if (PropList[i]->getName() == "SDNPOptInFlag") {
Properties |= 1 << SDNPOptInFlag;
+ } else if (PropList[i]->getName() == "SDNPMayStore") {
+ Properties |= 1 << SDNPMayStore;
+ } else if (PropList[i]->getName() == "SDNPMayLoad") {
+ Properties |= 1 << SDNPMayLoad;
+ } else if (PropList[i]->getName() == "SDNPSideEffect") {
+ Properties |= 1 << SDNPSideEffect;
} else {
cerr << "Unsupported SD Node property '" << PropList[i]->getName()
<< "' on ComplexPattern '" << R->getName() << "'!\n";
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index bcb8be6..ed48c33 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -152,22 +152,36 @@ public:
: CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
}
- void Analyze(Record *InstRecord) {
+ /// 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; // No pattern.
+ return false; // No pattern.
}
// FIXME: Assume only the first tree is the pattern. The others are clobber
// nodes.
AnalyzeNode(Pattern->getTree(0));
+ return true;
}
private:
void AnalyzeNode(const TreePatternNode *N) {
- if (N->isLeaf())
+ if (N->isLeaf()) {
+ if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+ Record *LeafRec = DI->getDef();
+ // Handle ComplexPattern leaves.
+ if (LeafRec->isSubClassOf("ComplexPattern")) {
+ const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
+ if (CP.hasProperty(SDNPMayStore)) mayStore = true;
+ if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
+ if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+ }
+ }
return;
+ }
// Analyze children.
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
@@ -180,17 +194,10 @@ private:
// Get information about the SDNode for the operator.
const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
- // If node writes to memory, it obviously stores to memory.
- if (OpInfo.hasProperty(SDNPMayStore))
- mayStore = true;
-
- // If it reads memory, remember this.
- if (OpInfo.hasProperty(SDNPMayLoad))
- mayLoad = true;
-
- // If it reads memory, remember this.
- if (OpInfo.hasProperty(SDNPSideEffect))
- HasSideEffects = true;
+ // Notice properties of the node.
+ if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
+ if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
+ if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
// If this is an intrinsic, analyze it.
@@ -213,7 +220,8 @@ void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
bool &HasSideEffects) {
MayStore = MayLoad = HasSideEffects = false;
- InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
+ bool HadPattern =
+ InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
// InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
@@ -239,15 +247,18 @@ void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
}
if (Inst.neverHasSideEffects) {
- // If we already decided that this instruction has no side effects, then the
- // .td file entry is redundant.
- if (!HasSideEffects)
- fprintf(stderr,
- "Warning: neverHasSideEffects flag explicitly set on instruction"
- " '%s' but flag already inferred from pattern.\n",
- Inst.TheDef->getName().c_str());
+ if (HadPattern)
+ fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
+ "which already has a pattern\n", Inst.TheDef->getName().c_str());
HasSideEffects = false;
}
+
+ if (Inst.hasSideEffects) {
+ if (HasSideEffects)
+ fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
+ "which already inferred this.\n", Inst.TheDef->getName().c_str());
+ HasSideEffects = true;
+ }
}