aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp148
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h5
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h2
-rw-r--r--utils/TableGen/CodeGenTarget.cpp12
-rw-r--r--utils/TableGen/CodeGenTarget.h4
-rw-r--r--utils/TableGen/DAGISelEmitter.h1
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp137
-rw-r--r--utils/TableGen/InstrInfoEmitter.h6
8 files changed, 163 insertions, 152 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index a570c8f6d2..8c46b35fa1 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -965,7 +965,7 @@ static bool OnlyOnRHSOfCommutative(TreePatternNode *N) {
/// that can never possibly work), and to prevent the pattern permuter from
/// generating stuff that is useless.
bool TreePatternNode::canPatternMatch(std::string &Reason,
- CodeGenDAGPatterns &CDP){
+ const CodeGenDAGPatterns &CDP) {
if (isLeaf()) return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
@@ -1226,6 +1226,11 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
// Generate variants. For example, commutative patterns can match
// multiple ways. Add them to PatternsToMatch as well.
GenerateVariants();
+
+ // Infer instruction flags. For example, we can detect loads,
+ // stores, and side effects in many cases by examining an
+ // instruction's pattern.
+ InferInstructionFlags();
}
CodeGenDAGPatterns::~CodeGenDAGPatterns() {
@@ -1558,6 +1563,131 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
InstImpInputs, InstImpResults);
}
+//===----------------------------------------------------------------------===//
+// Instruction Analysis
+//===----------------------------------------------------------------------===//
+
+class InstAnalyzer {
+ const CodeGenDAGPatterns &CDP;
+ bool &mayStore;
+ bool &mayLoad;
+ bool &HasSideEffects;
+public:
+ InstAnalyzer(const CodeGenDAGPatterns &cdp,
+ bool &maystore, bool &mayload, bool &hse)
+ : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
+ }
+
+ /// 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.
+ }
+
+ // 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 (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)
+ AnalyzeNode(N->getChild(i));
+
+ // Ignore set nodes, which are not SDNodes.
+ if (N->getOperator()->getName() == "set")
+ return;
+
+ // Get information about the SDNode for the operator.
+ const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
+
+ // 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.
+ if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
+ mayLoad = true;// These may load memory.
+
+ if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
+ mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
+
+ if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
+ // WriteMem intrinsics can have other strange effects.
+ HasSideEffects = true;
+ }
+ }
+
+};
+
+static void InferFromPattern(const CodeGenInstruction &Inst,
+ bool &MayStore, bool &MayLoad,
+ bool &HasSideEffects,
+ const CodeGenDAGPatterns &CDP) {
+ MayStore = MayLoad = HasSideEffects = false;
+
+ 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.
+ // If we decided that this is a store from the pattern, then the .td file
+ // entry is redundant.
+ if (MayStore)
+ fprintf(stderr,
+ "Warning: mayStore flag explicitly set on instruction '%s'"
+ " but flag already inferred from pattern.\n",
+ Inst.TheDef->getName().c_str());
+ 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)
+ fprintf(stderr,
+ "Warning: mayLoad flag explicitly set on instruction '%s'"
+ " but flag already inferred from pattern.\n",
+ Inst.TheDef->getName().c_str());
+ MayLoad = true;
+ }
+
+ if (Inst.neverHasSideEffects) {
+ 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;
+ }
+}
+
/// ParseInstructions - Parse all of the instructions, inlining and resolving
/// any fragments involved. This populates the Instructions list with fully
/// resolved instructions.
@@ -1791,6 +1921,22 @@ void CodeGenDAGPatterns::ParseInstructions() {
}
}
+
+void CodeGenDAGPatterns::InferInstructionFlags() {
+ std::map<std::string, CodeGenInstruction> &InstrDescs =
+ Target.getInstructions();
+ for (std::map<std::string, CodeGenInstruction>::iterator
+ II = InstrDescs.begin(), E = InstrDescs.end(); II != E; ++II) {
+ CodeGenInstruction &InstInfo = II->second;
+ // Determine properties of the instruction from its pattern.
+ bool MayStore, MayLoad, HasSideEffects;
+ InferFromPattern(InstInfo, MayStore, MayLoad, HasSideEffects, *this);
+ InstInfo.mayStore = MayStore;
+ InstInfo.mayLoad = MayLoad;
+ InstInfo.hasSideEffects = HasSideEffects;
+ }
+}
+
void CodeGenDAGPatterns::ParsePatterns() {
std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 6000e551ec..0d29eb5165 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -17,7 +17,6 @@
#include <set>
-#include "TableGenBackend.h"
#include "CodeGenTarget.h"
#include "CodeGenIntrinsics.h"
@@ -277,7 +276,7 @@ public: // Higher level manipulation routines.
/// canPatternMatch - If it is impossible for this pattern to match on this
/// target, fill in Reason and return false. Otherwise, return true.
- bool canPatternMatch(std::string &Reason, CodeGenDAGPatterns &CDP);
+ bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
};
@@ -467,6 +466,7 @@ public:
CodeGenDAGPatterns(RecordKeeper &R);
~CodeGenDAGPatterns();
+ CodeGenTarget &getTargetInfo() { return Target; }
const CodeGenTarget &getTargetInfo() const { return Target; }
Record *getSDNodeNamed(const std::string &Name) const;
@@ -556,6 +556,7 @@ private:
void ParseDefaultOperands();
void ParseInstructions();
void ParsePatterns();
+ void InferInstructionFlags();
void GenerateVariants();
void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index 036882c8e0..4515ebcdc6 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -49,7 +49,7 @@ namespace llvm {
// types.
bool isOverloaded;
- CodeGenIntrinsic(Record *R, CodeGenTarget *CGT);
+ CodeGenIntrinsic(Record *R);
};
/// LoadIntrinsics - Read all of the intrinsics defined in the specified
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index da34ebf38e..78d39ee06f 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -394,20 +394,12 @@ std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
std::vector<CodeGenIntrinsic> Result;
- // If we are in the context of a target .td file, get the target info so that
- // we can decode the current intptr_t.
- CodeGenTarget *CGT = 0;
- if (Records.getClass("Target") &&
- Records.getAllDerivedDefinitions("Target").size() == 1)
- CGT = new CodeGenTarget();
-
for (unsigned i = 0, e = I.size(); i != e; ++i)
- Result.push_back(CodeGenIntrinsic(I[i], CGT));
- delete CGT;
+ Result.push_back(CodeGenIntrinsic(I[i]));
return Result;
}
-CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
+CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
TheDef = R;
std::string DefName = R->getName();
ModRef = WriteMem;
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index a14f6303bd..b066b6aa2b 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -145,6 +145,10 @@ public:
if (Instructions.empty()) ReadInstructions();
return Instructions;
}
+ std::map<std::string, CodeGenInstruction> &getInstructions() {
+ if (Instructions.empty()) ReadInstructions();
+ return Instructions;
+ }
CodeGenInstruction &getInstruction(const std::string &Name) const {
const std::map<std::string, CodeGenInstruction> &Insts = getInstructions();
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 534326e926..1b47bcc156 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -14,6 +14,7 @@
#ifndef DAGISEL_EMITTER_H
#define DAGISEL_EMITTER_H
+#include "TableGenBackend.h"
#include "CodeGenDAGPatterns.h"
#include <set>
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index cc03c6aab7..57d72b436e 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -138,131 +138,6 @@ void InstrInfoEmitter::EmitOperandInfo(std::ostream &OS,
}
//===----------------------------------------------------------------------===//
-// Instruction Analysis
-//===----------------------------------------------------------------------===//
-
-class InstAnalyzer {
- const CodeGenDAGPatterns &CDP;
- bool &mayStore;
- bool &mayLoad;
- bool &HasSideEffects;
-public:
- InstAnalyzer(const CodeGenDAGPatterns &cdp,
- bool &maystore, bool &mayload, bool &hse)
- : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
- }
-
- /// 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.
- }
-
- // 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 (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)
- AnalyzeNode(N->getChild(i));
-
- // Ignore set nodes, which are not SDNodes.
- if (N->getOperator()->getName() == "set")
- return;
-
- // Get information about the SDNode for the operator.
- const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
-
- // 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.
- if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
- mayLoad = true;// These may load memory.
-
- if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
- mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
-
- if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
- // WriteMem intrinsics can have other strange effects.
- HasSideEffects = true;
- }
- }
-
-};
-
-void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
- bool &MayStore, bool &MayLoad,
- bool &HasSideEffects) {
- MayStore = MayLoad = HasSideEffects = false;
-
- 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.
- // If we decided that this is a store from the pattern, then the .td file
- // entry is redundant.
- if (MayStore)
- fprintf(stderr,
- "Warning: mayStore flag explicitly set on instruction '%s'"
- " but flag already inferred from pattern.\n",
- Inst.TheDef->getName().c_str());
- 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)
- fprintf(stderr,
- "Warning: mayLoad flag explicitly set on instruction '%s'"
- " but flag already inferred from pattern.\n",
- Inst.TheDef->getName().c_str());
- MayLoad = true;
- }
-
- if (Inst.neverHasSideEffects) {
- 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;
- }
-}
-
-
-//===----------------------------------------------------------------------===//
// Main Output.
//===----------------------------------------------------------------------===//
@@ -273,7 +148,7 @@ void InstrInfoEmitter::run(std::ostream &OS) {
EmitSourceFileHeader("Target Instruction Descriptors", OS);
OS << "namespace llvm {\n\n";
- CodeGenTarget Target;
+ CodeGenTarget &Target = CDP.getTargetInfo();
const std::string &TargetName = Target.getName();
Record *InstrInfo = Target.getInstructionSet();
@@ -321,10 +196,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
std::map<std::vector<Record*>, unsigned> &EmittedLists,
const OperandInfoMapTy &OpInfo,
std::ostream &OS) {
- // Determine properties of the instruction from its pattern.
- bool mayStore, mayLoad, HasSideEffects;
- InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects);
-
int MinOperands = 0;
if (!Inst.OperandList.empty())
// Each logical operand can be multiple MI operands.
@@ -344,8 +215,8 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)";
if (Inst.isCall) OS << "|(1<<TID::Call)";
if (Inst.isSimpleLoad) OS << "|(1<<TID::SimpleLoad)";
- if (mayLoad) OS << "|(1<<TID::MayLoad)";
- if (mayStore) OS << "|(1<<TID::MayStore)";
+ if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)";
+ if (Inst.mayStore) OS << "|(1<<TID::MayStore)";
if (Inst.isPredicable) OS << "|(1<<TID::Predicable)";
if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)";
if (Inst.isCommutable) OS << "|(1<<TID::Commutable)";
@@ -356,7 +227,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
if (Inst.usesCustomDAGSchedInserter)
OS << "|(1<<TID::UsesCustomDAGSchedInserter)";
if (Inst.isVariadic) OS << "|(1<<TID::Variadic)";
- if (HasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)";
+ if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)";
OS << ", 0";
// Emit all of the target-specific flags...
diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h
index 977d3dbaf1..2dd3a0f44f 100644
--- a/utils/TableGen/InstrInfoEmitter.h
+++ b/utils/TableGen/InstrInfoEmitter.h
@@ -29,7 +29,7 @@ class CodeGenInstruction;
class InstrInfoEmitter : public TableGenBackend {
RecordKeeper &Records;
- const CodeGenDAGPatterns CDP;
+ CodeGenDAGPatterns CDP;
std::map<std::string, unsigned> ItinClassMap;
public:
@@ -41,10 +41,6 @@ public:
private:
typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
- // Instruction analysis.
- void InferFromPattern(const CodeGenInstruction &Inst,
- bool &MayStore, bool &MayLoad, bool &HasSideEffects);
-
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,
std::map<std::vector<Record*>, unsigned> &EL,