diff options
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 148 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 5 | ||||
-rw-r--r-- | utils/TableGen/CodeGenIntrinsics.h | 2 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 12 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.h | 4 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.h | 1 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 137 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.h | 6 |
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, |