diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-10 07:59:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-10 07:59:24 +0000 |
commit | ba7e756c22446a17a72632b8d4ac66cbdaab33f7 (patch) | |
tree | 35b58e8e83a49bdd3f3449e138228e57cacb0b77 /utils/TableGen | |
parent | 1778a1590125dbef01b8d85128a11b6fb212b26f (diff) | |
download | external_llvm-ba7e756c22446a17a72632b8d4ac66cbdaab33f7.zip external_llvm-ba7e756c22446a17a72632b8d4ac66cbdaab33f7.tar.gz external_llvm-ba7e756c22446a17a72632b8d4ac66cbdaab33f7.tar.bz2 |
Start inferring side effect information more aggressively, and fix many bugs in the
x86 backend where instructions were not marked maystore/mayload, and perf issues where
instructions were not marked neverHasSideEffects. It would be really nice if we could
write patterns for copy instructions.
I have audited all the x86 instructions down to MOVDQAmr. The flags on others and on
other targets are probably not right in all cases, but no clients currently use this
info that are enabled by default.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45829 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.h | 3 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 55 |
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; + } } |