From bc0b9f70ae072d695e0eb7ceb729b3306b0679fe Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 10 Jan 2008 05:39:30 +0000 Subject: [PATCH] start inferring 'no side effects'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45822 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 2 + utils/TableGen/CodeGenTarget.h | 3 +- utils/TableGen/InstrInfoEmitter.cpp | 111 +++++++++++++------------- utils/TableGen/InstrInfoEmitter.h | 2 +- 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index ee2d6346794..7851b328c70 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -321,6 +321,8 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) { Properties |= 1 << SDNPMayStore; } else if (PropList[i]->getName() == "SDNPMayLoad") { Properties |= 1 << SDNPMayLoad; + } else if (PropList[i]->getName() == "SDNPSideEffect") { + Properties |= 1 << SDNPSideEffect; } else { cerr << "Unknown SD Node property '" << PropList[i]->getName() << "' on node '" << R->getName() << "'!\n"; diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 07407334196..922c2b41a10 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -38,7 +38,8 @@ enum SDNP { SDNPInFlag, SDNPOptInFlag, SDNPMayLoad, - SDNPMayStore + SDNPMayStore, + SDNPSideEffect }; /// getValueType - Return the MVT::ValueType that the specified TableGen record diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index e652fc1c5ab..7f25f3c462c 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -145,20 +145,17 @@ class InstAnalyzer { const CodeGenDAGPatterns &CDP; bool &mayStore; bool &mayLoad; - bool &NeverHasSideEffects; + bool &HasSideEffects; public: InstAnalyzer(const CodeGenDAGPatterns &cdp, - bool &maystore, bool &mayload, bool &nhse) - : CDP(cdp), mayStore(maystore), mayLoad(mayload), NeverHasSideEffects(nhse){ + bool &maystore, bool &mayload, bool &hse) + : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){ } void Analyze(Record *InstRecord) { const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern(); if (Pattern == 0) return; // No pattern. - // Assume there is no side-effect unless we see one. - NeverHasSideEffects = true; - // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. AnalyzeNode(Pattern->getTree(0)); @@ -169,73 +166,85 @@ private: if (N->isLeaf()) return; - if (N->getOperator()->getName() != "set") { - // 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 (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { - // If this is an intrinsic, analyze it. - if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) { - mayStore = true;// Intrinsics that can write to memory are 'mayStore'. - } - - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) - mayLoad = true;// These may also load memory. - } - } - + // 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()); + + // 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; + + 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 &NeverHasSideEffects) { - mayStore = mayLoad = NeverHasSideEffects = false; + bool &MayStore, bool &MayLoad, + bool &HasSideEffects) { + MayStore = MayLoad = HasSideEffects = false; - InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef); + 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) + 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; + 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) + 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; + MayLoad = true; } - - NeverHasSideEffects = Inst.neverHasSideEffects; - -#if 0 - // If the .td file explicitly says there is no side effect, believe it. - if (Inst.neverHasSideEffects) - NeverHasSideEffects = true; -#endif + 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()); + HasSideEffects = false; + } } @@ -299,14 +308,8 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, const OperandInfoMapTy &OpInfo, std::ostream &OS) { // Determine properties of the instruction from its pattern. - bool mayStore, mayLoad, NeverHasSideEffects; - InferFromPattern(Inst, mayStore, mayLoad, NeverHasSideEffects); - - if (NeverHasSideEffects && Inst.mayHaveSideEffects) { - std::cerr << "error: Instruction '" << Inst.TheDef->getName() - << "' is marked with 'mayHaveSideEffects', but it can never have them!\n"; - exit(1); - } + bool mayStore, mayLoad, HasSideEffects; + InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects); int MinOperands = 0; if (!Inst.OperandList.empty()) @@ -341,7 +344,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, OS << "|(1<